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
@ -513,6 +513,7 @@ int initgroups(const char *, gid_t);
|
||||
int iruserok(unsigned long, int, const char *, const char *);
|
||||
int iruserok_sa(const void *, int, int, const char *, const char *);
|
||||
int issetugid(void);
|
||||
long lpathconf(const char *, int);
|
||||
#ifndef _MKDTEMP_DECLARED
|
||||
char *mkdtemp(char *);
|
||||
#define _MKDTEMP_DECLARED
|
||||
|
@ -159,6 +159,7 @@ MLINKS+=mq_send.2 mq_timedsend.2
|
||||
MLINKS+=ntp_adjtime.2 ntp_gettime.2
|
||||
MLINKS+=open.2 openat.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+=readlink.2 readlinkat.2
|
||||
MLINKS+=recv.2 recvfrom.2 recv.2 recvmsg.2
|
||||
|
@ -346,6 +346,7 @@ FBSD_1.1 {
|
||||
jail_set;
|
||||
jail_remove;
|
||||
linkat;
|
||||
lpathconf;
|
||||
mkdirat;
|
||||
mkfifoat;
|
||||
mknodat;
|
||||
|
@ -28,11 +28,12 @@
|
||||
.\" @(#)pathconf.2 8.1 (Berkeley) 6/4/93
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd June 25, 2009
|
||||
.Dd July 7, 2009
|
||||
.Dt PATHCONF 2
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm pathconf ,
|
||||
.Nm lpathconf ,
|
||||
.Nm fpathconf
|
||||
.Nd get configurable pathname variables
|
||||
.Sh LIBRARY
|
||||
@ -42,10 +43,13 @@
|
||||
.Ft long
|
||||
.Fn pathconf "const char *path" "int name"
|
||||
.Ft long
|
||||
.Fn lpathconf "const char *path" "int name"
|
||||
.Ft long
|
||||
.Fn fpathconf "int fd" "int name"
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Fn pathconf
|
||||
.Fn pathconf ,
|
||||
.Fn lpathconf
|
||||
and
|
||||
.Fn fpathconf
|
||||
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.
|
||||
.Pp
|
||||
For
|
||||
.Fn pathconf ,
|
||||
.Fn pathconf
|
||||
and
|
||||
.Fn lpathconf ,
|
||||
the
|
||||
.Fa path
|
||||
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
|
||||
.Li <unistd.h> .
|
||||
.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:
|
||||
.Pp
|
||||
.Bl -tag -width 6n
|
||||
@ -239,3 +257,7 @@ and
|
||||
.Fn fpathconf
|
||||
system calls first appeared in
|
||||
.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_FSCTL 43194 /* 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
|
||||
|
@ -900,3 +900,4 @@
|
||||
struct msqid_ds32 *buf); }
|
||||
512 AUE_SHMCTL STD { int freebsd32_shmctl(int shmid, int cmd, \
|
||||
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/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/namei.h>
|
||||
#include <sys/unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/syscallsubr.h>
|
||||
@ -669,7 +670,7 @@ svr4_sys_pathconf(td, uap)
|
||||
return (0);
|
||||
default:
|
||||
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);
|
||||
return (error);
|
||||
}
|
||||
|
@ -66,6 +66,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/file.h> /* Must come after sys/malloc.h */
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/namei.h>
|
||||
#include <sys/priv.h>
|
||||
#include <sys/reboot.h>
|
||||
#include <sys/resourcevar.h>
|
||||
@ -763,7 +764,7 @@ ibcs2_pathconf(td, uap)
|
||||
|
||||
CHECKALTEXIST(td, uap->path, &path);
|
||||
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);
|
||||
return (error);
|
||||
}
|
||||
|
@ -910,5 +910,6 @@
|
||||
struct msqid_ds *buf); }
|
||||
512 AUE_SHMCTL NOSTD { int shmctl(int shmid, int cmd, \
|
||||
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:
|
||||
; sys/compat/freebsd32/syscalls.master
|
||||
|
@ -2506,17 +2506,36 @@ pathconf(td, 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
|
||||
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;
|
||||
int error, vfslocked;
|
||||
|
||||
NDINIT(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF | MPSAFE |
|
||||
AUDITVNODE1, pathseg, path, td);
|
||||
NDINIT(&nd, LOOKUP, LOCKSHARED | LOCKLEAF | MPSAFE | AUDITVNODE1 |
|
||||
flags, pathseg, path, td);
|
||||
if ((error = namei(&nd)) != 0)
|
||||
return (error);
|
||||
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,
|
||||
enum uio_seg pathseg, int flags, int mode);
|
||||
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_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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user