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