...
Compliant Solution (POSIX)
POSIX defines the O_NONBLOCK flag to open() which will ensure that delayed operations on the file do not hang the program.
When opening a FIFO with
O_RDONLYorO_WRONLYset: IfO_NONBLOCKis set:
An open() for reading only will return without delay. An open() for writing only will return an error if no process currently has the file open for reading.
IfO_NONBLOCKis clear:
An open() for reading only will block the calling thread until a thread opens the file for writing. An open() for writing only will block the calling thread until a thread opens the file for reading.When opening a block special or character special file that supports non-blocking opens:
IfO_NONBLOCKis set:
The open() function will return without blocking for the device to be ready or available. Subsequent behaviour of the device is device-specific.
IfO_NONBLOCKis clear:
The open() function will block the calling thread until the device is ready or available before returning.Otherwise, the behaviour of
O_NONBLOCKis unspecified.
Once the file is open, programmers Programmers can use the POSIX statfstat() function to obtain information about a named file, and the S_ISREG() macro to determine if the file is a regular file. Additionally,
Since the behavior of O_NONBLOCK flag to open() will ensure that delayed operations on the file do not hang the program on subsequent calls to read() or write() is unspecified, it is advisable to disable the flag once we are sure the file in question is not a special device.
| Code Block | ||
|---|---|---|
| ||
struct stat prestat_sinfo; struct stat post_sint fildes; int fildesflags; if (!fgets(filename, sizeof(filename), stdin)) { /* handle error */ } if ((statfildes = open(filename, O_NONBLOCK, O_WRONLY)) == &pre_s-1) { /* handle error */ } if ((fstat(fildes, &stat_info) != 0) || (!S_ISREG(prestat_sinfo.st_mode))) { /* handle error */ } /* dueOptional: todrop athe raceO_NONBLOCK conditionnow here,that we are sure willthis verifyis witha fstatgood laterfile */ if ((fildesflags = openfcntl(filenamefildes, O_NONBLOCK, O_WRONLYF_GETFL)) == -1) { /* handle error */ } if (fstat(fcntl(fildes, &post_s) != 0) { /* handle error */ } if(!(pre_s.st_mode == post_s.st_mode && pre_s.st_ino == post_s.st_ino && pre_s.st_dev == post_s.st_dev)F_SETFL, flags & ~O_NONBLOCK) != 0) { /* handle error */ } /* operate on file */ |
...