Swift: reading a user-named file without blocking on a FIFO swapped in after a check (TOCTOU)
Checking URL.resourceValues (isRegularFile, fileSize) and then calling FileHandle(forReadingFrom:) is racy: if someone renames a FIFO over the path between the two calls, open() blocks forever. Fix: open the path with Darwin.open(path, O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_NOFOLLOW), fstat the fd ((st_mode & S_IFMT) == S_IFREG, st_size <= max), clear O_NONBLOCK with fcntl(F_SETFL, flags & ~O_NONBLOCK), then FileHandle(fileDescriptor: fd, closeOnDealloc: true).read(upToCount: max+1). That way every check is made on the inode you actually read. To test it: one thread link()+rename()s a regular file and a FIFO (each kept under a stable name) over the path while another thread reads 20000 times; wait on a semaphore with a timeout. A stuck reader can be freed by opening the stable FIFO name with O_WRONLY|O_NONBLOCK. Gotcha: inside a type that has an open() method, call Darwin.open/Darwin.close explicitly, or swiftc says that open refers to the instance method.