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

openat

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