Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- int
- sys_open(void)
- {
- char *path;
- int fd, omode;
- struct file *f;
- struct inode *ip;
- if(argstr(0, &path) < 0 || argint(1, &omode) < 0)
- return -1;
- ip = namei(path);
- if (ip == 0) {
- if(omode & O_CREATE){
- int mode;
- if (argint(2, &mode) < 0 || !check_permissions(mode))
- return -1;
- begin_trans();
- ip = create(path, T_FILE, 0, 0, proc->euid, (uint)mode);
- commit_trans();
- if(ip == 0) {
- return -1;
- }
- } else {
- return -1;
- }
- } else {
- ilock(ip);
- }
- // by this moment we hold ip
- if (ip->type == T_MUTEX) {
- iunlockput(ip);
- return -1;
- }
- if(ip->type == T_DIR && omode != O_RDONLY){
- iunlockput(ip);
- return -1;
- }
- if (((omode & O_WRONLY) || (omode & O_RDWR)) && !can_write(ip)) {
- iunlockput(ip);
- return -1;
- }
- if (!(omode & O_WRONLY) && !can_read(ip)) {
- iunlockput(ip);
- return -1;
- }
- if (ip->type == T_FIFO) {
- if (omode & O_RDWR)
- goto fail_put;
- if (ip->pipe == 0) {
- ip->pipe = fifo_pipe_alloc(ip);
- if (ip->pipe == 0)
- goto fail_put;
- }
- struct pipe *pipe = ip->pipe;
- /* the situation with locks and channels here is a bit messy, so
- pipe->lock is used to protect pipe->readopen AND pipe->writeopen
- &pipe->readopen is used to wait for the reader */
- acquire(&pipe->lock);
- iunlock(ip);
- if (omode == O_RDONLY) {
- struct file *f = fifo_file_alloc(pipe, 0);
- while (pipe->writeopen == 0) {
- wakeup(&pipe->readopen);
- sleep(&pipe->writeopen, &pipe->lock);
- }
- wakeup(&pipe->readopen);
- release(&pipe->lock);
- fd = fdalloc(f);
- } else {
- struct file *f = fifo_file_alloc(pipe, 1);
- while (pipe->readopen == 0) {
- wakeup(&pipe->writeopen);
- sleep(&pipe->readopen, &pipe->lock);
- }
- wakeup(&pipe->writeopen);
- release(&pipe->lock);
- fd = fdalloc(f);
- }
- if (fd < 0)
- goto fail;
- return fd;
- fail_put:
- iunlockput(ip);
- return -1;
- fail:
- iunlock(ip);
- return -1;
- }
- if((f = filealloc()) == 0 || (fd = fdalloc(f)) < 0){
- if(f)
- fileclose(f);
- iunlockput(ip);
- return -1;
- }
- iunlock(ip);
- f->type = FD_INODE;
- f->ip = ip;
- f->off = 0;
- f->readable = !(omode & O_WRONLY);
- f->writable = (omode & O_WRONLY) || (omode & O_RDWR);
- return fd;
- }
- int
- sys_mkdir(void)
- {
- char *path;
- struct inode *ip;
- int mode;
- begin_trans();
- if(argstr(0, &path) < 0 || argint(1, &mode) < 0 || !check_permissions(mode) || (ip = create(path, T_DIR, 0, 0, proc->euid, (uint)mode)) == 0){
- commit_trans();
- return -1;
- }
- iunlockput(ip);
- commit_trans();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement