Index: lib/libutil/flopen.3 =================================================================== --- lib/libutil/flopen.3 +++ lib/libutil/flopen.3 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd July 28, 2017 +.Dd March 19, 2021 .Dt FLOPEN 3 .Os .Sh NAME @@ -49,21 +49,12 @@ The .Fn flopen function opens or creates a file and acquires an exclusive lock on it. -It is essentially equivalent with calling +It is equivalent to .Fn open -with the same parameters followed by -.Fn flock -with an -.Fa operation +with the +.Fa flags argument of -.Dv LOCK_EX , -except that -.Fn flopen -will attempt to detect and handle races that may occur between opening -/ creating the file and locking it. -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. +.Dv O_EXLOCK . .Pp If .Fa flags Index: lib/libutil/flopen.c =================================================================== --- lib/libutil/flopen.c +++ lib/libutil/flopen.c @@ -39,87 +39,19 @@ #include -/* - * Reliably open and lock a file. - * - * Please do not modify this code without first reading the revision history - * and discussing your changes with . Don't be fooled by the - * code's apparent simplicity; there would be no need for this function if it - * was easy to get right. - */ static int vflopenat(int dirfd, const char *path, int flags, va_list ap) { - int fd, operation, serrno, trunc; - struct stat sb, fsb; mode_t mode; -#ifdef O_EXLOCK - flags &= ~O_EXLOCK; -#endif - mode = 0; if (flags & O_CREAT) { mode = (mode_t)va_arg(ap, int); /* mode_t promoted to int */ } - operation = LOCK_EX; - if (flags & O_NONBLOCK) - operation |= LOCK_NB; - - trunc = (flags & O_TRUNC); - flags &= ~O_TRUNC; - - for (;;) { - if ((fd = openat(dirfd, path, flags, mode)) == -1) - /* non-existent or no access */ - return (-1); - if (flock(fd, operation) == -1) { - /* unsupported or interrupted */ - serrno = errno; - (void)close(fd); - errno = serrno; - return (-1); - } - if (fstatat(dirfd, path, &sb, 0) == -1) { - /* disappeared from under our feet */ - (void)close(fd); - continue; - } - if (fstat(fd, &fsb) == -1) { - /* can't happen [tm] */ - serrno = errno; - (void)close(fd); - errno = serrno; - return (-1); - } - if (sb.st_dev != fsb.st_dev || - sb.st_ino != fsb.st_ino) { - /* changed under our feet */ - (void)close(fd); - continue; - } - if (trunc && ftruncate(fd, 0) != 0) { - /* can't happen [tm] */ - serrno = errno; - (void)close(fd); - errno = serrno; - return (-1); - } - /* - * The following change is provided as a specific example to - * avoid. - */ -#if 0 - if (fcntl(fd, F_SETFD, FD_CLOEXEC) != 0) { - serrno = errno; - (void)close(fd); - errno = serrno; - return (-1); - } -#endif - return (fd); - } + flags &= ~O_SHLOCK; + flags |= O_EXLOCK; + return (openat(dirfd, path, flags, mode)); } int