int svr4_getpmsg(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)) error = timod_getmsg(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; }
asmlinkage int solaris_getmsg(unsigned int fd, u32 arg1, u32 arg2, u32 arg3) { struct file *filp; struct inode *ino; struct strbuf *ctlptr, *datptr; struct strbuf ctl, dat; int *flgptr; int flags; int error = -EBADF; SOLD("entry"); lock_kernel(); if(fd >= NR_OPEN) goto out; filp = current->files->fd[fd]; if(!filp) goto out; ino = filp->f_dentry->d_inode; if (!ino) goto out; if (!ino->i_sock) goto out; ctlptr = (struct strbuf *)A(arg1); datptr = (struct strbuf *)A(arg2); flgptr = (int *)A(arg3); error = -EFAULT; if (ctlptr) { if (copy_from_user(&ctl,ctlptr,sizeof(struct strbuf)) || put_user(-1,&ctlptr->len)) goto out; } else ctl.maxlen = -1; if (datptr) { if (copy_from_user(&dat,datptr,sizeof(struct strbuf)) || put_user(-1,&datptr->len)) goto out; } else dat.maxlen = -1; if (get_user(flags,flgptr)) goto out; switch (flags) { case 0: case MSG_HIPRI: case MSG_ANY: case MSG_BAND: break; default: error = -EINVAL; goto out; } error = timod_getmsg(fd,(char*)A(ctl.buf),ctl.maxlen,&ctlptr->len, (char*)A(dat.buf),dat.maxlen,&datptr->len,&flags); if (!error && put_user(flags,flgptr)) error = -EFAULT; out: unlock_kernel(); SOLD("done"); return error; }