version 1.447, 2012/02/01 05:46:45 |
version 1.448, 2012/02/11 23:16:17 |
Line 119 __KERNEL_RCSID(0, "$NetBSD$"); |
|
Line 119 __KERNEL_RCSID(0, "$NetBSD$"); |
|
static int change_flags(struct vnode *, u_long, struct lwp *); |
static int change_flags(struct vnode *, u_long, struct lwp *); |
static int change_mode(struct vnode *, int, struct lwp *l); |
static int change_mode(struct vnode *, int, struct lwp *l); |
static int change_owner(struct vnode *, uid_t, gid_t, struct lwp *, int); |
static int change_owner(struct vnode *, uid_t, gid_t, struct lwp *, int); |
|
static int do_open(lwp_t *, struct pathbuf *, int, int, int *); |
|
|
/* |
/* |
* This table is used to maintain compatibility with 4.3BSD |
* This table is used to maintain compatibility with 4.3BSD |
Line 1464 chdir_lookup(const char *path, int where |
|
Line 1465 chdir_lookup(const char *path, int where |
|
} |
} |
|
|
/* |
/* |
* Check permissions, allocate an open file structure, |
* Internals of sys_open - path has already been converted into a pathbuf |
* and call the device open routine if any. |
* (so we can easily reuse this function from other parts of the kernel, |
|
* like posix_spawn post-processing). |
*/ |
*/ |
int |
static int |
sys_open(struct lwp *l, const struct sys_open_args *uap, register_t *retval) |
do_open(lwp_t *l, struct pathbuf *pb, int open_flags, int open_mode, int *fd) |
{ |
{ |
/* { |
|
syscallarg(const char *) path; |
|
syscallarg(int) flags; |
|
syscallarg(int) mode; |
|
} */ |
|
struct proc *p = l->l_proc; |
struct proc *p = l->l_proc; |
struct cwdinfo *cwdi = p->p_cwdi; |
struct cwdinfo *cwdi = p->p_cwdi; |
file_t *fp; |
file_t *fp; |
struct vnode *vp; |
struct vnode *vp; |
int flags, cmode; |
int flags, cmode; |
int indx, error; |
int indx, error; |
struct pathbuf *pb; |
|
struct nameidata nd; |
struct nameidata nd; |
|
|
flags = FFLAGS(SCARG(uap, flags)); |
flags = FFLAGS(open_flags); |
if ((flags & (FREAD | FWRITE)) == 0) |
if ((flags & (FREAD | FWRITE)) == 0) |
return (EINVAL); |
return EINVAL; |
|
|
error = pathbuf_copyin(SCARG(uap, path), &pb); |
|
if (error) { |
|
return error; |
|
} |
|
|
|
if ((error = fd_allocfile(&fp, &indx)) != 0) { |
if ((error = fd_allocfile(&fp, &indx)) != 0) { |
pathbuf_destroy(pb); |
pathbuf_destroy(pb); |
return error; |
return error; |
} |
} |
/* We're going to read cwdi->cwdi_cmask unlocked here. */ |
/* We're going to read cwdi->cwdi_cmask unlocked here. */ |
cmode = ((SCARG(uap, mode) &~ cwdi->cwdi_cmask) & ALLPERMS) &~ S_ISTXT; |
cmode = ((open_mode &~ cwdi->cwdi_cmask) & ALLPERMS) &~ S_ISTXT; |
NDINIT(&nd, LOOKUP, FOLLOW | TRYEMULROOT, pb); |
NDINIT(&nd, LOOKUP, FOLLOW | TRYEMULROOT, pb); |
l->l_dupfd = -indx - 1; /* XXX check for fdopen */ |
l->l_dupfd = -indx - 1; /* XXX check for fdopen */ |
if ((error = vn_open(&nd, flags, cmode)) != 0) { |
if ((error = vn_open(&nd, flags, cmode)) != 0) { |
Line 1507 sys_open(struct lwp *l, const struct sys |
|
Line 1498 sys_open(struct lwp *l, const struct sys |
|
l->l_dupfd >= 0 && /* XXX from fdopen */ |
l->l_dupfd >= 0 && /* XXX from fdopen */ |
(error = |
(error = |
fd_dupopen(l->l_dupfd, &indx, flags, error)) == 0) { |
fd_dupopen(l->l_dupfd, &indx, flags, error)) == 0) { |
*retval = indx; |
*fd = indx; |
pathbuf_destroy(pb); |
pathbuf_destroy(pb); |
return (0); |
return (0); |
} |
} |
if (error == ERESTART) |
if (error == ERESTART) |
error = EINTR; |
error = EINTR; |
pathbuf_destroy(pb); |
pathbuf_destroy(pb); |
return (error); |
return error; |
} |
} |
|
|
l->l_dupfd = 0; |
l->l_dupfd = 0; |
Line 1525 sys_open(struct lwp *l, const struct sys |
|
Line 1516 sys_open(struct lwp *l, const struct sys |
|
return error; |
return error; |
|
|
VOP_UNLOCK(vp); |
VOP_UNLOCK(vp); |
*retval = indx; |
*fd = indx; |
fd_affix(p, fp, indx); |
fd_affix(p, fp, indx); |
return (0); |
return 0; |
|
} |
|
|
|
int |
|
fd_open(const char *path, int open_flags, int open_mode, int *fd) |
|
{ |
|
struct pathbuf *pb; |
|
|
|
if ((open_flags & (FREAD | FWRITE)) == 0) |
|
return EINVAL; |
|
|
|
pb = pathbuf_create(path); |
|
if (pb == NULL) |
|
return ENOMEM; |
|
|
|
return do_open(curlwp, pb, open_flags, open_mode, fd); |
|
} |
|
|
|
/* |
|
* Check permissions, allocate an open file structure, |
|
* and call the device open routine if any. |
|
*/ |
|
int |
|
sys_open(struct lwp *l, const struct sys_open_args *uap, register_t *retval) |
|
{ |
|
/* { |
|
syscallarg(const char *) path; |
|
syscallarg(int) flags; |
|
syscallarg(int) mode; |
|
} */ |
|
struct pathbuf *pb; |
|
int result, flags, error; |
|
|
|
flags = FFLAGS(SCARG(uap, flags)); |
|
if ((flags & (FREAD | FWRITE)) == 0) |
|
return (EINVAL); |
|
|
|
error = pathbuf_copyin(SCARG(uap, path), &pb); |
|
if (error) |
|
return error; |
|
|
|
error = do_open(l, pb, SCARG(uap, flags), SCARG(uap, mode), &result); |
|
if (error) |
|
return error; |
|
|
|
*retval = result; |
|
return 0; |
} |
} |
|
|
int |
int |