2013-06-23 3 views
1

Я пытаюсь узнать трубы, и я пытаюсь эту программу:трубы и от дочернего процесса не работает

#include<stdio.h> 
#include<string.h> 
#include<unistd.h> 
#include<errno.h> 
#include<sys/types.h> 
#include<fcntl.h> 

#define MAXLINE 100 
void main(){ 

int pipe1[2],pipe2[2]; 
pid_t childpid; 
if(pipe(pipe1)<0){ 
      perror("Unable to create the pipe for pipe1"); 
      exit(-1); 
    } 
    if(pipe(pipe2)<0){ 
      perror("Unable to create the pipe for pipe1"); 
      exit(-1); 
    } 
    childpid=fork(); 
    printf("The child PID is:%d\n",childpid); 
    if(childpid==0){ 
      printf("In the child process"); 
      close(pipe1[1]); 
      close(pipe2[0]); 
      server(pipe1[0],pipe2[1]); 
      exit(0); 
    } 

    close(pipe1[0]); 
    close(pipe2[1]); 

    client(pipe2[0],pipe1[1]); 
    waitpid(childpid,NULL,0); 
    exit(0); 
} 

void client(int readfd,int writefd){ 

    int n,len; 
    char buff[MAXLINE]; 
    printf("Please enter the name of the file to be read:"); 
    fgets(buff,MAXLINE,stdin); 
    len=strlen(buff); 
    if(buff[len-1]=='\n') 
      len--; 

    write(writefd,buff,len); 
    printf("File name written into the pipe\n"); 
    printf("The num of bytes written are:\n",read(readfd,buff,MAXLINE)); 
    while((n-read(readfd,buff,MAXLINE))>0){ 
      printf("Trying to read the content\n"); 
      write(STDOUT_FILENO,buff,n); 
    } 
} 

void server(int readfd,int writefd){ 

    int fd,n; 
    char buff[MAXLINE + 1]; 
    write(writefd,"Yello in the server process",strlen("Yello in the server process")); 

    if((n=read(readfd,buff,MAXLINE))==0) 
      perror("End of file while reading"); 
    buff[n]='\0'; 
    if((fd=fopen(buff,O_RDONLY))<0){ 
      snprintf(buff+n,sizeof(buff)-n,"Can't open, %s",strerror(errno)); 
      n=strlen(buff); 
      write(writefd,buff,n); 
    } 
    while((n=read(fd,buff,MAXLINE))>0){ 
      write(writefd,buff,n); 
      close(fd); 
    } 
} 

Проблема, я введите имя файла и программа просто выходит. Я попытался выполнить дочерний процесс gdb, установив «дочерний режим« follow-fork-mode », и до сих пор ничего не происходит. Любые идеи относительно того, где я могу ошибиться?

Хорошо, еще одна дополнительная информация об отладке: Я установил режим follow-fork в child.and он вызывает ошибку сегментации при открытии файла.

Программный сигнал SIGSEGV, ошибка сегментации. [Переключение на обработку 28025] в _IO_file_fopen() 0x00197f08 из /lib/libc.so.6

+0

Прежде всего, ваша программа не содержит необходимых включать i.e. '#include '. – 0decimal0

+0

Вы скопировали и вставили свои сообщения об ошибках, поэтому, если вам не удалось создать 'pipe2', вам будет интересно узнать, почему' pipe1' не удалось.Возвращаемым типом 'main()' является 'int', а не' void'. Не забудьте завершить сообщения с помощью новой строки; они не появятся до вывода новой строки. –

+0

@ user1295872 В какой системе вы работаете? – 0decimal0

ответ

1

Этот код в client() выглядит подозрительно:

