Почему конец записи канала принимает один байт, и после этого происходит сбой с ошибкой EBADF? - PullRequest
1 голос
/ 05 января 2011

У меня проблема с моей программой, которая использует очередь сообщений IPC.Несмотря на то, что IPC работает нормально, есть проблема с pipe, которую я пока не смог решить.Это код подпроцесса моей программы.Он читает один байт из файла и затем должен записать его в канал.

char buf;
  int r;
  r = read(fileR, &buf, 1);
  if(r == 0){//file is empty
   cout<<"Empty"<<endl;
   lseek(fileR, 0, SEEK_SET);
   msgbuf.mtype = subProcessCount+1;
   msgbuf.mtext[0] = whichPid;
   sendAndCheck(queue, 3);
  }else{
   //cout<<whichPid<<" writing "<<buf<<" to pipe"<<endl;
   cout<<"Closing pipe[0]"<<endl;
   close(comPipe[0]);
   if(write(comPipe[1], &buf, 1) == -1){
    switch(errno){
     case EACCES: cout<<"EACCESS"; break;
     case EIDRM: cout<<"EIDRM"; break;
     case ENOENT: cout<<"ENOENT"; break;
     case ENOMEM: cout<<"ENOMEM"; break;
     case ENOSPC: cout<<"ENOSPC"; break;
     case EFAULT: cout<<"EFAULT"; break;
     case EINTR: cout<<"EINTR"; break;
     case EINVAL: cout<<"EINVAL"; break;
     case EPIPE: cout<<"EPIPE"; break;
     case EAGAIN: cout<<"EAGAIN"; break;
     case EBADF: cout<<"EBADF"; break;
     case EFBIG: cout<<"EFBIG"; break;
     case EIO: cout<<"EIO"; break;
     default: cout<<"writefail"<<endl; break;
    }
   }else{
    cout<<"written";
   }
   close(comPipe[1]);
   cout<<"Closing pipe[1]"<<endl;
  }

Это код родительского процесса, который должен читать из этого канала после завершения дочернего процесса (а затемзапишите его в fifo, но теперь это не важно).

 close(comPipe[1]);   
 cout<<"Closing pipe[1]"<<endl;
 outfifo = open(pathBuf.mtext, O_WRONLY );
while(1){
r = read(comPipe[0], &buffer, BUF_SIZE);
cout<<"Buffer size: "<<r<<endl;
write(outfifo, &buffer, r);
if(r < BUF_SIZE){
  break;
 }
}
close(comPipe[0]);
cout<<"Closing pipe[0]"<<endl;
close(outfifo);

Когда я проверяю его, первый байт попадает в канал, но каждый следующий байт заставляет write () возвращать -1 и устанавливать ошибку в EBADF.

У вас есть подсказка о том, что там происходит?Заранее спасибо, Небриль

Ответы [ 4 ]

2 голосов
/ 05 января 2011

Вы закрываете канал после одной записи. Насколько я понимаю, вернуть его нельзя, как только он закроется. Последующие записи в этот файловый дескриптор (который я на самом деле нигде не вижу в вашем коде) установит ошибку «плохой файл», потому что канал больше не существует.

0 голосов
/ 05 января 2011

Я начал отчаяться и сделал несколько случайных вещей. Один на самом деле работал! Я бросил каждый close(comPipe[1]); звонок, и теперь он жив! Спасибо за помощь, ребята :). До сих пор не знаю, почему он так себя ведет, но, может быть, он кому-нибудь поможет ... когда-нибудь

0 голосов
/ 05 января 2011

Ваш код, по-видимому, закрывает канал после записи одного байта.Я не вижу петель.

Ваш читатель тоже выглядит немного странно.

0 голосов
/ 05 января 2011

Ваша проблема, вероятно, здесь:

r = read(comPipe[0], &buffer, BUF_SIZE);
cout<<"Buffer size: "<<r<<endl;  
write(outfifo, &buffer, r);
if(r < BUF_SIZE){ 

Вы выходите из цикла, когда r < BUF_SIZE, но после чтения одного байта, r == 1.Вместо этого попробуйте:

written = write(outfifo, &buffer, r);
if (written < r) {

Это сломается и завершится, когда ваш сервер больше не сможет писать в outfifo.

...