Cannot switch to lock mode using fcntl on linux

I have an example program:

int main()
{
   const char* fn = "/tmp/tmpfifo";
   int i = mkfifo(fn, 0666);
   int fd = open(fn, O_RDONLY | O_NONBLOCK);
   int flags = fcntl(fd, F_GETFL);
   flags &= ~O_NONBLOCK;
   fcntl(fd, F_SETFL, flags);

   char buf[1024];
   int rd= read(fd, buf, 100);
   cout << rd << endl;
   remove(fn);
   return 0;
}

It seems that after removing the flag without blocking from the file descriptor, the call readshould be blocked until something is written to FIFO, but my program always works without blocking and the rd=0result. Could you explain this behavior? Thank!

+4
source share
3 answers

The behavior you see is expected. You have done the following:

  • He opened the end of FIFO reading with the help O_NONBLOCKthat the writer was not present in FIFO. This ensures that open()it succeeds immediately.
  • O_NONBLOCK . , () , FIFO , FIFO. , .
+2

! , O_NONBLOCK, 3 . 3- , O_NONBLOCK reset!

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

int main()
{
   char buf[1024];
   int rd;
   const char* fn = "prova.txt";
   int i = mkfifo(fn, 0666);
   int fd = open(fn, O_RDONLY); // | O_NONBLOCK);
   int flags = fcntl(fd, F_GETFL);
   //flags &= ~O_NONBLOCK;
   printf("1) Waits!\t\tflags=0%08o\n",flags);

   rd= read(fd, buf, 100);
   printf("%d %o\n",rd,flags);

   flags |= O_NONBLOCK;
   printf("2) Doesn't wait!\tflags=0%08o\n",flags);
   fcntl(fd, F_SETFL, flags);
   rd= read(fd, buf, 100);
   printf("%d %o\n",rd,flags);  

   //This doen't act the flag ????
   flags &= ~O_NONBLOCK;
   fcntl(fd, F_SETFL, flags);
   flags=fcntl(fd, F_GETFL);
   printf("3) Waits!\t\tflags=0%08o\n",flags);
   rd= read(fd, buf, 100);
   printf("%d %o\n",rd,flags);

   puts("End!");
   return 0;
}

:

sergio@zarathustra:~$ ./a.out &
[2] 6555
sergio@zarathustra:~$ echo xxx >> prova.txt
1) Waits!       flags=000100000
4 100000
2) Doesn't wait!    flags=000104000
0 104000
3) Waits!       flags=000100000
0 100000
End!
sergio@zarathustra:~$ 
0

, . , , , , .

, read, , :

ftrace

pipe_read - . , EOF.

, , -, , open , , open , , . . read , ( ), .

If you want to wait for the writer to open the channel, do not use O_NONBLOCKin a call open. If you use O_NONBLOCKin open, then on the other end of the channel there may not be anyone, and calls readcan simply return EOF without blocking.

So, briefly make sure that someone is at the other end of the pipe when you read it.

0
source

All Articles