asmlinkage int solaris_putmsg(unsigned int fd, u32 arg1, u32 arg2, u32 arg3) { struct file *filp; struct inode *ino; struct strbuf __user *ctlptr; struct strbuf __user *datptr; struct strbuf ctl, dat; int flags = (int) arg3; int error = -EBADF; struct fdtable *fdt; SOLD("entry"); lock_kernel(); if (fd >= sysctl_nr_open) goto out; fdt = files_fdtable(current->files); filp = fdt->fd[fd]; if(!filp) goto out; ino = filp->f_dentry->d_inode; if (!ino) goto out; if (!S_ISSOCK(ino->i_mode) && (imajor(ino) != 30 || iminor(ino) != 1)) goto out; ctlptr = A(arg1); datptr = A(arg2); error = -EFAULT; if (ctlptr) { if (copy_from_user(&ctl,ctlptr,sizeof(ctl))) goto out; if (ctl.len < 0 && flags) { error = -EINVAL; goto out; } } else { ctl.len = 0; ctl.buf = 0; } if (datptr) { if (copy_from_user(&dat,datptr,sizeof(dat))) goto out; } else { dat.len = 0; dat.buf = 0; } error = timod_putmsg(fd,A(ctl.buf),ctl.len, A(dat.buf),dat.len,flags); out: unlock_kernel(); SOLD("done"); return error; }
asmlinkage int solaris_putmsg(unsigned int fd, u32 arg1, u32 arg2, u32 arg3) { struct file *filp; struct inode *ino; struct strbuf *ctlptr, *datptr; struct strbuf ctl, dat; int flags = (int) arg3; int error = -EBADF; SOLD("entry"); lock_kernel(); if(fd >= NR_OPEN) goto out; read_lock(¤t->files->file_lock); filp = fcheck(fd); read_unlock(¤t->files->file_lock); if(!filp) goto out; ino = filp->f_dentry->d_inode; if (!ino) goto out; if (!ino->i_sock && (MAJOR(ino->i_rdev) != 30 || MINOR(ino->i_rdev) != 1)) goto out; ctlptr = (struct strbuf *)A(arg1); datptr = (struct strbuf *)A(arg2); error = -EFAULT; if (ctlptr) { if (copy_from_user(&ctl,ctlptr,sizeof(ctl))) goto out; if (ctl.len < 0 && flags) { error = -EINVAL; goto out; } } else { ctl.len = 0; ctl.buf = 0; } if (datptr) { if (copy_from_user(&dat,datptr,sizeof(dat))) goto out; } else { dat.len = 0; dat.buf = 0; } error = timod_putmsg(fd,(char*)A(ctl.buf),ctl.len, (char*)A(dat.buf),dat.len,flags); out: unlock_kernel(); SOLD("done"); return error; }
int svr4_putpmsg(struct pt_regs *regs) { struct file *fp; struct inode *ip; int fd; int error = -EBADF; fd = (int)get_syscall_parameter(regs, 0); fp = fget(fd); if (fp) { ip = fp->f_dentry->d_inode; if (S_ISSOCK(ip->i_mode) || IS_SPX(ip)) error = timod_putmsg(fd, ip, 1, regs); fput(fp); } return error; }
static inline int solaris_timod(unsigned int fd, unsigned int cmd, u32 arg, int len, int *len_p) { int ret; switch (cmd & 0xff) { case 141: /* TI_OPTMGMT */ { int i; u32 prim; SOLD("TI_OPMGMT entry"); ret = timod_putmsg(fd, (char *)A(arg), len, NULL, -1, 0); SOLD("timod_putmsg() returned"); if (ret) return (-ret << 8) | TSYSERR; i = MSG_HIPRI; SOLD("calling timod_getmsg()"); ret = timod_getmsg(fd, (char *)A(arg), len, len_p, NULL, -1, NULL, &i); SOLD("timod_getmsg() returned"); if (ret) return (-ret << 8) | TSYSERR; SOLD("ret ok"); if (get_user(prim, (u32 *)A(arg))) return (EFAULT << 8) | TSYSERR; SOLD("got prim"); if (prim == T_ERROR_ACK) { u32 tmp, tmp2; SOLD("prim is T_ERROR_ACK"); if (get_user(tmp, (u32 *)A(arg)+3) || get_user(tmp2, (u32 *)A(arg)+2)) return (EFAULT << 8) | TSYSERR; return (tmp2 << 8) | tmp; } SOLD("TI_OPMGMT return 0"); return 0; } case 142: /* TI_BIND */ { int i; u32 prim; SOLD("TI_BIND entry"); ret = timod_putmsg(fd, (char *)A(arg), len, NULL, -1, 0); SOLD("timod_putmsg() returned"); if (ret) return (-ret << 8) | TSYSERR; len = 1024; /* Solaris allows arbitrary return size */ i = MSG_HIPRI; SOLD("calling timod_getmsg()"); ret = timod_getmsg(fd, (char *)A(arg), len, len_p, NULL, -1, NULL, &i); SOLD("timod_getmsg() returned"); if (ret) return (-ret << 8) | TSYSERR; SOLD("ret ok"); if (get_user(prim, (u32 *)A(arg))) return (EFAULT << 8) | TSYSERR; SOLD("got prim"); if (prim == T_ERROR_ACK) { u32 tmp, tmp2; SOLD("prim is T_ERROR_ACK"); if (get_user(tmp, (u32 *)A(arg)+3) || get_user(tmp2, (u32 *)A(arg)+2)) return (EFAULT << 8) | TSYSERR; return (tmp2 << 8) | tmp; } SOLD("no ERROR_ACK requested"); if (prim != T_OK_ACK) return TBADSEQ; SOLD("OK_ACK requested"); i = MSG_HIPRI; SOLD("calling timod_getmsg()"); ret = timod_getmsg(fd, (char *)A(arg), len, len_p, NULL, -1, NULL, &i); SOLD("timod_getmsg() returned"); if (ret) return (-ret << 8) | TSYSERR; SOLD("TI_BIND return ok"); return 0; } case 140: /* TI_GETINFO */ case 143: /* TI_UNBIND */ case 144: /* TI_GETMYNAME */ case 145: /* TI_GETPEERNAME */ case 146: /* TI_SETMYNAME */ case 147: /* TI_SETPEERNAME */ ; } return TNOTSUPPORT; }