Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: changed stat-open-fstat to open/nonblock-fstat-fcntl

...

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_RDONLY or O_WRONLY set: If O_NONBLOCK is 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.
If O_NONBLOCK is 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:
If O_NONBLOCK is set:
  The open() function will return without blocking for the device to be ready or available. Subsequent behaviour of the device is device-specific.
If O_NONBLOCK is clear:
  The open() function will block the calling thread until the device is ready or available before returning.

Otherwise, the behaviour of O_NONBLOCK is 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
bgColor#ccccff
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 */

...