static int svr4_semop(int arg1, struct sembuf *arg2, int arg3) { int retval; #if defined(CONFIG_ABI_TRACE) if (abi_traced(ABI_TRACE_API)) { struct sembuf tmp, *tp = arg2; int i; for (i = 0; i < arg3; i++) { if (copy_from_user (&tmp, tp, sizeof(tmp))) { __abi_trace("semop(-EFAULT)\n"); break; } __abi_trace("semop(%d, %d, 0%o)\n", tmp.sem_num, tmp.sem_op, tmp.sem_flg); tp++; } } #endif #ifdef CONFIG_65BIT retval=SYS(semop, arg1, arg2, arg3); #else retval=SYS(ipc,SEMOP,arg1,arg3,0,arg2); #endif return retval; }
static int svr4_semctl(int arg1, int arg2, int arg3, union semun *arg4) { int retval, cmd = svr4sem2linux[arg3]; switch (arg3) { case SVR4_SEM_SETALL: case SVR4_SEM_GETALL: return __ibcs2_semctl(arg1, 0, cmd, arg4); case SVR4_IPC_RMID: case SVR4_IPC_RMID_L: case SVR4_SEM_SETVAL: case SVR4_SEM_GETVAL: case SVR4_SEM_GETPID: case SVR4_SEM_GETNCNT: case SVR4_SEM_GETZCNT: #ifdef CONFIG_65BIT retval = SYS(semctl, arg1, arg2, cmd, arg4, 0); #else retval = SYS(ipc,SEMCTL, arg1, arg2, cmd, arg4, 0); #endif return retval; case SVR4_IPC_SET: case SVR4_IPC_STAT: return __ibcs2_semctl(arg1, arg2, cmd, arg4); case SVR4_IPC_STAT_L: case SVR4_IPC_SET_L: return __abi4_semctl(arg1, arg2, cmd, arg4); } #if defined(CONFIG_ABI_TRACE) __abi_trace("semctl: unsupported command %d\n", arg3); #endif return -EINVAL; }
int svr4_msgsys(struct pt_regs *regp) { int err, cmd, arg1, arg2, arg3, arg4, arg5; /* * Special handling as msgrcv is ugly. */ cmd = get_syscall_parameter(regp, 0); arg1 = get_syscall_parameter(regp, 1); arg2 = get_syscall_parameter(regp, 2); switch (cmd) { case SVR4_msgget: #ifdef CONFIG_65BIT err = SYS(msgget, arg1, arg2); #else err = SYS(ipc,MSGGET,arg1,arg2); #endif return err; case SVR4_msgctl: arg3 = get_syscall_parameter(regp, 3); return svr4_msgctl(arg1, arg2, (caddr_t)((long)arg3)); case SVR4_msgrcv: arg3 = get_syscall_parameter(regp, 3); arg4 = get_syscall_parameter(regp, 4); arg5 = get_syscall_parameter(regp, 5); #ifdef CONFIG_65BIT err = SYS(msgrcv, arg1, arg2, arg3, arg4, arg5); #else err = SYS(ipc,MSGRCV+0x10000,arg1,arg3,arg5,arg2,arg4); #endif return err; case SVR4_msgsnd: arg3 = get_syscall_parameter(regp, 3); arg4 = get_syscall_parameter(regp, 4); #ifdef CONFIG_65BIT err = SYS(msgsnd, arg1, arg2, arg3, arg4); #else err = SYS(ipc,MSGSND,arg1,arg3,arg4,arg2); #endif return ((err > 0) ? 0 : err); } #if defined(CONFIG_ABI_TRACE) __abi_trace("msgsys: unsupported command: %x\n", cmd); #endif return -EINVAL; }
int abi_do_setsockopt(unsigned long *sp) { int error; int level, optname; error = verify_area(VERIFY_READ, ((unsigned long *)sp), 5*sizeof(long)); if (error) return error; get_user(level, ((unsigned long *)sp)+1); get_user(optname, ((unsigned long *)sp)+2); if (abi_traced(ABI_TRACE_STREAMS|ABI_TRACE_SOCKSYS)) { u_long optval, optlen; get_user(optval, ((u_long *)sp) + 3); get_user(optlen, ((u_long *)sp) + 4); __abi_trace("setsockopt level=%d, optname=%d, " "optval=0x%08lx, optlen=0x%08lx\n", level, optname, optval, optlen); } switch (level) { case 0: /* IPPROTO_IP aka SOL_IP */ /* This is correct for the SCO family. Hopefully * it is correct for other SYSV... */ optname--; if (optname == 0) optname = 4; if (optname > 4) { optname += 24; if (optname <= 33) optname--; if (optname < 32 || optname > 36) return -EINVAL; } put_user(optname, ((unsigned long *)sp)+2); break; case 0xffff: put_user(SOL_SOCKET, ((unsigned long *)sp)+1); optname = map_value(current->exec_domain->sockopt_map, optname, 0); put_user(optname, ((unsigned long *)sp)+2); switch (optname) { case SO_LINGER: { unsigned long optlen; /* SO_LINGER takes a struct linger * as the argument but some code * uses an int and expects to get * away without an error. Sigh... */ get_user(optlen, ((unsigned long *)sp)+4); if (optlen == sizeof(int)) return 0; break; } /* The following are not currently implemented * under Linux so we must fake them in * reasonable ways. (Only SO_PROTOTYPE is * documented in SCO's man page). */ case SO_PROTOTYPE: case SO_ORDREL: case SO_SNDTIMEO: case SO_RCVTIMEO: return -ENOPROTOOPT; case SO_USELOOPBACK: case SO_SNDLOWAT: case SO_RCVLOWAT: return 0; /* The following are not currenty implemented * under Linux and probably aren't settable * anyway. */ case SO_IMASOCKET: return -ENOPROTOOPT; } default: /* FIXME: We assume everything else uses the * same level and option numbers. This is true * for IPPROTO_TCP(/SOL_TCP) and TCP_NDELAY * but is known to be incorrect for other * potential options :-(. */ break; } return sys_socketcall(SYS_SETSOCKOPT, sp); }
/* * XXX: this function is a _horrible_ mess. */ static int timod_optmgmt(int fd, struct pt_regs * regs, int flag, char * opt_buf, int opt_len, int do_ret) { struct file * fp = fcheck(fd); char *ret_buf, *ret_base; u_int old_esp, *tsp; int is_tli, error, failed; int ret_len, ret_space; error=0; if (opt_buf && opt_len > 0) { if (!access_ok(VERIFY_READ, opt_buf, opt_len)) return -EFAULT; } /* * FIXME: * We should be able to detect the difference between * TLI and XTI requests at run time? */ #ifdef CONFIG_ABI_TLI_OPTMGMT is_tli = 1; #else is_tli = 0; #endif if (!do_ret && (!opt_buf || opt_len <= 0)) return 0; /* * Grab some space on the user stack to work with. We need 6 longs * to build an argument frame for [gs]etsockopt calls. We also * need space to build the return buffer. This will be at least * as big as the given options buffer but the given options * buffer may not include space for option values so we allow two * longs for each option multiple of the option header size * and hope that big options will not exhaust our space and * trash the stack. */ ret_space = 1024 + opt_len + 2*sizeof(long)*(opt_len / (is_tli ? sizeof(struct opthdr) : sizeof(struct t_opthdr))); ret_buf = ret_base = (char *)(_SP(regs) - ret_space); ret_len = 0; old_esp = _SP(regs); _SP(regs) -= ret_space + 6*sizeof(long); tsp = (unsigned int *)_SP(regs); if (!access_ok(VERIFY_WRITE, tsp, 6*sizeof(long))) { _SP(regs) = old_esp; return -EFAULT; } failed = 0; #ifndef CONFIG_ABI_TLI_OPTMGMT if (is_tli) { printk(KERN_WARNING "%d iBCS: TLI optmgmt requested but not supported\n", current->pid); } #else if (is_tli) while (opt_len >= sizeof(struct opthdr)) { struct opthdr opt; #if defined(CONFIG_ABI_TRACE) abi_trace(ABI_TRACE_STREAMS, "TLI optmgmt opt_len=%d, " "ret_buf=0x%08lx, ret_len=%d, ret_space=%d\n", opt_len, (unsigned long)ret_buf, ret_len, ret_space); #endif if (copy_from_user(&opt, opt_buf, sizeof(struct opthdr))) return -EFAULT; /* Idiot check... */ if (opt.len > opt_len) { failed = TBADOPT; break; } #if defined(CONFIG_ABI_TRACE) if (abi_traced(ABI_TRACE_STREAMS)) { unsigned long v; get_user(v, (unsigned long *)(opt_buf+sizeof(struct opthdr))); __abi_trace("TLI optmgmt fd=%d, level=%ld, " "name=%ld, value=%ld\n", fd, opt.level, opt.name, v); } #endif /* Check writable space in the return buffer. */ if (!access_ok(VERIFY_WRITE, ret_buf, sizeof(struct opthdr))) { failed = TSYSERR; break; } /* Flag values: * T_NEGOTIATE means try and set it. * T_DEFAULT means get the default value. * (return the current for now) * T_CHECK means get the current value. */ error = 0; if (flag == T_NEGOTIATE) { put_user(fd, tsp); put_user(opt.level, tsp+1); put_user(opt.name, tsp+2); put_user((long)opt_buf+sizeof(struct opthdr), tsp+3); put_user(opt.len, tsp+4); error = abi_do_setsockopt(tsp); if (error) { #if defined(CONFIG_ABI_TRACE) abi_trace(ABI_TRACE_STREAMS, "setsockopt failed: %d\n", error); #endif failed = TBADOPT; break; } } if (!error) { int len; put_user(fd, tsp); put_user(opt.level, tsp+1); put_user(opt.name, tsp+2); put_user((long)ret_buf+sizeof(struct opthdr), tsp+3); put_user((long)(tsp+5), tsp+4); put_user(ret_space, tsp+5); error = abi_do_getsockopt(tsp); if (error) { #if defined(CONFIG_ABI_TRACE) abi_trace(ABI_TRACE_STREAMS, "getsockopt failed: %d\n", error); #endif failed = TBADOPT; break; } get_user(len, tsp+5); if (copy_to_user(ret_buf, &opt, sizeof(opt))) return -EFAULT; put_user(len, &((struct opthdr *)opt_buf)->len); ret_space -= sizeof(struct opthdr) + len; ret_len += sizeof(struct opthdr) + len; ret_buf += sizeof(struct opthdr) + len; } opt_len -= sizeof(struct opthdr) + opt.len; opt_buf += sizeof(struct opthdr) + opt.len; } #endif /* CONFIG_ABI_TLI_OPTMGMT */ #ifndef CONFIG_ABI_XTI_OPTMGMT else { printk(KERN_WARNING "%d iBCS: XTI optmgmt requested but not supported\n", current->pid); } #else else while (opt_len >= sizeof(struct t_opthdr)) {
static int svr4_msgctl(int arg1, int cmd, char *arg3) { struct ibcs2_msqid_ds im; struct abi4_msqid_ds im4; struct msqid_ds lm; mm_segment_t fs; int err; switch (cmd) { case SVR4_IPC_SET: err = copy_from_user(&im, arg3, sizeof(im)) ? -EFAULT : 0; if (err) break; imsq_to_lmsq(&im, &lm); fs = get_fs(); set_fs(get_ds()); #ifdef CONFIG_65BIT err = SYS(msgctl, arg1, IPC_SET, &lm); #else err = SYS(ipc,MSGCTL,arg1, IPC_SET,0, &lm); #endif set_fs(fs); lmsq_to_imsq(&lm, &im); err = copy_to_user(arg3, &im, sizeof(im)) ? -EFAULT : 0; break; case SVR4_IPC_SET_L: err = copy_from_user(&im4, arg3, sizeof(im4)) ? -EFAULT : 0; if (err) break; imsq_to_lmsq_l(&im4, &lm); fs = get_fs(); set_fs(get_ds()); #ifdef CONFIG_65BIT err = SYS(msgctl, arg1, IPC_SET, &lm); #else err = SYS(ipc,MSGCTL,arg1, IPC_SET,0, &lm); #endif set_fs(fs); lmsq_to_imsq_l(&lm, &im4); err = copy_to_user(arg3, &im4, sizeof(im4)) ? -EFAULT : 0; break; case SVR4_IPC_RMID: case SVR4_IPC_RMID_L: #ifdef CONFIG_65BIT err= SYS(msgctl, arg1, IPC_RMID, arg3); #else err = SYS(ipc,MSGCTL,arg1, IPC_RMID,0, arg3); #endif return err; case SVR4_IPC_STAT: fs = get_fs(); set_fs(get_ds()); #ifdef CONFIG_65BIT err = SYS(msgctl, arg1, IPC_STAT, &lm); #else err = SYS(ipc,MSGCTL,arg1, IPC_STAT,0, &lm); #endif set_fs(fs); if (err < 0) break; lmsq_to_imsq(&lm, &im); err = copy_to_user(arg3, &im, sizeof(im)) ? -EFAULT : 0; break; case SVR4_IPC_STAT_L: fs = get_fs(); set_fs(get_ds()); #ifdef CONFIG_65BIT err = SYS(msgctl, arg1, IPC_STAT, &lm); #else err = SYS(ipc,MSGCTL,arg1, IPC_STAT,0, &lm); #endif set_fs(fs); if (err < 0) break; lmsq_to_imsq_l(&lm, &im4); err = copy_to_user(arg3, &im4, sizeof(im4)) ? -EFAULT : 0; break; default: #if defined(CONFIG_ABI_TRACE) __abi_trace("msgctl: unsupported command: %x\n", cmd); #endif err = -EINVAL; } return (err); }
int svr4_shmsys(struct pt_regs *regp) { int arg1, arg2, arg3, cmd, err = 0; u_long raddr; mm_segment_t fs; cmd = get_syscall_parameter(regp, 0); if (cmd == SVR4_shmdt) { err = svr4_shmdt(regp); goto out; } arg1 = get_syscall_parameter(regp, 1); arg2 = get_syscall_parameter(regp, 2); arg3 = get_syscall_parameter(regp, 3); switch (cmd) { case SVR4_shmat: #if defined(CONFIG_ABI_TRACE) abi_trace(ABI_TRACE_API, "shmat(%d, %x, %o)\n", arg1, arg2, arg3); #endif fs = get_fs(); set_fs(get_ds()); #ifdef CONFIG_65BIT err = SYS(shmat, arg1, arg2, arg3, &raddr); #else err = SYS(ipc,SHMAT+0x10000,arg1,arg3,&raddr,arg2); #endif set_fs(fs); if (err >= 0) err = (int)raddr; #if defined(CONFIG_ABI_TRACE) abi_trace(ABI_TRACE_API, "shmat returns %x\n", err); #endif break; case SVR4_shmget: #if defined(CONFIG_ABI_TRACE) abi_trace(ABI_TRACE_API, "shmget(%d, %x, %o)\n", arg1, arg2, arg3); #endif #ifdef CONFIG_65BIT err = SYS(shmget, arg1, arg2, arg3); #else err = SYS(ipc,SHMGET,arg1, arg2, arg3); #endif #if defined(CONFIG_ABI_TRACE) abi_trace(ABI_TRACE_API, "shmget returns %d\n", err); #endif break; case SVR4_shmctl: err = svr4_shmctl(arg1, arg2, (char *)((long)arg3)); break; default: #if defined(CONFIG_ABI_TRACE) __abi_trace("shmsys: unsupported command: %x\n", cmd); #endif err = -EINVAL; } out: if (err < 0 && err > -255) { set_error(regp, iABI_errors(-err)); #if defined(CONFIG_ABI_TRACE) abi_trace(ABI_TRACE_API, "Error %d\n", get_result(regp)); #endif return 0; } clear_error(regp); set_result(regp, err); return 0; }
static int svr4_shmctl(int arg1, int cmd, char *arg3) { struct ibcs2_shmid_ds is; struct abi4_shmid_ds is4; struct shmid_ds ls; mm_segment_t fs; int err; #if defined(CONFIG_ABI_TRACE) abi_trace(ABI_TRACE_API, "shmctl(%d, %x, %p)\n", arg1, cmd, arg3); #endif switch (cmd) { case SVR4_SHM_LOCK: #ifdef CONFIG_65BIT err = SYS(shmctl, arg1, SHM_LOCK, (struct shmid_ds *)arg3); #else err = SYS(ipc,SHMCTL,arg1, SHM_LOCK,0, (struct shmid_ds *)arg3); #endif return err; case SVR4_SHM_UNLOCK: #ifdef CONFIG_65BIT err = SYS(shmctl, arg1, SHM_UNLOCK, (struct shmid_ds *)arg3); #else err = SYS(ipc,SHMCTL,arg1, SHM_UNLOCK,0, (struct shmid_ds *)arg3); #endif return err; case SVR4_IPC_SET: err = copy_from_user(&is, arg3, sizeof(is)) ? -EFAULT : 0; if (err) break; ishm_to_lshm(&is, &ls); fs = get_fs(); set_fs(get_ds()); #ifdef CONFIG_65BIT err = SYS(shmctl, arg1, IPC_SET, &ls); #else err = SYS(ipc,SHMCTL,arg1, IPC_SET,0, &ls); #endif set_fs(fs); if (err < 0) break; lshm_to_ishm(&ls, &is); err = copy_to_user(arg3, &is, sizeof(is)) ? -EFAULT : 0; break; case SVR4_IPC_SET_L: err = copy_from_user(&is4, arg3, sizeof(is4)) ? -EFAULT : 0; if (err) break; ishm_to_lshm_l(&is4, &ls); fs = get_fs(); set_fs(get_ds()); #ifdef CONFIG_65BIT err = SYS(shmctl, arg1, IPC_SET, &ls); #else err = SYS(ipc,SHMCTL,arg1, IPC_SET,0, &ls); #endif set_fs(fs); if (err < 0) break; lshm_to_ishm_l(&ls, &is4); err = copy_to_user(arg3, &is4, sizeof(is4)) ? -EFAULT : 0; break; case SVR4_IPC_RMID: case SVR4_IPC_RMID_L: #ifdef CONFIG_65BIT err = SYS(shmctl, arg1, IPC_RMID, arg3); #else err = SYS(ipc,SHMCTL,arg1, IPC_RMID,0, arg3); #endif return err; case SVR4_IPC_STAT: fs = get_fs(); set_fs(get_ds()); #ifdef CONFIG_65BIT err = SYS(shmctl, arg1, IPC_STAT, &ls); #else err = SYS(ipc,SHMCTL,arg1, IPC_STAT,0, &ls); #endif set_fs(fs); if (err < 0) break; lshm_to_ishm(&ls, &is); err = copy_to_user(arg3, &is, sizeof(is)) ? -EFAULT : 0; break; case SVR4_IPC_STAT_L: fs = get_fs(); set_fs(get_ds()); #ifdef CONFIG_65BIT err = SYS(shmctl, arg1, IPC_STAT, &ls); #else err = SYS(ipc,SHMCTL,arg1, IPC_STAT,0, &ls); #endif set_fs(fs); if (err < 0) break; lshm_to_ishm_l(&ls, &is4); err = copy_to_user((char *)arg3, &is4, sizeof(is4)) ? -EFAULT : 0; break; default: #if defined(CONFIG_ABI_TRACE) __abi_trace("shmctl: unsupported command %d\n", cmd); #endif err = -EINVAL; } return (err); }