There is an optimization in chmod(1), that makes it not to call chmod(2)
if the new file mode is the same as it was before; however, this optimization must be disabled for filesystems that support NFSv4 ACLs. Chmod uses pathconf(2) to determine whether this is the case - however, pathconf(2) always follows symbolic links, while the 'chmod -h' doesn't. This change adds lpathconf(3) to make it possible to solve that problem in a clean way. Reviewed by: rwatson (earlier version) Approved by: re (kib)
This commit is contained in:
parent
6b53d5c0e7
commit
c38898116a
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=195458
@ -513,6 +513,7 @@ int initgroups(const char *, gid_t);
|
|||||||
int iruserok(unsigned long, int, const char *, const char *);
|
int iruserok(unsigned long, int, const char *, const char *);
|
||||||
int iruserok_sa(const void *, int, int, const char *, const char *);
|
int iruserok_sa(const void *, int, int, const char *, const char *);
|
||||||
int issetugid(void);
|
int issetugid(void);
|
||||||
|
long lpathconf(const char *, int);
|
||||||
#ifndef _MKDTEMP_DECLARED
|
#ifndef _MKDTEMP_DECLARED
|
||||||
char *mkdtemp(char *);
|
char *mkdtemp(char *);
|
||||||
#define _MKDTEMP_DECLARED
|
#define _MKDTEMP_DECLARED
|
||||||
|
@ -159,6 +159,7 @@ MLINKS+=mq_send.2 mq_timedsend.2
|
|||||||
MLINKS+=ntp_adjtime.2 ntp_gettime.2
|
MLINKS+=ntp_adjtime.2 ntp_gettime.2
|
||||||
MLINKS+=open.2 openat.2
|
MLINKS+=open.2 openat.2
|
||||||
MLINKS+=pathconf.2 fpathconf.2
|
MLINKS+=pathconf.2 fpathconf.2
|
||||||
|
MLINKS+=pathconf.2 lpathconf.2
|
||||||
MLINKS+=read.2 pread.2 read.2 preadv.2 read.2 readv.2
|
MLINKS+=read.2 pread.2 read.2 preadv.2 read.2 readv.2
|
||||||
MLINKS+=readlink.2 readlinkat.2
|
MLINKS+=readlink.2 readlinkat.2
|
||||||
MLINKS+=recv.2 recvfrom.2 recv.2 recvmsg.2
|
MLINKS+=recv.2 recvfrom.2 recv.2 recvmsg.2
|
||||||
|
@ -346,6 +346,7 @@ FBSD_1.1 {
|
|||||||
jail_set;
|
jail_set;
|
||||||
jail_remove;
|
jail_remove;
|
||||||
linkat;
|
linkat;
|
||||||
|
lpathconf;
|
||||||
mkdirat;
|
mkdirat;
|
||||||
mkfifoat;
|
mkfifoat;
|
||||||
mknodat;
|
mknodat;
|
||||||
|
@ -28,11 +28,12 @@
|
|||||||
.\" @(#)pathconf.2 8.1 (Berkeley) 6/4/93
|
.\" @(#)pathconf.2 8.1 (Berkeley) 6/4/93
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd June 25, 2009
|
.Dd July 7, 2009
|
||||||
.Dt PATHCONF 2
|
.Dt PATHCONF 2
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
.Nm pathconf ,
|
.Nm pathconf ,
|
||||||
|
.Nm lpathconf ,
|
||||||
.Nm fpathconf
|
.Nm fpathconf
|
||||||
.Nd get configurable pathname variables
|
.Nd get configurable pathname variables
|
||||||
.Sh LIBRARY
|
.Sh LIBRARY
|
||||||
@ -42,10 +43,13 @@
|
|||||||
.Ft long
|
.Ft long
|
||||||
.Fn pathconf "const char *path" "int name"
|
.Fn pathconf "const char *path" "int name"
|
||||||
.Ft long
|
.Ft long
|
||||||
|
.Fn lpathconf "const char *path" "int name"
|
||||||
|
.Ft long
|
||||||
.Fn fpathconf "int fd" "int name"
|
.Fn fpathconf "int fd" "int name"
|
||||||
.Sh DESCRIPTION
|
.Sh DESCRIPTION
|
||||||
The
|
The
|
||||||
.Fn pathconf
|
.Fn pathconf ,
|
||||||
|
.Fn lpathconf
|
||||||
and
|
and
|
||||||
.Fn fpathconf
|
.Fn fpathconf
|
||||||
system calls provide a method for applications to determine the current
|
system calls provide a method for applications to determine the current
|
||||||
@ -53,7 +57,9 @@ value of a configurable system limit or option variable associated
|
|||||||
with a pathname or file descriptor.
|
with a pathname or file descriptor.
|
||||||
.Pp
|
.Pp
|
||||||
For
|
For
|
||||||
.Fn pathconf ,
|
.Fn pathconf
|
||||||
|
and
|
||||||
|
.Fn lpathconf ,
|
||||||
the
|
the
|
||||||
.Fa path
|
.Fa path
|
||||||
argument is the name of a file or directory.
|
argument is the name of a file or directory.
|
||||||
@ -68,6 +74,18 @@ argument specifies the system variable to be queried.
|
|||||||
Symbolic constants for each name value are found in the include file
|
Symbolic constants for each name value are found in the include file
|
||||||
.Li <unistd.h> .
|
.Li <unistd.h> .
|
||||||
.Pp
|
.Pp
|
||||||
|
The
|
||||||
|
.Fn lpathconf
|
||||||
|
system call is like
|
||||||
|
.Fn pathconf
|
||||||
|
except in the case where the named file is a symbolic link,
|
||||||
|
in which case
|
||||||
|
.Fn lpathconf
|
||||||
|
returns information about the link,
|
||||||
|
while
|
||||||
|
.Fn pathconf
|
||||||
|
returns information about the file the link references.
|
||||||
|
.Pp
|
||||||
The available values are as follows:
|
The available values are as follows:
|
||||||
.Pp
|
.Pp
|
||||||
.Bl -tag -width 6n
|
.Bl -tag -width 6n
|
||||||
@ -239,3 +257,7 @@ and
|
|||||||
.Fn fpathconf
|
.Fn fpathconf
|
||||||
system calls first appeared in
|
system calls first appeared in
|
||||||
.Bx 4.4 .
|
.Bx 4.4 .
|
||||||
|
The
|
||||||
|
.Fn lpathconf
|
||||||
|
system call first appeared in
|
||||||
|
.Fx 8.0 .
|
||||||
|
@ -597,6 +597,7 @@
|
|||||||
#define AUE_PWRITE 43193 /* Darwin/FreeBSD. */
|
#define AUE_PWRITE 43193 /* Darwin/FreeBSD. */
|
||||||
#define AUE_FSCTL 43194 /* Darwin. */
|
#define AUE_FSCTL 43194 /* Darwin. */
|
||||||
#define AUE_FFSCTL 43195 /* Darwin. */
|
#define AUE_FFSCTL 43195 /* Darwin. */
|
||||||
|
#define AUE_LPATHCONF 43196 /* FreeBSD. */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Darwin BSM uses a number of AUE_O_* definitions, which are aliased to the
|
* Darwin BSM uses a number of AUE_O_* definitions, which are aliased to the
|
||||||
|
@ -900,3 +900,4 @@
|
|||||||
struct msqid_ds32 *buf); }
|
struct msqid_ds32 *buf); }
|
||||||
512 AUE_SHMCTL STD { int freebsd32_shmctl(int shmid, int cmd, \
|
512 AUE_SHMCTL STD { int freebsd32_shmctl(int shmid, int cmd, \
|
||||||
struct shmid_ds32 *buf); }
|
struct shmid_ds32 *buf); }
|
||||||
|
513 AUE_LPATHCONF STD { int lpathconf(char *path, int name); }
|
||||||
|
@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <sys/jail.h>
|
#include <sys/jail.h>
|
||||||
#include <sys/kernel.h>
|
#include <sys/kernel.h>
|
||||||
#include <sys/malloc.h>
|
#include <sys/malloc.h>
|
||||||
|
#include <sys/namei.h>
|
||||||
#include <sys/unistd.h>
|
#include <sys/unistd.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/syscallsubr.h>
|
#include <sys/syscallsubr.h>
|
||||||
@ -669,7 +670,7 @@ svr4_sys_pathconf(td, uap)
|
|||||||
return (0);
|
return (0);
|
||||||
default:
|
default:
|
||||||
CHECKALTEXIST(td, uap->path, &path);
|
CHECKALTEXIST(td, uap->path, &path);
|
||||||
error = kern_pathconf(td, path, UIO_SYSSPACE, name);
|
error = kern_pathconf(td, path, UIO_SYSSPACE, name, FOLLOW);
|
||||||
free(path, M_TEMP);
|
free(path, M_TEMP);
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
@ -66,6 +66,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <sys/malloc.h>
|
#include <sys/malloc.h>
|
||||||
#include <sys/file.h> /* Must come after sys/malloc.h */
|
#include <sys/file.h> /* Must come after sys/malloc.h */
|
||||||
#include <sys/mutex.h>
|
#include <sys/mutex.h>
|
||||||
|
#include <sys/namei.h>
|
||||||
#include <sys/priv.h>
|
#include <sys/priv.h>
|
||||||
#include <sys/reboot.h>
|
#include <sys/reboot.h>
|
||||||
#include <sys/resourcevar.h>
|
#include <sys/resourcevar.h>
|
||||||
@ -763,7 +764,7 @@ ibcs2_pathconf(td, uap)
|
|||||||
|
|
||||||
CHECKALTEXIST(td, uap->path, &path);
|
CHECKALTEXIST(td, uap->path, &path);
|
||||||
uap->name++; /* iBCS2 _PC_* defines are offset by one */
|
uap->name++; /* iBCS2 _PC_* defines are offset by one */
|
||||||
error = kern_pathconf(td, path, UIO_SYSSPACE, uap->name);
|
error = kern_pathconf(td, path, UIO_SYSSPACE, uap->name, FOLLOW);
|
||||||
free(path, M_TEMP);
|
free(path, M_TEMP);
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
@ -910,5 +910,6 @@
|
|||||||
struct msqid_ds *buf); }
|
struct msqid_ds *buf); }
|
||||||
512 AUE_SHMCTL NOSTD { int shmctl(int shmid, int cmd, \
|
512 AUE_SHMCTL NOSTD { int shmctl(int shmid, int cmd, \
|
||||||
struct shmid_ds *buf); }
|
struct shmid_ds *buf); }
|
||||||
|
513 AUE_LPATHCONF STD { int lpathconf(char *path, int name); }
|
||||||
; Please copy any additions and changes to the following compatability tables:
|
; Please copy any additions and changes to the following compatability tables:
|
||||||
; sys/compat/freebsd32/syscalls.master
|
; sys/compat/freebsd32/syscalls.master
|
||||||
|
@ -2506,17 +2506,36 @@ pathconf(td, uap)
|
|||||||
} */ *uap;
|
} */ *uap;
|
||||||
{
|
{
|
||||||
|
|
||||||
return (kern_pathconf(td, uap->path, UIO_USERSPACE, uap->name));
|
return (kern_pathconf(td, uap->path, UIO_USERSPACE, uap->name, FOLLOW));
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef _SYS_SYSPROTO_H_
|
||||||
|
struct lpathconf_args {
|
||||||
|
char *path;
|
||||||
|
int name;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
int
|
||||||
|
lpathconf(td, uap)
|
||||||
|
struct thread *td;
|
||||||
|
register struct lpathconf_args /* {
|
||||||
|
char *path;
|
||||||
|
int name;
|
||||||
|
} */ *uap;
|
||||||
|
{
|
||||||
|
|
||||||
|
return (kern_pathconf(td, uap->path, UIO_USERSPACE, uap->name, NOFOLLOW));
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
kern_pathconf(struct thread *td, char *path, enum uio_seg pathseg, int name)
|
kern_pathconf(struct thread *td, char *path, enum uio_seg pathseg, int name,
|
||||||
|
u_long flags)
|
||||||
{
|
{
|
||||||
struct nameidata nd;
|
struct nameidata nd;
|
||||||
int error, vfslocked;
|
int error, vfslocked;
|
||||||
|
|
||||||
NDINIT(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF | MPSAFE |
|
NDINIT(&nd, LOOKUP, LOCKSHARED | LOCKLEAF | MPSAFE | AUDITVNODE1 |
|
||||||
AUDITVNODE1, pathseg, path, td);
|
flags, pathseg, path, td);
|
||||||
if ((error = namei(&nd)) != 0)
|
if ((error = namei(&nd)) != 0)
|
||||||
return (error);
|
return (error);
|
||||||
vfslocked = NDHASGIANT(&nd);
|
vfslocked = NDHASGIANT(&nd);
|
||||||
|
@ -145,7 +145,7 @@ int kern_open(struct thread *td, char *path, enum uio_seg pathseg,
|
|||||||
int kern_openat(struct thread *td, int fd, char *path,
|
int kern_openat(struct thread *td, int fd, char *path,
|
||||||
enum uio_seg pathseg, int flags, int mode);
|
enum uio_seg pathseg, int flags, int mode);
|
||||||
int kern_pathconf(struct thread *td, char *path, enum uio_seg pathseg,
|
int kern_pathconf(struct thread *td, char *path, enum uio_seg pathseg,
|
||||||
int name);
|
int name, u_long flags);
|
||||||
int kern_pipe(struct thread *td, int fildes[2]);
|
int kern_pipe(struct thread *td, int fildes[2]);
|
||||||
int kern_preadv(struct thread *td, int fd, struct uio *auio, off_t offset);
|
int kern_preadv(struct thread *td, int fd, struct uio *auio, off_t offset);
|
||||||
int kern_ptrace(struct thread *td, int req, pid_t pid, void *addr,
|
int kern_ptrace(struct thread *td, int req, pid_t pid, void *addr,
|
||||||
|
Loading…
Reference in New Issue
Block a user