- Tweak kern_msgctl() to return a copy of the requested message queue id
structure in the struct pointed to by the 3rd argument for IPC_STAT and get rid of the 4th argument. The old way returned a pointer into the kernel array that the calling function would then access afterwards without holding the appropriate locks and doing non-lock-safe things like copyout() with the data anyways. This change removes that unsafeness and resulting race conditions as well as simplifying the interface. - Implement kern_foo wrappers for stat(), lstat(), fstat(), statfs(), fstatfs(), and fhstatfs(). Use these wrappers to cut out a lot of code duplication for freebsd4 and netbsd compatability system calls. - Add a new lookup function kern_alternate_path() that looks up a filename under an alternate prefix and determines which filename should be used. This is basically a more general version of linux_emul_convpath() that can be shared by all the ABIs thus allowing for further reduction of code duplication.
This commit is contained in:
parent
c90110d639
commit
76951d21d1
@ -637,7 +637,6 @@ linux_msgctl(struct thread *td, struct linux_msgctl_args *args)
|
||||
int error, bsd_cmd;
|
||||
struct l_msqid_ds linux_msqid;
|
||||
struct msqid_ds bsd_msqid;
|
||||
struct msqid_ds *bsd_msqptr;
|
||||
|
||||
error = linux_msqid_pullup(args->cmd & LINUX_IPC_64,
|
||||
&linux_msqid, (caddr_t)PTRIN(args->buf));
|
||||
@ -647,13 +646,13 @@ linux_msgctl(struct thread *td, struct linux_msgctl_args *args)
|
||||
if (bsd_cmd == LINUX_IPC_SET)
|
||||
linux_to_bsd_msqid_ds(&linux_msqid, &bsd_msqid);
|
||||
|
||||
error = kern_msgctl(td, args->msqid, bsd_cmd, &bsd_msqid, &bsd_msqptr);
|
||||
error = kern_msgctl(td, args->msqid, bsd_cmd, &bsd_msqid);
|
||||
if (error != 0)
|
||||
if (bsd_cmd != LINUX_IPC_RMID || error != EINVAL)
|
||||
return (error);
|
||||
|
||||
if (bsd_cmd == LINUX_IPC_STAT) {
|
||||
bsd_to_linux_msqid_ds(bsd_msqptr, &linux_msqid);
|
||||
bsd_to_linux_msqid_ds(&bsd_msqid, &linux_msqid);
|
||||
return (linux_msqid_pushdown(args->cmd & LINUX_IPC_64,
|
||||
&linux_msqid, (caddr_t)PTRIN(args->buf)));
|
||||
}
|
||||
|
@ -1030,20 +1030,15 @@ struct ofstat_args {
|
||||
int
|
||||
ofstat(struct thread *td, struct ofstat_args *uap)
|
||||
{
|
||||
struct file *fp;
|
||||
struct stat ub;
|
||||
struct ostat oub;
|
||||
struct stat ub;
|
||||
int error;
|
||||
|
||||
if ((error = fget(td, uap->fd, &fp)) != 0)
|
||||
goto done2;
|
||||
error = fo_stat(fp, &ub, td->td_ucred, td);
|
||||
error = kern_fstat(td, uap->fd, &ub);
|
||||
if (error == 0) {
|
||||
cvtstat(&ub, &oub);
|
||||
error = copyout(&oub, uap->sb, sizeof(oub));
|
||||
}
|
||||
fdrop(fp, td);
|
||||
done2:
|
||||
return (error);
|
||||
}
|
||||
#endif /* COMPAT_43 */
|
||||
@ -1064,17 +1059,25 @@ struct fstat_args {
|
||||
int
|
||||
fstat(struct thread *td, struct fstat_args *uap)
|
||||
{
|
||||
struct file *fp;
|
||||
struct stat ub;
|
||||
int error;
|
||||
|
||||
if ((error = fget(td, uap->fd, &fp)) != 0)
|
||||
goto done2;
|
||||
error = fo_stat(fp, &ub, td->td_ucred, td);
|
||||
error = kern_fstat(td, uap->fd, &ub);
|
||||
if (error == 0)
|
||||
error = copyout(&ub, uap->sb, sizeof(ub));
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
kern_fstat(struct thread *td, int fd, struct stat *sbp)
|
||||
{
|
||||
struct file *fp;
|
||||
int error;
|
||||
|
||||
if ((error = fget(td, fd, &fp)) != 0)
|
||||
return (error);
|
||||
error = fo_stat(fp, sbp, td->td_ucred, td);
|
||||
fdrop(fp, td);
|
||||
done2:
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -1094,20 +1097,15 @@ struct nfstat_args {
|
||||
int
|
||||
nfstat(struct thread *td, struct nfstat_args *uap)
|
||||
{
|
||||
struct file *fp;
|
||||
struct stat ub;
|
||||
struct nstat nub;
|
||||
struct stat ub;
|
||||
int error;
|
||||
|
||||
if ((error = fget(td, uap->fd, &fp)) != 0)
|
||||
goto done2;
|
||||
error = fo_stat(fp, &ub, td->td_ucred, td);
|
||||
error = kern_fstat(td, uap->fd, &ub);
|
||||
if (error == 0) {
|
||||
cvtnstat(&ub, &nub);
|
||||
error = copyout(&nub, uap->sb, sizeof(nub));
|
||||
}
|
||||
fdrop(fp, td);
|
||||
done2:
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
@ -397,26 +397,24 @@ msgctl(td, uap)
|
||||
int msqid = uap->msqid;
|
||||
int cmd = uap->cmd;
|
||||
struct msqid_ds msqbuf;
|
||||
struct msqid_ds *msqptr;
|
||||
int error;
|
||||
|
||||
DPRINTF(("call to msgctl(%d, %d, 0x%x)\n", msqid, cmd, uap->buf));
|
||||
if (cmd == IPC_SET &&
|
||||
(error = copyin(uap->buf, &msqbuf, sizeof(msqbuf))) != 0)
|
||||
return (error);
|
||||
error = kern_msgctl(td, msqid, cmd, &msqbuf, &msqptr);
|
||||
error = kern_msgctl(td, msqid, cmd, &msqbuf);
|
||||
if (cmd == IPC_STAT && error == 0)
|
||||
error = copyout(msqptr, uap->buf, sizeof(struct msqid_ds));
|
||||
error = copyout(&msqbuf, uap->buf, sizeof(struct msqid_ds));
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
kern_msgctl(td, msqid, cmd, msqbuf, msqptr)
|
||||
kern_msgctl(td, msqid, cmd, msqbuf)
|
||||
struct thread *td;
|
||||
int msqid;
|
||||
int cmd;
|
||||
struct msqid_ds *msqbuf;
|
||||
struct msqid_ds **msqptr;
|
||||
{
|
||||
int rval, error, msqix;
|
||||
register struct msqid_kernel *msqkptr;
|
||||
@ -545,7 +543,7 @@ kern_msgctl(td, msqid, cmd, msqbuf, msqptr)
|
||||
DPRINTF(("requester doesn't have read access\n"));
|
||||
goto done2;
|
||||
}
|
||||
*msqptr = &(msqkptr->u);
|
||||
*msqbuf = msqkptr->u;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -558,7 +556,7 @@ kern_msgctl(td, msqid, cmd, msqbuf, msqptr)
|
||||
td->td_retval[0] = rval;
|
||||
done2:
|
||||
mtx_unlock(&msq_mtx);
|
||||
return(error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
#ifndef _SYS_SYSPROTO_H_
|
||||
|
@ -220,6 +220,19 @@ statfs(td, uap)
|
||||
char *path;
|
||||
struct statfs *buf;
|
||||
} */ *uap;
|
||||
{
|
||||
struct statfs sf;
|
||||
int error;
|
||||
|
||||
error = kern_statfs(td, uap->path, UIO_USERSPACE, &sf);
|
||||
if (error == 0)
|
||||
error = copyout(&sf, uap->buf, sizeof(sf));
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
kern_statfs(struct thread *td, char *path, enum uio_seg pathseg,
|
||||
struct statfs *buf)
|
||||
{
|
||||
struct mount *mp;
|
||||
struct statfs *sp, sb;
|
||||
@ -227,7 +240,7 @@ statfs(td, uap)
|
||||
struct nameidata nd;
|
||||
|
||||
mtx_lock(&Giant);
|
||||
NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path, td);
|
||||
NDINIT(&nd, LOOKUP, FOLLOW, pathseg, path, td);
|
||||
if ((error = namei(&nd)) != 0) {
|
||||
mtx_unlock(&Giant);
|
||||
return (error);
|
||||
@ -258,7 +271,8 @@ statfs(td, uap)
|
||||
sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0;
|
||||
sp = &sb;
|
||||
}
|
||||
return (copyout(sp, uap->buf, sizeof(*sp)));
|
||||
*buf = *sp;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -277,13 +291,25 @@ fstatfs(td, uap)
|
||||
int fd;
|
||||
struct statfs *buf;
|
||||
} */ *uap;
|
||||
{
|
||||
struct statfs sf;
|
||||
int error;
|
||||
|
||||
error = kern_fstatfs(td, uap->fd, &sf);
|
||||
if (error == 0)
|
||||
error = copyout(&sf, uap->buf, sizeof(sf));
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
kern_fstatfs(struct thread *td, int fd, struct statfs *buf)
|
||||
{
|
||||
struct file *fp;
|
||||
struct mount *mp;
|
||||
struct statfs *sp, sb;
|
||||
int error;
|
||||
|
||||
if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0)
|
||||
if ((error = getvnode(td->td_proc->p_fd, fd, &fp)) != 0)
|
||||
return (error);
|
||||
mtx_lock(&Giant);
|
||||
mp = fp->f_vnode->v_mount;
|
||||
@ -315,7 +341,8 @@ fstatfs(td, uap)
|
||||
sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0;
|
||||
sp = &sb;
|
||||
}
|
||||
return (copyout(sp, uap->buf, sizeof(*sp)));
|
||||
*buf = *sp;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -431,29 +458,14 @@ freebsd4_statfs(td, uap)
|
||||
struct ostatfs *buf;
|
||||
} */ *uap;
|
||||
{
|
||||
struct mount *mp;
|
||||
struct statfs *sp;
|
||||
struct ostatfs osb;
|
||||
struct statfs sf;
|
||||
int error;
|
||||
struct nameidata nd;
|
||||
|
||||
NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path, td);
|
||||
if ((error = namei(&nd)) != 0)
|
||||
return (error);
|
||||
mp = nd.ni_vp->v_mount;
|
||||
sp = &mp->mnt_stat;
|
||||
NDFREE(&nd, NDF_ONLY_PNBUF);
|
||||
vrele(nd.ni_vp);
|
||||
#ifdef MAC
|
||||
error = mac_check_mount_stat(td->td_ucred, mp);
|
||||
error = kern_statfs(td, uap->path, UIO_USERSPACE, &sf);
|
||||
if (error)
|
||||
return (error);
|
||||
#endif
|
||||
error = VFS_STATFS(mp, sp, td);
|
||||
if (error)
|
||||
return (error);
|
||||
sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
|
||||
cvtstatfs(td, sp, &osb);
|
||||
cvtstatfs(td, &sf, &osb);
|
||||
return (copyout(&osb, uap->buf, sizeof(osb)));
|
||||
}
|
||||
|
||||
@ -474,29 +486,14 @@ freebsd4_fstatfs(td, uap)
|
||||
struct ostatfs *buf;
|
||||
} */ *uap;
|
||||
{
|
||||
struct file *fp;
|
||||
struct mount *mp;
|
||||
struct statfs *sp;
|
||||
struct ostatfs osb;
|
||||
struct statfs sf;
|
||||
int error;
|
||||
|
||||
if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0)
|
||||
return (error);
|
||||
mp = fp->f_vnode->v_mount;
|
||||
fdrop(fp, td);
|
||||
if (mp == NULL)
|
||||
return (EBADF);
|
||||
#ifdef MAC
|
||||
error = mac_check_mount_stat(td->td_ucred, mp);
|
||||
error = kern_fstatfs(td, uap->fd, &sf);
|
||||
if (error)
|
||||
return (error);
|
||||
#endif
|
||||
sp = &mp->mnt_stat;
|
||||
error = VFS_STATFS(mp, sp, td);
|
||||
if (error)
|
||||
return (error);
|
||||
sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
|
||||
cvtstatfs(td, sp, &osb);
|
||||
cvtstatfs(td, &sf, &osb);
|
||||
return (copyout(&osb, uap->buf, sizeof(osb)));
|
||||
}
|
||||
|
||||
@ -598,34 +595,17 @@ freebsd4_fhstatfs(td, uap)
|
||||
struct ostatfs *buf;
|
||||
} */ *uap;
|
||||
{
|
||||
struct statfs *sp;
|
||||
struct mount *mp;
|
||||
struct vnode *vp;
|
||||
struct ostatfs osb;
|
||||
struct statfs sf;
|
||||
fhandle_t fh;
|
||||
int error;
|
||||
|
||||
error = suser(td);
|
||||
if (error)
|
||||
return (error);
|
||||
if ((error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t))) != 0)
|
||||
return (error);
|
||||
if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL)
|
||||
return (ESTALE);
|
||||
if ((error = VFS_FHTOVP(mp, &fh.fh_fid, &vp)))
|
||||
return (error);
|
||||
mp = vp->v_mount;
|
||||
sp = &mp->mnt_stat;
|
||||
vput(vp);
|
||||
#ifdef MAC
|
||||
error = mac_check_mount_stat(td->td_ucred, mp);
|
||||
error = kern_fhstatfs(td, fh, &sf);
|
||||
if (error)
|
||||
return (error);
|
||||
#endif
|
||||
if ((error = VFS_STATFS(mp, sp, td)) != 0)
|
||||
return (error);
|
||||
sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
|
||||
cvtstatfs(td, sp, &osb);
|
||||
cvtstatfs(td, &sf, &osb);
|
||||
return (copyout(&osb, uap->buf, sizeof(osb)));
|
||||
}
|
||||
|
||||
@ -1972,15 +1952,8 @@ ostat(td, uap)
|
||||
struct stat sb;
|
||||
struct ostat osb;
|
||||
int error;
|
||||
struct nameidata nd;
|
||||
|
||||
NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
|
||||
uap->path, td);
|
||||
if ((error = namei(&nd)) != 0)
|
||||
return (error);
|
||||
NDFREE(&nd, NDF_ONLY_PNBUF);
|
||||
error = vn_stat(nd.ni_vp, &sb, td->td_ucred, NOCRED, td);
|
||||
vput(nd.ni_vp);
|
||||
error = kern_stat(td, uap->path, UIO_USERSPACE, &sb);
|
||||
if (error)
|
||||
return (error);
|
||||
cvtstat(&sb, &osb);
|
||||
@ -2005,20 +1978,11 @@ olstat(td, uap)
|
||||
struct ostat *ub;
|
||||
} */ *uap;
|
||||
{
|
||||
struct vnode *vp;
|
||||
struct stat sb;
|
||||
struct ostat osb;
|
||||
int error;
|
||||
struct nameidata nd;
|
||||
|
||||
NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
|
||||
uap->path, td);
|
||||
if ((error = namei(&nd)) != 0)
|
||||
return (error);
|
||||
vp = nd.ni_vp;
|
||||
error = vn_stat(vp, &sb, td->td_ucred, NOCRED, td);
|
||||
NDFREE(&nd, NDF_ONLY_PNBUF);
|
||||
vput(vp);
|
||||
error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb);
|
||||
if (error)
|
||||
return (error);
|
||||
cvtstat(&sb, &osb);
|
||||
@ -2075,15 +2039,26 @@ stat(td, uap)
|
||||
{
|
||||
struct stat sb;
|
||||
int error;
|
||||
|
||||
error = kern_stat(td, uap->path, UIO_USERSPACE, &sb);
|
||||
if (error == 0)
|
||||
error = copyout(&sb, uap->ub, sizeof (sb));
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
kern_stat(struct thread *td, char *path, enum uio_seg pathseg, struct stat *sbp)
|
||||
{
|
||||
struct nameidata nd;
|
||||
int vfslocked;
|
||||
struct stat sb;
|
||||
int error, vfslocked;
|
||||
|
||||
#ifdef LOOKUP_SHARED
|
||||
NDINIT(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF | NOOBJ | MPSAFE,
|
||||
UIO_USERSPACE, uap->path, td);
|
||||
pathseg, path, td);
|
||||
#else
|
||||
NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ | MPSAFE, UIO_USERSPACE,
|
||||
uap->path, td);
|
||||
NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ | MPSAFE, pathseg, path,
|
||||
td);
|
||||
#endif
|
||||
if ((error = namei(&nd)) != 0)
|
||||
return (error);
|
||||
@ -2094,8 +2069,8 @@ stat(td, uap)
|
||||
VFS_UNLOCK_GIANT(vfslocked);
|
||||
if (error)
|
||||
return (error);
|
||||
error = copyout(&sb, uap->ub, sizeof (sb));
|
||||
return (error);
|
||||
*sbp = sb;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2115,14 +2090,26 @@ lstat(td, uap)
|
||||
struct stat *ub;
|
||||
} */ *uap;
|
||||
{
|
||||
struct stat sb;
|
||||
int error;
|
||||
|
||||
error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb);
|
||||
if (error == 0)
|
||||
error = copyout(&sb, uap->ub, sizeof (sb));
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
kern_lstat(struct thread *td, char *path, enum uio_seg pathseg, struct stat *sbp)
|
||||
{
|
||||
struct vnode *vp;
|
||||
struct stat sb;
|
||||
struct nameidata nd;
|
||||
int vfslocked;
|
||||
int error, vfslocked;
|
||||
|
||||
/* XXX LOOKUP_SHARED? */
|
||||
NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ | MPSAFE,
|
||||
UIO_USERSPACE, uap->path, td);
|
||||
pathseg, path, td);
|
||||
if ((error = namei(&nd)) != 0)
|
||||
return (error);
|
||||
vfslocked = NDHASGIANT(&nd);
|
||||
@ -2133,16 +2120,12 @@ lstat(td, uap)
|
||||
VFS_UNLOCK_GIANT(vfslocked);
|
||||
if (error)
|
||||
return (error);
|
||||
error = copyout(&sb, uap->ub, sizeof (sb));
|
||||
return (error);
|
||||
*sbp = sb;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Implementation of the NetBSD stat() function.
|
||||
* XXX This should probably be collapsed with the FreeBSD version,
|
||||
* as the differences are only due to vn_stat() clearing spares at
|
||||
* the end of the structures. vn_stat could be split to avoid this,
|
||||
* and thus collapse the following to close to zero code.
|
||||
* Implementation of the NetBSD [l]stat() functions.
|
||||
*/
|
||||
void
|
||||
cvtnstat(sb, nsb)
|
||||
@ -2185,18 +2168,8 @@ nstat(td, uap)
|
||||
struct stat sb;
|
||||
struct nstat nsb;
|
||||
int error;
|
||||
struct nameidata nd;
|
||||
int vfslocked;
|
||||
|
||||
NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ | MPSAFE, UIO_USERSPACE,
|
||||
uap->path, td);
|
||||
if ((error = namei(&nd)) != 0)
|
||||
return (error);
|
||||
vfslocked = NDHASGIANT(&nd);
|
||||
NDFREE(&nd, NDF_ONLY_PNBUF);
|
||||
error = vn_stat(nd.ni_vp, &sb, td->td_ucred, NOCRED, td);
|
||||
vput(nd.ni_vp);
|
||||
VFS_UNLOCK_GIANT(vfslocked);
|
||||
error = kern_stat(td, uap->path, UIO_USERSPACE, &sb);
|
||||
if (error)
|
||||
return (error);
|
||||
cvtnstat(&sb, &nsb);
|
||||
@ -2221,23 +2194,11 @@ nlstat(td, uap)
|
||||
struct nstat *ub;
|
||||
} */ *uap;
|
||||
{
|
||||
int error;
|
||||
struct vnode *vp;
|
||||
struct stat sb;
|
||||
struct nstat nsb;
|
||||
struct nameidata nd;
|
||||
int vfslocked;
|
||||
int error;
|
||||
|
||||
NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ | MPSAFE,
|
||||
UIO_USERSPACE, uap->path, td);
|
||||
if ((error = namei(&nd)) != 0)
|
||||
return (error);
|
||||
vfslocked = NDHASGIANT(&nd);
|
||||
vp = nd.ni_vp;
|
||||
NDFREE(&nd, NDF_ONLY_PNBUF);
|
||||
error = vn_stat(vp, &sb, td->td_ucred, NOCRED, td);
|
||||
vput(vp);
|
||||
VFS_UNLOCK_GIANT(vfslocked);
|
||||
error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb);
|
||||
if (error)
|
||||
return (error);
|
||||
cvtnstat(&sb, &nsb);
|
||||
@ -4233,18 +4194,30 @@ fhstatfs(td, uap)
|
||||
struct fhandle *u_fhp;
|
||||
struct statfs *buf;
|
||||
} */ *uap;
|
||||
{
|
||||
struct statfs sf;
|
||||
fhandle_t fh;
|
||||
int error;
|
||||
|
||||
if ((error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t))) != 0)
|
||||
return (error);
|
||||
error = kern_fhstatfs(td, fh, &sf);
|
||||
if (error == 0)
|
||||
error = copyout(&sf, uap->buf, sizeof(sf));
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
kern_fhstatfs(struct thread *td, fhandle_t fh, struct statfs *buf)
|
||||
{
|
||||
struct statfs *sp;
|
||||
struct mount *mp;
|
||||
struct vnode *vp;
|
||||
fhandle_t fh;
|
||||
int error;
|
||||
|
||||
error = suser(td);
|
||||
if (error)
|
||||
return (error);
|
||||
if ((error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t))) != 0)
|
||||
return (error);
|
||||
if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL)
|
||||
return (ESTALE);
|
||||
if ((error = VFS_FHTOVP(mp, &fh.fh_fid, &vp)))
|
||||
@ -4265,7 +4238,8 @@ fhstatfs(td, uap)
|
||||
sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
|
||||
if ((error = VFS_STATFS(mp, sp, td)) != 0)
|
||||
return (error);
|
||||
return (copyout(sp, uap->buf, sizeof(*sp)));
|
||||
*buf = *sp;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/mount.h>
|
||||
#include <sys/filedesc.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/syscallsubr.h>
|
||||
#ifdef KTRACE
|
||||
#include <sys/ktrace.h>
|
||||
#endif
|
||||
@ -807,3 +808,115 @@ relookup(dvp, vpp, cnp)
|
||||
*vpp = NULL;
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine if there is a suitable alternate filename under the specified
|
||||
* prefix for the specified path. If the create flag is set, then the
|
||||
* alternate prefix will be used so long as the parent directory exists.
|
||||
* This is used by the various compatiblity ABIs so that Linux binaries prefer
|
||||
* files under /compat/linux for example. The chosen path (whether under
|
||||
* the prefix or under /) is returned in a kernel malloc'd buffer pointed
|
||||
* to by pathbuf. The caller is responsible for free'ing the buffer from
|
||||
* the M_TEMP bucket if one is returned.
|
||||
*/
|
||||
int
|
||||
kern_alternate_path(struct thread *td, const char *prefix, char *path,
|
||||
enum uio_seg pathseg, char **pathbuf, int create)
|
||||
{
|
||||
struct nameidata nd, ndroot;
|
||||
char *ptr, *buf, *cp;
|
||||
size_t len, sz;
|
||||
int error;
|
||||
|
||||
buf = (char *) malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
|
||||
*pathbuf = buf;
|
||||
|
||||
/* Copy the prefix into the new pathname as a starting point. */
|
||||
len = strlcpy(buf, prefix, MAXPATHLEN);
|
||||
if (len >= MAXPATHLEN) {
|
||||
*pathbuf = NULL;
|
||||
free(buf, M_TEMP);
|
||||
return (EINVAL);
|
||||
}
|
||||
sz = MAXPATHLEN - len;
|
||||
ptr = buf + len;
|
||||
|
||||
/* Append the filename to the prefix. */
|
||||
if (pathseg == UIO_SYSSPACE)
|
||||
error = copystr(path, ptr, sz, &len);
|
||||
else
|
||||
error = copyinstr(path, ptr, sz, &len);
|
||||
|
||||
if (error) {
|
||||
*pathbuf = NULL;
|
||||
free(buf, M_TEMP);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/* Only use a prefix with absolute pathnames. */
|
||||
if (*ptr != '/') {
|
||||
error = EINVAL;
|
||||
goto keeporig;
|
||||
}
|
||||
|
||||
/* XXX: VFS_LOCK_GIANT? */
|
||||
mtx_lock(&Giant);
|
||||
|
||||
/*
|
||||
* We know that there is a / somewhere in this pathname.
|
||||
* Search backwards for it, to find the file's parent dir
|
||||
* to see if it exists in the alternate tree. If it does,
|
||||
* and we want to create a file (cflag is set). We don't
|
||||
* need to worry about the root comparison in this case.
|
||||
*/
|
||||
|
||||
if (create) {
|
||||
for (cp = &ptr[len] - 1; *cp != '/'; cp--);
|
||||
*cp = '\0';
|
||||
|
||||
NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, td);
|
||||
error = namei(&nd);
|
||||
*cp = '/';
|
||||
if (error != 0)
|
||||
goto nd_failed;
|
||||
} else {
|
||||
NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, td);
|
||||
|
||||
error = namei(&nd);
|
||||
if (error != 0)
|
||||
goto nd_failed;
|
||||
|
||||
/*
|
||||
* We now compare the vnode of the prefix to the one
|
||||
* vnode asked. If they resolve to be the same, then we
|
||||
* ignore the match so that the real root gets used.
|
||||
* This avoids the problem of traversing "../.." to find the
|
||||
* root directory and never finding it, because "/" resolves
|
||||
* to the emulation root directory. This is expensive :-(
|
||||
*/
|
||||
NDINIT(&ndroot, LOOKUP, FOLLOW, UIO_SYSSPACE, prefix, td);
|
||||
|
||||
/* We shouldn't ever get an error from this namei(). */
|
||||
error = namei(&ndroot);
|
||||
if (error == 0) {
|
||||
if (nd.ni_vp == ndroot.ni_vp)
|
||||
error = ENOENT;
|
||||
|
||||
NDFREE(&ndroot, NDF_ONLY_PNBUF);
|
||||
vrele(ndroot.ni_vp);
|
||||
}
|
||||
}
|
||||
|
||||
NDFREE(&nd, NDF_ONLY_PNBUF);
|
||||
vrele(nd.ni_vp);
|
||||
|
||||
nd_failed:
|
||||
/* XXX: VFS_UNLOCK_GIANT? */
|
||||
mtx_unlock(&Giant);
|
||||
|
||||
keeporig:
|
||||
/* If there was an error, use the original path name. */
|
||||
if (error)
|
||||
bcopy(ptr, buf, len);
|
||||
return (error);
|
||||
}
|
||||
|
@ -220,6 +220,19 @@ statfs(td, uap)
|
||||
char *path;
|
||||
struct statfs *buf;
|
||||
} */ *uap;
|
||||
{
|
||||
struct statfs sf;
|
||||
int error;
|
||||
|
||||
error = kern_statfs(td, uap->path, UIO_USERSPACE, &sf);
|
||||
if (error == 0)
|
||||
error = copyout(&sf, uap->buf, sizeof(sf));
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
kern_statfs(struct thread *td, char *path, enum uio_seg pathseg,
|
||||
struct statfs *buf)
|
||||
{
|
||||
struct mount *mp;
|
||||
struct statfs *sp, sb;
|
||||
@ -227,7 +240,7 @@ statfs(td, uap)
|
||||
struct nameidata nd;
|
||||
|
||||
mtx_lock(&Giant);
|
||||
NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path, td);
|
||||
NDINIT(&nd, LOOKUP, FOLLOW, pathseg, path, td);
|
||||
if ((error = namei(&nd)) != 0) {
|
||||
mtx_unlock(&Giant);
|
||||
return (error);
|
||||
@ -258,7 +271,8 @@ statfs(td, uap)
|
||||
sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0;
|
||||
sp = &sb;
|
||||
}
|
||||
return (copyout(sp, uap->buf, sizeof(*sp)));
|
||||
*buf = *sp;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -277,13 +291,25 @@ fstatfs(td, uap)
|
||||
int fd;
|
||||
struct statfs *buf;
|
||||
} */ *uap;
|
||||
{
|
||||
struct statfs sf;
|
||||
int error;
|
||||
|
||||
error = kern_fstatfs(td, uap->fd, &sf);
|
||||
if (error == 0)
|
||||
error = copyout(&sf, uap->buf, sizeof(sf));
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
kern_fstatfs(struct thread *td, int fd, struct statfs *buf)
|
||||
{
|
||||
struct file *fp;
|
||||
struct mount *mp;
|
||||
struct statfs *sp, sb;
|
||||
int error;
|
||||
|
||||
if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0)
|
||||
if ((error = getvnode(td->td_proc->p_fd, fd, &fp)) != 0)
|
||||
return (error);
|
||||
mtx_lock(&Giant);
|
||||
mp = fp->f_vnode->v_mount;
|
||||
@ -315,7 +341,8 @@ fstatfs(td, uap)
|
||||
sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0;
|
||||
sp = &sb;
|
||||
}
|
||||
return (copyout(sp, uap->buf, sizeof(*sp)));
|
||||
*buf = *sp;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -431,29 +458,14 @@ freebsd4_statfs(td, uap)
|
||||
struct ostatfs *buf;
|
||||
} */ *uap;
|
||||
{
|
||||
struct mount *mp;
|
||||
struct statfs *sp;
|
||||
struct ostatfs osb;
|
||||
struct statfs sf;
|
||||
int error;
|
||||
struct nameidata nd;
|
||||
|
||||
NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path, td);
|
||||
if ((error = namei(&nd)) != 0)
|
||||
return (error);
|
||||
mp = nd.ni_vp->v_mount;
|
||||
sp = &mp->mnt_stat;
|
||||
NDFREE(&nd, NDF_ONLY_PNBUF);
|
||||
vrele(nd.ni_vp);
|
||||
#ifdef MAC
|
||||
error = mac_check_mount_stat(td->td_ucred, mp);
|
||||
error = kern_statfs(td, uap->path, UIO_USERSPACE, &sf);
|
||||
if (error)
|
||||
return (error);
|
||||
#endif
|
||||
error = VFS_STATFS(mp, sp, td);
|
||||
if (error)
|
||||
return (error);
|
||||
sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
|
||||
cvtstatfs(td, sp, &osb);
|
||||
cvtstatfs(td, &sf, &osb);
|
||||
return (copyout(&osb, uap->buf, sizeof(osb)));
|
||||
}
|
||||
|
||||
@ -474,29 +486,14 @@ freebsd4_fstatfs(td, uap)
|
||||
struct ostatfs *buf;
|
||||
} */ *uap;
|
||||
{
|
||||
struct file *fp;
|
||||
struct mount *mp;
|
||||
struct statfs *sp;
|
||||
struct ostatfs osb;
|
||||
struct statfs sf;
|
||||
int error;
|
||||
|
||||
if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0)
|
||||
return (error);
|
||||
mp = fp->f_vnode->v_mount;
|
||||
fdrop(fp, td);
|
||||
if (mp == NULL)
|
||||
return (EBADF);
|
||||
#ifdef MAC
|
||||
error = mac_check_mount_stat(td->td_ucred, mp);
|
||||
error = kern_fstatfs(td, uap->fd, &sf);
|
||||
if (error)
|
||||
return (error);
|
||||
#endif
|
||||
sp = &mp->mnt_stat;
|
||||
error = VFS_STATFS(mp, sp, td);
|
||||
if (error)
|
||||
return (error);
|
||||
sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
|
||||
cvtstatfs(td, sp, &osb);
|
||||
cvtstatfs(td, &sf, &osb);
|
||||
return (copyout(&osb, uap->buf, sizeof(osb)));
|
||||
}
|
||||
|
||||
@ -598,34 +595,17 @@ freebsd4_fhstatfs(td, uap)
|
||||
struct ostatfs *buf;
|
||||
} */ *uap;
|
||||
{
|
||||
struct statfs *sp;
|
||||
struct mount *mp;
|
||||
struct vnode *vp;
|
||||
struct ostatfs osb;
|
||||
struct statfs sf;
|
||||
fhandle_t fh;
|
||||
int error;
|
||||
|
||||
error = suser(td);
|
||||
if (error)
|
||||
return (error);
|
||||
if ((error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t))) != 0)
|
||||
return (error);
|
||||
if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL)
|
||||
return (ESTALE);
|
||||
if ((error = VFS_FHTOVP(mp, &fh.fh_fid, &vp)))
|
||||
return (error);
|
||||
mp = vp->v_mount;
|
||||
sp = &mp->mnt_stat;
|
||||
vput(vp);
|
||||
#ifdef MAC
|
||||
error = mac_check_mount_stat(td->td_ucred, mp);
|
||||
error = kern_fhstatfs(td, fh, &sf);
|
||||
if (error)
|
||||
return (error);
|
||||
#endif
|
||||
if ((error = VFS_STATFS(mp, sp, td)) != 0)
|
||||
return (error);
|
||||
sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
|
||||
cvtstatfs(td, sp, &osb);
|
||||
cvtstatfs(td, &sf, &osb);
|
||||
return (copyout(&osb, uap->buf, sizeof(osb)));
|
||||
}
|
||||
|
||||
@ -1972,15 +1952,8 @@ ostat(td, uap)
|
||||
struct stat sb;
|
||||
struct ostat osb;
|
||||
int error;
|
||||
struct nameidata nd;
|
||||
|
||||
NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
|
||||
uap->path, td);
|
||||
if ((error = namei(&nd)) != 0)
|
||||
return (error);
|
||||
NDFREE(&nd, NDF_ONLY_PNBUF);
|
||||
error = vn_stat(nd.ni_vp, &sb, td->td_ucred, NOCRED, td);
|
||||
vput(nd.ni_vp);
|
||||
error = kern_stat(td, uap->path, UIO_USERSPACE, &sb);
|
||||
if (error)
|
||||
return (error);
|
||||
cvtstat(&sb, &osb);
|
||||
@ -2005,20 +1978,11 @@ olstat(td, uap)
|
||||
struct ostat *ub;
|
||||
} */ *uap;
|
||||
{
|
||||
struct vnode *vp;
|
||||
struct stat sb;
|
||||
struct ostat osb;
|
||||
int error;
|
||||
struct nameidata nd;
|
||||
|
||||
NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
|
||||
uap->path, td);
|
||||
if ((error = namei(&nd)) != 0)
|
||||
return (error);
|
||||
vp = nd.ni_vp;
|
||||
error = vn_stat(vp, &sb, td->td_ucred, NOCRED, td);
|
||||
NDFREE(&nd, NDF_ONLY_PNBUF);
|
||||
vput(vp);
|
||||
error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb);
|
||||
if (error)
|
||||
return (error);
|
||||
cvtstat(&sb, &osb);
|
||||
@ -2075,15 +2039,26 @@ stat(td, uap)
|
||||
{
|
||||
struct stat sb;
|
||||
int error;
|
||||
|
||||
error = kern_stat(td, uap->path, UIO_USERSPACE, &sb);
|
||||
if (error == 0)
|
||||
error = copyout(&sb, uap->ub, sizeof (sb));
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
kern_stat(struct thread *td, char *path, enum uio_seg pathseg, struct stat *sbp)
|
||||
{
|
||||
struct nameidata nd;
|
||||
int vfslocked;
|
||||
struct stat sb;
|
||||
int error, vfslocked;
|
||||
|
||||
#ifdef LOOKUP_SHARED
|
||||
NDINIT(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF | NOOBJ | MPSAFE,
|
||||
UIO_USERSPACE, uap->path, td);
|
||||
pathseg, path, td);
|
||||
#else
|
||||
NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ | MPSAFE, UIO_USERSPACE,
|
||||
uap->path, td);
|
||||
NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ | MPSAFE, pathseg, path,
|
||||
td);
|
||||
#endif
|
||||
if ((error = namei(&nd)) != 0)
|
||||
return (error);
|
||||
@ -2094,8 +2069,8 @@ stat(td, uap)
|
||||
VFS_UNLOCK_GIANT(vfslocked);
|
||||
if (error)
|
||||
return (error);
|
||||
error = copyout(&sb, uap->ub, sizeof (sb));
|
||||
return (error);
|
||||
*sbp = sb;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2115,14 +2090,26 @@ lstat(td, uap)
|
||||
struct stat *ub;
|
||||
} */ *uap;
|
||||
{
|
||||
struct stat sb;
|
||||
int error;
|
||||
|
||||
error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb);
|
||||
if (error == 0)
|
||||
error = copyout(&sb, uap->ub, sizeof (sb));
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
kern_lstat(struct thread *td, char *path, enum uio_seg pathseg, struct stat *sbp)
|
||||
{
|
||||
struct vnode *vp;
|
||||
struct stat sb;
|
||||
struct nameidata nd;
|
||||
int vfslocked;
|
||||
int error, vfslocked;
|
||||
|
||||
/* XXX LOOKUP_SHARED? */
|
||||
NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ | MPSAFE,
|
||||
UIO_USERSPACE, uap->path, td);
|
||||
pathseg, path, td);
|
||||
if ((error = namei(&nd)) != 0)
|
||||
return (error);
|
||||
vfslocked = NDHASGIANT(&nd);
|
||||
@ -2133,16 +2120,12 @@ lstat(td, uap)
|
||||
VFS_UNLOCK_GIANT(vfslocked);
|
||||
if (error)
|
||||
return (error);
|
||||
error = copyout(&sb, uap->ub, sizeof (sb));
|
||||
return (error);
|
||||
*sbp = sb;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Implementation of the NetBSD stat() function.
|
||||
* XXX This should probably be collapsed with the FreeBSD version,
|
||||
* as the differences are only due to vn_stat() clearing spares at
|
||||
* the end of the structures. vn_stat could be split to avoid this,
|
||||
* and thus collapse the following to close to zero code.
|
||||
* Implementation of the NetBSD [l]stat() functions.
|
||||
*/
|
||||
void
|
||||
cvtnstat(sb, nsb)
|
||||
@ -2185,18 +2168,8 @@ nstat(td, uap)
|
||||
struct stat sb;
|
||||
struct nstat nsb;
|
||||
int error;
|
||||
struct nameidata nd;
|
||||
int vfslocked;
|
||||
|
||||
NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ | MPSAFE, UIO_USERSPACE,
|
||||
uap->path, td);
|
||||
if ((error = namei(&nd)) != 0)
|
||||
return (error);
|
||||
vfslocked = NDHASGIANT(&nd);
|
||||
NDFREE(&nd, NDF_ONLY_PNBUF);
|
||||
error = vn_stat(nd.ni_vp, &sb, td->td_ucred, NOCRED, td);
|
||||
vput(nd.ni_vp);
|
||||
VFS_UNLOCK_GIANT(vfslocked);
|
||||
error = kern_stat(td, uap->path, UIO_USERSPACE, &sb);
|
||||
if (error)
|
||||
return (error);
|
||||
cvtnstat(&sb, &nsb);
|
||||
@ -2221,23 +2194,11 @@ nlstat(td, uap)
|
||||
struct nstat *ub;
|
||||
} */ *uap;
|
||||
{
|
||||
int error;
|
||||
struct vnode *vp;
|
||||
struct stat sb;
|
||||
struct nstat nsb;
|
||||
struct nameidata nd;
|
||||
int vfslocked;
|
||||
int error;
|
||||
|
||||
NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ | MPSAFE,
|
||||
UIO_USERSPACE, uap->path, td);
|
||||
if ((error = namei(&nd)) != 0)
|
||||
return (error);
|
||||
vfslocked = NDHASGIANT(&nd);
|
||||
vp = nd.ni_vp;
|
||||
NDFREE(&nd, NDF_ONLY_PNBUF);
|
||||
error = vn_stat(vp, &sb, td->td_ucred, NOCRED, td);
|
||||
vput(vp);
|
||||
VFS_UNLOCK_GIANT(vfslocked);
|
||||
error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb);
|
||||
if (error)
|
||||
return (error);
|
||||
cvtnstat(&sb, &nsb);
|
||||
@ -4233,18 +4194,30 @@ fhstatfs(td, uap)
|
||||
struct fhandle *u_fhp;
|
||||
struct statfs *buf;
|
||||
} */ *uap;
|
||||
{
|
||||
struct statfs sf;
|
||||
fhandle_t fh;
|
||||
int error;
|
||||
|
||||
if ((error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t))) != 0)
|
||||
return (error);
|
||||
error = kern_fhstatfs(td, fh, &sf);
|
||||
if (error == 0)
|
||||
error = copyout(&sf, uap->buf, sizeof(sf));
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
kern_fhstatfs(struct thread *td, fhandle_t fh, struct statfs *buf)
|
||||
{
|
||||
struct statfs *sp;
|
||||
struct mount *mp;
|
||||
struct vnode *vp;
|
||||
fhandle_t fh;
|
||||
int error;
|
||||
|
||||
error = suser(td);
|
||||
if (error)
|
||||
return (error);
|
||||
if ((error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t))) != 0)
|
||||
return (error);
|
||||
if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL)
|
||||
return (ESTALE);
|
||||
if ((error = VFS_FHTOVP(mp, &fh.fh_fid, &vp)))
|
||||
@ -4265,7 +4238,8 @@ fhstatfs(td, uap)
|
||||
sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
|
||||
if ((error = VFS_STATFS(mp, sp, td)) != 0)
|
||||
return (error);
|
||||
return (copyout(sp, uap->buf, sizeof(*sp)));
|
||||
*buf = *sp;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -32,20 +32,24 @@
|
||||
#include <sys/uio.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/mac.h>
|
||||
#include <sys/mount.h>
|
||||
|
||||
struct itimerval;
|
||||
struct image_args;
|
||||
struct mbuf;
|
||||
struct msghdr;
|
||||
struct msqid_ds;
|
||||
struct rlimit;
|
||||
struct rusage;
|
||||
struct sockaddr;
|
||||
struct itimerval;
|
||||
struct msqid_ds;
|
||||
struct image_args;
|
||||
struct stat;
|
||||
|
||||
int kern___getcwd(struct thread *td, u_char *buf, enum uio_seg bufseg,
|
||||
u_int buflen);
|
||||
int kern_access(struct thread *td, char *path, enum uio_seg pathseg,
|
||||
int flags);
|
||||
int kern_alternate_path(struct thread *td, const char *prefix, char *path,
|
||||
enum uio_seg pathseg, char **pathbuf, int create);
|
||||
int kern_bind(struct thread *td, int fd, struct sockaddr *sa);
|
||||
int kern_chdir(struct thread *td, char *path, enum uio_seg pathseg);
|
||||
int kern_chmod(struct thread *td, char *path, enum uio_seg pathseg,
|
||||
@ -56,6 +60,9 @@ int kern_connect(struct thread *td, int fd, struct sockaddr *sa);
|
||||
int kern_execve(struct thread *td, struct image_args *args,
|
||||
struct mac *mac_p);
|
||||
int kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg);
|
||||
int kern_fhstatfs(struct thread *td, fhandle_t fh, struct statfs *buf);
|
||||
int kern_fstat(struct thread *td, int fd, struct stat *sbp);
|
||||
int kern_fstatfs(struct thread *td, int fd, struct statfs *buf);
|
||||
int kern_futimes(struct thread *td, int fd, struct timeval *tptr,
|
||||
enum uio_seg tptrseg);
|
||||
int kern_getitimer(struct thread *, u_int, struct itimerval *);
|
||||
@ -66,6 +73,8 @@ int kern_lchown(struct thread *td, char *path, enum uio_seg pathseg,
|
||||
int uid, int gid);
|
||||
int kern_link(struct thread *td, char *path, char *link,
|
||||
enum uio_seg segflg);
|
||||
int kern_lstat(struct thread *td, char *path, enum uio_seg pathseg,
|
||||
struct stat *sbp);
|
||||
int kern_lutimes(struct thread *td, char *path, enum uio_seg pathseg,
|
||||
struct timeval *tptr, enum uio_seg tptrseg);
|
||||
int kern_mkdir(struct thread *td, char *path, enum uio_seg segflg,
|
||||
@ -74,8 +83,7 @@ int kern_mkfifo(struct thread *td, char *path, enum uio_seg pathseg,
|
||||
int mode);
|
||||
int kern_mknod(struct thread *td, char *path, enum uio_seg pathseg,
|
||||
int mode, int dev);
|
||||
int kern_msgctl(struct thread *, int, int, struct msqid_ds *,
|
||||
struct msqid_ds **);
|
||||
int kern_msgctl(struct thread *, int, int, struct msqid_ds *);
|
||||
int kern_nanosleep(struct thread *td, struct timespec *rqt,
|
||||
struct timespec *rmt);
|
||||
int kern_open(struct thread *td, char *path, enum uio_seg pathseg,
|
||||
@ -106,6 +114,10 @@ int kern_sigaltstack(struct thread *td, stack_t *ss, stack_t *oss);
|
||||
int kern_sigprocmask(struct thread *td, int how,
|
||||
sigset_t *set, sigset_t *oset, int old);
|
||||
int kern_sigsuspend(struct thread *td, sigset_t mask);
|
||||
int kern_stat(struct thread *td, char *path, enum uio_seg pathseg,
|
||||
struct stat *sbp);
|
||||
int kern_statfs(struct thread *td, char *path, enum uio_seg pathseg,
|
||||
struct statfs *buf);
|
||||
int kern_symlink(struct thread *td, char *path, char *link,
|
||||
enum uio_seg segflg);
|
||||
int kern_truncate(struct thread *td, char *path, enum uio_seg pathseg,
|
||||
|
Loading…
Reference in New Issue
Block a user