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);
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to