int tty_ioctl(struct inode *inode, struct file *file, int cmd, register char *arg) { register struct tty *tty = determine_tty(inode->i_rdev); int ret; switch (cmd) { case TCGETS: ret = verified_memcpy_tofs(arg, &tty->termios, sizeof(struct termios)); break; case TCSETS: case TCSETSW: case TCSETSF: ret = verified_memcpy_fromfs(&tty->termios, arg, sizeof(struct termios)); /* Inform driver that things have changed */ if (tty->ops->ioctl != NULL) tty->ops->ioctl(tty, cmd, arg); break; default: ret = (tty->ops->ioctl == NULL) ? -EINVAL : tty->ops->ioctl(tty, cmd, arg); } return ret; }
int sys_pipe(unsigned int *filedes) { int fd[2]; int error; debug("PIPE: called.\n"); if ((error = do_pipe(fd))) return error; debug2("PIPE: Returned %d %d.\n", fd[0], fd[1]); return verified_memcpy_tofs(filedes, fd, 2 * sizeof(int)); }
/* return the time of day to the user */ int sys_gettimeofday(register struct timeval *tv, struct timezone *tz) { struct timeval tmp_tv; jiff_t now; /* load the current time into the structures passed */ if (tv != NULL) { now = jiffies; tmp_tv.tv_sec = xtime.tv_sec + (now / HZ); tmp_tv.tv_usec = xtime.tv_usec + ((now % HZ) * (1000000l / HZ)); if (verified_memcpy_tofs(tv, &tmp_tv, sizeof(struct timeval))) return -EFAULT; } if (tz != NULL) if (verified_memcpy_tofs(tz, &xzone, sizeof(struct timezone))) return -EFAULT; /* success */ return 0; }
static int file_ioctl(register struct file *filp, unsigned int cmd, unsigned int arg) { loff_t val; register struct file_operations *fop = filp->f_op; if (cmd == FIONREAD) { /* switch (cmd) { */ /* case FIONREAD: */ val = filp->f_inode->i_size - filp->f_pos; return verified_memcpy_tofs((char *) arg, (char *) &val, sizeof(loff_t)); } if (fop && fop->ioctl) return fop->ioctl(filp->f_inode, filp, cmd, arg); return -EINVAL; }
int sys_wait4(pid_t pid, int *status, int options) { register __ptask p = current; register pid_t *lastendp = &p->child_lastend; if (!((options & WNOHANG) || (*lastendp))) interruptible_sleep_on(&p->child_wait); if (*lastendp) { if (status) { if (verified_memcpy_tofs(status, &p->lastend_status, sizeof(int)) != 0) { return -EFAULT; } } options = *lastendp; /* TRASHING options!!! */ *lastendp = 0; return options; } return -EINTR; }
int sys_ustat(__u16 dev, struct ustat *ubuf) { register struct super_block *s; struct ustat tmp; struct statfs sbuf; int error; s = get_super(to_kdev_t(dev)); if (s == NULL) return -EINVAL; if (!(s->s_op->statfs_kern)) return -ENOSYS; s->s_op->statfs_kern(s, &sbuf, sizeof(struct statfs)); memset(&tmp, 0, sizeof(struct ustat)); tmp.f_tfree = sbuf.f_bfree; tmp.f_tinode = sbuf.f_ffree; if (error = verified_memcpy_tofs(ubuf, &tmp, sizeof(struct ustat))) return error; return 0; }
static void do_meta_request(kdev_t device) { struct ud_driver *driver = get_driver(major); struct ud_request *udr; struct request *req; char *buff; int major = MAJOR(device); printk("do_meta_request %d %x\n", major, blk_dev[major].current_request); if (NULL == driver) { end_request(0, req->rq_dev); return; } printk("1"); while (1) { req = blk_dev[major].current_request; printk("2"); if (!req || req->rq_dev < 0 || req->rq_sector == -1) return; printk("5"); udr = new_request(); udr->udr_type = UDR_BLK + req->rq_cmd; udr->udr_ptr = req->rq_sector; udr->udr_minor = MINOR(req->rq_dev); printk("6"); post_request(driver, udr); printk("7"); /* Should really check here whether we have a request */ if (req->rq_cmd == WRITE) { /* Can't do this, copies to the wrong task */ #if 0 verified_memcpy_tofs(driver->udd_data, buff, BLOCK_SIZE); /* FIXME FIXME */ fmemcpy(driver->udd_task->mm.dseg, driver->udd_data, get_ds(), buff, 1024); #endif } printk("8"); /* Wake up the driver so it can deal with the request */ wake_up(&driver->udd_wait); printk("request init: wake driver, sleeping\n"); sleep_on(&udr->udr_wait); printk("request continue\n"); /* REQUEST HAS BEEN RETURNED BY USER PROGRAM */ /* request must be dealt with and ended */ if (udr->udr_status == 1) { end_request(0, req->rq_dev); udr->udr_status = 0; continue; } udr->udr_status = 0; buff = req->rq_buffer; if (req->rq_cmd == READ) { /* Can't do this, copies from the wrong task */ #if 0 verified_memcpy_fromfs(buff, driver->udd_data, BLOCK_SIZE); /* FIXME FIXME */ fmemcpy(get_ds(), buff, driver->udd_task->mm.dseg, driver->udd_data, 1024); #endif } end_request(1, req->rq_dev); wake_up(&udr->udr_wait); } }
static int meta_ioctl(struct inode *inode, struct file *filp, int cmd, char *arg) { struct ud_driver *driver; int i, minor = MINOR(inode->i_rdev); printk("meta_ioctl %d %x\n", cmd, inode->i_rdev); if (minor == 0) { if (cmd != META_CREAT) return -EINVAL; printk("registering new "); for (i = 0; i < MAX_UDD; i++) if (drivers[i].udd_type == UDD_NONE) { minor = i + 1; break; } if (minor == 0) return -ENODEV; driver = &drivers[i]; verified_memcpy_fromfs(driver, arg, sizeof(struct ud_driver_trunc)); if (driver->udd_type == UDD_CHR_DEV) { printk("char "); if (register_chrdev(driver->udd_major, "meta", &ucd_fops) < 0) { goto reg_err; } } else if (driver->udd_type == UDD_BLK_DEV) { if ((i = verfy_area(driver->udd_data, 1024)) != 0) { driver->udd_type = UDD_NONE; return i; } printk("block "); /* verify are here on buffer */ if (register_blkdev(driver->udd_major, "meta", &ubd_fops) < 0) { goto reg_err; } blk_dev[driver->udd_major].request_fn = do_meta_request; } printk("device\n"); driver->udd_task = current; #if 0 driver->udd_rwait = NULL; /* FIXME: Not valid */ #endif return minor; reg_err: driver->udd_type = UDD_NONE; return -ENODEV; } driver = &drivers[minor - 1]; if (driver->udd_task != current) { printk("task mismatch %x %x\n", driver->udd_task, current); return -EINVAL; } switch (cmd) { case META_POLL: printk("waiting for request\n"); #if 0 driver->udd_wait = NULL; /* FIXME: not valid */ #endif driver->udd_req = NULL; wake_up(&driver->udd_rwait); interruptible_sleep_on(&driver->udd_wait); printk("Waking up\n"); if (driver->udd_req != NULL) { verified_memcpy_tofs(arg, driver->udd_req, sizeof(struct ud_request)); printk("here is the request\n"); return 0; } printk("No request! up\n"); return -EINTR; break; case META_ACK: printk("acknowledge request\n"); if (driver->udd_req == NULL) { printk("No request was pending!\n"); return -EINVAL; } verified_memcpy_fromfs(driver->udd_req, arg, sizeof(struct ud_request_trunc)); wake_up(&driver->udd_req->udr_wait); #if 0 driver->udd_req->udr_wait = NULL; /* FIXME: Not valid */ #endif interruptible_sleep_on(&driver->udd_req->udr_wait); break; default: printk("Bad ioctl\n"); return -EINVAL; } return 0; }