Implement chflagsat(2) system call, similar to fchmodat(2), but operates on
file flags. Reviewed by: kib, jilles Sponsored by: The FreeBSD Foundation
This commit is contained in:
parent
5fc1bac315
commit
635dbe90f2
@ -570,6 +570,7 @@
|
||||
43206:AUE_CAP_FCNTLS_GET:cap_fcntls_get(2):fm
|
||||
43207:AUE_BINDAT:bindat(2):nt
|
||||
43208:AUE_CONNECTAT:connectat(2):nt
|
||||
43209:AUE_CHFLAGSAT:chflagsat(2):fm
|
||||
#
|
||||
# Solaris userspace events.
|
||||
#
|
||||
|
@ -386,6 +386,7 @@ FBSD_1.3 {
|
||||
cap_rights_get;
|
||||
cap_rights_limit;
|
||||
cap_sandboxed;
|
||||
chflagsat;
|
||||
clock_getcpuclockid2;
|
||||
connectat;
|
||||
ffclock_getcounter;
|
||||
|
@ -610,6 +610,7 @@
|
||||
#define AUE_CAP_FCNTLS_GET 43206 /* TrustedBSD. */
|
||||
#define AUE_BINDAT 43207 /* TrustedBSD. */
|
||||
#define AUE_CONNECTAT 43208 /* TrustedBSD. */
|
||||
#define AUE_CHFLAGSAT 43209 /* FreeBSD-specific. */
|
||||
|
||||
/*
|
||||
* Darwin BSM uses a number of AUE_O_* definitions, which are aliased to the
|
||||
|
@ -1020,3 +1020,5 @@
|
||||
int namelen); }
|
||||
539 AUE_CONNECTAT NOPROTO { int connectat(int fd, int s, caddr_t name, \
|
||||
int namelen); }
|
||||
540 AUE_CHFLAGSAT NOPROTO { int chflagsat(int fd, const char *path, \
|
||||
u_long flags, int atflag); }
|
||||
|
@ -445,6 +445,7 @@ olio_listio
|
||||
##
|
||||
## Operations relative to directory capabilities.
|
||||
##
|
||||
chflagsat
|
||||
faccessat
|
||||
fchmodat
|
||||
fchownat
|
||||
|
@ -970,5 +970,7 @@
|
||||
int namelen); }
|
||||
539 AUE_CONNECTAT STD { int connectat(int fd, int s, caddr_t name, \
|
||||
int namelen); }
|
||||
540 AUE_CHFLAGSAT STD { int chflagsat(int fd, const char *path, \
|
||||
u_long flags, int atflag); }
|
||||
; Please copy any additions and changes to the following compatability tables:
|
||||
; sys/compat/freebsd32/syscalls.master
|
||||
|
@ -101,6 +101,10 @@ SDT_PROBE_ARGTYPE(vfs, , stat, reg, 1, "int");
|
||||
|
||||
static int chroot_refuse_vdir_fds(struct filedesc *fdp);
|
||||
static int getutimes(const struct timeval *, enum uio_seg, struct timespec *);
|
||||
static int kern_chflags(struct thread *td, const char *path,
|
||||
enum uio_seg pathseg, u_long flags);
|
||||
static int kern_chflagsat(struct thread *td, int fd, const char *path,
|
||||
enum uio_seg pathseg, u_long flags, int atflag);
|
||||
static int setfflags(struct thread *td, struct vnode *, u_long);
|
||||
static int setutimes(struct thread *td, struct vnode *,
|
||||
const struct timespec *, int, int);
|
||||
@ -2669,17 +2673,38 @@ sys_chflags(td, uap)
|
||||
u_long flags;
|
||||
} */ *uap;
|
||||
{
|
||||
int error;
|
||||
struct nameidata nd;
|
||||
|
||||
AUDIT_ARG_FFLAGS(uap->flags);
|
||||
NDINIT(&nd, LOOKUP, FOLLOW | AUDITVNODE1, UIO_USERSPACE, uap->path, td);
|
||||
if ((error = namei(&nd)) != 0)
|
||||
return (error);
|
||||
NDFREE(&nd, NDF_ONLY_PNBUF);
|
||||
error = setfflags(td, nd.ni_vp, uap->flags);
|
||||
vrele(nd.ni_vp);
|
||||
return (error);
|
||||
return (kern_chflags(td, uap->path, UIO_USERSPACE, uap->flags));
|
||||
}
|
||||
|
||||
#ifndef _SYS_SYSPROTO_H_
|
||||
struct chflagsat_args {
|
||||
int fd;
|
||||
const char *path;
|
||||
u_long flags;
|
||||
int atflag;
|
||||
}
|
||||
#endif
|
||||
int
|
||||
sys_chflagsat(struct thread *td, struct chflagsat_args *uap)
|
||||
{
|
||||
int fd = uap->fd;
|
||||
char *path = uap->path;
|
||||
u_long flags = uap->flags;
|
||||
int atflag = uap->atflag;
|
||||
|
||||
if (atflag & ~AT_SYMLINK_NOFOLLOW)
|
||||
return (EINVAL);
|
||||
|
||||
return (kern_chflagsat(td, fd, path, UIO_USERSPACE, flags, atflag));
|
||||
}
|
||||
|
||||
static int
|
||||
kern_chflags(struct thread *td, const char *path, enum uio_seg pathseg,
|
||||
u_long flags)
|
||||
{
|
||||
|
||||
return (kern_chflagsat(td, AT_FDCWD, path, pathseg, flags, 0));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2693,16 +2718,26 @@ sys_lchflags(td, uap)
|
||||
u_long flags;
|
||||
} */ *uap;
|
||||
{
|
||||
int error;
|
||||
struct nameidata nd;
|
||||
|
||||
AUDIT_ARG_FFLAGS(uap->flags);
|
||||
NDINIT(&nd, LOOKUP, NOFOLLOW | AUDITVNODE1, UIO_USERSPACE, uap->path,
|
||||
td);
|
||||
return (kern_chflagsat(td, AT_FDCWD, uap->path, UIO_USERSPACE,
|
||||
uap->flags, AT_SYMLINK_NOFOLLOW));
|
||||
}
|
||||
|
||||
static int
|
||||
kern_chflagsat(struct thread *td, int fd, const char *path,
|
||||
enum uio_seg pathseg, u_long flags, int atflag)
|
||||
{
|
||||
struct nameidata nd;
|
||||
int error, follow;
|
||||
|
||||
AUDIT_ARG_FFLAGS(flags);
|
||||
follow = (atflag & AT_SYMLINK_NOFOLLOW) ? NOFOLLOW : FOLLOW;
|
||||
NDINIT_ATRIGHTS(&nd, LOOKUP, follow | AUDITVNODE1, pathseg, path, fd,
|
||||
CAP_FCHFLAGS, td);
|
||||
if ((error = namei(&nd)) != 0)
|
||||
return (error);
|
||||
NDFREE(&nd, NDF_ONLY_PNBUF);
|
||||
error = setfflags(td, nd.ni_vp, uap->flags);
|
||||
error = setfflags(td, nd.ni_vp, flags);
|
||||
vrele(nd.ni_vp);
|
||||
return (error);
|
||||
}
|
||||
|
@ -102,6 +102,7 @@
|
||||
/* VFS methods. */
|
||||
#define CAP_FCHDIR 0x0000000000000200ULL
|
||||
#define CAP_FCHFLAGS 0x0000000000000100ULL
|
||||
#define CAP_CHFLAGSAT CAP_FCHFLAGS
|
||||
#define CAP_FCHMOD 0x0000000000000400ULL
|
||||
#define CAP_FCHMODAT CAP_FCHMOD
|
||||
#define CAP_FCHOWN 0x0000000000000800ULL
|
||||
|
@ -293,6 +293,7 @@ struct nstat {
|
||||
__BEGIN_DECLS
|
||||
#if __BSD_VISIBLE
|
||||
int chflags(const char *, unsigned long);
|
||||
int chflagsat(int, const char *, unsigned long, int);
|
||||
#endif
|
||||
int chmod(const char *, mode_t);
|
||||
#if __BSD_VISIBLE
|
||||
|
Loading…
x
Reference in New Issue
Block a user