Introduce the flopenat(3) function.

Reviewed by:	des, emaste
Differential Revision:	https://reviews.freebsd.org/D11690
This commit is contained in:
Mariusz Zaborski 2017-08-04 14:24:24 +00:00
parent 49f347f450
commit 73979478cc
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=322054
4 changed files with 58 additions and 10 deletions

View File

@ -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 \

View File

@ -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

View File

@ -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;
@ -123,3 +119,27 @@ flopen(const char *path, int flags, ...)
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);
}

View File

@ -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);