diff options
author | des <des@FreeBSD.org> | 2007-05-10 14:52:57 +0000 |
---|---|---|
committer | des <des@FreeBSD.org> | 2007-05-10 14:52:57 +0000 |
commit | 50d71f5464b9302c59bba4260b8b48f2ebef7142 (patch) | |
tree | f0b7fc85fde1f8d40a730e691489335d8a05a91e /lib | |
parent | 5d25ea6b6214552539112dbc8d1bdc8f79460dd6 (diff) | |
download | FreeBSD-src-50d71f5464b9302c59bba4260b8b48f2ebef7142.zip FreeBSD-src-50d71f5464b9302c59bba4260b8b48f2ebef7142.tar.gz |
DTRT when O_NONBLOCK is specified.
MFC after: 3 weeks
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libutil/flopen.3 | 22 | ||||
-rw-r--r-- | lib/libutil/flopen.c | 11 |
2 files changed, 29 insertions, 4 deletions
diff --git a/lib/libutil/flopen.3 b/lib/libutil/flopen.3 index 53a2132..0e5fbada 100644 --- a/lib/libutil/flopen.3 +++ b/lib/libutil/flopen.3 @@ -60,6 +60,17 @@ Thus, it is well suited for opening lock files, PID files, spool files, mailboxes and other kinds of files which are used for synchronization between processes. .Pp +If +.Va flags +includes +.Dv O_NONBLOCK +and the file is already locked, +.Fn flopen +will fail and set +.Va errno +to +.Dv EWOULDBLOCK . +.Pp As with .Fn flopen , the additional @@ -68,7 +79,18 @@ argument is required if .Va flags includes .Dv O_CREAT . +.Sh RETURN VALUES +If successful, +.Fn flopen +returns a valid file descriptor. +Otherwise, it returns -1, and sets +.Va errno +as described in +.Xr flock 2 +and +.Xr open 2 . .Sh SEE ALSO +.Xr errno 2 , .Xr flock 2 , .Xr open 2 .Sh AUTHORS diff --git a/lib/libutil/flopen.c b/lib/libutil/flopen.c index 66d4e47..39cb81f 100644 --- a/lib/libutil/flopen.c +++ b/lib/libutil/flopen.c @@ -39,29 +39,32 @@ __FBSDID("$FreeBSD$"); int flopen(const char *path, int flags, ...) { + int fd, operation, serrno; struct stat sb, fsb; mode_t mode; - int fd, serrno; #ifdef O_EXLOCK flags &= ~O_EXLOCK; #endif + mode = 0; if (flags & O_CREAT) { va_list ap; va_start(ap, flags); mode = va_arg(ap, int); /* mode_t promoted to int */ va_end(ap); - } else { - mode = 0; } + operation = LOCK_EX; + if (flags & O_NONBLOCK) + operation |= LOCK_NB; + for (;;) { if ((fd = open(path, flags, mode)) == -1) /* non-existent or no access */ return (-1); - if (flock(fd, LOCK_EX) == -1) { + if (flock(fd, operation) == -1) { /* unsupported or interrupted */ serrno = errno; close(fd); |