DTRT when O_NONBLOCK is specified.

MFC after:	3 weeks
This commit is contained in:
Dag-Erling Smørgrav 2007-05-10 14:52:57 +00:00
parent 9667055264
commit 3dea593400
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=169447
2 changed files with 29 additions and 4 deletions

View File

@ -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

View File

@ -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);