while((n-read(readfd,buff,MAXLINE))>0){ 

Конечно, это должно быть:

while ((n = read(readfd, buff, MAXLINE)) > 0) 
{ 

Изменения, произошедшие от - до =, являются важными, конечно; остальное - косметическое (и одно даже противоречиво).


Вы также должны обратить внимание на предупреждения компилятора. С учетом:

int fd,n; 
... 
if((fd=fopen(buff,O_RDONLY))<0){ 

Невозможно компилировать его без серьезных предупреждений; fopen() возвращает FILE *, а не дескриптор файла (int).


У вас также есть некоторые странные сообщения. Сервер отправляет сообщение клиенту перед чтением имени файла с клиента. Клиент, OTOH, не обязательно читает это сообщение отдельно; он получает информацию и сообщает, сколько у нее байтов. Это может включать в себя часть файла, а также вводное сообщение.


Вы не должны закрывать файл в цикле, который считывает данные из него:

while((n=read(fd,buff,MAXLINE))>0){ 
     write(writefd,buff,n); 
     close(fd); 
} 

Закрытие должно быть вне цикла.


Этот код более-менее работает; это грязнее, чем хотелось бы, но он работает более или менее.

#include <errno.h> 
#include <fcntl.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <unistd.h> 

#define MAXLINE 100 

static void server(int readfd, int writefd); 
static void client(int readfd, int writefd); 

int main(void) 
{ 
    int pipe1[2], pipe2[2]; 
    pid_t childpid; 
    if (pipe(pipe1)<0) 
    { 
     perror("Unable to create the pipe for pipe1"); 
     exit(-1); 
    } 
    if (pipe(pipe2)<0) 
    { 
     perror("Unable to create the pipe for pipe2"); 
     exit(-1); 
    } 
    childpid = fork(); 
    printf("The child PID is:%d\n", childpid); 
    if (childpid == 0) 
    { 
     printf("In the child process\n"); 
     close(pipe1[1]); 
     close(pipe2[0]); 
     server(pipe1[0], pipe2[1]); 
     exit(0); 
    } 

    close(pipe1[0]); 
    close(pipe2[1]); 

    client(pipe2[0], pipe1[1]); 
    waitpid(childpid, NULL, 0); 
    return 0; 
} 

static void client(int readfd, int writefd) 
{ 
    int n, len; 
    char buff[MAXLINE]; 
    printf("Please enter the name of the file to be read:"); 
    fgets(buff, MAXLINE, stdin); 
    len = strlen(buff); 
    if (buff[len-1]=='\n') 
      len--; 

    write(writefd, buff, len); 
    printf("File name (%.*s) written into the pipe\n", len, buff); 
    printf("The num of bytes written are: %d\n", (int)read(readfd, buff, MAXLINE)); 
    while ((n = read(readfd, buff, MAXLINE)) > 0) 
    { 
      printf("Trying to read the content\n"); 
      write(STDOUT_FILENO, buff, n); 
    } 
} 

static void server(int readfd, int writefd) 
{ 
    int fd, n; 
    char buff[MAXLINE + 1]; 

    fprintf(stderr, "Server: %d\n", (int)getpid()); 
    write(writefd, "Yello in the server process", strlen("Yello in the server process")); 

    if ((n = read(readfd, buff, MAXLINE))==0) 
     perror("End of file while reading"); 
    buff[n] = '\0'; 
    if ((fd = open(buff, O_RDONLY)) < 0) 
    { 
      snprintf(buff+n, sizeof(buff)-n, "Can't open, %s", strerror(errno)); 
      n = strlen(buff); 
      write(writefd, buff, n); 
    } 
    else 
    { 
     while ((n = read(fd, buff, MAXLINE)) > 0) 
     { 
      if (write(writefd, buff, n) != n) 
      { 
       fprintf(stderr, "Write failed in server\n"); 
       break; 
      } 
     } 
     close(fd); 
    } 
} 

Обратите внимание, что код не пытается использовать дескриптор файла, который он не может открыть. Это не сбой; проблема n-read(...) является одной из основных проблем, несмотря на комментарии. Еще одна значительная часть проблемы - неправильное использование fopen() для open().

+0

Я думаю, OP также должен описать, в какой системе он работает? Разве это не важно, так как мы работаем над созданием процессов, поэтому вопрос все еще не очень ясен. – 0decimal0

+1

С упоминанием '/ lib/libc.so.6', это система на основе Unix (и, скорее всего, система на базе Linux); это действительно не имеет значения, какой из них ... для целей этой программы они все одинаковые. –

Смежные вопросы