开发者

Why does the pipe write end accepts one byte and after that fails with error EBADF?

开发者 https://www.devze.com 2023-02-03 01:24 出处:网络
I have a problem with my program, which is using IPC message queue. Althought IPC works fine, there is an issue with pipe, which I wasn\'t able to resolve yet. This is the code of subprocess of my pro

I have a problem with my program, which is using IPC message queue. Althought IPC works fine, there is an issue with pipe, which I wasn't able to resolve yet. This is the code of subprocess of my program. It reads one byte from a file and then is supposed to write it to a 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;
   开发者_C百科  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;
  }

This is the code of the parent process, which should read from this pipe when the child process finishes (and then write it to fifo, but now it's not important).

 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);

When I test it, first byte goes into the pipe, but every next byte makes write() return -1 and set error to EBADF.

Have you got a clue about what is going on there? Thanks in advance, Nebril


You are closing the pipe after one write. As I understand it there is no getting it back once it is closed. Subsequent writes to that file descriptor (which I don't actually see anywhere in your code) will set the error "bad file" because the pipe no longer exists.


Your problem is likely here:

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

You are exiting your loop when r < BUF_SIZE, but after you read one byte, r == 1. Instead, try:

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

That will break and exit when your server can no longer write to outfifo.


Your code appears to close the pipe after writing one byte. I don't see any looping.

Your reader looks a little odd also.


I started beeing desperate and I did some random things. One actually worked! I threw every close(comPipe[1]); call away and now it's alive! Thanks for help guys :). Still no idea why did it behave like that, but maybe it will help someone... sometime :D

0

精彩评论

暂无评论...
验证码 换一张
取 消