sys_open() doesn't meaningfully respect the O_ASYNC flag -- the resulting
fd/filp has the flag set, but f_op->fasync() is not invoked. Worse yet,
fcntl()/ioctl() only call f_op->fasync() if FASYNC changes, so one must
presently undo and then redo the O_ASYNC before it works.
This contradicts fcntl(2)'s explicit remarks under the F_SETOWN section. (Man
page is excerpting glibc manual.) Behavior can be seen with ttys open()d
O_ASYNC or, as I noticed it, with a FIFO using Jeremy Elson's excellent
pipe-fasync patch on 2.4.14 (hope to see that in 2.5!). [1]
Two tempting corrections:
A. open() implies FASYNCery
(fasync() called if defined)
B. open() unconditionally clears O_ASYNC
(FASYNC must be manually F_SETFL'd/FIOASYNC'd)
Obviously A follows the man page and common sense. Jeremy was kind enough to
do some preliminary investigation of modifying sys_open() to accomplish this,
noting that f_op->release would have to be called if fasync failed [2] (and
that this might pose some subtle difficulties).
OTOH, B is simple and agreeable. Sockets and (even patched) unnamed pipes
don't have the luxury of an atomic O_ASYNC upon initialization AFAIK.
Further, the merit of fasync() alongside open() is debatable -- one still must
separately F_SETOWN before signals start rolling in.
Time to solicit more input. Are there serious implementation barriers to A?
Are there better alternatives to A and B that correct the obstinate O_ASYNC
flag upon open() problem?
Pls. CC me in any replies.
Regards,
Mike
Notes:
[1] Jeremy Elson: "[PATCH] SIGIO for FIFOs (fs/pipe.c, kernel 2.4.x)"
http://marc.theaimsgroup.com/?l=linux-kernel&m=99803716129556&w=2
[2] open() could return the fd and unset O_ASYNC on f_op->fasync failure,
but that's rather awkward -- little better than manual fcntl()ing.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/