提交 9cc8199d 创建 作者: Nickolai Zeldovich's avatar Nickolai Zeldovich

openat

上级 bbb74797
......@@ -2,3 +2,5 @@
#define O_WRONLY 0x001
#define O_RDWR 0x002
#define O_CREATE 0x200
#define AT_FDCWD -100
......@@ -31,7 +31,7 @@ long sys_kill(int);
long sys_link(const char*, const char*);
long sys_mkdir(const char*);
long sys_mknod(const char*, int, int);
long sys_open(const char*, int);
long sys_openat(int, const char*, int);
long sys_pipe(int*);
long sys_read(int, char*, int);
long sys_sbrk(int);
......
......@@ -99,7 +99,7 @@ int filewrite(struct file*, char*, int n);
int namecmp(const char*, const char*);
struct inode* dirlookup(struct inode*, char*);
struct inode* ialloc(u32, short);
struct inode* namei(const char*);
struct inode* namei(inode *cwd, const char*);
void iput(struct inode*);
struct inode* iget(u32 dev, u32 inum);
void ilock(struct inode*, int writer);
......@@ -110,7 +110,7 @@ int readi(struct inode*, char*, u32, u32);
void stati(struct inode*, struct stat*);
int writei(struct inode*, char*, u32, u32);
struct inode* idup(struct inode*);
struct inode* nameiparent(const char*, char*);
struct inode* nameiparent(inode *cwd, const char*, char*);
int dirlink(struct inode*, const char*, u32);
void dir_init(struct inode *dp);
void dir_flush(struct inode *dp);
......
......@@ -8,7 +8,7 @@
#define SYS_close 7
#define SYS_kill 8
#define SYS_exec 9
#define SYS_open 10
#define SYS_openat 10
#define SYS_mknod 11
#define SYS_unlink 12
#define SYS_fstat 13
......
......@@ -30,6 +30,7 @@ void halt(void);
ssize_t pread(int, void*, size_t, off_t);
int async(int, size_t, off_t, u32, u32);
int script(void *addr, u64 len, u64 chunk);
int openat(int dirfd, const char *pathname, int omode);
// ulib.c
int stat(char*, struct stat*);
......
......@@ -41,7 +41,7 @@ long (*syscalls[])(u64, u64, u64, u64, u64) = {
SYSCALL(link),
SYSCALL(mkdir),
SYSCALL(mknod),
SYSCALL(open),
SYSCALL(openat),
SYSCALL(pipe),
SYSCALL(read),
SYSCALL(sbrk),
......
......@@ -153,7 +153,7 @@ exec(const char *path, char **argv)
struct vmap *oldvmap;
prof_start(exec_prof);
if((ip = namei(path)) == 0)
if((ip = namei(myproc()->cwd, path)) == 0)
return -1;
gc_begin_epoch();
......
......@@ -745,7 +745,7 @@ skipelem(const char **rpath, char *name)
// If parent != 0, return the inode for the parent and copy the final
// path element into name, which must have room for DIRSIZ bytes.
static struct inode*
namex(const char *path, int nameiparent, char *name)
namex(inode *cwd, const char *path, int nameiparent, char *name)
{
struct inode *ip, *next;
int r;
......@@ -754,7 +754,7 @@ namex(const char *path, int nameiparent, char *name)
if(*path == '/')
ip = iget(ROOTDEV, ROOTINO);
else
ip = idup(myproc()->cwd);
ip = idup(cwd);
while((r = skipelem(&path, name)) == 1){
next = 0;
......@@ -790,17 +790,17 @@ namex(const char *path, int nameiparent, char *name)
}
struct inode*
namei(const char *path)
namei(inode *cwd, const char *path)
{
char name[DIRSIZ];
struct inode *r = namex(path, 0, name);
struct inode *r = namex(cwd, path, 0, name);
//cprintf("namei: %s -> %x (%d)\n", path, r, r?r->inum:0);
return r;
}
struct inode*
nameiparent(const char *path, char *name)
nameiparent(inode *cwd, const char *path, char *name)
{
return namex(path, 1, name);
return namex(cwd, path, 1, name);
}
......@@ -101,7 +101,7 @@ forkret(void)
// in which to call cv_sleep().
if(myproc()->cwd == nullptr) {
mtstart(forkret, myproc());
myproc()->cwd = namei("/");
myproc()->cwd = namei(myproc()->cwd, "/");
mtstop(myproc());
}
......
......@@ -132,7 +132,7 @@ sys_link(const char *old, const char *newn)
if(argcheckstr(old) < 0 || argcheckstr(newn) < 0)
return -1;
if((ip = namei(old)) == 0)
if((ip = namei(myproc()->cwd, old)) == 0)
return -1;
ilock(ip, 1);
if(ip->type == T_DIR){
......@@ -143,7 +143,7 @@ sys_link(const char *old, const char *newn)
iupdate(ip);
iunlock(ip);
if((dp = nameiparent(newn, name)) == 0)
if((dp = nameiparent(myproc()->cwd, newn, name)) == 0)
goto bad;
if(dp->dev != ip->dev || dirlink(dp, name, ip->inum) < 0)
goto bad;
......@@ -185,7 +185,7 @@ sys_unlink(const char *path)
if(argcheckstr(path) < 0)
return -1;
if((dp = nameiparent(path, name)) == 0)
if((dp = nameiparent(myproc()->cwd, path, name)) == 0)
return -1;
if(dp->type != T_DIR)
panic("sys_unlink");
......@@ -234,13 +234,13 @@ sys_unlink(const char *path)
}
static struct inode*
create(const char *path, short type, short major, short minor)
create(inode *cwd, const char *path, short type, short major, short minor)
{
struct inode *ip, *dp;
char name[DIRSIZ];
retry:
if((dp = nameiparent(path, name)) == 0)
if((dp = nameiparent(cwd, path, name)) == 0)
return 0;
if(dp->type != T_DIR)
panic("create");
......@@ -284,20 +284,32 @@ create(const char *path, short type, short major, short minor)
}
long
sys_open(const char *path, int omode)
sys_openat(int dirfd, const char *path, int omode)
{
int fd;
struct file *f;
struct inode *ip;
struct inode *cwd;
if (dirfd == AT_FDCWD) {
cwd = myproc()->cwd;
} else if (dirfd < 0 || dirfd >= NOFILE) {
return -1;
} else {
struct file *fdir = myproc()->ofile[dirfd];
if (fdir->type != file::FD_INODE)
return -1;
cwd = fdir->ip;
}
if(argcheckstr(path) < 0)
return -1;
if(omode & O_CREATE){
if((ip = create(path, T_FILE, 0, 0)) == 0)
if((ip = create(cwd, path, T_FILE, 0, 0)) == 0)
return -1;
} else {
retry:
if((ip = namei(path)) == 0)
if((ip = namei(cwd, path)) == 0)
return -1;
ilock(ip, 0);
if(ip->type == 0) {
......@@ -335,7 +347,7 @@ sys_mkdir(const char *path)
{
struct inode *ip;
if(argcheckstr(path) < 0 || (ip = create(path, T_DIR, 0, 0)) == 0)
if(argcheckstr(path) < 0 || (ip = create(myproc()->cwd, path, T_DIR, 0, 0)) == 0)
return -1;
iunlockput(ip);
return 0;
......@@ -348,7 +360,7 @@ sys_mknod(const char *path, int major, int minor)
int len;
if((len=argcheckstr(path)) < 0 ||
(ip = create(path, T_DEV, major, minor)) == 0)
(ip = create(myproc()->cwd, path, T_DEV, major, minor)) == 0)
return -1;
iunlockput(ip);
return 0;
......@@ -359,7 +371,7 @@ sys_chdir(const char *path)
{
struct inode *ip;
if(argcheckstr(path) < 0 || (ip = namei(path)) == 0)
if(argcheckstr(path) < 0 || (ip = namei(myproc()->cwd, path)) == 0)
return -1;
ilock(ip, 0);
if(ip->type != T_DIR){
......
......@@ -130,3 +130,9 @@ memmove(void *vdst, const void *vsrc, int n)
*dst++ = *src++;
return vdst;
}
int
open(const char *path, int omode)
{
return openat(AT_FDCWD, path, omode);
}
......@@ -25,7 +25,7 @@ SYSCALL(write)
SYSCALL(close)
SYSCALL(kill)
SYSCALL_INT(exec)
SYSCALL(open)
SYSCALL(openat)
SYSCALL(mknod)
SYSCALL(unlink)
SYSCALL(fstat)
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论