/* * Writes to a file. */ PUBLIC ssize_t sys_write(int fd, const void *buf, size_t n) { dev_t dev; /* Device number. */ struct file *f; /* File. */ struct inode *i; /* Inode. */ ssize_t count = 0; /* Bytes actually written. */ /* Invalid file descriptor. */ if ((fd < 0) || (fd >= OPEN_MAX) || ((f = curr_proc->ofiles[fd]) == NULL)) return (-EBADF); /* File not opened for writing. */ if (ACCMODE(f->oflag) == O_RDONLY) return (-EBADF); /* Invalid buffer. */ if (!chkmem(buf, n, MAY_READ)) return (-EINVAL); i = f->inode; /* Append mode. */ if (f->oflag & O_APPEND) f->pos = i->size; /* Character special file. */ if (S_ISCHR(i->mode)) { dev = i->blocks[0]; count = cdev_write(dev, buf, n); return (count); } /* Block special file. */ else if (S_ISBLK(i->mode)) { dev = i->blocks[0]; count = bdev_write(dev, buf, n, f->pos); } /* Pipe file. */ else if (S_ISFIFO(i->mode)) { kprintf("write to pipe"); count = pipe_write(i, buf, n); } /* Regular file. */ else if (S_ISREG(i->mode)) count = file_write(i, buf, n, f->pos); /* Failed to write. */ if (count < 0) return (curr_proc->errno); f->pos += count; return (count); }
/* * Gets tty settings. */ PRIVATE int tty_gets(struct tty *tty, struct termios *termiosp) { /* Invalid termios pointer. */ if (!chkmem(termiosp, sizeof(struct termios), MAY_WRITE)) return (-EINVAL); kmemcpy(termiosp, &tty->term, sizeof(struct termios)); return (0); }
struct task_s * new_task (void) { struct task_s *task; task = malloc (sizeof(struct task_s)); chkmem (task); task->refcnt = 0; return task; }
struct continuation_s * new_continuation (void) { struct continuation_s *cont; cont = malloc (sizeof(struct continuation_s)); chkmem (cont); cont->refcnt = 0; return cont; }
struct expression_s * new_expression (void) { struct expression_s *expr; expr = malloc (sizeof(struct expression_s)); chkmem (expr); expr->refcnt = 0; return expr; }
struct function_s * new_function (void) { struct function_s *fun; fun = malloc (sizeof(struct function_s)); chkmem (fun); fun->refcnt = 0; return fun; }
/* * Reads from a file. */ PUBLIC ssize_t sys_read(int fd, void *buf, size_t n) { dev_t dev; /* Device number. */ struct file *f; /* File. */ struct inode *i; /* Inode. */ ssize_t count; /* Bytes actually read. */ /* Invalid file descriptor. */ if ((fd < 0) || (fd >= OPEN_MAX) || ((f = curr_proc->ofiles[fd]) == NULL)) return (-EBADF); /* File not opened for reading. */ if (ACCMODE(f->oflag) == O_WRONLY) return (-EBADF); #if (EDUCATIONAL_KERNEL == 0) /* Invalid buffer. */ if (!chkmem(buf, n, MAY_WRITE)) return (-EINVAL); #endif /* Nothing to do. */ if (n == 0) return (0); i = f->inode; /* Character special file. */ if (S_ISCHR(i->mode)) { dev = i->blocks[0]; count = cdev_read(dev, buf, n); return (count); } /* Block special file. */ else if (S_ISBLK(i->mode)) { dev = i->blocks[0]; count = bdev_read(dev, buf, n, f->pos); } /* Pipe file. */ else if (S_ISFIFO(i->mode)) { kprintf("read from pipe"); count = pipe_read(i, buf, n); } /* Regular file/directory. */ else if ((S_ISDIR(i->mode)) || (S_ISREG(i->mode))) count = file_read(i, buf, n, f->pos); /* Unknown file type. */ else return (-EINVAL); /* Failed to read. */ if (count < 0) return (curr_proc->errno); inode_touch(i); f->pos += count; return (count); }