Commit 71f70795 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Resync vfl.c with FreeBSD's flopen.c

parent c316df77
...@@ -32,6 +32,5 @@ ...@@ -32,6 +32,5 @@
#define VFL_H_INCLUDED #define VFL_H_INCLUDED
int VFL_Open(const char *, int, ...); int VFL_Open(const char *, int, ...);
int VFL_Test(int fd, pid_t *pid);
#endif #endif
/*- /*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2007-2009 Dag-Erling Coïdan Smørgrav * Copyright (c) 2007-2009 Dag-Erling Coïdan Smørgrav
* All rights reserved. * All rights reserved.
* *
...@@ -24,7 +26,7 @@ ...@@ -24,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* Derived from: * Derived from:
* $FreeBSD: head/lib/libutil/flopen.c 309344 2016-12-01 02:21:36Z cem $ * $FreeBSD: head/lib/libutil/flopen.c 326219 2017-11-26 02:00:33Z pfg $
*/ */
#include "config.h" #include "config.h"
...@@ -48,8 +50,8 @@ ...@@ -48,8 +50,8 @@
* code's apparent simplicity; there would be no need for this function if it * code's apparent simplicity; there would be no need for this function if it
* was easy to get right. * was easy to get right.
*/ */
int static int
VFL_Open(const char *path, int flags, ...) vflopenat(int dirfd, const char *path, int flags, va_list ap)
{ {
int fd, operation, serrno, trunc; int fd, operation, serrno, trunc;
struct stat sb, fsb; struct stat sb, fsb;
...@@ -61,11 +63,7 @@ VFL_Open(const char *path, int flags, ...) ...@@ -61,11 +63,7 @@ VFL_Open(const char *path, int flags, ...)
mode = 0; mode = 0;
if (flags & O_CREAT) { if (flags & O_CREAT) {
va_list ap;
va_start(ap, flags);
mode = (mode_t)va_arg(ap, int); /* mode_t promoted to int */ mode = (mode_t)va_arg(ap, int); /* mode_t promoted to int */
va_end(ap);
} }
operation = LOCK_EX; operation = LOCK_EX;
...@@ -76,7 +74,7 @@ VFL_Open(const char *path, int flags, ...) ...@@ -76,7 +74,7 @@ VFL_Open(const char *path, int flags, ...)
flags &= ~O_TRUNC; flags &= ~O_TRUNC;
for (;;) { for (;;) {
if ((fd = open(path, flags, mode)) == -1) if ((fd = openat(dirfd, path, flags, mode)) == -1)
/* non-existent or no access */ /* non-existent or no access */
return (-1); return (-1);
if (flock(fd, operation) == -1) { if (flock(fd, operation) == -1) {
...@@ -86,7 +84,7 @@ VFL_Open(const char *path, int flags, ...) ...@@ -86,7 +84,7 @@ VFL_Open(const char *path, int flags, ...)
errno = serrno; errno = serrno;
return (-1); return (-1);
} }
if (stat(path, &sb) == -1) { if (fstatat(dirfd, path, &sb, 0) == -1) {
/* disappeared from under our feet */ /* disappeared from under our feet */
(void)close(fd); (void)close(fd);
continue; continue;
...@@ -127,26 +125,14 @@ VFL_Open(const char *path, int flags, ...) ...@@ -127,26 +125,14 @@ VFL_Open(const char *path, int flags, ...)
} }
} }
/* Tests if the given fd is locked through flopen
* If pid is non-NULL, stores the pid of the process holding the lock there
* Returns 1 if the file is locked
* Returns 0 if the file is unlocked
* Returns -1 on error (and errno)
*/
int int
VFL_Test(int fd, pid_t *pid) VFL_Open(const char *path, int flags, ...)
{ {
struct flock lock; va_list ap;
int ret;
memset(&lock, 0, sizeof lock);
lock.l_type = F_WRLCK;
lock.l_whence = SEEK_SET;
if (fcntl(fd, F_GETLK, &lock) == -1) va_start(ap, flags);
return (-1); ret = vflopenat(AT_FDCWD, path, flags, ap);
if (lock.l_type == F_UNLCK) va_end(ap);
return (0); return (ret);
if (pid != NULL)
*pid = lock.l_pid;
return (1);
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment