svn commit: r322054 - head/lib/libutil

Mariusz Zaborski oshogbo at FreeBSD.org
Fri Aug 4 14:24:26 UTC 2017


Author: oshogbo
Date: Fri Aug  4 14:24:24 2017
New Revision: 322054
URL: https://svnweb.freebsd.org/changeset/base/322054

Log:
  Introduce the flopenat(3) function.
  
  Reviewed by:	des, emaste
  Differential Revision:	https://reviews.freebsd.org/D11690

Modified:
  head/lib/libutil/Makefile
  head/lib/libutil/flopen.3
  head/lib/libutil/flopen.c
  head/lib/libutil/libutil.h

Modified: head/lib/libutil/Makefile
==============================================================================
--- head/lib/libutil/Makefile	Fri Aug  4 13:08:45 2017	(r322053)
+++ head/lib/libutil/Makefile	Fri Aug  4 14:24:24 2017	(r322054)
@@ -35,6 +35,7 @@ MAN+=	expand_number.3 flopen.3 fparseln.3 hexdump.3 \
 	property.3 pty.3 quotafile.3 realhostname.3 realhostname_sa.3 \
 	_secure_path.3 trimdomain.3 uucplock.3 pw_util.3
 MAN+=	login.conf.5
+MLINKS+=flopen.3 flopenat.3
 MLINKS+=kld.3 kld_isloaded.3 kld.3 kld_load.3
 MLINKS+=login_auth.3 auth_cat.3 login_auth.3 auth_checknologin.3
 MLINKS+=login_cap.3 login_close.3 login_cap.3 login_getcapbool.3 \

Modified: head/lib/libutil/flopen.3
==============================================================================
--- head/lib/libutil/flopen.3	Fri Aug  4 13:08:45 2017	(r322053)
+++ head/lib/libutil/flopen.3	Fri Aug  4 14:24:24 2017	(r322054)
@@ -25,11 +25,12 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd June 6, 2009
+.Dd July 28, 2017
 .Dt FLOPEN 3
 .Os
 .Sh NAME
-.Nm flopen
+.Nm flopen ,
+.Nm flopenat
 .Nd "Reliably open and lock a file"
 .Sh LIBRARY
 .Lb libutil
@@ -40,6 +41,10 @@
 .Fn flopen "const char *path" "int flags"
 .Ft int
 .Fn flopen "const char *path" "int flags" "mode_t mode"
+.Ft int
+.Fn flopenat "int fd" "const char *path" "int flags"
+.Ft int
+.Fn flopenat "int fd" "const char *path" "int flags" "mode_t mode"
 .Sh DESCRIPTION
 The
 .Fn flopen
@@ -79,6 +84,27 @@ argument is required if
 .Va flags
 includes
 .Dv O_CREAT .
+.Pp
+The
+.Fn flopenat
+function is equivalent to the
+.Fn flopen
+function except in the case where the
+.Fa path
+specifies a relative path.
+In this case the file to be opened is determined relative to the directory
+associated with the file descriptor
+.Fa fd
+instead of the current working directory.
+If
+.Fn flopenat
+is passed the special value
+.Dv AT_FDCWD
+in the
+.Fa fd
+parameter, the current working directory is used
+and the behavior is identical to a call to
+.Fn flopen .
 .Sh RETURN VALUES
 If successful,
 .Fn flopen

Modified: head/lib/libutil/flopen.c
==============================================================================
--- head/lib/libutil/flopen.c	Fri Aug  4 13:08:45 2017	(r322053)
+++ head/lib/libutil/flopen.c	Fri Aug  4 14:24:24 2017	(r322054)
@@ -45,8 +45,8 @@ __FBSDID("$FreeBSD$");
  * code's apparent simplicity; there would be no need for this function if it
  * was easy to get right.
  */
-int
-flopen(const char *path, int flags, ...)
+static int
+vflopenat(int dirfd, const char *path, int flags, va_list ap)
 {
 	int fd, operation, serrno, trunc;
 	struct stat sb, fsb;
@@ -58,11 +58,7 @@ flopen(const char *path, int flags, ...)
 
 	mode = 0;
 	if (flags & O_CREAT) {
-		va_list ap;
-
-		va_start(ap, flags);
 		mode = (mode_t)va_arg(ap, int); /* mode_t promoted to int */
-		va_end(ap);
 	}
 
         operation = LOCK_EX;
@@ -73,7 +69,7 @@ flopen(const char *path, int flags, ...)
 	flags &= ~O_TRUNC;
 
 	for (;;) {
-		if ((fd = open(path, flags, mode)) == -1)
+		if ((fd = openat(dirfd, path, flags, mode)) == -1)
 			/* non-existent or no access */
 			return (-1);
 		if (flock(fd, operation) == -1) {
@@ -83,7 +79,7 @@ flopen(const char *path, int flags, ...)
 			errno = serrno;
 			return (-1);
 		}
-		if (stat(path, &sb) == -1) {
+		if (fstatat(dirfd, path, &sb, 0) == -1) {
 			/* disappeared from under our feet */
 			(void)close(fd);
 			continue;
@@ -122,4 +118,28 @@ flopen(const char *path, int flags, ...)
 #endif
 		return (fd);
 	}
+}
+
+int
+flopen(const char *path, int flags, ...)
+{
+	va_list ap;
+	int ret;
+
+	va_start(ap, flags);
+	ret = vflopenat(AT_FDCWD, path, flags, ap);
+	va_end(ap);
+	return (ret);
+}
+
+int
+flopenat(int dirfd, const char *path, int flags, ...)
+{
+	va_list ap;
+	int ret;
+
+	va_start(ap, flags);
+	ret = vflopenat(dirfd, path, flags, ap);
+	va_end(ap);
+	return (ret);
 }

Modified: head/lib/libutil/libutil.h
==============================================================================
--- head/lib/libutil/libutil.h	Fri Aug  4 13:08:45 2017	(r322053)
+++ head/lib/libutil/libutil.h	Fri Aug  4 14:24:24 2017	(r322054)
@@ -93,6 +93,7 @@ int	expand_number(const char *_buf, uint64_t *_num);
 int	extattr_namespace_to_string(int _attrnamespace, char **_string);
 int	extattr_string_to_namespace(const char *_string, int *_attrnamespace);
 int	flopen(const char *_path, int _flags, ...);
+int	flopenat(int _dirfd, const char *_path, int _flags, ...);
 int	forkpty(int *_amaster, char *_name,
 	    struct termios *_termp, struct winsize *_winp);
 void	hexdump(const void *_ptr, int _length, const char *_hdr, int _flags);


More information about the svn-src-all mailing list