diff -Nru linux-2.6.7/abi/cxenix/Makefile linux-2.6.7-abi/abi/cxenix/Makefile --- linux-2.6.7/abi/cxenix/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/cxenix/Makefile 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,7 @@ + +abi-cxenix-objs := sysent.o misc.o stubs.o signal.o pathconf.o utsname.o + +obj-$(CONFIG_ABI_SCO) += abi-cxenix.o + +abi-cxenix.o: $(abi-cxenix-objs) + $(LD) -r -o $@ $(abi-cxenix-objs) diff -Nru linux-2.6.7/abi/cxenix/misc.c linux-2.6.7-abi/abi/cxenix/misc.c --- linux-2.6.7/abi/cxenix/misc.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/cxenix/misc.c 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,296 @@ +/* + * misc.c - misc cxenix() subcalls + * + * Copyright (c) 1993,1994 Drew Sullivan + * Copyright (c) 1994-1996 Mike Jagdis + */ + +#ident "%W% %G%" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + + +struct timeb { + time_t time; + u_short millitm; + short timezone; + short dstflag; +}; + +enum { + XF_UNLCK = 0, + XF_WRLCK = 1, + XF_RDLCK = 3, +}; + +struct ibcs_flock { + short l_type; + short l_whence; + off_t l_start; + off_t l_len; + short l_sysid; + short l_pid; +}; + + +/* + * locking() requires mandatory locking. Processes that attempt to + * read or write a region locked with locking() are required to block. + * You need to build a kernel with mandatory locking support and set + * the permissions on the required file to setgid, no group execute. + */ +int +xnx_locking(int fd, int mode, unsigned long size) +{ + struct flock fl; + mm_segment_t old_fs; + int error; + + if ((mode < 0 || mode > 7) && mode != 20) { +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_API, + "unsupported locking() mode=0x%x\n", mode); +#endif + return -EINVAL; + } + + /* + * Modes 5, 6 & 7 are very like the fcntl mechanism but + * we can't just punt to that because the type values are + * different. + */ + if (mode > 4 && mode < 8) { + struct ibcs_flock *ifl = (struct ibcs_flock *)size; + short t; + + error = verify_area(VERIFY_READ, ifl, sizeof(*ifl)); + if (error) + return error; + + get_user(t, &ifl->l_type); + switch (t) { + case XF_UNLCK: t = F_UNLCK; break; + case XF_WRLCK: t = F_WRLCK; break; + case XF_RDLCK: t = F_RDLCK; break; + default: return -EINVAL; + } + put_user(t, &ifl->l_type); + + error = sys_fcntl(fd, mode, (u_long)ifl); + + get_user(t, &ifl->l_type); + switch (t) { + case F_UNLCK: t = XF_UNLCK; break; + case F_WRLCK: t = XF_WRLCK; break; + case F_RDLCK: t = XF_RDLCK; break; + } + put_user(t, &ifl->l_type); + + get_user(t, &ifl->l_sysid); + put_user(t, &ifl->l_pid); + put_user(0, &ifl->l_sysid); + return error; + } + + fl.l_type = (mode == 0 ? F_UNLCK + : ((mode <= 2 || mode == 20) ? F_WRLCK + : F_RDLCK)); + fl.l_whence = 1; + fl.l_start = 0; + fl.l_len = size; + + old_fs = get_fs(); + set_fs (get_ds()); + error = sys_fcntl(fd, (mode == 5) ? F_GETLK + : (!(mode % 2) ? F_SETLK : F_SETLKW), (u_long)&fl); + set_fs(old_fs); + return error; +} + + +/* Check if input is available */ +int +xnx_rdchk(int fd) +{ + int error, nbytes; + mm_segment_t old_fs; + + old_fs = get_fs(); + set_fs (get_ds()); + error = sys_ioctl(fd, FIONREAD, (long)&nbytes); + set_fs(old_fs); + + if (error < 0) return error; + return nbytes ? 1 : 0; +} + +/* + * Linux has a stub sys_ftime. Perhaps this should be there? On the other + * hand it's an old call that probably shouldn't be used by most modern + * applications so perhaps it's better here where it needn't bloat the + * base kernel. + */ +int +xnx_ftime(struct timeb *tp) +{ + struct timeval tv; + struct timezone tz; + int error; + mm_segment_t old_fs; + + error = verify_area(VERIFY_WRITE, tp, sizeof(struct timeb)); + if (error) + return error; + + old_fs = get_fs(); + set_fs (get_ds()); + error = sys_gettimeofday(&tv, &tz); + set_fs(old_fs); + if (error) + return error; + + put_user(tv.tv_sec, &tp->time); + put_user((unsigned short)(tv.tv_usec/1000), &tp->millitm); + put_user((short)tz.tz_minuteswest, &tp->timezone); + put_user((short)tz.tz_dsttime, &tp->dstflag); + + return 0; +} + +#define USE_NEW_NAP_CODE + +#ifndef USE_NEW_NAP_CODE +static __inline __sighandler_t +sigaction(int sig, __sighandler_t handler) +{ + struct k_sigaction *k = ¤t->sighand->action[sig-1]; + __sighandler_t old_handler; + + spin_lock(¤t->sighand->siglock); + old_handler = k->sa.sa_handler; + k->sa.sa_handler = handler; + spin_unlock(¤t->sighand->siglock); + + return old_handler; +} +#endif + +/* go to sleep for period milliseconds */ +/* - returns either an EINTR error or returns the elapsed time */ +/* Note: + for SCO OpenServer 5.0.6 the original nap was fixed so that it + no longer waits a minimum of 2 tick (20ms) + but fewer time with a 10 ms granularity */ +long +xnx_nap(long period) +{ +#ifdef USE_NEW_NAP_CODE + // Hz means the number of jiffies per second. + // the below code needs HZ to be 1 <= HZ <= 1000 + // in order to work correctly in any case. +#if HZ > 1000 +#error this code only works with HZ <= 1000 +#endif + struct timeval tv1, tv2; + struct timezone tz; + mm_segment_t oldfs; + long period_s; // seconds part + long period_ms_hz; // milli seconds part, scaled to a base of HZ + long period_j; // jiffies + + if (!period) + return 0; // zereo request, zero reply + + oldfs = get_fs(); + set_fs(get_ds()); + sys_gettimeofday(&tv1, &tz); + + period_s = period / 1000; + period_ms_hz = (period - period_s * 1000) * HZ; + period_j = period_s * HZ + period_ms_hz / 1000; + // take care of rounding errors, round up + if (period > period_j * (1000 / HZ)) period_j++; + + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout (period_j); + + sys_gettimeofday(&tv2, &tz); + set_fs(oldfs); + + if (signal_pending(current)) + return -EINTR; // interrupted + return (tv2.tv_sec - tv1.tv_sec) * 1000 + + (tv2.tv_usec - tv1.tv_usec + 500) / 1000; +#else + __sighandler_t old_handler; + struct itimerval it; + struct timeval tv1, tv2; + struct timezone tz; + mm_segment_t oldfs; + + if (!period) + return 0; + + it.it_interval.tv_sec = 0; + it.it_interval.tv_usec = 0; + it.it_value.tv_sec = 0; + it.it_value.tv_usec = period * 1000; + + oldfs = get_fs(); + set_fs(get_ds()); + + sys_gettimeofday(&tv1, &tz); + old_handler = sigaction(SIGALRM, SIG_DFL); // SIG_DFL -> terminate + sys_setitimer(ITIMER_REAL, &it, NULL); + sys_pause(); + sigaction(SIGALRM, old_handler); + sys_gettimeofday(&tv2, &tz); + set_fs(oldfs); + + deactivate_signal(current, SIGALRM); + + if (signal_pending(current)) + return -EINTR; + return ((tv2.tv_sec - tv1.tv_sec) * 1000000 + + (tv2.tv_usec - tv1.tv_usec)) / 1000; +#endif +} + +/* + * eaccess() checks access to the given path using the effective + * uid/gid rather than the real uid/gid. + */ +int +xnx_eaccess(char *path, int mode) +{ + uid_t ouid; + gid_t ogid; + int err; + + ouid = current->uid; + ogid = current->gid; + current->uid = current->euid; + current->gid = current->egid; + + err = sys_access(path, mode); + + current->uid = ouid; + current->gid = ogid; + + return err; +} diff -Nru linux-2.6.7/abi/cxenix/pathconf.c linux-2.6.7-abi/abi/cxenix/pathconf.c --- linux-2.6.7/abi/cxenix/pathconf.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/cxenix/pathconf.c 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,140 @@ +/* + * pathconf.c - support for xenix pathconf + * + * Copyright (c) 1993,1994 Drew Sullivan + * Copyright (c) 1994-1996 Mike Jagdis + */ + +#ident "%W% %G%" + +#include +#include +#include +#include +#include +#include +#include +#include + + +enum { + _PC_LINK_MAX = 0, + _PC_MAX_CANON = 1, + _PC_MAX_INPUT = 2, + _PC_NAME_MAX = 3, + _PC_PATH_MAX = 4, + _PC_PIPE_BUF = 5, + _PC_CHOWN_RESTRICTED = 6, + _PC_NO_TRUNC = 7, + _PC_VDISABLE = 8, +}; + +static int +xnx_name_max(char *path) +{ + struct statfs stf; + mm_segment_t fs; + char *p; + int error; + + p = getname(path); + if (IS_ERR(p)) + return PTR_ERR(p); + + fs = get_fs(); + set_fs(get_ds()); + error = sys_statfs(p, &stf); + set_fs(fs); + + putname(p); + if (error) + return (error); + return (stf.f_namelen); +} + +int +xnx_pathconf(char *path, int name) +{ + switch (name) { + case _PC_LINK_MAX: + /* + * Although Linux headers define values on a per + * filesystem basis there is no way to access + * these without hard coding fs information here + * so for now we use a bogus value. + */ + return LINK_MAX; + case _PC_MAX_CANON: + return MAX_CANON; + case _PC_MAX_INPUT: + return MAX_INPUT; + case _PC_PATH_MAX: + return PATH_MAX; + case _PC_PIPE_BUF: + return PIPE_BUF; + case _PC_CHOWN_RESTRICTED: + /* + * We should really think about this and tell + * the truth. + */ + return 0; + case _PC_NO_TRUNC: + /* Not sure... It could be fs dependent? */ + return 1; + case _PC_VDISABLE: + return 1; + case _PC_NAME_MAX: + return xnx_name_max(path); + } + return -EINVAL; +} + +int +xnx_fpathconf(int fildes, int name) +{ + switch (name) { + case _PC_LINK_MAX: + /* + * Although Linux headers define values on a per + * filesystem basis there is no way to access + * these without hard coding fs information here + * so for now we use a bogus value. + */ + return LINK_MAX; + case _PC_MAX_CANON: + return MAX_CANON; + case _PC_MAX_INPUT: + return MAX_INPUT; + case _PC_PATH_MAX: + return PATH_MAX; + case _PC_PIPE_BUF: + return PIPE_BUF; + case _PC_CHOWN_RESTRICTED: + /* + * We should really think about this and tell + * the truth. + */ + return 0; + case _PC_NO_TRUNC: + /* Not sure... It could be fs dependent? */ + return 1; + case _PC_VDISABLE: + return 1; + case _PC_NAME_MAX: + { + struct statfs buf; + int error; + mm_segment_t old_fs; + + old_fs = get_fs(); + set_fs (get_ds()); + error = sys_fstatfs(fildes, &buf); + set_fs(old_fs); + if (!error) + return buf.f_namelen; + return error; + } + } + + return -EINVAL; +} diff -Nru linux-2.6.7/abi/cxenix/signal.c linux-2.6.7-abi/abi/cxenix/signal.c --- linux-2.6.7/abi/cxenix/signal.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/cxenix/signal.c 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,89 @@ +#ident "%W% %G%" + +#include +#include +#include +#include +#define __KERNEL_SYSCALLS__ +#include +#include + +#include +#include + +#include +#include + + +int +xnx_sigaction(int sco_signum, const struct sco_sigaction *action, + struct sco_sigaction *oldaction) +{ + struct sco_sigaction new_sa, old_sa; + struct sigaction nsa, osa; + mm_segment_t fs; + int error, signo; + + if (sco_signum >= NSIGNALS) + return -EINVAL; + signo = current_thread_info()->exec_domain->signal_map[sco_signum]; + + if (oldaction) { + error = verify_area(VERIFY_WRITE, oldaction, + sizeof(struct sco_sigaction)); + if (error) + return (error); + } + + if (action) { + error = copy_from_user(&new_sa, action, + sizeof(struct sco_sigaction)); + if (error) + return -EFAULT; + nsa.sa_restorer = NULL; + nsa.sa_handler = new_sa.sa_handler; + nsa.sa_mask = map_sigvec_to_kernel(new_sa.sa_mask, + current_thread_info()->exec_domain->signal_map); + nsa.sa_flags = SA_NOMASK; + if (new_sa.sa_flags & SCO_SA_NOCLDSTOP) + nsa.sa_flags |= SA_NOCLDSTOP; + } + + fs = get_fs(); + set_fs(get_ds()); + error = sys_rt_sigaction(signo, action ? &nsa : NULL, + oldaction ? &osa : NULL, sizeof(sigset_t)); + set_fs(fs); + + if (error || !oldaction) + return (error); + + old_sa.sa_handler = osa.sa_handler; + old_sa.sa_mask = map_sigvec_from_kernel(osa.sa_mask, + current_thread_info()->exec_domain->signal_invmap); + old_sa.sa_flags = 0; + if (osa.sa_flags & SA_NOCLDSTOP) + old_sa.sa_flags |= SCO_SA_NOCLDSTOP; + + if (copy_to_user(oldaction, &old_sa, sizeof(struct sco_sigaction))) + return -EFAULT; + return 0; +} + +int +xnx_sigpending(u_long *setp) +{ + sigset_t lxpending; + u_long pending; + + spin_lock_irq(¤t->sighand->siglock); + sigandsets(&lxpending, ¤t->blocked, ¤t->pending.signal); + spin_unlock_irq(¤t->sighand->siglock); + + pending = map_sigvec_from_kernel(lxpending, + current_thread_info()->exec_domain->signal_invmap); + + if (copy_to_user(setp, &pending, sizeof(u_long))) + return -EFAULT; + return 0; +} diff -Nru linux-2.6.7/abi/cxenix/stubs.c linux-2.6.7-abi/abi/cxenix/stubs.c --- linux-2.6.7/abi/cxenix/stubs.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/cxenix/stubs.c 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,123 @@ +/* + * stubs.c - stubs for unimplemented cxenix subcalls + * + * Copyright (c) 1993,1994 Drew Sullivan. + * Copyright (c) 1994-1996 Mike Jagdis. + */ + +#ident "%W% %G%" + +#include +#include +#include + +#include + + +int +xnx_creatsem(char *sem_name, int mode) +{ + return -EPERM; +} + +int +xnx_opensem(char *sem_name) +{ + return -EPERM; +} + +int +xnx_sigsem(int sem_num) +{ + return -EPERM; +} + +int +xnx_waitsem(int sem_num) +{ + return -EPERM; +} + +int +xnx_nbwaitsem(int sem_num) +{ + return -EPERM; +} + + +int +xnx_sdget(char *path, int flags, long size, int mode) +{ + return -EPERM; +} + +int +xnx_sdfree(char* addr) +{ + return -EPERM; +} + +int +xnx_sdenter(char *addr, int flags) +{ + return -EPERM; +} + +int +xnx_sdleave(char *addr) +{ + return -EPERM; +} + +int +xnx_sdgetv(char *addr) +{ + return -EPERM; +} + +int +xnx_sdwaitv(char *addr, int vnum) +{ + return -EPERM; +} + + +/* + * This allows processes to be allowed to exceed available swap. The man + * page isn't too clear - it seems to suggest Xenix supports physical + * memory > swap but this doesn't make sense to me? It almost certainly + * isn't useful for Linux to actually do anything with this - just lie. + */ +enum { + XNX_PRHUGEX = 1, + XNX_PRNORMEX = 2, +}; + +int +xnx_proctl(int pid, int command, char *arg) +{ + return 0; +} + +int +xnx_execseg(excode_t oldaddr, unsigned size) +{ + return -EPERM; +} + + +int +xnx_unexecseg(excode_t addr) +{ + return -EPERM; +} + +/* + * This allows running adb without executing any programs, but disassembly + * will work fine with that lie. + */ +int +xnx_paccess(int pid, int cmd, int offset, int count, char *ptr) +{ + return 0; +} diff -Nru linux-2.6.7/abi/cxenix/sysent.c linux-2.6.7-abi/abi/cxenix/sysent.c --- linux-2.6.7/abi/cxenix/sysent.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/cxenix/sysent.c 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,96 @@ +#ident "%W% %G%" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + + +MODULE_DESCRIPTION("Xenix/OpenServer cxenix call support"); +MODULE_AUTHOR("Christoph Hellwig, partially taken from iBCS"); +MODULE_LICENSE("GPL"); + + +static struct sysent cxenix_table[] = { +/* 0 */ { 0, Ukn, "syscall", "" }, +/* 1 */ { xnx_locking, 3, "locking", "ddd" }, +/* 2 */ { xnx_creatsem, 2, "creatsem", "sd" }, +/* 3 */ { xnx_opensem, 1, "opensem", "s" }, +/* 4 */ { xnx_sigsem, 1, "sigsem", "d" }, +/* 5 */ { xnx_waitsem, 1, "waitsem", "d" }, +/* 6 */ { xnx_nbwaitsem, 1, "nbwaitsem", "d" }, +/* 7 */ { xnx_rdchk, 1, "rdchk", "d" }, +/* 8 */ { 0, Ukn, "stkgro", "" }, +/* 9 */ { 0, Ukn, "?", "" }, +/* 10 */ { sys_ftruncate, 2, "chsize", "dd" }, +/* 11 */ { xnx_ftime, 1, "ftime", "x" }, +/* 12 */ { xnx_nap, 1, "nap", "d" }, +/* 13 */ { xnx_sdget, 4, "sdget", "sddd" }, +/* 14 */ { xnx_sdfree, 1, "sdfree", "x" }, +/* 15 */ { xnx_sdenter, 2, "sdenter", "xd" }, +/* 16 */ { xnx_sdleave, 1, "sdleave", "x" }, +/* 17 */ { xnx_sdgetv, 1, "sdgetv", "x" }, +/* 18 */ { xnx_sdwaitv, 2, "sdwaitv", "xd" }, +/* 19 */ { 0, Ukn, "brkctl", "" }, +/* 20 */ { 0, Ukn, "?", "" }, +/* 21 */ { 0, 2, "sco-getcwd?", "dx" }, +/* 22 */ { 0, Ukn, "?", "" }, +/* 23 */ { 0, Ukn, "?", "" }, +/* 24 */ { 0, Ukn, "?", "" }, +/* 25 */ { 0, Ukn, "?", "" }, +/* 26 */ { 0, Ukn, "?", "" }, +/* 27 */ { 0, Ukn, "?", "" }, +/* 28 */ { 0, Ukn, "?", "" }, +/* 29 */ { 0, Ukn, "?", "" }, +/* 30 */ { 0, Ukn, "?", "" }, +/* 31 */ { 0, Ukn, "?", "" }, +/* 32 */ { xnx_proctl, 3, "proctl", "ddx" }, +/* 33 */ { xnx_execseg, 2, "execseg", "xd" }, +/* 34 */ { xnx_unexecseg, 1, "unexecseg", "x" }, +/* 35 */ { 0, Ukn, "?", "" }, +/* 36 */ { sys_select, 5, "select", "dxxxx" }, +/* 37 */ { xnx_eaccess, 2, "eaccess", "so" }, +/* 38 */ { xnx_paccess, 5, "paccess", "dddds" }, +/* 39 */ { xnx_sigaction, 3, "sigaction", "dxx" }, +/* 40 */ { abi_sigprocmask, 3, "sigprocmask", "dxx" }, +/* 41 */ { xnx_sigpending, 1, "sigpending", "x" }, +/* 42 */ { abi_sigsuspend, Spl, "sigsuspend", "x" }, +/* 43 */ { sys_getgroups16, 2, "getgroups", "dx" }, +/* 44 */ { sys_setgroups16, 2, "setgroups", "dx" }, +/* 45 */ { ibcs_sysconf, 1, "sysconf", "d" }, +/* 46 */ { xnx_pathconf, 2, "pathconf", "sd" }, +/* 47 */ { xnx_fpathconf, 2, "fpathconf", "dd" }, +/* 48 */ { sys_rename, 2, "rename", "ss" }, +/* 49 */ { 0, Ukn, "?", "" }, +/* 50 */ { xnx_utsname, 1, "utsname", "x" }, +/* 51 */ { 0, Ukn, "?", "" }, +/* 52 */ { 0, Ukn, "?", "" }, +/* 53 */ { 0, Ukn, "?", "" }, +/* 54 */ { 0, Ukn, "?", "" }, +/* 55 */ { sys_getitimer, 2, "getitimer", "dx" }, +/* 56 */ { sys_setitimer, 3, "setitimer", "dxx" } +}; + + +void cxenix(struct pt_regs *regs) +{ + int sysno = regs->eax >> 8; + + if (sysno >= ARRAY_SIZE(cxenix_table)) + set_error(regs, iABI_errors(-EINVAL)); + else + lcall7_dispatch(regs, &cxenix_table[sysno], 1); +} + +#if defined(CONFIG_ABI_SYSCALL_MODULES) +EXPORT_SYMBOL(cxenix); +#endif diff -Nru linux-2.6.7/abi/cxenix/utsname.c linux-2.6.7-abi/abi/cxenix/utsname.c --- linux-2.6.7/abi/cxenix/utsname.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/cxenix/utsname.c 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,89 @@ +/* + * utsname.c - support for the utsname subcall of cxenix + * + * Copyright (C) 1994 Mike Jagdis (jaggy@purplet.demon.co.uk) + */ + +#ident "%W% %G%" + +#include +#include +#include +#include +#include +#include + + +static char sco_serial[10] = "public"; + +struct xnx_utsname { + char sysname[9]; + char nodename[9]; + char release[16]; + char kernelid[20]; + char machine[9]; + char bustype[9]; + char sysserial[10]; + u_short sysorigin; + u_short sysoem; + char numusers[9]; + u_short numcpu; +}; + +#define set_utsfield(to, from, dotchop) \ + { \ + char *p; \ + int i, len = (sizeof(to) > sizeof(from) ? sizeof(from) : sizeof(to)); \ + __copy_to_user(to, from, len); \ + if (dotchop) \ + for (p=from,i=0; *p && *p != '.' && --len; p++,i++); \ + else \ + i = len - 1; \ + __put_user('\0', to+i); \ + } + + +int +xnx_utsname(u_long addr) +{ + struct xnx_utsname *utp = (struct xnx_utsname *)addr; + int error; + + /* + * This shouldn't be invoked by anything that isn't running + * in the SCO personality. I can envisage a program that uses + * this to test if utp is running on SCO or not. It probably + * won't happen but let's make sure utp doesn't anyway... + */ + if (!is_cur_personality(PER_SCOSVR3)) + return -ENOSYS; + + down_read(&uts_sem); + error = verify_area(VERIFY_WRITE, utp, sizeof (struct xnx_utsname)); + if (!error) { + if (abi_fake_utsname) { + set_utsfield(utp->sysname, "SCO_SV", 0); + set_utsfield(utp->nodename, system_utsname.nodename, 1); + set_utsfield(utp->release, "3.2v5.0.0\0", 0); + } else { + set_utsfield(utp->sysname, system_utsname.nodename, 1); + set_utsfield(utp->nodename, system_utsname.nodename, 1); + set_utsfield(utp->release, system_utsname.release, 0); + } + set_utsfield(utp->kernelid, system_utsname.version, 0); + set_utsfield(utp->machine, system_utsname.machine, 0); + if (EISA_bus) { + set_utsfield(utp->bustype, "EISA", 0); + } else { + set_utsfield(utp->bustype, "ISA", 0); + } + set_utsfield(utp->sysserial, sco_serial, 0); + __put_user(0xffff, &utp->sysorigin); + __put_user(0xffff, &utp->sysoem); + set_utsfield(utp->numusers, "unlim", 0); + __put_user(1, &utp->numcpu); + } + up_read(&uts_sem); + + return (error); +} diff -Nru linux-2.6.7/abi/ibcs/Makefile linux-2.6.7-abi/abi/ibcs/Makefile --- linux-2.6.7/abi/ibcs/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/ibcs/Makefile 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,7 @@ + +abi-ibcs-objs := sysent.o + +obj-$(CONFIG_ABI_IBCS) += abi-ibcs.o + +abi-ibcs.o: $(abi-ibcs-objs) + $(LD) -r -o $@ $(abi-ibcs-objs) diff -Nru linux-2.6.7/abi/ibcs/sysent.c linux-2.6.7-abi/abi/ibcs/sysent.c --- linux-2.6.7/abi/ibcs/sysent.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/ibcs/sysent.c 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,412 @@ +/* + * Copyright (c) 2001 Christoph Hellwig. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ident "%W% %G%" + +/* + * SVR4 personality switch. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +MODULE_DESCRIPTION("iBCS2/iABI4 personality"); +MODULE_AUTHOR("Christoph Hellwig, partially taken from iBCS"); +MODULE_LICENSE("GPL"); + + +/* + * We could remove some of the long identity mapped runs but at the + * expense of extra comparisons for each mapping at run time... + */ +static u_char ibcs_err_table[] = { +/* 0 - 9 */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, +/* 10 - 19 */ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, +/* 20 - 29 */ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, +/* 30 - 39 */ 30, 31, 32, 33, 34, 45, 78, 46, 89, 93, +/* 40 - 49 */ 90, 90, 35, 36, 37, 38, 39, 40, 41, 42, +/* 50 - 59 */ 43, 44, 50, 51, 52, 53, 54, 55, 56, 57, +/* 60 - 69 */ 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, +/* 70 - 79 */ 70, 71, 74, 76, 77, 79, 80, 81, 82, 83, +/* 80 - 89 */ 84, 85, 86, 87, 88, 91, 92, 94, 95, 96, +/* 90 - 99 */ 97, 98, 99, 120, 121, 122, 123, 124, 125, 126, +/* 100 - 109 */ 127, 128, 129, 130, 131, 132, 133, 134, 143, 144, +/* 110 - 119 */ 145, 146, 147, 148, 149, 150, 22, 135, 137, 138, +/* 120 - 122 */ 139, 140, 28 +}; + +/* + * Map Linux RESTART* values (512,513,514) to EINTR + */ +static u_char lnx_err_table[] = { +/* 512 - 514 */ EINTR, EINTR, EINTR +}; + +struct map_segment ibcs_err_map[] = { + { 0, 0+sizeof(ibcs_err_table)-1, ibcs_err_table }, + { 512, 512+sizeof(lnx_err_table)-1, lnx_err_table }, + { -1 } +}; + +static long linux_to_ibcs_signals[NSIGNALS+1] = { +/* 0 - 3 */ 0, IBCS_SIGHUP, IBCS_SIGINT, IBCS_SIGQUIT, +/* 4 - 7 */ IBCS_SIGILL, IBCS_SIGTRAP, IBCS_SIGABRT, -1, +/* 8 - 11 */ IBCS_SIGFPE, IBCS_SIGKILL, IBCS_SIGUSR1, IBCS_SIGSEGV, +/* 12 - 15 */ IBCS_SIGUSR2, IBCS_SIGPIPE, IBCS_SIGALRM, IBCS_SIGTERM, +/* 16 - 19 */ IBCS_SIGSEGV, IBCS_SIGCHLD, IBCS_SIGCONT, IBCS_SIGSTOP, +/* 20 - 23 */ IBCS_SIGTSTP, IBCS_SIGTTIN, IBCS_SIGTTOU, IBCS_SIGURG, +/* 24 - 27 */ IBCS_SIGGXCPU, IBCS_SIGGXFSZ, IBCS_SIGVTALRM, IBCS_SIGPROF, +/* 28 - 31 */ IBCS_SIGWINCH, IBCS_SIGIO, IBCS_SIGPWR, -1, +/* 32 */ -1 +}; + +static long ibcs_to_linux_signals[NSIGNALS+1] = { +/* 0 - 3 */ 0, SIGHUP, SIGINT, SIGQUIT, +/* 4 - 7 */ SIGILL, SIGTRAP, SIGIOT, SIGUNUSED, +/* 8 - 11 */ SIGFPE, SIGKILL, SIGUNUSED, SIGSEGV, +/* 12 - 15 */ SIGUNUSED, SIGPIPE, SIGALRM, SIGTERM, +/* 16 - 19 */ SIGUSR1, SIGUSR2, SIGCHLD, SIGPWR, +/* 20 - 23 */ SIGWINCH, SIGURG, SIGPOLL, SIGSTOP, +/* 24 - 27 */ SIGTSTP, SIGCONT, SIGTTIN, SIGTTOU, +/* 28 - 31 */ SIGVTALRM, SIGPROF, SIGXCPU, SIGXFSZ, +/* 32 */ -1 +}; + +static char ibcs_socktype[] = { + SOCK_STREAM, + SOCK_DGRAM, + 0, + SOCK_RAW, + SOCK_RDM, + SOCK_SEQPACKET +}; + +static struct map_segment ibcs_socktype_map[] = { + { 1, 6, ibcs_socktype }, + { -1 } +}; + +static struct map_segment ibcs_sockopt_map[] = { + { 0x0001, 0x0001, (char *)SO_DEBUG }, + { 0x0002, 0x0002, (char *)__SO_ACCEPTCON }, + { 0x0004, 0x0004, (char *)SO_REUSEADDR }, + { 0x0008, 0x0008, (char *)SO_KEEPALIVE }, + { 0x0010, 0x0010, (char *)SO_DONTROUTE }, + { 0x0020, 0x0020, (char *)SO_BROADCAST }, + { 0x0040, 0x0040, (char *)SO_USELOOPBACK }, + { 0x0080, 0x0080, (char *)SO_LINGER }, + { 0x0100, 0x0100, (char *)SO_OOBINLINE }, + { 0x0200, 0x0200, (char *)SO_ORDREL }, + { 0x0400, 0x0400, (char *)SO_IMASOCKET }, + { 0x1001, 0x1001, (char *)SO_SNDBUF }, + { 0x1002, 0x1002, (char *)SO_RCVBUF }, + { 0x1003, 0x1003, (char *)SO_SNDLOWAT }, + { 0x1004, 0x1004, (char *)SO_RCVLOWAT }, + { 0x1005, 0x1005, (char *)SO_SNDTIMEO }, + { 0x1006, 0x1006, (char *)SO_RCVTIMEO }, + { 0x1007, 0x1007, (char *)SO_ERROR }, + { 0x1008, 0x1008, (char *)SO_TYPE }, + { 0x1009, 0x1009, (char *)SO_PROTOTYPE }, + { -1 } +}; + +static struct map_segment ibcs_af_map[] = { + { 0, 2, NULL }, + { -1 } +}; + + +static struct sysent ibcs_syscall_table[] = { + { abi_syscall, Fast, "syscall", "" }, /* 0 */ + { sys_exit, 1, "exit", "d" }, /* 1 */ + { abi_fork, Spl, "fork", "" }, /* 2 */ + { abi_read, 3, "read", "dpd" }, /* 3 */ + { sys_write, 3, "write", "dpd" }, /* 4 */ + { svr4_open, 3, "open", "soo" }, /* 5 */ + { sys_close, 1, "close", "d" }, /* 6 */ + { abi_wait, Spl, "wait", "xxx" }, /* 7 */ + { sys_creat, 2, "creat", "so" }, /* 8 */ + { sys_link, 2, "link", "ss" }, /* 9 */ + { sys_unlink, 1, "unlink", "s" }, /* 10 */ + { abi_exec, Spl, "exec", "sxx" }, /* 11 */ + { sys_chdir, 1, "chdir", "s" }, /* 12 */ + { abi_time, 0, "time", "" }, /* 13 */ + { svr4_mknod, 3, "mknod", "soo" }, /* 14 */ + { sys_chmod, 2, "chmod", "so" }, /* 15 */ + { sys_chown, 3, "chown", "sdd" }, /* 16 */ + { abi_brk, 1, "brk/break", "x" }, /* 17 */ + { svr4_stat, 2, "stat", "sp" }, /* 18 */ + { sys_lseek, 3, "seek/lseek", "ddd" }, /* 19 */ + { abi_getpid, Spl, "getpid", "" }, /* 20 */ + { 0, Ukn, "mount", "" }, /* 21 */ + { sys_umount, 1, "umount", "s" }, /* 22 */ + { sys_setuid, 1, "setuid", "d" }, /* 23 */ + { abi_getuid, Spl, "getuid", "" }, /* 24 */ + { sys_stime, 1, "stime", "d" }, /* 25 */ + { 0, Ukn, "ptrace", "" }, /* 26 */ + { sys_alarm, 1, "alarm", "d" }, /* 27 */ + { svr4_fstat, 2, "fstat", "dp" }, /* 28 */ + { sys_pause, 0, "pause", "" }, /* 29 */ + { sys_utime, 2, "utime", "xx" }, /* 30 */ + { 0, Ukn, "stty", "" }, /* 31 */ + { 0, Ukn, "gtty", "" }, /* 32 */ + { sys_access, 2, "access", "so" }, /* 33 */ + { sys_nice, 1, "nice", "d" }, /* 34 */ + { svr4_statfs, 4, "statfs", "spdd" }, /* 35 */ + { sys_sync, 0, "sync", "" }, /* 36 */ + { abi_kill, 2, "kill", "dd" }, /* 37 */ + { svr4_fstatfs, 4, "fstatfs", "dpdd" }, /* 38 */ + { abi_procids, Spl, "procids", "d" }, /* 39 */ + { 0, Ukn, "cxenix", "" }, /* 40 */ + { sys_dup, 1, "dup", "d" }, /* 41 */ + { abi_pipe, Spl, "pipe", "" }, /* 42 */ + { sys_times, 1, "times", "p" }, /* 43 */ + { 0, Ukn, "prof", "" }, /* 44 */ + { 0, Ukn, "lock/plock", "" }, /* 45 */ + { sys_setgid, 1, "setgid", "d" }, /* 46 */ + { abi_getgid, Spl, "getgid", "" }, /* 47 */ + { abi_sigfunc, Fast, "sigfunc", "xxx" }, /* 48 */ + { svr4_msgsys, Spl, "msgsys", "dxddd" }, /* 49 */ + { svr4_sysi86, 3, "sysi86", "d" }, /* 50 */ + { sys_acct, 1, "acct/sysacct", "x" }, /* 51 */ + { svr4_shmsys, Fast, "shmsys", "ddxo" }, /* 52 */ + { svr4_semsys, Spl, "semsys", "dddx" }, /* 53 */ + { svr4_ioctl, Spl, "ioctl", "dxx" }, /* 54 */ + { 0, 3, "uadmin", "xxx" }, /* 55 */ + { 0, Ukn, "?", "" }, /* 56 */ + { v7_utsname, 1, "utsys", "x" }, /* 57 */ + { sys_fsync, 1, "fsync", "d" }, /* 58 */ + { abi_exec, Spl, "execv", "spp" }, /* 59 */ + { sys_umask, 1, "umask", "o" }, /* 60 */ + { sys_chroot, 1, "chroot", "s" }, /* 61 */ + { svr4_fcntl, 3, "fcntl", "dxx" }, /* 62 */ + { svr4_ulimit, 2, "ulimit", "xx" }, /* 63 */ + { 0, Ukn, "?", "" }, /* 64 */ + { 0, Ukn, "?", "" }, /* 65 */ + { 0, Ukn, "?", "" }, /* 66 */ + { 0, Ukn, "?", "" }, /* 67 */ + { 0, Ukn, "?", "" }, /* 68 */ + { 0, Ukn, "?", "" }, /* 69 */ + { 0, Ukn, "advfs", "" }, /* 70 */ + { 0, Ukn, "unadvfs", "" }, /* 71 */ + { 0, Ukn, "rmount", "" }, /* 72 */ + { 0, Ukn, "rumount", "" }, /* 73 */ + { 0, Ukn, "rfstart", "" }, /* 74 */ + { 0, Ukn, "?", "" }, /* 75 */ + { 0, Ukn, "rdebug", "" }, /* 76 */ + { 0, Ukn, "rfstop", "" }, /* 77 */ + { 0, Ukn, "rfsys", "" }, /* 78 */ + { sys_rmdir, 1, "rmdir", "s" }, /* 79 */ + { abi_mkdir, 2, "mkdir", "so" }, /* 80 */ + { svr4_getdents, 3, "getdents", "dxd" }, /* 81 */ + { 0, Ukn, "libattach", "" }, /* 82 */ + { 0, Ukn, "libdetach", "" }, /* 83 */ + { svr4_sysfs, 3, "sysfs", "dxx" }, /* 84 */ + { svr4_getmsg, Spl, "getmsg", "dxxx" }, /* 85 */ + { svr4_putmsg, Spl, "putmsg", "dxxd" }, /* 86 */ + { sys_poll, 3, "poll", "xdd" }, /* 87 */ + { svr4_lstat, 2, "lstat", "sp" }, /* 88 */ + { sys_symlink, 2, "symlink", "ss" }, /* 89 */ + { sys_readlink, 3, "readlink", "spd" }, /* 90 */ + { sys_setgroups, 2, "setgroups", "dp" }, /* 91 */ + { sys_getgroups, 2, "getgroups", "dp" }, /* 92 */ + { sys_fchmod, 2, "fchmod", "do" }, /* 93 */ + { sys_fchown, 3, "fchown", "ddd" }, /* 94 */ + { abi_sigprocmask, 3, "sigprocmask", "dxx" }, /* 95 */ + { abi_sigsuspend, Spl, "sigsuspend", "x" }, /* 96 */ + { 0, 2, "sigaltstack", "xx" }, /* 97 */ + { abi_sigaction, 3, "sigaction", "dxx" }, /* 98 */ + { svr4_sigpending, 2, "sigpending", "dp" }, /* 99 */ + { svr4_context, Spl, "context", "" }, /* 100 */ + { 0, Ukn, "evsys", "" }, /* 101 */ + { 0, Ukn, "evtrapret", "" }, /* 102 */ + { svr4_statvfs, 2, "statvfs", "sp" }, /* 103 */ + { svr4_fstatvfs, 2, "fstatvfs", "dp" }, /* 104 */ + { 0, Ukn, "sysisc", "" }, /* 105 */ + { 0, Ukn, "nfssys", "" }, /* 106 */ + { 0, 4, "waitid", "ddxd" }, /* 107 */ + { 0, 3, "sigsendsys", "ddd" }, /* 108 */ + { svr4_hrtsys, Spl, "hrtsys", "xxx" }, /* 109 */ + { 0, 3, "acancel", "dxd" }, /* 110 */ + { 0, Ukn, "async", "" }, /* 111 */ + { 0, Ukn, "priocntlsys", "" }, /* 112 */ + { svr4_pathconf, 2, "pathconf", "sd" }, /* 113 */ + { 0, 3, "mincore", "xdx" }, /* 114 */ + { svr4_mmap, 6, "mmap", "xxxxdx"},/* 115 */ + { sys_mprotect, 3, "mprotect", "xdx" },/* 116 */ + { sys_munmap, 2, "munmap", "xd" },/* 117 */ + { svr4_fpathconf, 2, "fpathconf", "dd" }, /* 118 */ + { abi_fork, Spl, "vfork", "" }, /* 119 */ + { sys_fchdir, 1, "fchdir", "d" }, /* 120 */ + { sys_readv, 3, "readv", "dxd" }, /* 121 */ + { sys_writev, 3, "writev", "dxd" }, /* 122 */ + { svr4_xstat, 3, "xstat", "dsx" }, /* 123 */ + { svr4_lxstat, 3, "lxstat", "dsx" }, /* 124 */ + { svr4_fxstat, 3, "fxstat", "ddx" }, /* 125 */ + { svr4_xmknod, 4, "xmknod", "dsox" }, /* 126 */ + { 0, Ukn, "syslocal", "d" }, /* 127 */ + { svr4_getrlimit, 2, "setrlimit", "dx" }, /* 128 */ + { svr4_setrlimit, 2, "getrlimit", "dx" }, /* 129 */ + { 0, 3, "lchown", "sdd" }, /* 130 */ + { 0, Ukn, "memcntl", "" }, /* 131 */ +#if defined(CONFIG_ABI_XTI) + { svr4_getpmsg, 5, "getpmsg", "dxxxx" }, /* 132 */ + { svr4_putpmsg, 5, "putpmsg", "dxxdd" }, /* 133 */ +#else + { 0, 5, "getpmsg", "dxxxx" }, /* 132 */ + { 0, 5, "putpmsg", "dxxdd" }, /* 133 */ +#endif + { sys_rename, 2, "rename", "ss" }, /* 134 */ + { abi_utsname, 1, "uname", "x" }, /* 135 */ + { svr4_setegid, 1, "setegid", "d" }, /* 136 */ + { svr4_sysconfig, 1, "sysconfig", "d" }, /* 137 */ + { 0, Ukn, "adjtime", "" }, /* 138 */ + { svr4_sysinfo, 3, "systeminfo", "dsd" }, /* 139 */ + { socksys_syscall, 1, "socksys", "x" }, /* 140 */ + { svr4_seteuid, 1, "seteuid", "d" }, /* 141 */ + { 0, Ukn, "?", "" }, /* 142 */ + { 0, Ukn, "?", "" }, /* 143 */ + { 0, 2, "secsys", "dx" }, /* 144 */ + { 0, 4, "filepriv", "sdxd" }, /* 145 */ + { 0, 3, "procpriv", "dxd" }, /* 146 */ + { 0, 3, "devstat", "sdx" }, /* 147 */ + { 0, 5, "aclipc", "ddddx" }, /* 148 */ + { 0, 3, "fdevstat", "ddx" }, /* 149 */ + { 0, 3, "flvlfile", "ddx" }, /* 150 */ + { 0, 3, "lvlfile", "sdx" }, /* 151 */ + { 0, Ukn, "?", "" }, /* 152 */ + { 0, 2, "lvlequal", "xx" }, /* 153 */ + { 0, 2, "lvlproc", "dx" }, /* 154 */ + { 0, Ukn, "?", "" }, /* 155 */ + { 0, 4, "lvlipc", "dddx" }, /* 156 */ + { 0, 4, "acl", "sddx" }, /* 157 */ + { 0, Ukn, "auditevt", "" }, /* 158 */ + { 0, Ukn, "auditctl", "" }, /* 159 */ + { 0, Ukn, "auditdmp", "" }, /* 160 */ + { 0, Ukn, "auditlog", "" }, /* 161 */ + { 0, Ukn, "auditbuf", "" }, /* 162 */ + { 0, 2, "lvldom", "xx" }, /* 163 */ + { 0, Ukn, "lvlvfs", "" }, /* 164 */ + { 0, 2, "mkmld", "so" }, /* 165 */ + { 0, Ukn, "mlddone", "" }, /* 166 */ + { 0, 2, "secadvise", "xx" }, /* 167 */ + { 0, Ukn, "online", "" }, /* 168 */ + { sys_setitimer, 3, "setitimer", "dxx" }, /* 169 */ + { sys_getitimer, 2, "getitimer", "dx" }, /* 170 */ + { sys_gettimeofday, 2, "gettimeofday", "xx" }, /* 171 */ + { sys_settimeofday, 2, "settimeofday", "xx" }, /* 172 */ + { 0, Ukn, "lwpcreate", "" }, /* 173 */ + { 0, Ukn, "lwpexit", "" }, /* 174 */ + { 0, Ukn, "lwpwait", "" }, /* 175 */ + { 0, Ukn, "lwpself", "" }, /* 176 */ + { 0, Ukn, "lwpinfo", "" }, /* 177 */ + { 0, Ukn, "lwpprivate", "" }, /* 178 */ + { 0, Ukn, "processorbind","" }, /* 179 */ + { 0, Ukn, "processorexbind","" }, /* 180 */ + { 0, Ukn, "", "" }, /* 181 */ + { 0, Ukn, "sync_mailbox", "" }, /* 182 */ + { 0, Ukn, "prepblock", "" }, /* 183 */ + { 0, Ukn, "block", "" }, /* 184 */ + { 0, Ukn, "rdblock", "" }, /* 185 */ + { 0, Ukn, "unblock", "" }, /* 186 */ + { 0, Ukn, "cancelblock", "" }, /* 187 */ + { 0, Ukn, "?", "" }, /* 188 */ + { 0, Ukn, "pread", "" }, /* 189 */ + { 0, Ukn, "pwrite", "" }, /* 190 */ + { sys_truncate, 2, "truncate", "sd" }, /* 191 */ + { sys_ftruncate, 2, "ftruncate", "dd" }, /* 192 */ + { 0, Ukn, "lwpkill", "" }, /* 193 */ + { 0, Ukn, "sigwait", "" }, /* 194 */ + { 0, Ukn, "fork1", "" }, /* 195 */ + { 0, Ukn, "forkall", "" }, /* 196 */ + { 0, Ukn, "modload", "" }, /* 197 */ + { 0, Ukn, "moduload", "" }, /* 198 */ + { 0, Ukn, "modpath", "" }, /* 199 */ + { 0, Ukn, "modstat", "" }, /* 200 */ + { 0, Ukn, "modadm", "" }, /* 201 */ + { 0, Ukn, "getksym", "" }, /* 202 */ + { 0, Ukn, "lwpsuspend", "" }, /* 203 */ + { 0, Ukn, "lwpcontinue", "" }, /* 204 */ + { 0, Ukn, "?", "" }, /* 205 */ + { 0, Ukn, "?", "" }, /* 206 */ + { 0, Ukn, "?", "" }, /* 207 */ + { 0, Ukn, "?", "" }, + { 0, Ukn, "?", "" }, + { 0, Ukn, "?", "" }, + { 0, Ukn, "?", "" }, + { 0, Ukn, "?", "" }, + { 0, Ukn, "?", "" }, + { 0, Ukn, "?", "" }, + { 0, Ukn, "?", "" } +}; + +static void +ibcs_lcall7(int segment, struct pt_regs *regs) +{ + int sysno = regs->eax & 0xff; + + if (sysno >= ARRAY_SIZE(ibcs_syscall_table)) + set_error(regs, iABI_errors(-EINVAL)); + else + lcall7_dispatch(regs, &ibcs_syscall_table[regs->eax & 0xff], 1); +} + +static struct exec_domain ibcs_exec_domain = { + name: "iBCS2/iABI4", + handler: ibcs_lcall7, + pers_low: 1 /* PER_SVR4 */, + pers_high: 2 /* PER_SVR3 */, + signal_map: ibcs_to_linux_signals, + signal_invmap: linux_to_ibcs_signals, + err_map: ibcs_err_map, + socktype_map: ibcs_socktype_map, + sockopt_map: ibcs_sockopt_map, + af_map: ibcs_af_map, + module: THIS_MODULE +}; + +static int __init +ibcs_init(void) +{ + return register_exec_domain(&ibcs_exec_domain); +} + + +static void __exit +ibcs_exit(void) +{ + unregister_exec_domain(&ibcs_exec_domain); +} + +module_init(ibcs_init); +module_exit(ibcs_exit); diff -Nru linux-2.6.7/abi/isc/Makefile linux-2.6.7-abi/abi/isc/Makefile --- linux-2.6.7/abi/isc/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/isc/Makefile 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,7 @@ + +abi-isc-objs := sysent.o + +obj-$(CONFIG_ABI_ISC) += abi-isc.o + +abi-isc.o: $(abi-isc-objs) + $(LD) -r -o $@ $(abi-isc-objs) diff -Nru linux-2.6.7/abi/isc/sysent.c linux-2.6.7-abi/abi/isc/sysent.c --- linux-2.6.7/abi/isc/sysent.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/isc/sysent.c 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,460 @@ +/* + * Copyright (c) 2001 Christoph Hellwig. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ident "%W% %G%" + +/* + * ISC personality switch. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +MODULE_DESCRIPTION("ISC personality"); +MODULE_AUTHOR("Christoph Hellwig, partially taken from iBCS"); +MODULE_LICENSE("GPL"); + + +/* forward */ +static int isc_setostype(int); + +/* + * We could remove some of the long identity mapped runs but at the + * expense of extra comparisons for each mapping at run time... + */ +static u_char isc_err_table[] = { +/* 0 - 9 */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, +/* 10 - 19 */ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, +/* 20 - 29 */ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, +/* 30 - 39 */ 30, 31, 32, 33, 34, 45, 78, 46, 89, 93, +/* 40 - 49 */ 90, 90, 35, 36, 37, 38, 39, 40, 41, 42, +/* 50 - 59 */ 43, 44, 50, 51, 52, 53, 54, 55, 56, 57, +/* 60 - 69 */ 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, +/* 70 - 79 */ 70, 71, 74, 76, 77, 79, 80, 81, 82, 83, +/* 80 - 89 */ 84, 85, 86, 87, 88, 91, 92, 94, 95, 96, +/* 90 - 99 */ 97, 98, 99, 120, 121, 122, 123, 124, 125, 126, +/* 100 - 109 */ 127, 128, 129, 130, 131, 132, 133, 134, 143, 144, +/* 110 - 119 */ 145, 146, 147, 148, 149, 150, 22, 135, 137, 138, +/* 120 - 122 */ 139, 140, 28 +}; + +/* + * Map Linux RESTART* values (512,513,514) to EINTR + */ +static u_char lnx_err_table[] = { +/* 512 - 514 */ EINTR, EINTR, EINTR +}; + +struct map_segment isc_err_map[] = { + { 0, 0+sizeof(isc_err_table)-1, isc_err_table }, + { 512, 512+sizeof(lnx_err_table)-1, lnx_err_table }, + { -1 } +}; + +/* + * ISC's error mapping is a little different. + */ +static long linux_to_isc_signals[NSIGNALS+1] = { +/* 0 - 3 */ 0, IBCS_SIGHUP, IBCS_SIGINT, IBCS_SIGQUIT, +/* 4 - 7 */ IBCS_SIGILL, IBCS_SIGTRAP, IBCS_SIGABRT, -1, +/* 8 - 11 */ IBCS_SIGFPE, IBCS_SIGKILL, IBCS_SIGUSR1, IBCS_SIGSEGV, +/* 12 - 15 */ IBCS_SIGUSR2, IBCS_SIGPIPE, IBCS_SIGALRM, IBCS_SIGTERM, +/* 16 - 19 */ IBCS_SIGSEGV, IBCS_SIGCHLD, ISC_SIGCONT, ISC_SIGSTOP, +/* 20 - 23 */ ISC_SIGTSTP, IBCS_SIGTTIN, IBCS_SIGTTOU, IBCS_SIGUSR1, +/* 24 - 27 */ IBCS_SIGGXCPU, IBCS_SIGGXFSZ, IBCS_SIGVTALRM, IBCS_SIGPROF, +/* 28 - 31 */ IBCS_SIGWINCH, IBCS_SIGIO, IBCS_SIGPWR, -1, +/* 32 */ -1 +}; + +static long isc_to_linux_signals[NSIGNALS+1] = { +/* 0 - 3 */ 0, SIGHUP, SIGINT, SIGQUIT, +/* 4 - 7 */ SIGILL, SIGTRAP, SIGIOT, SIGUNUSED, +/* 8 - 11 */ SIGFPE, SIGKILL, SIGUNUSED, SIGSEGV, +/* 12 - 15 */ SIGUNUSED, SIGPIPE, SIGALRM, SIGTERM, +/* 16 - 19 */ SIGUSR1, SIGUSR2, SIGCHLD, SIGPWR, +/* 20 - 23 */ SIGWINCH, -1, SIGPOLL, SIGCONT, +/* 24 - 27 */ SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU, +/* 28 - 31 */ SIGVTALRM, SIGPROF, SIGXCPU, SIGXFSZ, +/* 32 */ -1 +}; + +static char isc_socktype[] = { + SOCK_STREAM, + SOCK_DGRAM, + 0, + SOCK_RAW, + SOCK_RDM, + SOCK_SEQPACKET +}; + +static struct map_segment isc_socktype_map[] = { + { 1, 6, isc_socktype }, + { -1 } +}; + +static struct map_segment isc_sockopt_map[] = { + { 0x0001, 0x0001, (char *)SO_DEBUG }, + { 0x0002, 0x0002, (char *)__SO_ACCEPTCON }, + { 0x0004, 0x0004, (char *)SO_REUSEADDR }, + { 0x0008, 0x0008, (char *)SO_KEEPALIVE }, + { 0x0010, 0x0010, (char *)SO_DONTROUTE }, + { 0x0020, 0x0020, (char *)SO_BROADCAST }, + { 0x0040, 0x0040, (char *)SO_USELOOPBACK }, + { 0x0080, 0x0080, (char *)SO_LINGER }, + { 0x0100, 0x0100, (char *)SO_OOBINLINE }, + { 0x0200, 0x0200, (char *)SO_ORDREL }, + { 0x0400, 0x0400, (char *)SO_IMASOCKET }, + { 0x1001, 0x1001, (char *)SO_SNDBUF }, + { 0x1002, 0x1002, (char *)SO_RCVBUF }, + { 0x1003, 0x1003, (char *)SO_SNDLOWAT }, + { 0x1004, 0x1004, (char *)SO_RCVLOWAT }, + { 0x1005, 0x1005, (char *)SO_SNDTIMEO }, + { 0x1006, 0x1006, (char *)SO_RCVTIMEO }, + { 0x1007, 0x1007, (char *)SO_ERROR }, + { 0x1008, 0x1008, (char *)SO_TYPE }, + { 0x1009, 0x1009, (char *)SO_PROTOTYPE }, + { -1 } +}; + +static struct map_segment isc_af_map[] = { + { 0, 2, NULL }, + { -1 } +}; + + +static struct sysent sysisc_table[] = { +/* 0 */ { 0, Ukn, "sysisc0", "" }, +/* 1 */ { isc_setostype, 1, "setostype", "d" }, +/* 2 */ { sys_rename, 2, "rename", "ss" }, +/* 3 */ { abi_sigaction, 3, "sigaction", "dxx" }, +/* 4 */ { abi_sigprocmask, 3, "sicprocmask", "dxx" }, +/* 5 */ { 0, 1, "sigpending", "x" }, +/* 6 */ { sys_getgroups16, 2, "getgroups", "dp" }, +/* 7 */ { sys_setgroups16, 2, "setgroups", "dp" }, +/* 8 */ { 0, Ukn, "pathconf", "" }, +/* 9 */ { 0, Ukn, "fpathconf", "" }, +/* 10 */ { ibcs_sysconf, 1, "sysconf", "d" }, +/* 11 */ { sys_waitpid, 3, "waitpid", "dxx" }, +/* 12 */ { sys_setsid, 0, "setsid", "" }, +/* 13 */ { sys_setpgid, 2, "setpgid", "dd" }, +/* 14 */ { 0, Ukn, "adduser", "" }, +/* 15 */ { 0, Ukn, "setuser", "" }, +/* 16 */ { 0, Ukn, "sysisc16", "" }, +/* 17 */ { abi_sigsuspend, Spl, "sigsuspend", "x" }, +/* 18 */ { sys_symlink, 2, "symlink", "ss" }, +/* 19 */ { sys_readlink, 3, "readlink", "spd" }, +/* 20 */ { 0, Ukn, "getmajor", "" } +}; + +static void +isc_sysisc(struct pt_regs *regs) +{ + int sysno; + + __get_user(sysno, ((unsigned long *)regs->esp)+1); + + if (sysno >= ARRAY_SIZE(sysisc_table)) + set_error(regs, iABI_errors(-EINVAL)); + else + lcall7_dispatch(regs, &sysisc_table[sysno], 2); +} + +static int +isc_setostype(int arg1) +{ + return 0; +} + +static struct sysent isc_syscall_table[] = { + { abi_syscall, Fast, "syscall", "" }, /* 0 */ + { sys_exit, 1, "exit", "d" }, /* 1 */ + { abi_fork, Spl, "fork", "" }, /* 2 */ + { abi_read, 3, "read", "dpd" }, /* 3 */ + { sys_write, 3, "write", "dpd" }, /* 4 */ + { svr4_open, 3, "open", "soo" }, /* 5 */ + { sys_close, 1, "close", "d" }, /* 6 */ + { abi_wait, Spl, "wait", "xxx" }, /* 7 */ + { sys_creat, 2, "creat", "so" }, /* 8 */ + { sys_link, 2, "link", "ss" }, /* 9 */ + { sys_unlink, 1, "unlink", "s" }, /* 10 */ + { abi_exec, Spl, "exec", "sxx" }, /* 11 */ + { sys_chdir, 1, "chdir", "s" }, /* 12 */ + { abi_time, 0, "time", "" }, /* 13 */ + { svr4_mknod, 3, "mknod", "soo" }, /* 14 */ + { sys_chmod, 2, "chmod", "so" }, /* 15 */ + { sys_chown, 3, "chown", "sdd" }, /* 16 */ + { abi_brk, 1, "brk/break", "x" }, /* 17 */ + { svr4_stat, 2, "stat", "sp" }, /* 18 */ + { sys_lseek, 3, "seek/lseek", "ddd" }, /* 19 */ + { abi_getpid, Spl, "getpid", "" }, /* 20 */ + { 0, Ukn, "mount", "" }, /* 21 */ + { sys_umount, 1, "umount", "s" }, /* 22 */ + { sys_setuid, 1, "setuid", "d" }, /* 23 */ + { abi_getuid, Spl, "getuid", "" }, /* 24 */ + { sys_stime, 1, "stime", "d" }, /* 25 */ + { 0, Ukn, "ptrace", "" }, /* 26 */ + { sys_alarm, 1, "alarm", "d" }, /* 27 */ + { svr4_fstat, 2, "fstat", "dp" }, /* 28 */ + { sys_pause, 0, "pause", "" }, /* 29 */ + { sys_utime, 2, "utime", "xx" }, /* 30 */ + { 0, Ukn, "stty", "" }, /* 31 */ + { 0, Ukn, "gtty", "" }, /* 32 */ + { sys_access, 2, "access", "so" }, /* 33 */ + { sys_nice, 1, "nice", "d" }, /* 34 */ + { svr4_statfs, 4, "statfs", "spdd" }, /* 35 */ + { sys_sync, 0, "sync", "" }, /* 36 */ + { abi_kill, 2, "kill", "dd" }, /* 37 */ + { svr4_fstatfs, 4, "fstatfs", "dpdd" }, /* 38 */ + { abi_procids, Spl, "procids", "d" }, /* 39 */ + { 0, Ukn, "cxenix", "" }, /* 40 */ + { sys_dup, 1, "dup", "d" }, /* 41 */ + { abi_pipe, Spl, "pipe", "" }, /* 42 */ + { sys_times, 1, "times", "p" }, /* 43 */ + { 0, Ukn, "prof", "" }, /* 44 */ + { 0, Ukn, "lock/plock", "" }, /* 45 */ + { sys_setgid, 1, "setgid", "d" }, /* 46 */ + { abi_getgid, Spl, "getgid", "" }, /* 47 */ + { abi_sigfunc, Fast, "sigfunc", "xxx" }, /* 48 */ + { svr4_msgsys, Spl, "msgsys", "dxddd" }, /* 49 */ + { svr4_sysi86, 3, "sysi86", "d" }, /* 50 */ + { sys_acct, 1, "acct/sysacct", "x" }, /* 51 */ + { svr4_shmsys, Fast, "shmsys", "ddxo" }, /* 52 */ + { svr4_semsys, Spl, "semsys", "dddx" }, /* 53 */ + { svr4_ioctl, Spl, "ioctl", "dxx" }, /* 54 */ + { 0, 3, "uadmin", "xxx" }, /* 55 */ + { 0, Ukn, "?", "" }, /* 56 */ + { v7_utsname, 1, "utsys", "x" }, /* 57 */ + { sys_fsync, 1, "fsync", "d" }, /* 58 */ + { abi_exec, Spl, "execv", "spp" }, /* 59 */ + { sys_umask, 1, "umask", "o" }, /* 60 */ + { sys_chroot, 1, "chroot", "s" }, /* 61 */ + { svr4_fcntl, 3, "fcntl", "dxx" }, /* 62 */ + { svr4_ulimit, 2, "ulimit", "xx" }, /* 63 */ + { 0, Ukn, "?", "" }, /* 64 */ + { 0, Ukn, "?", "" }, /* 65 */ + { 0, Ukn, "?", "" }, /* 66 */ + { 0, Ukn, "?", "" }, /* 67 */ + { 0, Ukn, "?", "" }, /* 68 */ + { 0, Ukn, "?", "" }, /* 69 */ + { 0, Ukn, "advfs", "" }, /* 70 */ + { 0, Ukn, "unadvfs", "" }, /* 71 */ + { 0, Ukn, "rmount", "" }, /* 72 */ + { 0, Ukn, "rumount", "" }, /* 73 */ + { 0, Ukn, "rfstart", "" }, /* 74 */ + { 0, Ukn, "?", "" }, /* 75 */ + { 0, Ukn, "rdebug", "" }, /* 76 */ + { 0, Ukn, "rfstop", "" }, /* 77 */ + { 0, Ukn, "rfsys", "" }, /* 78 */ + { sys_rmdir, 1, "rmdir", "s" }, /* 79 */ + { abi_mkdir, 2, "mkdir", "so" }, /* 80 */ + { svr4_getdents, 3, "getdents", "dxd" }, /* 81 */ + { 0, Ukn, "libattach", "" }, /* 82 */ + { 0, Ukn, "libdetach", "" }, /* 83 */ + { svr4_sysfs, 3, "sysfs", "dxx" }, /* 84 */ + { svr4_getmsg, Spl, "getmsg", "dxxx" }, /* 85 */ + { svr4_putmsg, Spl, "putmsg", "dxxd" }, /* 86 */ + { sys_poll, 3, "poll", "xdd" }, /* 87 */ + { svr4_lstat, 2, "lstat", "sp" }, /* 88 */ + { sys_symlink, 2, "symlink", "ss" }, /* 89 */ + { sys_readlink, 3, "readlink", "spd" }, /* 90 */ + { sys_setgroups, 2, "setgroups", "dp" }, /* 91 */ + { sys_getgroups, 2, "getgroups", "dp" }, /* 92 */ + { sys_fchmod, 2, "fchmod", "do" }, /* 93 */ + { sys_fchown, 3, "fchown", "ddd" }, /* 94 */ + { abi_sigprocmask, 3, "sigprocmask", "dxx" }, /* 95 */ + { abi_sigsuspend, Spl, "sigsuspend", "x" }, /* 96 */ + { 0, 2, "sigaltstack", "xx" }, /* 97 */ + { abi_sigaction, 3, "sigaction", "dxx" }, /* 98 */ + { svr4_sigpending, 2, "sigpending", "dp" }, /* 99 */ + { svr4_context, Spl, "context", "" }, /* 100 */ + { 0, Ukn, "evsys", "" }, /* 101 */ + { 0, Ukn, "evtrapret", "" }, /* 102 */ + { svr4_statvfs, 2, "statvfs", "sp" }, /* 103 */ + { svr4_fstatvfs, 2, "fstatvfs", "dp" }, /* 104 */ + { isc_sysisc, Fast, "sysisc", "" }, /* 105 */ + { 0, Ukn, "nfssys", "" }, /* 106 */ + { 0, 4, "waitid", "ddxd" }, /* 107 */ + { 0, 3, "sigsendsys", "ddd" }, /* 108 */ + { svr4_hrtsys, Spl, "hrtsys", "xxx" }, /* 109 */ + { 0, 3, "acancel", "dxd" }, /* 110 */ + { 0, Ukn, "async", "" }, /* 111 */ + { 0, Ukn, "priocntlsys", "" }, /* 112 */ + { svr4_pathconf, 2, "pathconf", "sd" }, /* 113 */ + { 0, 3, "mincore", "xdx" }, /* 114 */ + { svr4_mmap, 6, "mmap", "xxxxdx"},/* 115 */ + { sys_mprotect, 3, "mprotect", "xdx" },/* 116 */ + { sys_munmap, 2, "munmap", "xd" },/* 117 */ + { svr4_fpathconf, 2, "fpathconf", "dd" }, /* 118 */ + { abi_fork, Spl, "vfork", "" }, /* 119 */ + { sys_fchdir, 1, "fchdir", "d" }, /* 120 */ + { sys_readv, 3, "readv", "dxd" }, /* 121 */ + { sys_writev, 3, "writev", "dxd" }, /* 122 */ + { svr4_xstat, 3, "xstat", "dsx" }, /* 123 */ + { svr4_lxstat, 3, "lxstat", "dsx" }, /* 124 */ + { svr4_fxstat, 3, "fxstat", "ddx" }, /* 125 */ + { svr4_xmknod, 4, "xmknod", "dsox" }, /* 126 */ + { 0, Ukn, "syslocal", "d" }, /* 127 */ + { svr4_getrlimit, 2, "setrlimit", "dx" }, /* 128 */ + { svr4_setrlimit, 2, "getrlimit", "dx" }, /* 129 */ + { 0, 3, "lchown", "sdd" }, /* 130 */ + { 0, Ukn, "memcntl", "" }, /* 131 */ +#if defined(CONFIG_ABI_XTI) + { svr4_getpmsg, 5, "getpmsg", "dxxxx" }, /* 132 */ + { svr4_putpmsg, 5, "putpmsg", "dxxdd" }, /* 133 */ +#else + { 0, 5, "getpmsg", "dxxxx" }, /* 132 */ + { 0, 5, "putpmsg", "dxxdd" }, /* 133 */ +#endif + { sys_rename, 2, "rename", "ss" }, /* 134 */ + { abi_utsname, 1, "uname", "x" }, /* 135 */ + { svr4_setegid, 1, "setegid", "d" }, /* 136 */ + { svr4_sysconfig, 1, "sysconfig", "d" }, /* 137 */ + { 0, Ukn, "adjtime", "" }, /* 138 */ + { svr4_sysinfo, 3, "systeminfo", "dsd" }, /* 139 */ + { socksys_syscall, 1, "socksys", "x" }, /* 140 */ + { svr4_seteuid, 1, "seteuid", "d" }, /* 141 */ + { 0, Ukn, "?", "" }, /* 142 */ + { 0, Ukn, "?", "" }, /* 143 */ + { 0, 2, "secsys", "dx" }, /* 144 */ + { 0, 4, "filepriv", "sdxd" }, /* 145 */ + { 0, 3, "procpriv", "dxd" }, /* 146 */ + { 0, 3, "devstat", "sdx" }, /* 147 */ + { 0, 5, "aclipc", "ddddx" }, /* 148 */ + { 0, 3, "fdevstat", "ddx" }, /* 149 */ + { 0, 3, "flvlfile", "ddx" }, /* 150 */ + { 0, 3, "lvlfile", "sdx" }, /* 151 */ + { 0, Ukn, "?", "" }, /* 152 */ + { 0, 2, "lvlequal", "xx" }, /* 153 */ + { 0, 2, "lvlproc", "dx" }, /* 154 */ + { 0, Ukn, "?", "" }, /* 155 */ + { 0, 4, "lvlipc", "dddx" }, /* 156 */ + { 0, 4, "acl", "sddx" }, /* 157 */ + { 0, Ukn, "auditevt", "" }, /* 158 */ + { 0, Ukn, "auditctl", "" }, /* 159 */ + { 0, Ukn, "auditdmp", "" }, /* 160 */ + { 0, Ukn, "auditlog", "" }, /* 161 */ + { 0, Ukn, "auditbuf", "" }, /* 162 */ + { 0, 2, "lvldom", "xx" }, /* 163 */ + { 0, Ukn, "lvlvfs", "" }, /* 164 */ + { 0, 2, "mkmld", "so" }, /* 165 */ + { 0, Ukn, "mlddone", "" }, /* 166 */ + { 0, 2, "secadvise", "xx" }, /* 167 */ + { 0, Ukn, "online", "" }, /* 168 */ + { sys_setitimer, 3, "setitimer", "dxx" }, /* 169 */ + { sys_getitimer, 2, "getitimer", "dx" }, /* 170 */ + { sys_gettimeofday, 2, "gettimeofday", "xx" }, /* 171 */ + { sys_settimeofday, 2, "settimeofday", "xx" }, /* 172 */ + { 0, Ukn, "lwpcreate", "" }, /* 173 */ + { 0, Ukn, "lwpexit", "" }, /* 174 */ + { 0, Ukn, "lwpwait", "" }, /* 175 */ + { 0, Ukn, "lwpself", "" }, /* 176 */ + { 0, Ukn, "lwpinfo", "" }, /* 177 */ + { 0, Ukn, "lwpprivate", "" }, /* 178 */ + { 0, Ukn, "processorbind","" }, /* 179 */ + { 0, Ukn, "processorexbind","" }, /* 180 */ + { 0, Ukn, "", "" }, /* 181 */ + { 0, Ukn, "sync_mailbox", "" }, /* 182 */ + { 0, Ukn, "prepblock", "" }, /* 183 */ + { 0, Ukn, "block", "" }, /* 184 */ + { 0, Ukn, "rdblock", "" }, /* 185 */ + { 0, Ukn, "unblock", "" }, /* 186 */ + { 0, Ukn, "cancelblock", "" }, /* 187 */ + { 0, Ukn, "?", "" }, /* 188 */ + { 0, Ukn, "pread", "" }, /* 189 */ + { 0, Ukn, "pwrite", "" }, /* 190 */ + { sys_truncate, 2, "truncate", "sd" }, /* 191 */ + { sys_ftruncate, 2, "ftruncate", "dd" }, /* 192 */ + { 0, Ukn, "lwpkill", "" }, /* 193 */ + { 0, Ukn, "sigwait", "" }, /* 194 */ + { 0, Ukn, "fork1", "" }, /* 195 */ + { 0, Ukn, "forkall", "" }, /* 196 */ + { 0, Ukn, "modload", "" }, /* 197 */ + { 0, Ukn, "moduload", "" }, /* 198 */ + { 0, Ukn, "modpath", "" }, /* 199 */ + { 0, Ukn, "modstat", "" }, /* 200 */ + { 0, Ukn, "modadm", "" }, /* 201 */ + { 0, Ukn, "getksym", "" }, /* 202 */ + { 0, Ukn, "lwpsuspend", "" }, /* 203 */ + { 0, Ukn, "lwpcontinue", "" }, /* 204 */ + { 0, Ukn, "?", "" }, /* 205 */ + { 0, Ukn, "?", "" }, /* 206 */ + { 0, Ukn, "?", "" }, /* 207 */ + { 0, Ukn, "?", "" }, + { 0, Ukn, "?", "" }, + { 0, Ukn, "?", "" }, + { 0, Ukn, "?", "" }, + { 0, Ukn, "?", "" }, + { 0, Ukn, "?", "" }, + { 0, Ukn, "?", "" }, + { 0, Ukn, "?", "" } +}; + +static void +isc_lcall7(int segment, struct pt_regs *regs) +{ + int sysno = regs->eax & 0xff; + + if (sysno >= ARRAY_SIZE(isc_syscall_table)) + set_error(regs, iABI_errors(-EINVAL)); + else + lcall7_dispatch(regs, &isc_syscall_table[sysno], 1); +} + +static struct exec_domain isc_exec_domain = { + name: "ISC", + handler: isc_lcall7, + pers_low: 5 /* PER_ISCR4 */, + pers_high: 5 /* PER_ISCR4 */, + signal_map: isc_to_linux_signals, + signal_invmap: linux_to_isc_signals, + err_map: isc_err_map, + socktype_map: isc_socktype_map, + sockopt_map: isc_sockopt_map, + af_map: isc_af_map, + module: THIS_MODULE +}; + +static int __init +isc_init(void) +{ + return register_exec_domain(&isc_exec_domain); +} + + +static void __exit +isc_exit(void) +{ + unregister_exec_domain(&isc_exec_domain); +} + +module_init(isc_init); +module_exit(isc_exit); diff -Nru linux-2.6.7/abi/Kconfig linux-2.6.7-abi/abi/Kconfig --- linux-2.6.7/abi/Kconfig 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/Kconfig 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,166 @@ +# +# Linux-ABI configuration +# + +# this file gets source'ed into the kernel file formats menu entry +# via ./fs/Kconfig.binfmt + +config ABI + bool "Extended Linux-ABI support (alien binarys and syscalls)" + depends on X86=y + default n + help + Support for a few alien syscall interfaces. This allows you to run + a binary that got build for other Unix compatible platforms. + + +config ABI_SVR4 + tristate "SVR3/SVR4 family syscall support for x86 binarys" + depends on X86=y + depends on ABI + default n + + +comment "SVR3/SVR4 based syscall support for x86: (please check one or more)" + depends on ABI_SVR4 + +config ABI_IBCS + tristate "iBCS2/iABI4 syscall support" + depends on ABI_SVR4 + +config ABI_ISC + tristate "ISC syscall support" + depends on ABI_SVR4 + +config ABI_SCO + tristate "SCO OpenServer 5/SCO Unix 3.x/Xenix syscall support" + depends on ABI_SVR4 + +config ABI_SOLARIS + tristate "Solaris 2.x syscall support" + depends on ABI_SVR4 + +config ABI_UW7 + tristate "UnixWare 7.x syscall support" + depends on ABI_SVR4 + +config ABI_WYSE + tristate "Wyse V/386 syscall support" + depends on ABI_SVR4 + + +comment "SVR3/SVR4 related binary format support for x86:" + depends on ABI_SVR4 + +config BINFMT_COFF + tristate "COFF binary support (SVR3)" + depends on ABI_SVR4 + +config BINFMT_XOUT + tristate "x.out binary support (Xenix)" + depends on ABI_SVR4 + +config BINFMT_XOUT_X286 + bool "x.out segmented binary support (Xenix/80286)" + depends on BINFMT_XOUT + + +config ABI_LATE_PROBING + bool + prompt "Late probing of personality trough syscall handler" + depends on ABI + default y + help + There is a minor general uncertainty on identification of binary + formats. It might happen that statically linked SVr4 binary could + be falsely assigned to a Linux personality. Solaris/x86 binarys + are another sample for a falsely assigned Linux personality. + If this option is set the lcall handler for Linux will switch + to SVr4 personality as soon as lcall 0x07 is used, or it will + switch to Solaris personality when lcall 0x27 is used. + Since this on-the-fly personality switching is a one way path + a malicious program might make use of exactly that ability. + For system consistency reasons personality detection should go + that way. The better solution is to improve the personality + detection code at load time in contrast to runtime detection. + At present load time probing is not perfect, so better say yes. + +config ABI_TRACE + bool + prompt "Include prints for syscall tracking via ABI_TRACE ioctl" + depends on ABI + default y + help + This option allows to control the inclusion of code that prints + kernel messages for tracking special syscalls events like errors. + Typically this messages further have to be enabled via the + ABI_TRACE ioctl. This option will not remove the ioctl interface + but will only remove the backend coding which produces the prints. + You can disable thise option if you want to reduce the kernel size + or have other concerns, e.g. code size or possible message floods. + +# --- internal options, values will get derived from prior settings --- + +# the abi-util (./abi/util) codebase +# does currently only contain code for the ABI_TRACE coding +# and has to be present as soon as the SVR4 code is present. +config ABI_UTIL + tristate + depends on ABI_TRACE + default y if ABI_SVR4=y + default m if ABI_SVR4=m + default n + +config ABI_SPX + bool + depends on ABI!=n + default y + +config ABI_XTI + bool + depends on ABI!=n + default y + +config ABI_TLI_OPTMGMT + bool + depends on ABI!=n + default y + +config ABI_XTI_OPTMGMT + bool + depends on ABI!=n + default n + +# there are syscall interfaces which do get statically linked +config ABI_SYSCALL_STATICS + bool + default y if ABI_UW7=y || ABI_SOLARIS=y || ABI_IBCS=y || ABI_ISC=y || ABI_SCO=y || ABI_WYSE=y + default n + +# there are syscall interfaces which do get build as module +config ABI_SYSCALL_MODULES + bool + default y if ABI_UW7=m || ABI_SOLARIS=m || ABI_IBCS=m || ABI_ISC=m || ABI_SCO=m || ABI_WYSE=m + default n + +# the LCALL7 code for SVR4 family support must _not_ be a module +# when there is at least a single, statically bound syscall driver. +# if there are only modules, then the LCALL code can be a module as well. +# if there is no module at all then we dont need the LCALL7 code. +config ABI_LCALL7 + tristate + default y if ABI_SYSCALL_STATICS=y + default m if ABI_SYSCALL_MODULES=y + default n + +# notes: +# * only a static SVR4 core coding will allow static syscall drivers, +# * setting a syscall driver to modules will be the only way to allow +# this single module to plug into SVR4 core coding. +# * there is no generic "register my entrypoints" request for modules +# in the curent codebase. (this might be a TODO) +# * the exported LCALL7 syms will only be usefull to syscall driver modules. +# * LCALL7 is only usefull if there are syscall drivers (static or module). +# * an "empty" SVR4 might be usefull for debugging and non-x86 targets. + +### EOF ### diff -Nru linux-2.6.7/abi/Makefile linux-2.6.7-abi/abi/Makefile --- linux-2.6.7/abi/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/Makefile 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,8 @@ +obj-$(CONFIG_ABI) += util/ +obj-$(CONFIG_ABI_SVR4) += svr4/ +obj-$(CONFIG_ABI_SCO) += sco/ cxenix/ +obj-$(CONFIG_ABI_WYSE) += wyse/ +obj-$(CONFIG_ABI_UW7) += uw7/ +obj-$(CONFIG_ABI_SOLARIS) += solaris/ +obj-$(CONFIG_ABI_IBCS) += ibcs/ +obj-$(CONFIG_ABI_ISC) += isc/ diff -Nru linux-2.6.7/abi/sco/ioctl.c linux-2.6.7-abi/abi/sco/ioctl.c --- linux-2.6.7/abi/sco/ioctl.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/sco/ioctl.c 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,184 @@ +/* + * ioctl.c - SCO Unix ioctl(2) switch + * + * Copyright (C) 1991, 1992 Linus Torvalds + * + * Written by Drew Sullivan. + * Rewritten by Mike Jagdis. + */ + +#ident "%W% %G%" + +#include +#include +#include +#include +#include + +#include +#include +#include + + +/* + * do_ioctl() is a meta mapper, that is + * it looks up the class of the ioctl and then + * dispatchs to lower level routines to handle the + * mapping of the actual ioctls + */ +static int +do_ioctl(struct pt_regs *regs, int fd, unsigned long ioctl_num, void *arg) +{ + unsigned int class = ioctl_num >> 8; + char class_str[4]; + + switch (class) { + + /* + * SCO ioctls on the pseudo NFS device probably. + */ + case 0: + return abi_ioctl_socksys(fd, ioctl_num, arg); + + /* + * SCO console keyboard stuff? + */ + case 'A': + return -EINVAL; + + case 'm': + return sco_tape_ioctl(fd, ioctl_num, arg); + + case 't': + return bsd_ioctl_termios(fd, ioctl_num, arg); + + case 'f': + return svr4_fil_ioctl(fd, ioctl_num, arg); + + /* + * Xenix ioctl compatibility. + */ + case 'T': + return svr4_term_ioctl(fd, ioctl_num & 0xFF, arg); + + case ('i' << 16) | ('X' << 8): /* iBCS2 POSIX */ + case 'x': /* Pre-iBCS2 POSIX */ + return sco_term_ioctl(fd, ioctl_num & 0xFF, arg); + + case 'C': + case 'c': + return svr4_console_ioctl(fd, ioctl_num, arg); + + case ('i' << 16) | ('C' << 8): /* iBCS2 POSIX */ + return svr4_video_ioctl(fd, ioctl_num & 0xFF, arg); + + /* + * These aren't implemented and are never likely to be as they + * are specific to drivers for obscure hardware. (For those + * that don't know they're the JERQ ioctls. Says it all + * really!) + */ + case 'j': + return -EINVAL; + + /* + * The 'S' set could also be display mode switch + * ioctls in a SCO 3.2.x x<4 environment. It should + * depend on the descriptor they are applied to. + * According to ISC the Xenix STREAMS ioctls had the + * high bit set on the command to differentiate them + * from mode switch ioctls. Yuk, yuk, yuk... + */ + case 'S': + return svr4_stream_ioctl(regs, fd, ioctl_num & 0x7F, arg); + + /* + * These are STREAMS socket module ioctls. + */ + case 'I': +#if defined(CONFIG_ABI_XTI) + return svr4_sockmod_ioctl(fd, ioctl_num & 0xFF, arg); +#else + return -EINVAL; +#endif + + /* + * These are SCO ioctls - see vtkd.h + */ + case 'v': + case 'K': + return sco_vtkbd_ioctl(fd, ioctl_num, arg); + + /* + * SCO channel mapping. I can't find any documentation + * for this. These are the LD?MAP ioctls defined in + * sys/termio.h and sys/emap.h. They are used by mapchan. + */ + case 'D': + return -EINVAL; + } + + /* + * If we haven't handled it yet it must be a BSD style ioctl + * with a (possible) argument description in the high word of + * the opcode. + */ + switch (class & 0xff) { + + /* + * From SVR4 as specified in sys/iocomm.h. + */ + case 'f': + return svr4_fil_ioctl(fd, ioctl_num, arg); + + /* + * BSD or V7 terminal ioctls. + */ + case 't': + return bsd_ioctl_termios(fd, ioctl_num, arg); + + /* + * SVR3 streams based socket TCP/IP ioctls. + * + * These are handed over to the standard ioctl + * handler since /dev/socksys is an emulated device + * and front ends any sockets created through it. + * Note that 'S' ioctls without the BSDish argument + * type in the high bytes are STREAMS ioctls and 'I' + * ioctls without the BSDish type in the high bytes + * are the STREAMS socket module ioctls. (see above). + */ + case 'S': + case 'R': + case 'I': + return abi_ioctl_socksys(fd, ioctl_num, arg); + } + + /* + * If nothing has handled it yet someone may have to do some + * more work... + */ + class_str[0] = class & 0xFF0000 ? (char)((class >> 16) & 0xFF) : '.'; + class_str[1] = class & 0x00FF00 ? (char)((class >> 8) & 0xFF) : '.'; + class_str[2] = class & 0x0000FF ? (char)((class ) & 0xFF) : '.'; + class_str[3] = 0; + + printk(KERN_DEBUG "sco: ioctl(%d, %lx[%s], 0x%p) unsupported\n", + fd, ioctl_num, class_str, arg); + + return -EINVAL; +} + +int +sco_ioctl(struct pt_regs *regs) +{ + u_int num; + int fd; + caddr_t data; + + fd = (int)get_syscall_parameter(regs, 0); + num = (u_int)get_syscall_parameter(regs, 1); + data = (caddr_t)get_syscall_parameter(regs, 2); + + return do_ioctl(regs, fd, num, data); +} diff -Nru linux-2.6.7/abi/sco/Makefile linux-2.6.7-abi/abi/sco/Makefile --- linux-2.6.7/abi/sco/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/sco/Makefile 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,12 @@ + +abi-sco-objs := sysent.o misc.o mmap.o ptrace.o secureware.o \ + stat.o statvfs.o + +# various ioctl emulation stuff +abi-sco-objs += ioctl.o termios.o tapeio.o vtkbd.o + + +obj-$(CONFIG_ABI_SCO) += abi-sco.o + +abi-sco.o: $(abi-sco-objs) + $(LD) -r -o $@ $(abi-sco-objs) diff -Nru linux-2.6.7/abi/sco/misc.c linux-2.6.7-abi/abi/sco/misc.c --- linux-2.6.7/abi/sco/misc.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/sco/misc.c 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2001 Christoph Hellwig. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ident "%W% %G%" + +/* + * Misc SCO syscalls. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + +int +sco_lseek(int fd, u_long offset, int whence) +{ + int error; + + error = sys_lseek(fd, offset, whence); + if (error == -ESPIPE) { + struct file *fp = fget(fd); + struct inode *ip; + + if (fp == NULL) + goto out; + ip = fp->f_dentry->d_inode; + if (ip && (S_ISCHR(ip->i_mode) || S_ISBLK(ip->i_mode))) + error = 0; + fput(fp); + } +out: + return (error); +} + +int +sco_fcntl(int fd, u_int cmd, u_long arg) +{ + /* + * This could be SCO's get highest fd open if the fd we + * are called on is -1 otherwise it could be F_CHKFL. + */ + if (fd == -1 && cmd == 8) { + struct files_struct *files = current->files; + int rval; + + /* compare to ./fs/open.c: get_unused_fd */ + spin_lock(&files->file_lock); + rval = find_first_zero_bit(files->open_fds->fds_bits, files->max_fdset); + spin_unlock(&files->file_lock); + + return rval; + } + + return svr4_fcntl(fd, cmd, arg); +} + +int +sco_sysi86(int cmd, void *arg1, int arg2) +{ + switch (cmd) { + case 114 /*SI86GETFEATURES*/ : + /* + * No, I don't know what these feature flags actually + * _mean_. This vector just matches SCO OS 5.0.0. + */ +#define OSR5_FEATURES "\001\001\001\001\001\001\001\001\002\001\001\001" + arg2 = max(arg2, 12); + if (copy_to_user(arg1, OSR5_FEATURES, arg2)) + return -EFAULT; + return arg2; + default: + return svr4_sysi86(cmd, arg1, arg2); + } +} diff -Nru linux-2.6.7/abi/sco/mmap.c linux-2.6.7-abi/abi/sco/mmap.c --- linux-2.6.7/abi/sco/mmap.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/sco/mmap.c 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2001 Caldera Deutschland GmbH. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ident "%W% %G%" + +/* + * Support for mmap on SCO OpenServer 5. + */ +#include +#include +#include +#include +#include + +#include +#include + +#include + + +int +sco_mmap(u_long addr, size_t len, int prot, int flags, int fd, sco_off_t off) +{ + struct file *file; + u_long mapaddr; + + if (flags & SCO_MAP_UNIMPL) { +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_UNIMPL, + "unsupported mmap flags: 0x%x\n", flags & SCO_MAP_UNIMPL); +#endif + flags &= ~SCO_MAP_UNIMPL; + } + + file = fget(fd); + if (!file) + return -EBADF; + + flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); + down_write(¤t->mm->mmap_sem); + mapaddr = do_mmap(file, addr, len, prot, flags | MAP_FIXED, off); + up_write(¤t->mm->mmap_sem); + + fput(file); + + if (mapaddr == addr) + return 0; + return mapaddr; +} diff -Nru linux-2.6.7/abi/sco/ptrace.c linux-2.6.7-abi/abi/sco/ptrace.c --- linux-2.6.7/abi/sco/ptrace.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/sco/ptrace.c 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,112 @@ +/* + * ptrace.c - SCO OpenServer ptrace(2) support. + * + * Copyright (c) 1995 Mike Jagdis (jaggy@purplet.demon.co.uk) + */ + +#ident "%W% %G%" + +/* + * This file is nearly identical to abi/wyse/ptrace.c, please keep it in sync. + */ +#include +#include +#include +#include +#include +#include +#include +#define __KERNEL_SYSCALLS__ +#include +#include + +#include + +#include +#include + + +#define NREGS 19 +#define U(X) ((unsigned long)&((struct user *)0)->X) + +static unsigned long sco_to_linux_reg[NREGS] = { + U(regs.gs), U(regs.fs), U(regs.es), U(regs.ds), + U(regs.edi), U(regs.esi), + U(regs.ebp), + U(regs.esp /* ESP */), + U(regs.ebx), U(regs.edx), U(regs.ecx), U(regs.eax), + U(signal /* Trap */), + U(reserved /* ERR */), + U(regs.eip), U(regs.cs), U(regs.eflags), + U(regs.esp), U(regs.ss) +}; + +#if defined(CONFIG_ABI_TRACE) +static const char *regnam[] = { + "EBX", "ECX", "EDX", "ESI", "EDI", "EBP", "EAX", + "DS", "ES", "FS", "GS", "ORIG_EAX", "EIP", "CS", + "EFL", "UESP", "SS" +}; +#endif + +int +sco_ptrace(int req, int pid, u_long addr, u_long data) +{ + u_long res; + + /* + * Slight variations between iBCS and Linux codes. + */ + if (req == PTRACE_ATTACH) + req = 10; + else if (req == PTRACE_DETACH) + req = 11; + + if (req == 3 || req == 6) { + /* get offset of u_ar0 */ + if (addr == 0x1200) + return 0x4000; + + /* remap access to the registers. */ + if ((addr & 0xff00) == 0x4000) { /* Registers */ + addr = (addr & 0xff) >> 2; + if (addr > NREGS) + return -EIO; + addr = sco_to_linux_reg[addr]; + if (addr == -1) + return -EIO; + } + } + + if (req == 7 && data > 0) { + if (data > NSIGNALS) + return -EIO; + data = current_thread_info()->exec_domain->signal_map[data]; + } + + if (req == 1 || req == 2 || req == 3) { + mm_segment_t old_fs = get_fs(); + int error; + + set_fs(get_ds()); + error = sys_ptrace(req, pid, addr, (long)&res); + set_fs(old_fs); + + if (error) + return (error); + } + +#if defined(CONFIG_ABI_TRACE) + if (req == 3 || req == 6) { + abi_trace(ABI_TRACE_API, "%ld [%s] = 0x%08lx\n", + addr >> 2, (addr >> 2) < ARRAY_SIZE(regnam) ? + regnam[addr >> 2] : "???", + req == 3 ? res : data); + } +#endif + + if (req == 1 || req == 2 || req == 3) + return (res); + + return sys_ptrace(req, pid, addr, data); +} diff -Nru linux-2.6.7/abi/sco/secureware.c linux-2.6.7-abi/abi/sco/secureware.c --- linux-2.6.7/abi/sco/secureware.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/sco/secureware.c 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,63 @@ +/* + * Copyright (c) 1994 Mike Jagdis. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ident "%W% %G%" + +#include +#include +#include + +/* + * SecureWare, Inc. provided the C2 security subsystem used on SCO Unix. + * This is not that package. This does not even attempt to emulate + * that package. This emulates just enough of the "obvious" bits to + * allow some programs to get a bit further. It is not useful to + * try to implement C2 security in an emulator. Nor is it particularly + * useful to run SCO's secure admin programs on Linux anyway... + */ +enum { + SW_GETLUID = 0x01, + SW_SETLUID = 0x02, +}; + +int +sw_security(int cmd, void *p1, void *p2, void *p3, void *p4, void *p5) +{ + switch (cmd) { + case SW_GETLUID: + /* + * We want the login user id. We don't have it + * specifically so we'll just use the real uid + * instead - it should be good enough. + */ + return (current->uid); + case SW_SETLUID: + /* + * Strictly we should only be able to call setluid() + * once but we can't enforce that. We have the choice + * between having it always succeed or always fail. + * Since setluid() should only ever be invoked by + * things like login processes we always fail it. + */ + return -EPERM; + } + + printk(KERN_ERR "%s: unsupported security call cmd=%d\n", __FILE__, cmd); + return -EINVAL; +} diff -Nru linux-2.6.7/abi/sco/stat.c linux-2.6.7-abi/abi/sco/stat.c --- linux-2.6.7/abi/sco/stat.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/sco/stat.c 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2001 Caldera Deutschland GmbH. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * aint32_t with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ident "%W% %G%" + +/* + * SCO OpenServer xstat/fxstat/lxstat support. + */ +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + + +enum {SVR4_stat = 1, SCO_xstat = 51}; + +static int +report_sco_xstat(struct kstat *stp, struct sco_xstat *bufp) +{ + struct sco_xstat buf; + + memset(&buf, 0, sizeof(struct sco_xstat)); + + buf.st_dev = linux_to_sco_dev_t(stp->dev); + buf.st_ino = linux_to_sco_ino_t(stp->ino); + buf.st_mode = stp->mode; + buf.st_nlink = stp->nlink; + buf.st_uid = linux_to_sco_uid_t(stp->uid); + buf.st_gid = linux_to_sco_gid_t(stp->gid); + buf.st_rdev = linux_to_sco_dev_t(stp->rdev); + + if (stp->size > MAX_NON_LFS) + return -EOVERFLOW; /* XXX: what to return for SCO?? */ + + buf.st_size = stp->size; + + buf.st_atime = stp->atime.tv_sec; + buf.st_mtime = stp->mtime.tv_sec; + buf.st_ctime = stp->ctime.tv_sec; + + buf.st_blksize = stp->blksize; + buf.st_blocks = stp->blocks; + + strcpy(buf.st_fstype, "ext2"); + + buf.st_sco_flags = 0; /* 1 if remote */ + + if (copy_to_user(bufp, &buf, sizeof(struct sco_xstat))) + return -EFAULT; + return 0; +} + +int +sco_xstat(int vers, char *filename, void *bufp) +{ + struct kstat st; + int error; + + error = vfs_stat(filename, &st); + if (error) + return error; + + switch (vers) { + case SVR4_stat: + return report_svr4_stat(&st, bufp); + case SCO_xstat: + return report_sco_xstat(&st, bufp); + } + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_API, "xstat version %d not supported\n", vers); +#endif + return -EINVAL; +} + +int +sco_lxstat(int vers, char *filename, void *bufp) +{ + struct kstat st; + int error; + + error = vfs_lstat(filename, &st); + if (error) + return error; + + switch (vers) { + case SVR4_stat: + return report_svr4_stat(&st, bufp); + case SCO_xstat: + return report_sco_xstat(&st, bufp); + } + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_API, "lxstat version %d not supported\n", vers); +#endif + return -EINVAL; +} + +int +sco_fxstat(int vers, int fd, void *bufp) +{ + struct kstat st; + int error; + + error = vfs_fstat(fd, &st); + if (error) + return error; + + switch (vers) { + case SVR4_stat: + return report_svr4_stat(&st, bufp); + case SCO_xstat: + return report_sco_xstat(&st, bufp); + } + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_API, "fxstat version %d not supported\n", vers); +#endif + return -EINVAL; +} diff -Nru linux-2.6.7/abi/sco/statvfs.c linux-2.6.7-abi/abi/sco/statvfs.c --- linux-2.6.7/abi/sco/statvfs.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/sco/statvfs.c 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2001 Caldera Deutschland GmbH. + * Copyright (c) 2001 Christoph Hellwig. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ident "%W% %G%" + +/* + * SCO OpenServer statvfs/fstatvfs support. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + +static int +report_statvfs(struct vfsmount *mnt, struct inode *ip, struct sco_statvfs *bufp) +{ + struct sco_statvfs buf; + struct kstatfs s; + int error; + + error = vfs_statfs(mnt->mnt_sb, &s); + if (error) + return error; + + memset(&buf, 0, sizeof(struct sco_statvfs)); + + buf.f_bsize = s.f_bsize; + buf.f_frsize = s.f_bsize; + buf.f_blocks = s.f_blocks; + buf.f_bfree = s.f_bfree; + buf.f_bavail = s.f_bavail; + buf.f_files = s.f_files; + buf.f_free = s.f_ffree; + buf.f_favail = s.f_ffree; /* SCO addition in the middle! */ + buf.f_sid = ip->i_sb->s_dev; + + /* + * Get the name of the filesystem. + * + * Sadly, some code "in the wild" actually checks the name + * against a hard coded list to see if it is a "real" fs or not. + * + * I believe Informix Dynamic Server for SCO is one such. + */ + if (strncmp(ip->i_sb->s_type->name, "ext2", 4) == 0) + strcpy(buf.f_basetype, "HTFS"); + else + strcpy(buf.f_basetype, ip->i_sb->s_type->name); + + /* Check for a few flags statvfs wants but statfs doesn't have. */ + if (IS_RDONLY(ip)) + buf.f_flag |= 1; + if (mnt->mnt_flags & MNT_NOSUID) + buf.f_flag |= 2; + + buf.f_namemax = s.f_namelen; + + if (copy_to_user(bufp, &buf, sizeof(struct sco_statvfs))) + return -EFAULT; + return 0; +} + +int +sco_statvfs(char *filename, struct sco_statvfs *bufp) +{ + struct nameidata nd; + int error; + + error = user_path_walk(filename, &nd); + if (!error) { + error = report_statvfs(nd.mnt, nd.dentry->d_inode, bufp); + path_release(&nd); + } + return error; +} + +int +sco_fstatvfs(int fd, struct sco_statvfs *bufp) +{ + struct file *fp; + int error = -EBADF; + + fp = fget(fd); + if (fp) { + error = report_statvfs(fp->f_vfsmnt, + fp->f_dentry->d_inode, bufp); + fput(fp); + } + return error; +} diff -Nru linux-2.6.7/abi/sco/sysent.c linux-2.6.7-abi/abi/sco/sysent.c --- linux-2.6.7/abi/sco/sysent.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/sco/sysent.c 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,457 @@ +/* + * Copyright (c) 2001 Christoph Hellwig. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ident "%W% %G%" + +/* + * SCO Unix 3.x personality switch + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + + +MODULE_DESCRIPTION("OpenServer/Xenix personality"); +MODULE_AUTHOR("Christoph Hellwig, partially taken from iBCS"); +MODULE_LICENSE("GPL"); + + +static u_char sco_err_table[] = { +/* 0 - 9 */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, +/* 10 - 19 */ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, +/* 20 - 29 */ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, +/* 30 - 39 */ 30, 31, 32, 33, 34, 45, 78, 46, 89, 145, +/* 40 - 49 */ 150, 90, 35, 36, 37, 38, 39, 40, 41, 42, +/* 50 - 59 */ 43, 44, 50, 51, 52, 53, 54, 55, 56, 57, +/* 60 - 69 */ 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, +/* 70 - 79 */ 70, 71, 74, 76, 77, 79, 80, 81, 82, 83, +/* 80 - 89 */ 84, 85, 86, 87, 88, 152, 153, 22, 93, 94, +/* 90 - 99 */ 95, 96, 118, 97, 98, 99, 100, 101, 102, 103, +/* 100 - 109 */ 104, 105, 106, 107, 108, 63, 110, 111, 112, 113, +/* 110 - 119 */ 114, 115, 116, 117, 92, 91, 151, 135, 137, 138, +/* 120 - 122 */ 139, 140, 28 +}; + +/* + * Map Linux RESTART* values (512,513,514) to EINTR + */ +static u_char lnx_err_table[] = { +/* 512 - 514 */ EINTR, EINTR, EINTR +}; + +static struct map_segment sco_err_map[] = { + { 0, 0+sizeof(sco_err_table)-1, sco_err_table }, + { 512, 512+sizeof(lnx_err_table)-1, lnx_err_table }, + { -1 } +}; + +/* XXX: move to signal.h */ +#define SCO__SIGSTKFLT SCO_SIGTERM /* Stack fault */ + +static long linux_to_sco_signals[NSIGNALS + 1] = { +/* 0 - 3 */ 0, SCO_SIGHUP, SCO_SIGINT, SCO_SIGQUIT, +/* 4 - 7 */ SCO_SIGILL, SCO_SIGTRAP, SCO_SIGABRT, SCO_SIGBUS, +/* 8 - 11 */ SCO_SIGFPE, SCO_SIGKILL, SCO_SIGUSR1, SCO_SIGSEGV, +/* 12 - 15 */ SCO_SIGUSR2, SCO_SIGPIPE, SCO_SIGALRM, SCO_SIGTERM, +/* 16 - 19 */ SCO__SIGSTKFLT, SCO_SIGCLD, SCO_SIGCONT, SCO_SIGSTOP, +/* 20 - 23 */ SCO_SIGTSTP, SCO_SIGTTIN, SCO_SIGTTOU, SCO_SIGURG, +/* 24 - 27 */ SCO_SIGXCPU, SCO_SIGXFSZ, SCO_SIGVTALRM, SCO_SIGPROF, +/* 28 - 31 */ SCO_SIGWINCH, SCO_SIGPOLL, SCO_SIGPWR, SCO_SIGSYS, +/* 32 */ -1 +}; + +static long linux_to_xenix_signals[NSIGNALS+1] = { +/* 0 - 3 */ 0, IBCS_SIGHUP, IBCS_SIGINT, IBCS_SIGQUIT, +/* 4 - 7 */ IBCS_SIGILL, IBCS_SIGTRAP, IBCS_SIGABRT, -1, +/* 8 - 11 */ IBCS_SIGFPE, IBCS_SIGKILL, IBCS_SIGUSR1, IBCS_SIGSEGV, +/* 12 - 15 */ IBCS_SIGUSR2, IBCS_SIGPIPE, IBCS_SIGALRM, IBCS_SIGTERM, +/* 16 - 19 */ IBCS_SIGSEGV, IBCS_SIGCHLD, IBCS_SIGCONT, IBCS_SIGSTOP, +/* 20 - 23 */ IBCS_SIGTSTP, IBCS_SIGTTIN, IBCS_SIGTTOU, IBCS_SIGUSR1, +/* 24 - 27 */ IBCS_SIGGXCPU, IBCS_SIGGXFSZ, IBCS_SIGVTALRM, IBCS_SIGPROF, +/* 28 - 31 */ IBCS_SIGWINCH, 20 /*SIGIO*/, IBCS_SIGPWR, -1, +/* 32 */ -1 +}; + +static long sco_to_linux_signals[NSIGNALS+1] = { +/* 0 - 3 */ 0, SIGHUP, SIGINT, SIGQUIT, +/* 4 - 7 */ SIGILL, SIGTRAP, SIGIOT, SIGABRT, +/* 8 - 11 */ SIGFPE, SIGKILL, SIGBUS, SIGSEGV, +/* 12 - 15 */ SIGSYS, SIGPIPE, SIGALRM, SIGTERM, +/* 16 - 19 */ SIGUSR1, SIGUSR2, SIGCHLD, SIGPWR, +/* 20 - 23 */ SIGWINCH, SIGURG, SIGPOLL, SIGSTOP, +/* 24 - 27 */ SIGTSTP, SIGCONT, SIGTTIN, SIGTTOU, +/* 28 - 31 */ SIGVTALRM, SIGPROF, SIGXCPU, SIGXFSZ, +/* 32 */ -1 +}; + +static long xenix_to_linux_signals[NSIGNALS+1] = { +/* 0 - 3 */ 0, SIGHUP, SIGINT, SIGQUIT, +/* 4 - 7 */ SIGILL, SIGTRAP, SIGIOT, SIGUNUSED, +/* 8 - 11 */ SIGFPE, SIGKILL, SIGUNUSED, SIGSEGV, +/* 12 - 15 */ SIGUNUSED, SIGPIPE, SIGALRM, SIGTERM, +/* 16 - 19 */ SIGUSR1, SIGUSR2, SIGCHLD, SIGPWR, +/* 20 - 23 */ SIGPOLL, -1, -1, -1, +/* 24 - 27 */ -1, -1, -1, -1, +/* 28 - 31 */ -1, -1, -1, -1, +/* 32 */ -1 +}; + +static char sco_socktype[] = { + SOCK_STREAM, + SOCK_DGRAM, + 0, + SOCK_RAW, + SOCK_RDM, + SOCK_SEQPACKET +}; + +static struct map_segment sco_socktype_map[] = { + { 1, 6, sco_socktype }, + { -1 } +}; + +static struct map_segment sco_sockopt_map[] = { + { 0x0001, 0x0001, (char *)SO_DEBUG }, + { 0x0002, 0x0002, (char *)__SO_ACCEPTCON }, + { 0x0004, 0x0004, (char *)SO_REUSEADDR }, + { 0x0008, 0x0008, (char *)SO_KEEPALIVE }, + { 0x0010, 0x0010, (char *)SO_DONTROUTE }, + { 0x0020, 0x0020, (char *)SO_BROADCAST }, + { 0x0040, 0x0040, (char *)SO_USELOOPBACK }, + { 0x0080, 0x0080, (char *)SO_LINGER }, + { 0x0100, 0x0100, (char *)SO_OOBINLINE }, + { 0x0200, 0x0200, (char *)SO_ORDREL }, + { 0x0400, 0x0400, (char *)SO_IMASOCKET }, + { 0x1001, 0x1001, (char *)SO_SNDBUF }, + { 0x1002, 0x1002, (char *)SO_RCVBUF }, + { 0x1003, 0x1003, (char *)SO_SNDLOWAT }, + { 0x1004, 0x1004, (char *)SO_RCVLOWAT }, + { 0x1005, 0x1005, (char *)SO_SNDTIMEO }, + { 0x1006, 0x1006, (char *)SO_RCVTIMEO }, + { 0x1007, 0x1007, (char *)SO_ERROR }, + { 0x1008, 0x1008, (char *)SO_TYPE }, + { 0x1009, 0x1009, (char *)SO_PROTOTYPE }, + { -1 } +}; + +/* + * The first three entries (AF_UNSPEC, AF_UNIX and AF_INET) + * are identity mapped. All others aren't available under + * Linux, nor are Linux's AF_AX25 and AF_IPX available from + * SCO as far as I know. + */ +static struct map_segment sco_af_map[] = { + { 0, 2, NULL }, + { -1 } +}; + + +static struct sysent sco_syscall_table[] = { +/* 0 */ { abi_syscall, Fast, "syscall", "" }, +/* 1 */ { sys_exit, 1, "exit", "d" }, +/* 2 */ { abi_fork, Spl, "fork", "" }, +/* 3 */ { abi_read, 3, "read", "dpd" }, +/* 4 */ { sys_write, 3, "write", "dpd" }, +/* 5 */ { svr4_open, 3, "open", "soo" }, +/* 6 */ { sys_close, 1, "close", "d" }, +/* 7 */ { abi_wait, Spl, "wait", "xxx" }, +/* 8 */ { sys_creat, 2, "creat", "so" }, +/* 9 */ { sys_link, 2, "link", "ss" }, +/* 10 */ { sys_unlink, 1, "unlink", "s" }, +/* 11 */ { abi_exec, Spl, "exec", "sxx" }, +/* 12 */ { sys_chdir, 1, "chdir", "s" }, +/* 13 */ { abi_time, 0, "time", "" }, +/* 14 */ { svr4_mknod, 3, "mknod", "soo" }, +/* 15 */ { sys_chmod, 2, "chmod", "so" }, +/* 16 */ { sys_chown, 3, "chown", "sdd" }, +/* 17 */ { abi_brk, 1, "brk/break", "x" }, +/* 18 */ { svr4_stat, 2, "stat", "sp" }, +/* 19 */ { sco_lseek, 3, "seek/lseek", "ddd" }, +/* 20 */ { abi_getpid, Spl, "getpid", "" }, +/* 21 */ { 0, Ukn, "mount", "" }, +/* 22 */ { sys_umount, 1, "umount", "s" }, +/* 23 */ { sys_setuid, 1, "setuid", "d" }, +/* 24 */ { abi_getuid, Spl, "getuid", "" }, +/* 25 */ { sys_stime, 1, "stime", "d" }, +/* 26 */ { sco_ptrace, 4, "ptrace", "xdxx" }, +/* 27 */ { sys_alarm, 1, "alarm", "d" }, +/* 28 */ { svr4_fstat, 2, "fstat", "dp" }, +/* 29 */ { sys_pause, 0, "pause", "" }, +/* 30 */ { sys_utime, 2, "utime", "xx" }, +/* 31 */ { 0, Ukn, "stty", "" }, +/* 32 */ { 0, Ukn, "gtty", "" }, +/* 33 */ { sys_access, 2, "access", "so" }, +/* 34 */ { sys_nice, 1, "nice", "d" }, +/* 35 */ { svr4_statfs, 4, "statfs", "spdd" }, +/* 36 */ { sys_sync, 0, "sync", "" }, +/* 37 */ { abi_kill, 2, "kill", "dd" }, +/* 38 */ { svr4_fstatfs, 4, "fstatfs", "dpdd" }, +/* 39 */ { abi_procids, Spl, "procids", "d" }, +/* 40 */ { cxenix, Fast, "cxenix", "" }, +/* 41 */ { sys_dup, 1, "dup", "d" }, +/* 42 */ { abi_pipe, Spl, "pipe", "" }, +/* 43 */ { sys_times, 1, "times", "p" }, +/* 44 */ { 0 , Ukn, "prof", "" }, +/* 45 */ { 0, Ukn, "lock/plock", "" }, +/* 46 */ { sys_setgid, 1, "setgid", "d" }, +/* 47 */ { abi_getgid, Spl, "getgid", "" }, +/* 48 */ { abi_sigfunc, Fast, "sigfunc", "xxx" }, +/* 49 */ { svr4_msgsys, Spl, "msgsys", "dxddd" }, +/* 50 */ { sco_sysi86, 3, "sysi86/sys3b", "d" }, +/* 51 */ { sys_acct, 1, "acct/sysacct", "x" }, +/* 52 */ { svr4_shmsys, Fast, "shmsys", "ddxo" }, +/* 53 */ { svr4_semsys, Spl, "semsys", "dddx" }, +/* 54 */ { sco_ioctl, Spl, "ioctl", "dxx" }, +/* 55 */ { 0, 3, "uadmin", "xxx" }, +/* 56 */ { 0, Ukn, "?", "" }, +/* 57 */ { v7_utsname, 1, "utsys", "x" }, +/* 58 */ { sys_fsync, 1, "fsync", "d" }, +/* 59 */ { abi_exec, Spl, "execv", "spp" }, +/* 60 */ { sys_umask, 1, "umask", "o" }, +/* 61 */ { sys_chroot, 1, "chroot", "s" }, +/* 62 */ { sco_fcntl, 3, "fcntl", "dxx" }, +/* 63 */ { svr4_ulimit, 2, "ulimit", "xx" }, +/* 64 */ { 0, Ukn, "?", "" }, +/* 65 */ { 0, Ukn, "?", "" }, +/* 66 */ { 0, Ukn, "?", "" }, +/* 67 */ { 0, Ukn, "?", "" }, +/* 68 */ { 0, Ukn, "?", "" }, +/* 69 */ { 0, Ukn, "?", "" }, +/* 70 */ { 0, Ukn, "advfs", "" }, +/* 71 */ { 0, Ukn, "unadvfs", "" }, +/* 72 */ { 0, Ukn, "rmount", "" }, +/* 73 */ { 0, Ukn, "rumount", "" }, +/* 74 */ { 0, Ukn, "rfstart", "" }, +/* 75 */ { 0, Ukn, "?", "" }, +/* 76 */ { 0, Ukn, "rdebug", "" }, +/* 77 */ { 0, Ukn, "rfstop", "" }, +/* 78 */ { 0, Ukn, "rfsys", "" }, +/* 79 */ { sys_rmdir, 1, "rmdir", "s" }, +/* 80 */ { abi_mkdir, 2, "mkdir", "so" }, +/* 81 */ { svr4_getdents, 3, "getdents", "dxd" }, +/* 82 */ { 0, Ukn, "libattach", "" }, +/* 83 */ { 0, Ukn, "libdetach", "" }, +/* 84 */ { svr4_sysfs, 3, "sysfs", "dxx" }, +/* 85 */ { svr4_getmsg, Spl, "getmsg", "dxxx" }, +/* 86 */ { svr4_putmsg, Spl, "putmsg", "dxxd" }, +/* 87 */ { sys_poll, 3, "poll", "xdd" }, +/* 88 */ { 0, Ukn, "nosys88", "" }, +/* 89 */ { sw_security, 6, "security", "dxxxxx"}, +/* 90 */ { sys_symlink, 2, "symlink", "ss" }, +/* 91 */ { svr4_lstat, 2, "lstat", "sp" }, +/* 92 */ { sys_readlink, 3, "readlink", "spd" }, + + /* + * Ok, this is where the good-old SCO calls end. + * Everything from here onwards is OSR5-specific. + * + * In fact OSR5 documents only the following calls: + * + * o readv (121) + * o writev (122) + * o xstat (123) + * o lxstat (124) + * o fxstat (125) + * o clocal (127) + * o gettimeofday (171) + * o settimeofday (172) + * + * Everything else is guesswork (from AVR4/iABI4), even though + * the OSR5 ELF libs use at least some of those... (e.g. mmap). + */ + +/* 93 */ { 0, Ukn, "?", "" }, +/* 94 */ { 0, Ukn, "?", "" }, +/* 95 */ { abi_sigprocmask, 3, "sigprocmask", "dxx" }, +/* 96 */ { abi_sigsuspend, Spl, "sigsuspend", "x" }, +/* 97 */ { 0, 2, "sigaltstack", "xx" }, +/* 98 */ { abi_sigaction, 3, "sigaction", "dxx" }, +/* 99 */ { svr4_sigpending, 2, "sigpending", "dp" }, +/* 100 */ { svr4_context, Spl, "context", "" }, +/* 101 */ { 0, Ukn, "evsys", "" }, +/* 102 */ { 0, Ukn, "evtrapret", "" }, +/* 103 */ { sco_statvfs, 2, "statvfs", "sp" }, +/* 104 */ { sco_fstatvfs, 2, "fstatvfs", "dp" }, +/* 105 */ { 0, Ukn, "unimp (sysisc)","" }, +/* 106 */ { 0, Ukn, "nfssys", "" }, +/* 107 */ { 0, 4, "waitid", "ddxd" }, +/* 108 */ { 0, 3, "sigsendsys", "ddd" }, +/* 109 */ { svr4_hrtsys, Spl, "hrtsys", "xxx" }, +/* 110 */ { 0, 3, "acancel", "dxd" }, +/* 111 */ { 0, Ukn, "async", "" }, +/* 112 */ { 0, Ukn, "priocntlsys", "" }, +/* 113 */ { svr4_pathconf, 2, "pathconf", "sd" }, +/* 114 */ { sys_mincore, 3, "mincore", "xdx" }, +/* 115 */ { sco_mmap, 6, "mmap", "xxxxdx"}, +/* 116 */ { sys_mprotect, 3, "mprotect", "xdx" }, +/* 117 */ { sys_munmap, 2, "munmap", "xd" }, +/* 118 */ { svr4_fpathconf, 2, "fpathconf", "dd" }, +/* 119 */ { abi_fork, Spl, "vfork", "" }, +/* 120 */ { sys_fchdir, 1, "fchdir", "d" }, +/* 121 */ { sys_readv, 3, "readv", "dxd" }, +/* 122 */ { sys_writev, 3, "writev", "dxd" }, +/* 123 */ { sco_xstat, 3, "xstat", "dsx" }, +/* 124 */ { sco_lxstat, 3, "lxstat", "dsx" }, +/* 125 */ { sco_fxstat, 3, "fxstat", "ddx" }, +/* 126 */ { svr4_xmknod, 4, "xmknod", "dsox" }, +/* 127 */ { 0, Ukn, "syslocal", "d" }, +/* 128 */ { svr4_getrlimit, 2, "setrlimit", "dx" }, +/* 129 */ { svr4_setrlimit, 2, "getrlimit", "dx" }, +/* 130 */ { 0, Ukn, "?", "" }, +/* 131 */ { 0, Ukn, "?", "" }, +/* 132 */ { 0, Ukn, "?", "" }, +/* 133 */ { 0, Ukn, "?", "" }, +/* 134 */ { 0, Ukn, "?", "" }, +/* 135 */ { 0, Ukn, "?", "" }, +/* 136 */ { 0, Ukn, "?", "" }, +/* 137 */ { 0, Ukn, "?", "" }, +/* 138 */ { 0, Ukn, "?", "" }, +/* 139 */ { 0, Ukn, "?", "" }, +/* 140 */ { socksys_syscall, 1, "socksys", "x" }, +/* 141 */ { 0, Ukn, "?", "" }, +/* 142 */ { 0, Ukn, "?", "" }, +/* 143 */ { 0, Ukn, "?", "" }, + + /* + * The next three are used when an OSR5 app is launched by + * a UnixWare libc. + * + * These aren't supported by the UW7 personality either, but + * adding the names here makes the traces look saner. + */ + +/* 144 */ { 0, 2, "uw7-secsys", "dx" }, +/* 145 */ { 0, 4, "uw7-filepriv", "sdxd" }, +/* 146 */ { 0, 3, "uw7-procpriv", "dxd" }, + +/* 147 */ { 0, Ukn, "?", "" }, +/* 148 */ { 0, Ukn, "?", "" }, +/* 149 */ { 0, Ukn, "?", "" }, +/* 150 */ { 0, Ukn, "?", "" }, +/* 151 */ { 0, Ukn, "?", "" }, +/* 152 */ { 0, Ukn, "?", "" }, +/* 153 */ { 0, Ukn, "?", "" }, +/* 154 */ { 0, Ukn, "?", "" }, +/* 155 */ { 0, Ukn, "?", "" }, +/* 156 */ { 0, Ukn, "?", "" }, +/* 157 */ { 0, Ukn, "?", "" }, +/* 158 */ { 0, Ukn, "?", "" }, +/* 159 */ { 0, Ukn, "?", "" }, +/* 160 */ { 0, Ukn, "?", "" }, +/* 161 */ { 0, Ukn, "?", "" }, +/* 162 */ { 0, Ukn, "?", "" }, +/* 163 */ { 0, Ukn, "?", "" }, +/* 164 */ { 0, Ukn, "?", "" }, +/* 165 */ { 0, Ukn, "?", "" }, +/* 166 */ { 0, Ukn, "?", "" }, +/* 167 */ { 0, Ukn, "?", "" }, +/* 168 */ { 0, Ukn, "?", "" }, +/* 169 */ { 0, Ukn, "?", "" }, +/* 170 */ { 0, Ukn, "?", "" }, +/* 171 */ { sys_gettimeofday, 2, "gettimeofday", "xx" }, +/* 172 */ { sys_settimeofday, 2, "settimeofday", "xx" }, +}; + +static void +sco_lcall7(int segment, struct pt_regs *regs) +{ + int sysno = regs->eax & 0xff; + + if (sysno >= ARRAY_SIZE(sco_syscall_table)) + set_error(regs, iABI_errors(-EINVAL)); + else + lcall7_dispatch(regs, &sco_syscall_table[sysno], 1); +} + + +static struct exec_domain sco_exec_domain = { + name: "OpenServer", + handler: sco_lcall7, + pers_low: 3 /* PER_SCOSVR3, PER_OSR5 */, + pers_high: 3 /* PER_SCOSVR3, PER_OSR5 */, + signal_map: sco_to_linux_signals, + signal_invmap: linux_to_sco_signals, + err_map: sco_err_map, + socktype_map: sco_socktype_map, + sockopt_map: sco_sockopt_map, + af_map: sco_af_map, + module: THIS_MODULE +}; + +static struct exec_domain xenix_exec_domain = { + name: "Xenix", + handler: sco_lcall7, + pers_low: 7 /* PER_XENIX */, + pers_high: 7 /* PER_XENIX */, + signal_map: xenix_to_linux_signals, + signal_invmap: linux_to_xenix_signals, + err_map: sco_err_map, + socktype_map: sco_socktype_map, + sockopt_map: sco_sockopt_map, + af_map: sco_af_map, + module: THIS_MODULE +}; + + +static int __init +sco_module_init(void) +{ + int err; + + err = register_exec_domain(&sco_exec_domain); + if (err) { + return err; + } + + err = register_exec_domain(&xenix_exec_domain); + if (err) { + unregister_exec_domain(&sco_exec_domain); + return err; + } + + return err; +} + +static void __exit +sco_module_exit(void) +{ + unregister_exec_domain(&xenix_exec_domain); + unregister_exec_domain(&sco_exec_domain); +} + +module_init(sco_module_init); +module_exit(sco_module_exit); diff -Nru linux-2.6.7/abi/sco/tapeio.c linux-2.6.7-abi/abi/sco/tapeio.c --- linux-2.6.7/abi/sco/tapeio.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/sco/tapeio.c 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,112 @@ +#ident "%W% %G%" + +#include +#include +#include +#include + +#include + + +int +sco_tape_ioctl(int fd, u_int cmd, caddr_t data) +{ + struct mtop mtop; + mm_segment_t fs; + int error; + + mtop.mt_count = 1; + + switch (cmd & 0xff) { + case 1: /* MT_RESET */ + mtop.mt_op = MTRESET; + break; + + case 2: /* MT_RETEN */ + mtop.mt_op = MTRETEN; + break; + + case 3: /* MT_REWIND */ + mtop.mt_op = MTREW; + break; + + case 4: /* MT_ERASE */ + case 23: /* HP_ERASE */ + mtop.mt_op = MTERASE; + break; + + case 6: /* MT_RFM */ + mtop.mt_op = MTFSF; + break; + + case 7: /* MT_WFM */ + mtop.mt_op = MTWEOF; + break; + + case 8: /* MT_LOAD */ + mtop.mt_op = MTLOAD; + break; + + case 9: /* MT_UNLOAD */ + mtop.mt_op = MTOFFL; + break; + + case 19: /* MT_RSM */ + mtop.mt_op = MTFSS; + break; + + case 20: /* MT_WSM */ + mtop.mt_op = MTWSM; + break; + + case 21: /* MT_EOD */ + mtop.mt_op = MTEOM; + break; + + case 24: /* MT_SETBLK */ + mtop.mt_op = MTSETBLK; + mtop.mt_count = (int)data; + break; + + case 25: /* MT_LOCK */ + mtop.mt_op = MTLOCK; + break; + + case 26: /* MT_UNLOCK */ + mtop.mt_op = MTUNLOCK; + break; + + +#if 0 +/* + The following function codes are just copied from the SCO + include file. +*/ + + case 0: /* MT_STATUS */ + case 5: /* MT_AMOUNT */ + case 10: /* MT_DSTATUS */ + case 11: /* MT_FORMAT */ + case 12: /* MT_GETHDR */ + case 13: /* MT_PUTHDR */ + case 14: /* MT_GETNEWBB */ + case 15: /* MT_PUTNEWBB */ + case 16: /* MT_GETVTBL */ + case 17: /* MT_PUTVTBL */ + case 18: /* MT_SERVO */ + case 22: /* MT_FORMPART */ + case 38: /* MT_SETANSI */ + case 64: /* MT_REPORT */ +#endif + default: + printk (KERN_ERR "abi: SCO tape ioctl func=%d arg=%x unsupported\n", + cmd & 0xff, (int)data); + return -EINVAL; + } + + fs = get_fs(); + set_fs(get_ds()); + error = sys_ioctl(fd, MTIOCTOP, (long)&mtop); + set_fs(fs); + return (error); +} diff -Nru linux-2.6.7/abi/sco/termios.c linux-2.6.7-abi/abi/sco/termios.c --- linux-2.6.7/abi/sco/termios.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/sco/termios.c 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,186 @@ +/* + * Copyright (C) 1991, 1992 Linus Torvalds + * + * Written by Drew Sullivan. + * Rewritten by Mike Jagdis. + */ + +#ident "%W% %G%" + +#include +#include +#include +#include +#include +#include + +#include +#include + + +#define SCO_NCCS (SVR_NCC+5) + +struct sco_termios { + u_int16_t c_iflag; + u_int16_t c_oflag; + u_int16_t c_cflag; + u_int16_t c_lflag; + char c_line; + u_char c_cc[SCO_NCCS]; + char c_ispeed; + char c_ospeed; +}; + +static int +sco_to_linux_termios(int fd, int op, struct sco_termios *it) +{ + struct termios t; + mm_segment_t old_fs; + u_short lflag, r; + char sco_cc[SCO_NCCS]; + int error; + + error = verify_area(VERIFY_READ, it, sizeof(struct sco_termios)); + if (error) + return (error); + + old_fs = get_fs(); + set_fs(get_ds()); + error = sys_ioctl(fd, TCGETS, (long)&t); + set_fs(old_fs); + + if (error) + return (error); + + __get_user(t.c_iflag, &it->c_iflag); + t.c_iflag &= ~0100000; /* DOSMODE */ + + __get_user(t.c_oflag, &it->c_oflag); + + __get_user(t.c_cflag, &it->c_cflag); + if (t.c_cflag & 0100000) /* CRTSFL - SCO only? */ + t.c_cflag |= CRTSCTS; + t.c_cflag &= ~0170000; /* LOBLK|CTSFLOW|RTSFLOW|CRTSFL */ + + lflag = t.c_lflag; + t.c_lflag &= ~0100777; + __get_user(r, &it->c_lflag); + t.c_lflag |= r; + + if ((t.c_lflag & 0100000)) + sys_ioctl(fd, TIOCEXCL, 0); + else + sys_ioctl(fd, TIOCNXCL, 0); + + t.c_lflag &= ~0100000; + t.c_lflag |= (t.c_lflag & 0000400) << 7; /* Move IEXTEN */ + t.c_lflag &= ~0000400; + t.c_lflag |= (t.c_lflag & 0001000) >> 1; /* Move TOSTOP */ + t.c_lflag &= ~0001000; + t.c_lflag |= (lflag & 0001000); /* Restore ECHOCTL */ + + __get_user(t.c_line, &it->c_line); /* XXX Map this? */ + + copy_from_user(sco_cc, &it->c_cc, SCO_NCCS); + t.c_cc[0] = sco_cc[0]; + t.c_cc[1] = sco_cc[1]; + t.c_cc[2] = sco_cc[2]; + t.c_cc[3] = sco_cc[3]; + t.c_cc[7] = sco_cc[7]; + t.c_cc[8] = sco_cc[11]; + t.c_cc[9] = sco_cc[12]; + t.c_cc[10] = sco_cc[10]; + t.c_cc[16] = sco_cc[6]; + if (t.c_lflag & ICANON) { + t.c_cc[4] = sco_cc[4]; + t.c_cc[11] = sco_cc[5]; + } else { + t.c_cc[4] = sco_cc[8]; + t.c_cc[5] = sco_cc[5]; + t.c_cc[6] = sco_cc[4]; + t.c_cc[11] = sco_cc[9]; + } + + set_fs(get_ds()); + error = sys_ioctl(fd, op, (long)&t); + set_fs(old_fs); + + return (error); +} + +static int +linux_to_sco_termios(int fd, int op, struct sco_termios *it) +{ + struct termios t; + char sco_cc[SCO_NCCS]; + mm_segment_t old_fs; + int error; + + error = verify_area(VERIFY_WRITE, it, sizeof(struct sco_termios)); + if (error) + return (error); + + old_fs = get_fs(); + set_fs(get_ds()); + error = sys_ioctl(fd, op, (long)&t); + set_fs(old_fs); + if (error) + return (error); + + put_user(t.c_iflag & 0017777, &it->c_iflag); + + put_user(t.c_oflag & 0177777, &it->c_oflag); + + if (t.c_cflag & CRTSCTS) + t.c_cflag |= 0100000; /* CRTSFL - SCO only? */ + put_user(t.c_cflag & 0177777, &it->c_cflag); + + t.c_lflag &= ~0001000; + t.c_lflag |= (t.c_lflag & 0000400) << 1; + t.c_lflag &= ~0000400; + t.c_lflag |= (t.c_lflag & 0100000) >> 7; + t.c_lflag &= ~0100000; + put_user(t.c_lflag & 0001777, &it->c_lflag); + + put_user(t.c_line, &it->c_line); /* XXX Map this? */ + + sco_cc[0] = t.c_cc[0]; + sco_cc[1] = t.c_cc[1]; + sco_cc[2] = t.c_cc[2]; + sco_cc[3] = t.c_cc[3]; + sco_cc[6] = t.c_cc[16]; + sco_cc[7] = t.c_cc[7]; + sco_cc[8] = t.c_cc[4]; + sco_cc[9] = t.c_cc[11]; + sco_cc[10] = t.c_cc[10]; + sco_cc[11] = t.c_cc[8]; + sco_cc[12] = t.c_cc[9]; + if (t.c_lflag & ICANON) { + sco_cc[4] = t.c_cc[4]; + sco_cc[5] = t.c_cc[11]; + } else { + sco_cc[4] = t.c_cc[6]; + sco_cc[5] = t.c_cc[5]; + } + + copy_to_user(&it->c_cc, sco_cc, SCO_NCCS); + + return (error); +} + +int +sco_term_ioctl(int fd, unsigned int func, void *arg) +{ + switch(func) { + case 1: /* XCGETA */ + return linux_to_sco_termios(fd, TCGETS, arg); + case 2: /* XCSETA */ + return sco_to_linux_termios(fd, TCSETS, arg); + case 3: /* XCSETAW */ + return sco_to_linux_termios(fd, TCSETSW, arg); + case 4: /* XCSETAF */ + return sco_to_linux_termios(fd, TCSETSF, arg); + } + printk(KERN_ERR "iBCS: SCO termios ioctl %d unsupported\n", func); + return -EINVAL; +} diff -Nru linux-2.6.7/abi/sco/vtkbd.c linux-2.6.7-abi/abi/sco/vtkbd.c --- linux-2.6.7/abi/sco/vtkbd.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/sco/vtkbd.c 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,88 @@ +/* + * This provides internal emulation support for the SCO on + * the multiscreen console. More or less, this involves translating the + * input ioctl()'s into a similar Linux ioctl()'s. + * + * Not emulated SCO multiscreen functions: + * None. + * + * Not emulated SCO keyboard functions: + * KIOCDOSMODE set DOSMODE + * KIOCNONDOSMODE unset DOSMODE + * KDDISPINFO get display start and size + * KDGKBSTATE get state of keyboard shift keys + * + * Written by Scott Michel, scottm@intime.com + * (c) 1994 Scott Michel as part of the Linux iBCS-2 emulator project. + */ + +#ident "%W% %G%" + +#include +#include +#include +#include +#include +#include + + +static struct { + int in; /* only lower 8 bits */ + int out; /* Linux version */ +} trantab[] = { +#ifdef KDDISPTYPE + { 1, KDDISPTYPE }, +#endif + { 2, KDMAPDISP }, + { 3, KDUNMAPDISP }, + { 6, KDGKBMODE }, + { 7, KDSKBMODE }, + { 8, KDMKTONE }, + { 9, KDGETMODE }, + { 10, KDSETMODE }, + { 11, KDADDIO }, + { 12, KDDELIO }, + { 60, KDENABIO }, + { 61, KDDISABIO }, +#ifdef KIOCINFO + { 62, KIOCINFO }, +#endif + { 63, KIOCSOUND }, + { 64, KDGKBTYPE }, + { 65, KDGETLED }, + { 66, KDSETLED }, +}; + + +int +sco_vtkbd_ioctl(int fd, u_int cmd, caddr_t data) +{ + u_int gen = (cmd >> 8) & 0xff; + u_int spec = cmd & 0xff; + int newf, i; + + switch (gen) { + case 'V': + /* + * Could make this translation process table based, but, why + * waste the valuable kernel space ? + */ + + newf = (spec == 1 ? VT_OPENQRY : + (spec == 2 ? VT_SETMODE : + (spec == 3 ? VT_GETMODE : + (spec == 4 ? VT_RELDISP : + (spec == 5 ? VT_ACTIVATE : -1))))); + if (newf != -1) + return sys_ioctl(fd, newf, (long)data); + break; + case 'K': + for (i = 0; i < ARRAY_SIZE(trantab); i++) { + if (spec == trantab[i].in) + return sys_ioctl(fd, trantab[i].out, (long)data); + } + /* FALLTHROUGH */ + } + printk(KERN_ERR "%s: vtkd ioctl 0x%02x unsupported\n", __FILE__, cmd); + return -EINVAL; +} diff -Nru linux-2.6.7/abi/solaris/lfs.c linux-2.6.7-abi/abi/solaris/lfs.c --- linux-2.6.7/abi/solaris/lfs.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/solaris/lfs.c 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,235 @@ +/* + * Solaris Large File Summit support + */ + +#ident "%W% %G%" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + + +int +sol_open64(const char *fname, int flag, int mode) +{ + u_long args[3]; + int error, fd; + struct file *file; + mm_segment_t old_fs; + char *p; + struct sockaddr_un addr; + + fd = sys_open(fname, map_flags(flag, fl_svr4_to_linux) | O_LARGEFILE, mode); + if (fd < 0) + return fd; + + /* Sometimes a program may open a pathname which it expects + * to be a named pipe (or STREAMS named pipe) when the + * Linux domain equivalent is a Unix domain socket. (e.g. + * UnixWare uses a STREAMS named pipe /dev/X/Nserver.0 for + * X :0 but Linux uses a Unix domain socket /tmp/.X11-unix/X0) + * It isn't enough just to make the symlink because you cannot + * open() a socket and read/write it. If we spot the error we can + * switch to socket(), connect() and things will likely work + * as expected however. + */ + file = fget(fd); + if (!file) + return fd; /* Huh?!? */ + if (!S_ISSOCK(file->f_dentry->d_inode->i_mode)) { + fput(file); + return fd; + } + fput(file); + + sys_close(fd); + args[0] = AF_UNIX; + args[1] = SOCK_STREAM; + args[2] = 0; + old_fs = get_fs(); + set_fs(get_ds()); + fd = sys_socketcall(SYS_SOCKET, args); + set_fs(old_fs); + if (fd < 0) + return fd; + + p = getname(fname); + if (IS_ERR(p)) { + sys_close(fd); + return PTR_ERR(p); + } + if (strlen(p) >= UNIX_PATH_MAX) { + putname(p); + sys_close(fd); + return -E2BIG; + } + addr.sun_family = AF_UNIX; + strcpy(addr.sun_path, p); + putname(p); + + args[0] = fd; + args[1] = (int)&addr; + args[2] = sizeof(struct sockaddr_un); + set_fs(get_ds()); + error = sys_socketcall(SYS_CONNECT, args); + set_fs(old_fs); + if (error) { + sys_close(fd); + return error; + } + + return fd; +} + + +struct sol_dirent64 { + unsigned long long d_ino; + unsigned long long d_off; + unsigned short d_reclen; + char d_name[1]; +}; + + +/* If/when the readdir function is changed to read multiple entries + * at once this should be updated to take advantage of the fact. + * + * N.B. For Linux the reclen in a dirent is the number of characters + * in the filename, for SCO (at least) reclen is the total size of + * the particular dirent rounded up to the next multiple of 4. The SCO + * behaviour is faithfully emulated here. + * + * XXXX + * We don't truncate long filenames at all when copying. If we meet a + * long filename and the buffer supplied by the application simply isn't + * big enough to hold it we'll return without filling the buffer (i.e + * return 0). The application will see this as a (premature) end of + * directory. Is there a work around for this at all??? + */ +int +sol_getdents64(int fd, char *buf, int nbytes) +{ + int error, here, posn, reclen; + struct file *file; + struct old_linux_dirent *d; + mm_segment_t old_fs; + + error = verify_area(VERIFY_WRITE, buf, nbytes); + if (error) + return error; + + /* Check the file handle here. This is so we can access the current + * position in the file structure safely without a tedious call + * to sys_lseek that does nothing useful. + */ + file = fget(fd); + if (!file) + return -EBADF; + + d = (struct old_linux_dirent *)__get_free_page(GFP_KERNEL); + if (!d) { + fput(file); + return -ENOMEM; + } + + error = posn = reclen = 0; + while (posn + reclen < nbytes) { + int string_size; + struct sol_dirent64 tmpbuf; + /* Save the current position and get another dirent */ + here = file->f_pos; + old_fs = get_fs(); + set_fs (get_ds()); + error = old_readdir(fd, d, 1); + set_fs(old_fs); + if (error <= 0) + break; + + /* If it'll fit in the buffer save it. + * Otherwise back up so it is read next time around. + * Oh, if we're at the beginning of the buffer there's + * no chance that this entry will ever fit so don't + * copy it and don't back off - we'll just pretend it + * isn't here... + */ + string_size = d->d_namlen + 1; /* chars in d_name + trailing zero */ + reclen = (sizeof(long long) /* d_ino */ + + sizeof(long long) /* d_offset */ + + sizeof(unsigned short) /* d_namlen */ + + string_size + + 3) & (~3); /* align to a 4 byte boundary */ + if (posn + reclen <= nbytes) { + tmpbuf.d_off = file->f_pos; + tmpbuf.d_ino = d->d_ino; + tmpbuf.d_off = file->f_pos; + tmpbuf.d_reclen = reclen; + copy_to_user(buf+posn, &tmpbuf, + sizeof(struct sol_dirent64) -1); + copy_to_user(buf+posn+sizeof(struct sol_dirent64)-2, + &d->d_name, string_size); + posn += reclen; + } else if (posn) { + sys_lseek(fd, here, 0); + } /* else posn == 0 */ + } + + /* Loose the intermediate buffer. */ + free_page((unsigned long)d); + + fput(file); + + /* If we've put something in the buffer return the byte count + * otherwise return the error status. + */ + return ((posn > 0) ? posn : error); +} + + +int +sol_mmap64(u_int addr, u_int len, int prot, int flags, + int fd, u_int off_hi, u_int off) +{ + loff_t off64 = (off | ((loff_t)off_hi << 32)); + u_long pgoff = (off64 >> PAGE_SHIFT); + struct file *file = NULL; + int error; + + if ((off64 + PAGE_ALIGN(len)) < off64) + return -EINVAL; + + if (!(off64 & ~PAGE_MASK)) + return -EINVAL; + + flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); + if (!(flags & MAP_ANONYMOUS)) { + if (!(file = fget(fd))) + return -EBADF; + } + + if (!(flags & 0x80000000) && addr) + flags |= MAP_FIXED; + else + flags &= 0x7fffffff; + + down_write(¤t->mm->mmap_sem); + error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); + up_write(¤t->mm->mmap_sem); + + if (file) + fput(file); + return (error); +} diff -Nru linux-2.6.7/abi/solaris/Makefile linux-2.6.7-abi/abi/solaris/Makefile --- linux-2.6.7/abi/solaris/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/solaris/Makefile 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,7 @@ + +abi-solaris-objs:= lfs.o solarisx86.o socket.o stat.o sysent.o + +obj-$(CONFIG_ABI_SOLARIS) += abi-solaris.o + +abi-solaris.o: $(abi-solaris-objs) + $(LD) -r -o $@ $(abi-solaris-objs) diff -Nru linux-2.6.7/abi/solaris/socket.c linux-2.6.7-abi/abi/solaris/socket.c --- linux-2.6.7/abi/solaris/socket.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/solaris/socket.c 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,496 @@ +/* + * socket.c: Socket syscall emulation for Solaris 2.6+ + * + * Copyright (C) 1998 Jakub Jelinek (jj@ultra.linux.cz) + * + * 1999-08-19 Fixed socketpair code + * Jason Rappleye (rappleye@ccr.buffalo.edu) + */ + +#ident "%W% %G%" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define SOCK_SOL_STREAM 2 +#define SOCK_SOL_DGRAM 1 +#define SOCK_SOL_RAW 4 +#define SOCK_SOL_RDM 5 +#define SOCK_SOL_SEQPACKET 6 + +#define SOL_SO_SNDLOWAT 0x1003 +#define SOL_SO_RCVLOWAT 0x1004 +#define SOL_SO_SNDTIMEO 0x1005 +#define SOL_SO_RCVTIMEO 0x1006 +#define SOL_SO_STATE 0x2000 + +#define SOL_SS_NDELAY 0x040 +#define SOL_SS_NONBLOCK 0x080 +#define SOL_SS_ASYNC 0x100 + +#define SO_STATE 0x000e + + +/* + * 64 bit vs 32bit issues. + */ +#if BITS_PER_LONG == 32 +# define sys32_getsockopt sys_getsockopt +# define A(ptr) ((void *)(ptr)) +# define __kernel_size_t32 __kernel_size_t +#endif + + +int sunos_setsockopt(int fd, int level, int optname, u32 optval, + int optlen) +{ + int tr_opt = optname; + int ret; + + if (level == SOL_IP) { + /* Multicast socketopts (ttl, membership) */ + if (tr_opt >=2 && tr_opt <= 6) + tr_opt += 30; + } + ret = sys_setsockopt(fd, level, tr_opt, (char *)A(optval), optlen); + return ret; +} + +int sunos_getsockopt(int fd, int level, int optname, + u32 optval, u32 optlen) +{ + int tr_opt = optname; + int ret; + + if (level == SOL_IP) { + /* Multicast socketopts (ttl, membership) */ + if (tr_opt >=2 && tr_opt <= 6) + tr_opt += 30; + } + ret = sys32_getsockopt(fd, level, tr_opt, (char *)optval, (int *)optlen); + return ret; +} + +static int socket_check(int family, int type) +{ + if (family != PF_UNIX && family != PF_INET) + return -ESOCKTNOSUPPORT; + switch (type) { + case SOCK_SOL_STREAM: + type = SOCK_STREAM; + break; + case SOCK_SOL_DGRAM: + type = SOCK_DGRAM; + break; + case SOCK_SOL_RAW: + type = SOCK_RAW; + break; + case SOCK_SOL_RDM: + type = SOCK_RDM; + break; + case SOCK_SOL_SEQPACKET: + type = SOCK_SEQPACKET; + break; + default: + return -EINVAL; + } + return type; +} + +static int solaris_to_linux_sockopt(int optname) +{ + switch (optname) { + case SOL_SO_SNDLOWAT: + optname = SO_SNDLOWAT; + break; + case SOL_SO_RCVLOWAT: + optname = SO_RCVLOWAT; + break; + case SOL_SO_SNDTIMEO: + optname = SO_SNDTIMEO; + break; + case SOL_SO_RCVTIMEO: + optname = SO_RCVTIMEO; + break; + case SOL_SO_STATE: + optname = SO_STATE; + break; + }; + + return optname; +} + +int solaris_socket(int family, int type, int protocol) +{ + type = socket_check (family, type); + if (type < 0) + return type; + return sys_socket(family, type, protocol); +} + +int solaris_socketpair(int *usockvec) +{ + /* solaris socketpair really only takes one arg at the syscall + * level, int * usockvec. The libs apparently take care of + * making sure that family==AF_UNIX and type==SOCK_STREAM. The + * pointer we really want ends up residing in the first (and + * supposedly only) argument. + */ + + return sys_socketpair(AF_UNIX, SOCK_STREAM, 0, (int *)usockvec); +} + +int solaris_bind(int fd, struct sockaddr *addr, int addrlen) +{ + return sys_bind(fd, addr, addrlen); +} + +int solaris_setsockopt(int fd, int level, int optname, u32 optval, int optlen) +{ + optname = solaris_to_linux_sockopt(optname); + if (optname < 0) + return optname; + if (optname == SO_STATE) + return 0; + + return sunos_setsockopt(fd, level, optname, optval, optlen); +} + +int solaris_getsockopt(int fd, int level, int optname, u32 optval, u32 optlen) +{ + optname = solaris_to_linux_sockopt(optname); + if (optname < 0) + return optname; + + if (optname == SO_STATE) + optname = SOL_SO_STATE; + + return sunos_getsockopt(fd, level, optname, optval, optlen); +} + +int solaris_connect(int fd, struct sockaddr *addr, int addrlen) +{ + return sys_connect(fd, addr, addrlen); +} + +int solaris_accept(int fd, struct sockaddr *addr, int *addrlen) +{ + return sys_accept(fd, addr, addrlen); +} + +int solaris_listen(int fd, int backlog) +{ + return sys_listen(fd, backlog); +} + +int solaris_shutdown(int fd, int how) +{ + return sys_shutdown(fd, how); +} + +#define MSG_SOL_OOB 0x1 +#define MSG_SOL_PEEK 0x2 +#define MSG_SOL_DONTROUTE 0x4 +#define MSG_SOL_EOR 0x8 +#define MSG_SOL_CTRUNC 0x10 +#define MSG_SOL_TRUNC 0x20 +#define MSG_SOL_WAITALL 0x40 +#define MSG_SOL_DONTWAIT 0x80 + +static int solaris_to_linux_msgflags(int flags) +{ + int fl = flags & (MSG_OOB|MSG_PEEK|MSG_DONTROUTE); + + if (flags & MSG_SOL_EOR) fl |= MSG_EOR; + if (flags & MSG_SOL_CTRUNC) fl |= MSG_CTRUNC; + if (flags & MSG_SOL_TRUNC) fl |= MSG_TRUNC; + if (flags & MSG_SOL_WAITALL) fl |= MSG_WAITALL; + if (flags & MSG_SOL_DONTWAIT) fl |= MSG_DONTWAIT; + return fl; +} + +static int linux_to_solaris_msgflags(int flags) +{ + int fl = flags & (MSG_OOB|MSG_PEEK|MSG_DONTROUTE); + + if (flags & MSG_EOR) fl |= MSG_SOL_EOR; + if (flags & MSG_CTRUNC) fl |= MSG_SOL_CTRUNC; + if (flags & MSG_TRUNC) fl |= MSG_SOL_TRUNC; + if (flags & MSG_WAITALL) fl |= MSG_SOL_WAITALL; + if (flags & MSG_DONTWAIT) fl |= MSG_SOL_DONTWAIT; + return fl; +} + +int solaris_recvfrom(int s, char *buf, int len, int flags, u32 from, u32 fromlen) +{ + return sys_recvfrom(s, buf, len, solaris_to_linux_msgflags(flags), (struct sockaddr *)A(from), (int *)A(fromlen)); +} + +int solaris_recv(int s, char *buf, int len, int flags) +{ + return sys_recvfrom(s, buf, len, solaris_to_linux_msgflags(flags), NULL, NULL); +} + +int solaris_sendto(int s, char *buf, int len, int flags, u32 to, u32 tolen) +{ + return sys_sendto(s, buf, len, solaris_to_linux_msgflags(flags), (struct sockaddr *)A(to), (int)A(tolen)); +} + +int solaris_send(int s, char *buf, int len, int flags) +{ + return sys_sendto(s, buf, len, solaris_to_linux_msgflags(flags), NULL, 0); +} + +int solaris_getpeername(int fd, struct sockaddr *addr, int *addrlen) +{ + return sys_getpeername(fd, addr, addrlen); +} + +int solaris_getsockname(int fd, struct sockaddr *addr, int *addrlen) +{ + return sys_getsockname(fd, addr, addrlen); +} + +/* XXX This really belongs in some header file... -DaveM */ +#define MAX_SOCK_ADDR 128 /* 108 for Unix domain - + 16 for IP, 16 for IPX, + 24 for IPv6, + about 80 for AX.25 */ + +struct sol_nmsghdr { + u32 msg_name; + int msg_namelen; + u32 msg_iov; + u32 msg_iovlen; + u32 msg_control; + u32 msg_controllen; + u32 msg_flags; +}; + +struct sol_cmsghdr { + u32 cmsg_len; + int cmsg_level; + int cmsg_type; + unsigned char cmsg_data[0]; +}; + +struct iovec32 { + u32 iov_base; + u32 iov_len; +}; + +static inline int iov_from_user32_to_kern(struct iovec *kiov, + struct iovec32 *uiov32, + int niov) +{ + int tot_len = 0; + + while(niov > 0) { + u32 len, buf; + + if(get_user(len, &uiov32->iov_len) || + get_user(buf, &uiov32->iov_base)) { + tot_len = -EFAULT; + break; + } + tot_len += len; + kiov->iov_base = (void *)A(buf); + kiov->iov_len = (__kernel_size_t) len; + uiov32++; + kiov++; + niov--; + } + return tot_len; +} + +static inline int msghdr_from_user32_to_kern(struct msghdr *kmsg, + struct sol_nmsghdr *umsg) +{ + u32 tmp1, tmp2, tmp3; + int err; + + err = get_user(tmp1, &umsg->msg_name); + err |= __get_user(tmp2, &umsg->msg_iov); + err |= __get_user(tmp3, &umsg->msg_control); + if (err) + return -EFAULT; + + kmsg->msg_name = (void *)A(tmp1); + kmsg->msg_iov = (struct iovec *)A(tmp2); + kmsg->msg_control = (void *)A(tmp3); + + err = get_user(kmsg->msg_namelen, &umsg->msg_namelen); + err |= get_user(kmsg->msg_controllen, &umsg->msg_controllen); + err |= get_user(kmsg->msg_flags, &umsg->msg_flags); + + kmsg->msg_flags = solaris_to_linux_msgflags(kmsg->msg_flags); + + return err; +} + +/* I've named the args so it is easy to tell whose space the pointers are in. */ +static int verify_iovec32(struct msghdr *kern_msg, struct iovec *kern_iov, + char *kern_address, int mode) +{ + int tot_len; + + if(kern_msg->msg_namelen) { + if(mode==VERIFY_READ) { + int err = move_addr_to_kernel(kern_msg->msg_name, + kern_msg->msg_namelen, + kern_address); + if(err < 0) + return err; + } + kern_msg->msg_name = kern_address; + } else + kern_msg->msg_name = NULL; + + if(kern_msg->msg_iovlen > UIO_FASTIOV) { + kern_iov = kmalloc(kern_msg->msg_iovlen * sizeof(struct iovec), + GFP_KERNEL); + if(!kern_iov) + return -ENOMEM; + } + + tot_len = iov_from_user32_to_kern(kern_iov, + (struct iovec32 *)kern_msg->msg_iov, + kern_msg->msg_iovlen); + if(tot_len >= 0) + kern_msg->msg_iov = kern_iov; + else if(kern_msg->msg_iovlen > UIO_FASTIOV) + kfree(kern_iov); + + return tot_len; +} + +int solaris_sendmsg(int fd, struct sol_nmsghdr *user_msg, unsigned user_flags) +{ + struct socket *sock; + char address[MAX_SOCK_ADDR]; + struct iovec iov[UIO_FASTIOV]; + unsigned char ctl[sizeof(struct cmsghdr) + 20]; + unsigned char *ctl_buf = ctl; + struct msghdr kern_msg; + int err, total_len; + + if(msghdr_from_user32_to_kern(&kern_msg, user_msg)) + return -EFAULT; + if(kern_msg.msg_iovlen > UIO_MAXIOV) + return -EINVAL; + err = verify_iovec32(&kern_msg, iov, address, VERIFY_READ); + if (err < 0) + goto out; + total_len = err; + + if(kern_msg.msg_controllen) { + struct sol_cmsghdr *ucmsg = (struct sol_cmsghdr *)kern_msg.msg_control; + unsigned long *kcmsg; + __kernel_size_t32 cmlen; + + if(kern_msg.msg_controllen > sizeof(ctl) && + kern_msg.msg_controllen <= 256) { + err = -ENOBUFS; + ctl_buf = kmalloc(kern_msg.msg_controllen, GFP_KERNEL); + if(!ctl_buf) + goto out_freeiov; + } + __get_user(cmlen, &ucmsg->cmsg_len); + kcmsg = (unsigned long *) ctl_buf; + *kcmsg++ = (unsigned long)cmlen; + err = -EFAULT; + if(copy_from_user(kcmsg, &ucmsg->cmsg_level, + kern_msg.msg_controllen - sizeof(__kernel_size_t32))) + goto out_freectl; + kern_msg.msg_control = ctl_buf; + } + kern_msg.msg_flags = solaris_to_linux_msgflags(user_flags); + + lock_kernel(); + sock = sockfd_lookup(fd, &err); + if (sock != NULL) { + if (sock->file->f_flags & O_NONBLOCK) + kern_msg.msg_flags |= MSG_DONTWAIT; + err = sock_sendmsg(sock, &kern_msg, total_len); + sockfd_put(sock); + } + unlock_kernel(); + +out_freectl: + /* N.B. Use kfree here, as kern_msg.msg_controllen might change? */ + if(ctl_buf != ctl) + kfree(ctl_buf); +out_freeiov: + if(kern_msg.msg_iov != iov) + kfree(kern_msg.msg_iov); +out: + return err; +} + +int solaris_recvmsg(int fd, struct sol_nmsghdr *user_msg, unsigned user_flags) +{ + struct iovec iovstack[UIO_FASTIOV]; + struct msghdr kern_msg; + char addr[MAX_SOCK_ADDR]; + struct socket *sock; + struct iovec *iov = iovstack; + struct sockaddr *uaddr; + int *uaddr_len; + unsigned long cmsg_ptr; + int err, total_len, len = 0; + + if(msghdr_from_user32_to_kern(&kern_msg, user_msg)) + return -EFAULT; + if(kern_msg.msg_iovlen > UIO_MAXIOV) + return -EINVAL; + + uaddr = kern_msg.msg_name; + uaddr_len = &user_msg->msg_namelen; + err = verify_iovec32(&kern_msg, iov, addr, VERIFY_WRITE); + if (err < 0) + goto out; + total_len = err; + + cmsg_ptr = (unsigned long) kern_msg.msg_control; + kern_msg.msg_flags = 0; + + lock_kernel(); + sock = sockfd_lookup(fd, &err); + if (sock != NULL) { + if (sock->file->f_flags & O_NONBLOCK) + user_flags |= MSG_DONTWAIT; + err = sock_recvmsg(sock, &kern_msg, total_len, user_flags); + if(err >= 0) + len = err; + sockfd_put(sock); + } + unlock_kernel(); + + if(uaddr != NULL && err >= 0) + err = move_addr_to_user(addr, kern_msg.msg_namelen, uaddr, uaddr_len); + if(err >= 0) { + err = __put_user(linux_to_solaris_msgflags(kern_msg.msg_flags), &user_msg->msg_flags); + if(!err) { + /* XXX Convert cmsg back into userspace 32-bit format... */ + err = __put_user((unsigned long)kern_msg.msg_control - cmsg_ptr, + &user_msg->msg_controllen); + } + } + + if(kern_msg.msg_iov != iov) + kfree(kern_msg.msg_iov); +out: + if(err < 0) + return err; + return len; +} diff -Nru linux-2.6.7/abi/solaris/solarisx86.c linux-2.6.7-abi/abi/solaris/solarisx86.c --- linux-2.6.7/abi/solaris/solarisx86.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/solaris/solarisx86.c 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,84 @@ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + +int sol_llseek(struct pt_regs * regs) +{ + unsigned int fd; + unsigned long offset_high, offset_low; + unsigned origin; + long long res; + unsigned int rvalue; + mm_segment_t old_fs; + struct inode *inode; + struct file *file; + get_user(fd, ((unsigned int *)regs->esp)+1); + get_user(offset_low, ((unsigned long *)regs->esp)+2); + get_user(offset_high, ((unsigned long *)regs->esp)+3); + get_user(origin, ((unsigned int *)regs->esp)+4); + + old_fs = get_fs(); + set_fs(get_ds()); + rvalue = sys_llseek(fd,offset_high,offset_low,&res,origin); + set_fs(old_fs); + + if ( rvalue < -ENOIOCTLCMD) { + regs->edx = (res >> 32); + rvalue = (res & 0xffffffff); + } + else if (rvalue == -ESPIPE) { + /* Solaris allows you to seek on a pipe */ + file = fget(fd); + if (file) { + inode = file->f_dentry->d_inode; + if (inode && (S_ISCHR(inode->i_mode) + || S_ISBLK(inode->i_mode))) { + rvalue = 0; + regs->edx = 0; + } + fput(file); + } + } + + return rvalue; +} + +int sol_memcntl(unsigned addr, unsigned len, int cmd, unsigned arg, + int attr, int mask) +{ + // printk("ibcs_memcntl being ignored\n"); + return 0; +} + + +enum { + GETACL = 1, + SETACL = 2, + GETACLCNT = 3 +}; + +int sol_acl(char *pathp, int cmd, int nentries, void *aclbufp) +{ + switch (cmd) { + case GETACLCNT: + return 0; + + case GETACL: + return -EIO; + + case SETACL: + return -EPERM; + + default: + return -EINVAL; + } +} diff -Nru linux-2.6.7/abi/solaris/stat.c linux-2.6.7-abi/abi/solaris/stat.c --- linux-2.6.7/abi/solaris/stat.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/solaris/stat.c 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2001 Christoph Hellwig. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * aint32_t with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ident "%W% %G%" + +/* + * Solaris 2 stat64 & friends support. + */ +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + + +int +report_sol_stat64(struct kstat *stp, struct sol_stat64 *bufp) +{ + struct sol_stat64 buf; + + memset(&buf, 0, sizeof(struct sol_stat64)); + + + buf.st_dev = linux_to_sol_dev_t(stp->dev); + buf.st_ino = linux_to_sol_ino_t(stp->ino); + buf.st_mode = stp->mode; + buf.st_nlink = stp->nlink; + buf.st_uid = linux_to_sol_uid_t(stp->uid); + buf.st_gid = linux_to_sol_gid_t(stp->gid); + buf.st_rdev = linux_to_sol_dev_t(stp->rdev); + buf.st_size = stp->size; + + buf.st_atime = stp->atime.tv_sec; + buf.st_mtime = stp->mtime.tv_sec; + buf.st_ctime = stp->ctime.tv_sec; + + buf.st_blksize = stp->blksize; + buf.st_blocks = stp->blocks; + + strcpy(buf.st_fstype, "ext2"); + + if (copy_to_user(bufp, &buf, sizeof(struct sol_stat64))) + return -EFAULT; + return 0; +} + +int +sol_stat64(char *filename, struct sol_stat64 *bufp) +{ + struct kstat st; + int error; + + error = vfs_stat(filename, &st); + if (!error) + error = report_sol_stat64(&st, bufp); + return error; +} + +int +sol_lstat64(char *filename, struct sol_stat64 *bufp) +{ + struct kstat st; + int error; + + error = vfs_lstat(filename, &st); + if (!error) + error = report_sol_stat64(&st, bufp); + return error; +} + +int +sol_fstat64(int fd, struct sol_stat64 *bufp) +{ + struct kstat st; + int error; + + error = vfs_fstat(fd, &st); + if (!error) + error = report_sol_stat64(&st, bufp); + return error; +} diff -Nru linux-2.6.7/abi/solaris/sysent.c linux-2.6.7-abi/abi/solaris/sysent.c --- linux-2.6.7/abi/solaris/sysent.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/solaris/sysent.c 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,461 @@ +/* + * Copyright (c) 2001 Christoph Hellwig. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ident "%W% %G%" + +/* + * Solaris sysent and error tables. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include +#include + +/* kernel module specifications */ +#ifndef EXPORT_NO_SYMBOLS +#define EXPORT_NO_SYMBOLS +#endif + +MODULE_DESCRIPTION("Solaris personality"); +MODULE_AUTHOR("Christoph Hellwig, partially taken from iBCS"); +MODULE_LICENSE("GPL"); + +EXPORT_NO_SYMBOLS; + + +/* XXX kill this one */ +#define ITR(trace, name, args) ,name,args + + +/* + * We could remove some of the long identity mapped runs but at the + * expense of extra comparisons for each mapping at run time... + */ +static u_char solaris_err_table[] = { +/* 0 - 9 */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, +/* 10 - 19 */ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, +/* 20 - 29 */ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, +/* 30 - 39 */ 30, 31, 32, 33, 34, 45, 78, 46, 89, 93, +/* 40 - 49 */ 90, 90, 35, 36, 37, 38, 39, 40, 41, 42, +/* 50 - 59 */ 43, 44, 50, 51, 52, 53, 54, 55, 56, 57, +/* 60 - 69 */ 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, +/* 70 - 79 */ 70, 71, 74, 76, 77, 79, 80, 81, 82, 83, +/* 80 - 89 */ 84, 85, 86, 87, 88, 91, 92, 94, 95, 96, +/* 90 - 99 */ 97, 98, 99, 120, 121, 122, 123, 124, 125, 126, +/* 100 - 109 */ 127, 128, 129, 130, 131, 132, 133, 134, 143, 144, +/* 110 - 119 */ 145, 146, 147, 148, 149, 150, 22, 135, 137, 138, +/* 120 - 122 */ 139, 140, 28 +}; + +/* + * Map Linux RESTART* values (512,513,514) to EINTR + */ +static u_char lnx_err_table[] = { +/* 512 - 514 */ EINTR, EINTR, EINTR +}; + +struct map_segment solaris_err_map[] = { + { 0, 0+sizeof(solaris_err_table)-1, solaris_err_table }, + { 512, 512+sizeof(lnx_err_table)-1, lnx_err_table }, + { -1 } +}; + +static long linux_to_solaris_signals[NSIGNALS+1] = { +/* 0 - 3 */ 0, IBCS_SIGHUP, IBCS_SIGINT, IBCS_SIGQUIT, +/* 4 - 7 */ IBCS_SIGILL, IBCS_SIGTRAP, IBCS_SIGABRT, -1, +/* 8 - 11 */ IBCS_SIGFPE, IBCS_SIGKILL, IBCS_SIGUSR1, IBCS_SIGSEGV, +/* 12 - 15 */ IBCS_SIGUSR2, IBCS_SIGPIPE, IBCS_SIGALRM, IBCS_SIGTERM, +/* 16 - 19 */ IBCS_SIGSEGV, IBCS_SIGCHLD, IBCS_SIGCONT, IBCS_SIGSTOP, +/* 20 - 23 */ IBCS_SIGTSTP, IBCS_SIGTTIN, IBCS_SIGTTOU, IBCS_SIGURG, +/* 24 - 27 */ IBCS_SIGGXCPU, IBCS_SIGGXFSZ, IBCS_SIGVTALRM, IBCS_SIGPROF, +/* 28 - 31 */ IBCS_SIGWINCH, IBCS_SIGIO, IBCS_SIGPWR, -1, +/* 32 */ -1 +}; + +static long solaris_to_linux_signals[NSIGNALS+1] = { +/* 0 - 3 */ 0, SIGHUP, SIGINT, SIGQUIT, +/* 4 - 7 */ SIGILL, SIGTRAP, SIGIOT, SIGUNUSED, +/* 8 - 11 */ SIGFPE, SIGKILL, SIGUNUSED, SIGSEGV, +/* 12 - 15 */ SIGUNUSED, SIGPIPE, SIGALRM, SIGTERM, +/* 16 - 19 */ SIGUSR1, SIGUSR2, SIGCHLD, SIGPWR, +/* 20 - 23 */ SIGWINCH, SIGURG, SIGPOLL, SIGSTOP, +/* 24 - 27 */ SIGTSTP, SIGCONT, SIGTTIN, SIGTTOU, +/* 28 - 31 */ SIGVTALRM, SIGPROF, SIGXCPU, SIGXFSZ, +/* 32 */ -1 +}; + +static char solaris_socktype[] = { + SOCK_STREAM, + SOCK_DGRAM, + 0, + SOCK_RAW, + SOCK_RDM, + SOCK_SEQPACKET +}; + +static struct map_segment solaris_socktype_map[] = { + { 1, 6, solaris_socktype }, + { -1 } +}; + +static struct map_segment solaris_sockopt_map[] = { + { 0x0001, 0x0001, (char *)SO_DEBUG }, + { 0x0002, 0x0002, (char *)__SO_ACCEPTCON }, + { 0x0004, 0x0004, (char *)SO_REUSEADDR }, + { 0x0008, 0x0008, (char *)SO_KEEPALIVE }, + { 0x0010, 0x0010, (char *)SO_DONTROUTE }, + { 0x0020, 0x0020, (char *)SO_BROADCAST }, + { 0x0040, 0x0040, (char *)SO_USELOOPBACK }, + { 0x0080, 0x0080, (char *)SO_LINGER }, + { 0x0100, 0x0100, (char *)SO_OOBINLINE }, + { 0x0200, 0x0200, (char *)SO_ORDREL }, + { 0x0400, 0x0400, (char *)SO_IMASOCKET }, + { 0x1001, 0x1001, (char *)SO_SNDBUF }, + { 0x1002, 0x1002, (char *)SO_RCVBUF }, + { 0x1003, 0x1003, (char *)SO_SNDLOWAT }, + { 0x1004, 0x1004, (char *)SO_RCVLOWAT }, + { 0x1005, 0x1005, (char *)SO_SNDTIMEO }, + { 0x1006, 0x1006, (char *)SO_RCVTIMEO }, + { 0x1007, 0x1007, (char *)SO_ERROR }, + { 0x1008, 0x1008, (char *)SO_TYPE }, + { 0x1009, 0x1009, (char *)SO_PROTOTYPE }, + { -1 } +}; + +static struct map_segment solaris_af_map[] = { + { 0, 2, NULL }, + { -1 } +}; + + +static struct sysent solaris_syscall_table[] = { + { abi_syscall, Fast ITR(0, "syscall", "") }, /* 0 */ + { sys_exit, 1 ITR(0, "exit", "d") }, /* 1 */ + { abi_fork, Spl ITR(0, "fork", "") }, /* 2 */ + { abi_read, 3 ITR(0, "read", "dpd") }, /* 3 */ + { sys_write, 3 ITR(0, "write", "dpd") }, /* 4 */ + { svr4_open, 3 ITR(0, "open", "soo") }, /* 5 */ + { sys_close, 1 ITR(0, "close", "d") }, /* 6 */ + { abi_wait, Spl ITR(0, "wait", "xxx") }, /* 7 */ + { sys_creat, 2 ITR(0, "creat", "so") }, /* 8 */ + { sys_link, 2 ITR(0, "link", "ss") }, /* 9 */ + { sys_unlink, 1 ITR(0, "unlink", "s") }, /* 10 */ + { abi_exec, Spl ITR(0, "exec", "sxx") }, /* 11 */ + { sys_chdir, 1 ITR(0, "chdir", "s") }, /* 12 */ + { abi_time, 0 ITR(0, "time", "") }, /* 13 */ + { svr4_mknod, 3 ITR(0, "mknod", "soo") }, /* 14 */ + { sys_chmod, 2 ITR(0, "chmod", "so") }, /* 15 */ + { sys_chown, 3 ITR(0, "chown", "sdd") }, /* 16 */ + { abi_brk, 1 ITR(0, "brk/break", "x") }, /* 17 */ + { svr4_stat, 2 ITR(0, "stat", "sp") }, /* 18 */ + { sys_lseek, 3 ITR(0, "seek/lseek", "ddd") }, /* 19 */ + { abi_getpid, Spl ITR(0, "getpid", "") }, /* 20 */ + { 0, Ukn ITR(1, "mount", "") }, /* 21 */ + { sys_umount, 1 ITR(0, "umount", "s") }, /* 22 */ + { sys_setuid, 1 ITR(0, "setuid", "d") }, /* 23 */ + { abi_getuid, Spl ITR(0, "getuid", "") }, /* 24 */ + { sys_stime, 1 ITR(0, "stime", "d") }, /* 25 */ + { 0, Ukn ITR(0, "ptrace", "") }, /* 26 */ + { sys_alarm, 1 ITR(0, "alarm", "d") }, /* 27 */ + { svr4_fstat, 2 ITR(0, "fstat", "dp") }, /* 28 */ + { sys_pause, 0 ITR(0, "pause", "") }, /* 29 */ + { sys_utime, 2 ITR(0, "utime", "xx") }, /* 30 */ + { 0, Ukn ITR(0, "stty", "") }, /* 31 */ + { 0, Ukn ITR(1, "gtty", "") }, /* 32 */ + { sys_access, 2 ITR(0, "access", "so") }, /* 33 */ + { sys_nice, 1 ITR(0, "nice", "d") }, /* 34 */ + { svr4_statfs, 4 ITR(0, "statfs", "spdd") }, /* 35 */ + { sys_sync, 0 ITR(0, "sync", "") }, /* 36 */ + { abi_kill, 2 ITR(0, "kill", "dd") }, /* 37 */ + { svr4_fstatfs, 4 ITR(0, "fstatfs", "dpdd") }, /* 38 */ + { abi_procids, Spl ITR(0, "procids", "d") }, /* 39 */ + { 0, Ukn ITR(0, "cxenix", "") }, /* 40 */ + { sys_dup, 1 ITR(0, "dup", "d") }, /* 41 */ + { abi_pipe, Spl ITR(0, "pipe", "") }, /* 42 */ + { sys_times, 1 ITR(0, "times", "p") }, /* 43 */ + { 0, 0 ITR(0, "prof", "") }, /* 44 */ + { 0, Ukn ITR(1, "lock/plock", "") }, /* 45 */ + { sys_setgid, 1 ITR(0, "setgid", "d") }, /* 46 */ + { abi_getgid, Spl ITR(0, "getgid", "") }, /* 47 */ + { abi_sigfunc, Fast ITR(0, "sigfunc", "xxx") }, /* 48 */ + { svr4_msgsys, Spl ITR(0, "msgsys", "dxddd")}, /* 49 */ + { svr4_sysi86, 3 ITR(0, "sysi86/sys3b", "d") }, /* 50 */ + { sys_acct, 1 ITR(0, "acct/sysacct", "x") }, /* 51 */ + { svr4_shmsys, Fast ITR(0, "shmsys", "ddxo")}, /* 52 */ + { svr4_semsys, Spl ITR(0, "semsys", "dddx")}, /* 53 */ + { svr4_ioctl, Spl ITR(0, "ioctl", "dxx") }, /* 54 */ + { 0, 3 ITR(0, "uadmin", "xxx") }, /* 55 */ + { 0, Ukn ITR(1, "?", "") }, /* 56 */ + { v7_utsname, 1 ITR(0, "utsys", "x") }, /* 57 */ + { sys_fsync, 1 ITR(0, "fsync", "d") }, /* 58 */ + { abi_exec, Spl ITR(0, "execv", "spp") }, /* 59 */ + { sys_umask, 1 ITR(0, "umask", "o") }, /* 60 */ + { sys_chroot, 1 ITR(0, "chroot", "s") }, /* 61 */ + { svr4_fcntl, 3 ITR(0, "fcntl", "dxx") }, /* 62 */ + { svr4_ulimit, 2 ITR(0, "ulimit", "xx") }, /* 63 */ + { 0, Ukn ITR(1, "?", "") }, /* 64 */ + { 0, Ukn ITR(1, "?", "") }, /* 65 */ + { 0, Ukn ITR(1, "?", "") }, /* 66 */ + { 0, Ukn ITR(1, "?", "") }, /* 67 */ + { 0, Ukn ITR(1, "?", "") }, /* 68 */ + { 0, Ukn ITR(1, "?", "") }, /* 69 */ + { 0, Ukn ITR(1, "advfs", "") }, /* 70 */ + { 0, Ukn ITR(1, "unadvfs", "") }, /* 71 */ + { 0, Ukn ITR(1, "rmount", "") }, /* 72 */ + { 0, Ukn ITR(1, "rumount", "") }, /* 73 */ + { 0, Ukn ITR(1, "rfstart", "") }, /* 74 */ + { 0, Ukn ITR(1, "?", "") }, /* 75 */ + { 0, Ukn ITR(1, "rdebug", "") }, /* 76 */ + { 0, Ukn ITR(1, "rfstop", "") }, /* 77 */ + { 0, Ukn ITR(1, "rfsys", "") }, /* 78 */ + { sys_rmdir, 1 ITR(0, "rmdir", "s") }, /* 79 */ + { abi_mkdir, 2 ITR(0, "mkdir", "so") }, /* 80 */ + { svr4_getdents, 3 ITR(0, "getdents", "dxd") }, /* 81 */ + { 0, Ukn ITR(1, "libattach", "") }, /* 82 */ + { 0, Ukn ITR(1, "libdetach", "") }, /* 83 */ + { svr4_sysfs, 3 ITR(0, "sysfs", "dxx") }, /* 84 */ + { svr4_getmsg, Spl ITR(0, "getmsg", "dxxx") }, /* 85 */ + { svr4_putmsg, Spl ITR(0, "putmsg", "dxxd") }, /* 86 */ + { sys_poll, 3 ITR(0, "poll", "xdd") }, /* 87 */ + { svr4_lstat, 2 ITR(0, "lstat", "sp") }, /* 88 */ + { sys_symlink, 2 ITR(0, "symlink", "ss") }, /* 89 */ + { sys_readlink, 3 ITR(0, "readlink", "spd") }, /* 90 */ + { sys_setgroups, 2 ITR(0, "setgroups", "dp") }, /* 91 */ + { sys_getgroups, 2 ITR(0, "getgroups", "dp") }, /* 92 */ + { sys_fchmod, 2 ITR(0, "fchmod", "do") }, /* 93 */ + { sys_fchown, 3 ITR(0, "fchown", "ddd") }, /* 94 */ + { abi_sigprocmask, 3 ITR(0, "sigprocmask", "dxx") }, /* 95 */ + { abi_sigsuspend, Spl ITR(0, "sigsuspend", "x") }, /* 96 */ + { 0, 2 ITR(1, "sigaltstack", "xx") }, /* 97 */ + { abi_sigaction, 3 ITR(0, "sigaction", "dxx") }, /* 98 */ + { svr4_sigpending, 2 ITR(1, "sigpending", "dp") }, /* 99 */ + { svr4_context, Spl ITR(0, "context", "") }, /* 100 */ + { 0, Ukn ITR(1, "evsys", "") }, /* 101 */ + { 0, Ukn ITR(1, "evtrapret", "") }, /* 102 */ + { svr4_statvfs, 2 ITR(0, "statvfs", "sp") }, /* 103 */ + { svr4_fstatvfs, 2 ITR(0, "fstatvfs", "dp") }, /* 104 */ + { 0, Ukn ITR(0, "sysisc", "") }, /* 105 */ + { 0, Ukn ITR(1, "nfssys", "") }, /* 106 */ + { 0, 4 ITR(0, "waitid", "ddxd") }, /* 107 */ + { 0, 3 ITR(1, "sigsendsys", "ddd") }, /* 108 */ + { svr4_hrtsys, Spl ITR(0, "hrtsys", "xxx") }, /* 109 */ + { 0, 3 ITR(1, "acancel", "dxd") }, /* 110 */ + { 0, Ukn ITR(1, "async", "") }, /* 111 */ + { 0, Ukn ITR(1, "priocntlsys", "") }, /* 112 */ + { svr4_pathconf, 2 ITR(1, "pathconf", "sd") }, /* 113 */ + { 0, 3 ITR(1, "mincore", "xdx") }, /* 114 */ + { svr4_mmap, 6 ITR(0, "mmap", "xxxxdx") },/* 115 */ + { sys_mprotect, 3 ITR(0, "mprotect", "xdx") },/* 116 */ + { sys_munmap, 2 ITR(0, "munmap", "xd") },/* 117 */ + { svr4_fpathconf, 2 ITR(1, "fpathconf", "dd") }, /* 118 */ + { abi_fork, Spl ITR(0, "vfork", "") }, /* 119 */ + { sys_fchdir, 1 ITR(0, "fchdir", "d") }, /* 120 */ + { sys_readv, 3 ITR(0, "readv", "dxd") }, /* 121 */ + { sys_writev, 3 ITR(0, "writev", "dxd") }, /* 122 */ + { svr4_xstat, 3 ITR(0, "xstat", "dsx") }, /* 123 */ + { svr4_lxstat, 3 ITR(0, "lxstat", "dsx") }, /* 124 */ + { svr4_fxstat, 3 ITR(0, "fxstat", "ddx") }, /* 125 */ + { svr4_xmknod, 4 ITR(0, "xmknod", "dsox")}, /* 126 */ + { 0, Spl ITR(0, "syslocal", "d") }, /* 127 */ + { svr4_getrlimit, 2 ITR(0, "setrlimit", "dx") }, /* 128 */ + { svr4_setrlimit, 2 ITR(0, "getrlimit", "dx") }, /* 129 */ + { 0, 3 ITR(1, "lchown", "sdd") }, /* 130 */ + { 0, Ukn ITR(1, "memcntl", "") }, /* 131 */ +#ifdef CONFIG_ABI_XTI + { svr4_getpmsg, 5 ITR(0, "getpmsg", "dxxxx")}, /* 132 */ + { svr4_putpmsg, 5 ITR(0, "putpmsg", "dxxdd")}, /* 133 */ +#else + { 0, 5 ITR(0, "getpmsg", "dxxxx")}, /* 132 */ + { 0, 5 ITR(0, "putpmsg", "dxxdd")}, /* 133 */ +#endif + { sys_rename, 2 ITR(0, "rename", "ss") }, /* 134 */ + { abi_utsname, 1 ITR(0, "uname", "x") }, /* 135 */ + { svr4_setegid, 1 ITR(1, "setegid", "d") }, /* 136 */ + { svr4_sysconfig, 1 ITR(0, "sysconfig", "d") }, /* 137 */ + { 0, Ukn ITR(1, "adjtime", "") }, /* 138 */ + { svr4_sysinfo, 3 ITR(0, "systeminfo", "dsd") }, /* 139 */ + { socksys_syscall, 1 ITR(0, "socksys_syscall","x") }, /* 140 */ + { svr4_seteuid, 1 ITR(1, "seteuid", "d") }, /* 141 */ + { 0, Ukn ITR(1, "vtrace", "") }, /* 142 */ + { 0, Ukn ITR(1, "fork1", "") }, /* 143 */ + { 0, Ukn ITR(1, "sigtimedwait", "") }, /* 144 */ + { 0, Ukn ITR(1, "lwp_info", "") }, /* 145 */ + { 0, Ukn ITR(1, "yield", "") }, /* 146 */ + { 0, Ukn ITR(1, "lwp_sema_wait", "") }, /* 147 */ + { 0, Ukn ITR(1, "lwp_sema_post", "") }, /* 148 */ + { 0, Ukn ITR(1, "lwp_sema_trywait","") }, /* 149 */ + { 0, Ukn ITR(1, "?", "") }, /* 150 */ + { 0, Ukn ITR(1, "?", "") }, /* 151 */ + { 0, Ukn ITR(1, "modctl", "") }, /* 152 */ + { 0, Ukn ITR(1, "fchroot", "") }, /* 153 */ + { 0, Ukn ITR(1, "utimes", "") }, /* 154 */ + { 0, Ukn ITR(1, "vhangup", "") }, /* 155 */ + { sys_gettimeofday, 2 ITR(0, "gettimeofday", "xx") }, /* 156 */ + { sys_getitimer, 2 ITR(0, "getitimer", "dx") }, /* 157 */ + { sys_setitimer, 3 ITR(0, "setitimer", "dxx") }, /* 158 */ + { 0, Ukn ITR(1, "lwp_create", "") }, /* 159 */ + { 0, Ukn ITR(1, "lwp_exit", "") }, /* 160 */ + { 0, Ukn ITR(1, "lwp_suspend", "") }, /* 161 */ + { 0, Ukn ITR(1, "lwp_continue", "") }, /* 162 */ + { 0, Ukn ITR(1, "lwp_kill", "") }, /* 163 */ + { 0, Ukn ITR(1, "lwp_self", "") }, /* 164 */ + { 0, Ukn ITR(1, "lwp_setprivate","") }, /* 165 */ + { 0, Ukn ITR(1, "lwp_getprivate","") }, /* 166 */ + { 0, Ukn ITR(1, "lwp_wait", "") }, /* 167 */ + { 0, Ukn ITR(1, "lwp_mutex_unlock","") }, /* 168 */ + { 0, Ukn ITR(1, "lwp_mutex_lock","") }, /* 169 */ + { 0, Ukn ITR(1, "lwp_cond_wait", "") }, /* 170 */ + { 0, Ukn ITR(1, "lwp_cond_signal","") }, /* 171 */ + { 0, Ukn ITR(1, "lwp_cond_broadcast","") }, /* 172 */ + { sys_pread64, -4 ITR(1, "pread", "dpdd") }, /* 173 */ + { sys_pwrite64, -4 ITR(1, "pwrite", "dpdd") }, /* 174 */ + { sol_llseek, Spl ITR(1, "llseek", "dxxd") }, /* 175 */ + { 0, Ukn ITR(1, "inst_sync", "") }, /* 176 */ + { 0, Ukn ITR(1, "?", "") }, /* 177 */ + { 0, Ukn ITR(1, "kaio", "") }, /* 178 */ + { 0, Ukn ITR(1, "?", "") }, /* 179 */ + { 0, Ukn ITR(1, "?", "") }, /* 180 */ + { 0, Ukn ITR(1, "?", "") }, /* 181 */ + { 0, Ukn ITR(1, "?", "") }, /* 182 */ + { 0, Ukn ITR(1, "?", "") }, /* 183 */ + { 0, Ukn ITR(1, "tsolsys", "") }, /* 184 */ + { sol_acl, 4 ITR(1, "acl", "sddp") }, /* 185 */ + { 0, Ukn ITR(1, "auditsys", "") }, /* 186 */ + { 0, Ukn ITR(1, "processor_bind","") }, /* 187 */ + { 0, Ukn ITR(1, "processor_info","") }, /* 188 */ + { 0, Ukn ITR(1, "p_online", "") }, /* 189 */ + { 0, Ukn ITR(1, "sigqueue", "") }, /* 190 */ + { 0, Ukn ITR(1, "clock_gettime", "") }, /* 191 */ + { 0, Ukn ITR(1, "clock_settime", "") }, /* 192 */ + { 0, Ukn ITR(1, "clock_getres", "") }, /* 193 */ + { 0, Ukn ITR(1, "timer_create", "") }, /* 194 */ + { 0, Ukn ITR(1, "timer_delete", "") }, /* 195 */ + { 0, Ukn ITR(1, "timer_settime", "") }, /* 196 */ + { 0, Ukn ITR(1, "timer_gettime", "") }, /* 197 */ + { 0, Ukn ITR(1, "timer_getoverrun","") }, /* 198 */ + { sys_nanosleep, 2 ITR(1, "nanosleep", "pp") }, /* 199 */ + { 0, Ukn ITR(1, "modstat", "") }, /* 200 */ + { 0, Ukn ITR(1, "facl", "") }, /* 201 */ + { sys_setreuid, 2 ITR(1, "setreuid", "dd") }, /* 202 */ + { sys_setregid, 2 ITR(1, "setregid", "dd") }, /* 203 */ + { 0, Ukn ITR(1, "install_utrap", "") }, /* 204 */ + { 0, Ukn ITR(1, "signotify", "") }, /* 205 */ + { 0, Ukn ITR(1, "schedctl", "") }, /* 206 */ + { 0, Ukn ITR(1, "pset", "") }, /* 207 */ + { 0, Ukn ITR(1, "?", "") }, /* 208 */ + { 0, Ukn ITR(1, "resolvepath", "") }, /* 209 */ + { 0, Ukn ITR(1, "signotifywait", "") }, /* 210 */ + { 0, Ukn ITR(1, "lwp_sigredirect","") }, /* 211 */ + { 0, Ukn ITR(1, "lwp_alarm", "") }, /* 212 */ + { sol_getdents64, 3 ITR(0, "getdents64", "dxd") }, /* 213 */ + { sol_mmap64, 7 ITR(1, "mmap64", "pxdddxx")}, /*214 */ + { sol_stat64, 2 ITR(0, "stat64", "sp") }, /* 215 */ + { sol_lstat64, 2 ITR(0, "lstat64", "sp") }, /* 216 */ + { sol_fstat64, 2 ITR(0, "fstat64", "dp") }, /* 217 */ + { 0, Ukn ITR(1, "statvfs64", "") }, /* 218 */ + { 0, Ukn ITR(1, "fstatvfs64", "") }, /* 219 */ + { 0, Ukn ITR(1, "setrlimit64", "") }, /* 220 */ + { 0, Ukn ITR(1, "getrlimit64", "") }, /* 221 */ + { 0, Ukn ITR(1, "pread64", "") }, /* 222 */ + { 0, Ukn ITR(1, "pwrite64", "") }, /* 223 */ + { 0, Ukn ITR(1, "creat64", "") }, /* 224 */ + { sol_open64, 3 ITR(0, "open64", "soo") }, /* 225 */ + { 0, Ukn ITR(1, "rpcsys", "") }, /* 226 */ + { 0, Ukn ITR(1, "?", "") }, /* 227 */ + { 0, Ukn ITR(1, "?", "") }, /* 228 */ + { 0, Ukn ITR(1, "?", "") }, /* 229 */ + { solaris_socket, 3 ITR(1, "so_socket", "ddd") }, /* 230 */ + { solaris_socketpair,1 ITR(1, "so_socketpair", "dddx") }, /* 231 */ + { solaris_bind, 3 ITR(1, "bind", "dxd") }, /* 232 */ + { solaris_listen, 2 ITR(1, "listen", "dd") }, /* 233 */ + { solaris_accept, 3 ITR(1, "accept", "dxx") }, /* 234 */ + { solaris_connect, 3 ITR(1, "connect", "dxd") }, /* 235 */ + { solaris_shutdown, 2 ITR(1, "shutdown", "dd") }, /* 236 */ + { solaris_recv, 4 ITR(1, "recv", "dxdd") }, /* 237 */ + { solaris_recvfrom, 6 ITR(1, "recvfrom", "dxddxd")}, /* 238 */ + { solaris_recvmsg, 3 ITR(1, "recvmsg", "dxd") }, /* 239 */ + { solaris_send, 4 ITR(1, "send", "dxdd") }, /* 240 */ + { solaris_sendmsg, 3 ITR(0, "sendmsg", "dxd") }, /* 241 */ + { solaris_sendto, 6 ITR(1, "sendto", "dxddxd")}, /* 242 */ + { solaris_getpeername,3 ITR(1, "getpeername", "dxx") }, /* 243 */ + { solaris_getsockname,3 ITR(1, "getsockname", "dxx") }, /* 244 */ + { solaris_getsockopt,5 ITR(1, "getsockopt", "dddxx")}, /* 245 */ + { solaris_setsockopt,5 ITR(1, "setsockopt", "dddxd")}, /* 246 */ + { 0, Ukn ITR(1, "sockconfig", "") }, /* 247 */ + { 0, Ukn ITR(1, "ntp_gettime", "") }, /* 248 */ + { 0, Ukn ITR(0, "ntp_adjtime", "") }, /* 249 */ + { 0, Ukn ITR(1, "?", "") }, /* 250 */ + { 0, Ukn ITR(1, "?", "") }, /* 251 */ + { 0, Ukn ITR(1, "?", "") }, /* 252 */ + { 0, Ukn ITR(1, "?", "") }, /* 253 */ + { 0, Ukn ITR(1, "?", "") }, /* 254 */ + { 0, Ukn ITR(1, "?", "") } /* 255 */ +}; + +static void solaris_lcall7(int segment, struct pt_regs * regs) +{ + int sysno = regs->eax & 0xff; + + if (sysno >= ARRAY_SIZE(solaris_syscall_table)) + set_error(regs, iABI_errors(-EINVAL)); + else + lcall7_dispatch(regs, &solaris_syscall_table[sysno], 1); +} + +static struct exec_domain solaris_exec_domain = { + name: "Solaris", + handler: solaris_lcall7, + pers_low: 13 /* PER_SOLARIS */, + pers_high: 13 /* PER_SOLARIS */, + signal_map: solaris_to_linux_signals, + signal_invmap: linux_to_solaris_signals, + err_map: solaris_err_map, + socktype_map: solaris_socktype_map, + sockopt_map: solaris_sockopt_map, + af_map: solaris_af_map, + module: THIS_MODULE, +}; + + +static void __exit solaris_cleanup(void) +{ + unregister_exec_domain(&solaris_exec_domain); +} + +static int __init solaris_init(void) +{ + return register_exec_domain(&solaris_exec_domain); +} + +module_init(solaris_init); +module_exit(solaris_cleanup); diff -Nru linux-2.6.7/abi/svr4/consio.c linux-2.6.7-abi/abi/svr4/consio.c --- linux-2.6.7/abi/svr4/consio.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/svr4/consio.c 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,53 @@ +#ident "%W% %G%" + +#include +#include +#include +#include + + +int +svr4_console_ioctl(int fd, u_int cmd, caddr_t data) +{ + switch (cmd) { + case 0x6301: /* CONS_CURRENT: Get display adapter type */ + case 0x6302: /* CONS_GET: Get display mode setting */ + /* + * Always error so the application never tries + * anything overly fancy on the console. + */ + return -EINVAL; + case 0x4304: /* _TTYDEVTYPE */ + /* If on console then 1, if pseudo tty then 2 */ + return 2; + } + + printk(KERN_ERR "iBCS: console ioctl %d unsupported\n", cmd); + return -EINVAL; +} + +int +svr4_video_ioctl(int fd, u_int cmd, caddr_t data) +{ + switch (cmd) { + case 1: /* MAP_CLASS */ + /* Get video memory map & IO privilege */ + break; + + /* This doesn't agree with my SCO 3.2.4 ???? */ + case 4: /* C_IOC */ + /* see /etc/conf/pack.d/cn/class.h on any SCO unix box :-) */ + break; + + default: + break; + } + + printk(KERN_ERR "iBCS: video ioctl %d unsupported\n", cmd); + return -EINVAL; +} + +#if defined(CONFIG_ABI_SYSCALL_MODULES) +EXPORT_SYMBOL(svr4_console_ioctl); +EXPORT_SYMBOL(svr4_video_ioctl); +#endif diff -Nru linux-2.6.7/abi/svr4/fcntl.c linux-2.6.7-abi/abi/svr4/fcntl.c --- linux-2.6.7/abi/svr4/fcntl.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/svr4/fcntl.c 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2002 Caldera Deutschland GmbH. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ident "@(#)fcntl.c 1.1 02/23/02" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + + +struct svr4_flock { + int16_t l_type; /* numbers don't match */ + int16_t l_whence; + svr4_off_t l_start; + svr4_off_t l_len; /* 0 means to end of file */ + int16_t l_sysid; + int16_t l_pid; +}; + + +/* + * ISC (at least) assumes O_CREAT if O_TRUNC is given. + * This is emulated here but is it correct for SVR4 in general? + */ +unsigned short fl_svr4_to_linux[] = { + 0x0001, 0x0002, 0x0800, 0x0400, 0x1000, 0x0000, 0x0000, 0x0800, + 0x0040, 0x0240, 0x0080, 0x0100, 0x0000, 0x0000, 0x0000, 0x0000 +}; + +unsigned short fl_linux_to_svr4[] = { + 0x0001, 0x0002, 0x0000, 0x0000, 0x0000, 0x0000, 0x0100, 0x0400, + 0x0800, 0x0200, 0x0008, 0x0004, 0x0010, 0x0000, 0x0000, 0x0000 +}; + +static inline int svr4_fcntl_flock(int fd, unsigned int cmd, unsigned long arg) +{ + struct svr4_flock fl, *flp = (struct svr4_flock *)arg; + struct flock l_fl; + mm_segment_t fs; + int rval; + + /* + * We are not supposed to fail once the lock is set, + * thus we check the userspace pointer for writeaccess now. + */ + rval = verify_area(VERIFY_WRITE, flp, sizeof(struct svr4_flock)); + if (rval) + return -EFAULT; + + rval = copy_from_user(&fl, flp, sizeof(struct svr4_flock)); + if (rval) + return -EFAULT; + + l_fl.l_type = fl.l_type - 1; + l_fl.l_whence = fl.l_whence; + l_fl.l_start = fl.l_start; + l_fl.l_len = fl.l_len; + l_fl.l_pid = fl.l_pid; + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_API, + "lock l_type: %d l_whence: %d " + "l_start: %u l_len: %u " + "l_sysid: %d l_pid: %d\n", + fl.l_type, fl.l_whence, + fl.l_start, fl.l_len, + fl.l_sysid, fl.l_pid); +#endif + + fs = get_fs(); + set_fs(get_ds()); + rval = sys_fcntl(fd, cmd, (unsigned long)&l_fl); + set_fs(fs); + + if (rval) + return rval; + + fl.l_type = l_fl.l_type + 1; + fl.l_whence = l_fl.l_whence; + fl.l_start = l_fl.l_start; + fl.l_len = l_fl.l_len; + fl.l_sysid = 0; + fl.l_pid = l_fl.l_pid; + + __copy_to_user(flp, &fl, sizeof(struct svr4_flock)); + return 0; +} + +int svr4_fcntl(int fd, unsigned int cmd, unsigned long arg) +{ + int rval; + + switch (cmd) { + case 0: /* F_DUPFD */ + case 1: /* F_GETFD */ + case 2: /* F_SETFD */ + return sys_fcntl(fd, cmd, arg); + case 3: /* F_GETFL */ + rval = sys_fcntl(fd, cmd, arg); + return map_flags(rval, fl_linux_to_svr4); + case 4: /* F_SETFL */ + arg = map_flags(arg, fl_svr4_to_linux); + return sys_fcntl(fd, cmd, arg); + case 14: /* F_GETLK SVR4 */ + cmd = 5; + /*FALLTHROUGH*/ + case 5: /* F_GETLK */ + case 6: /* F_SETLK */ + case 7: /* F_SETLKW */ + return svr4_fcntl_flock(fd, cmd, arg); + case 10: /* F_ALLOCSP */ + /* Extend allocation for specified portion of file. */ + return 0; + case 11: /* F_FREESP */ + /* Free a portion of a file. */ + return 0; + + /* + * These are intended to support the Xenix chsize() and + * rdchk() system calls. I don't know if these may be + * generated by applications or not. + */ + case 0x6000: /* F_CHSIZE */ + return sys_ftruncate(fd, arg); + case 0x6001: /* F_RDCHK */ + { + mm_segment_t fs; + int nbytes; + + fs = get_fs(); + set_fs(get_ds()); + rval = sys_ioctl(fd, FIONREAD, (long)&nbytes); + set_fs(fs); + + if (rval < 0) + return rval; + return (nbytes ? 1 : 0); + } + + case 8: /* F_CHKFL */ + /*FALLTHROUGH*/ + + /* + * These are made from the Xenix locking() system call. + * According to available documentation these would + * never be generated by an application - only by the + * kernel Xenix support. + */ + case 0x6300: /* F_LK_UNLCK */ + case 0x7200: /* F_LK_LOCK */ + case 0x6200: /* F_LK_NBLCK */ + case 0x7100: /* F_LK_RLCK */ + case 0x6100: /* F_LK_NBRLCK */ + /*FALLTHROUGH*/ + + default: +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_API, + "unsupported fcntl 0x%x, arg 0x%lx\n", cmd, arg); +#endif + return -EINVAL; + } +} + +#if defined(CONFIG_ABI_SYSCALL_MODULES) +EXPORT_SYMBOL(fl_svr4_to_linux); +EXPORT_SYMBOL(svr4_fcntl); +#endif diff -Nru linux-2.6.7/abi/svr4/filio.c linux-2.6.7-abi/abi/svr4/filio.c --- linux-2.6.7/abi/svr4/filio.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/svr4/filio.c 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2001 Christoph Hellwig. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ident "%W% %G%" + +/* + * SVR4 file ioctls. + */ + +#include +#include +#include +#include +#include + +#include +#include + +#include + + +int +svr4_fil_ioctl(int fd, u_int cmd, caddr_t data) +{ + switch (cmd) { + /* FIOCLEX */ + case BSD__IOV('f', 1): + case BSD__IO('f', 1): + FD_SET(fd, current->files->close_on_exec); + return 0; + + /* FIONCLEX */ + case BSD__IOV('f', 2): + case BSD__IO('f', 2): + FD_CLR(fd, current->files->close_on_exec); + return 0; + + case BSD__IOV('f', 3): + case BSD__IO('f', 3): { + int error, nbytes; + mm_segment_t fs; + + fs = get_fs(); + set_fs(get_ds()); + error = sys_ioctl(fd, FIONREAD, (long)&nbytes); + set_fs(fs); + + return (error <= 0 ? error : nbytes); + } + + /* FGETOWN */ + case BSD__IOW('f', 123, int): + return sys_ioctl(fd, FIOGETOWN, (long)data); + + /* FSETOWN */ + case BSD__IOW('f', 124, int): + return sys_ioctl(fd, FIOSETOWN, (long)data); + + /* FIOASYNC */ + case BSD__IOW('f', 125, int): + return sys_ioctl(fd, FIOASYNC, (long)data); + + /* FIONBIO */ + case BSD__IOW('f', 126, int): + return sys_ioctl(fd, FIONBIO, (long)data); + + /* FIONREAD */ + case BSD__IOR('f', 127, int): + return sys_ioctl(fd, FIONREAD, (long)data); + } + + printk(KERN_ERR "%s: file ioctl 0x%08x unsupported\n", __FUNCTION__, cmd); + return -EINVAL; +} + +#if defined(CONFIG_ABI_SYSCALL_MODULES) +EXPORT_SYMBOL(svr4_fil_ioctl); +#endif diff -Nru linux-2.6.7/abi/svr4/hrtsys.c linux-2.6.7-abi/abi/svr4/hrtsys.c --- linux-2.6.7/abi/svr4/hrtsys.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/svr4/hrtsys.c 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,192 @@ +/* + * Copyright (C) 1994 Eric Youngdale. + * + * The hrtsys interface is used by SVR4, and is effectively a way of doing + * itimer. I do not know why this is used instead of the regular itimer + * stuff, but it appears to be related to bsd programs/functionality. + */ + +#ident "%W% %G%" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + + +struct hrt_time_t { + unsigned long secs; + unsigned long sub_sec; /* Less than one second. */ + unsigned long resolution; /* Resolution of timer */ +}; + +struct hrtcmd { + int cmd; + int clk; + struct hrt_time_t interval; + struct hrt_time_t tod; + int flags; + int error; + int reserved[3]; +}; + +static int +ibcs_hrtcntl (struct pt_regs * regs) +{ + unsigned int param[4]; + struct timeval * tv; + int i, error; + + for (i=0; i<4; i++) + param[i] = get_syscall_parameter (regs, 1+i); + + if (param[0] != 1 || param[1] != 1 || param[2] != 0) + return -EINVAL; + + tv = (struct timeval *) param[3]; + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_API, "hrtcntl(0x%lx)\n", (u_long)tv); +#endif + + error = verify_area(VERIFY_WRITE, (char *) tv,sizeof *tv); + if (error) + return error; + + return sys_gettimeofday(tv, NULL); +} + +static int +ibcs_hrtalarm (struct pt_regs * regs) +{ + struct itimerval get_buffer; + struct hrtcmd * hcmd; + int i, error, cmd, retval, which; + mm_segment_t old_fs = get_fs(); + + i = get_syscall_parameter (regs, 2); + if(i != 1) + return -EINVAL; + + hcmd = (struct hrtcmd *) get_syscall_parameter (regs, 1); + + error = verify_area (VERIFY_WRITE, (char *) hcmd,sizeof *hcmd); + if (error) + return error; + + get_user (cmd, ((unsigned long *) hcmd)); + + /* Now figure out which clock we want to fiddle with */ + get_user (which, ((unsigned long *) hcmd)+1); + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_API, "hrtalarm(0x%lx %d)\n", + (u_long)cmd, which); +#endif + + switch (which) { + case 4: + which = 2; + break; + case 2: + which = 1; + break; + case 1: + which = 0; + break; + default: + return -EINVAL; + }; + + switch (cmd) { + case 0xc: + if(({long r; get_user(r, ((unsigned long *) hcmd)+4); r;}) != 1000000) + return -EINVAL; + copy_from_user(&get_buffer.it_value, ((unsigned long *) hcmd)+2, + sizeof(struct timeval)); + memset(&get_buffer.it_interval, 0, sizeof(struct timeval)); + set_fs(get_ds()); + retval = sys_setitimer(which, &get_buffer, NULL); + set_fs(old_fs); + break; + case 0xd: + set_fs(get_ds()); + retval = sys_getitimer(which, &get_buffer); + set_fs(old_fs); + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_API, "hrtalarm(d %lx) %lx %lx %lx %lx\n", + (u_long)hcmd, + get_buffer.it_interval.tv_sec, + get_buffer.it_interval.tv_usec, + get_buffer.it_value.tv_sec, + get_buffer.it_value.tv_usec); +#endif + + put_user(1000000, &hcmd->interval.resolution); + copy_to_user(((unsigned long *) hcmd)+2, &get_buffer.it_interval, + sizeof(get_buffer)); + retval = 1; + break; + case 0xf: + if(({long r; get_user(r, ((unsigned long *) hcmd)+4); r;}) != 1000000) + return -EINVAL; + if(({long r; get_user(r, ((unsigned long *) hcmd)+7); r;}) != 1000000) + return -EINVAL; + copy_from_user(&get_buffer.it_value, &hcmd->tod, + sizeof(struct timeval)); + copy_from_user(&get_buffer.it_interval, &hcmd->interval, + sizeof(struct timeval)); + set_fs(get_ds()); + retval = sys_setitimer(which, &get_buffer, NULL); + set_fs(old_fs); + break; + case 0x10: + memset(&get_buffer, 0, sizeof(get_buffer)); + set_fs(get_ds()); + retval = sys_setitimer(which, &get_buffer, NULL); + set_fs(old_fs); + break; + default: + retval = -EINVAL; + }; + + return retval; +} + +int +svr4_hrtsys (struct pt_regs * regs) +{ + int func, retval; + + func = get_syscall_parameter (regs, 0); + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_API, "hrtsys(%d)\n", func); +#endif + + switch (func) { + case 0: + retval = ibcs_hrtcntl(regs); + break; + case 1: + retval = ibcs_hrtalarm(regs); + break; + case 2: + case 3: + default: + retval = -EINVAL; + } + + return retval; +} + +#if defined(CONFIG_ABI_SYSCALL_MODULES) +EXPORT_SYMBOL(svr4_hrtsys); +#endif diff -Nru linux-2.6.7/abi/svr4/ioctl.c linux-2.6.7-abi/abi/svr4/ioctl.c --- linux-2.6.7/abi/svr4/ioctl.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/svr4/ioctl.c 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,198 @@ +/* + * Copyright (C) 1991, 1992 Linus Torvalds + * + * Written by Drew Sullivan. + * Rewritten by Mike Jagdis. + */ + +#ident "%W% %G%" + +#include +#include +#include +#include +#include +#include + +#include +#include + + +/* + * __svr4_ioctl() is a meta mapper, that is + * it looks up the class of the ioctl and then + * dispatchs to lower level routines to handle the + * mapping of the actual ioctls + */ +int +__svr4_ioctl(struct pt_regs *regs, int fd, unsigned long ioctl_num, void *arg) +{ + unsigned int class = ioctl_num >> 8; + char class_str[4]; + + switch (class) { + + /* + * SCO ioctls on the pseudo NFS device probably. + */ + case 0: + return abi_ioctl_socksys(fd, ioctl_num, arg); + + /* + * SCO console keyboard stuff? + */ + case 'A': + return -EINVAL; + + case 't': + return svr4_tape_ioctl(fd, ioctl_num, arg); + + case 'f': + return svr4_fil_ioctl(fd, ioctl_num, arg); + + /* + * Xenix ioctl compatibility. + */ + case 'T': + return svr4_term_ioctl(fd, ioctl_num & 0xFF, arg); + + case 'C': + case 'c': + return svr4_console_ioctl(fd, ioctl_num, arg); + + case ('i' << 16) | ('C' << 8): /* iBCS2 POSIX */ + return svr4_video_ioctl(fd, ioctl_num & 0xFF, arg); + + /* + * SCO 3.2.2 uses ('X'<<8)|1 for access to the video map + * and the 'X' set is also used for synchronous comm + * lines (I think?). SVR4 uses it for tty extensions to + * support hardware flow control and external clocks. + */ + case 'X': + return svr4_termiox_ioctl(fd, ioctl_num & 0xFF, arg); + + /* + * These aren't implemented and are never likely to be as they + * are specific to drivers for obscure hardware. (For those + * that don't know they're the JERQ ioctls. Says it all + * really!) + */ + case 'j': + return -EINVAL; + + /* + * The 'S' set could also be display mode switch + * ioctls in a SCO 3.2.x x<4 environment. It should + * depend on the descriptor they are applied to. + * According to ISC the Xenix STREAMS ioctls had the + * high bit set on the command to differentiate them + * from mode switch ioctls. Yuk, yuk, yuk... + */ + case 'S': + return svr4_stream_ioctl(regs, fd, ioctl_num & 0x7F, arg); + + /* + * These are STREAMS socket module ioctls. + */ + case 'I': +#if defined(CONFIG_ABI_XTI) + return svr4_sockmod_ioctl(fd, ioctl_num & 0xFF, arg); +#else + return -EINVAL; +#endif + + /* + * EUC ioctls. These are something to do with chararcter + * code set conversions in SVR4. If we don't support + * them the correct thing to do is to return EINVAL. + */ + case 'E' | 0x80: + return -EINVAL; + + /* + * SCO channel mapping. I can't find any documentation + * for this. These are the LD?MAP ioctls defined in + * sys/termio.h and sys/emap.h. They are used by mapchan. + */ + case 'D': + return -EINVAL; + } + + /* + * If we haven't handled it yet it must be a BSD style ioctl + * with a (possible) argument description in the high word of + * the opcode. + */ + switch (class & 0xff) { + + /* + * From SVR4 as specified in sys/iocomm.h. + */ + case 'f': + return svr4_fil_ioctl(fd, ioctl_num, arg); + + /* + * BSD or V7 terminal ioctls. + */ + case 't': + return bsd_ioctl_termios(fd, ioctl_num, arg); + + /* + * "Traditional" BSD and Wyse V/386 3.2.1A TCP/IP ioctls. + */ + case 's': + case 'r': + case 'i': + return abi_ioctl_socksys(fd, ioctl_num, arg); + + /* + * SVR3 streams based socket TCP/IP ioctls. + * + * These are handed over to the standard ioctl + * handler since /dev/socksys is an emulated device + * and front ends any sockets created through it. + * Note that 'S' ioctls without the BSDish argument + * type in the high bytes are STREAMS ioctls and 'I' + * ioctls without the BSDish type in the high bytes + * are the STREAMS socket module ioctls. (see above). + */ + case 'S': + case 'R': + case 'I': + return abi_ioctl_socksys(fd, ioctl_num, arg); + } + + /* + * If nothing has handled it yet someone may have to do some + * more work... + */ + class_str[0] = class & 0xFF0000 ? (char)((class >> 16) & 0xFF) : '.'; + class_str[1] = class & 0x00FF00 ? (char)((class >> 8) & 0xFF) : '.'; + class_str[2] = class & 0x0000FF ? (char)((class ) & 0xFF) : '.'; + class_str[3] = 0; + + printk(KERN_DEBUG "svr4: ioctl(%d, %lx[%s], 0x%p) unsupported\n", + fd, ioctl_num, class_str, arg); + + return -EINVAL; +} + +int +svr4_ioctl(struct pt_regs * regs) +{ + u_int num; + int fd; + caddr_t data; + + fd = (int)get_syscall_parameter(regs, 0); + num = (u_int)get_syscall_parameter(regs, 1); + data = (caddr_t)get_syscall_parameter(regs, 2); + + return __svr4_ioctl(regs, fd, num, data); +} + +#if defined(CONFIG_ABI_SYSCALL_MODULES) +EXPORT_SYMBOL(__svr4_ioctl); +EXPORT_SYMBOL(svr4_ioctl); +#endif diff -Nru linux-2.6.7/abi/svr4/ipc.c linux-2.6.7-abi/abi/svr4/ipc.c --- linux-2.6.7/abi/svr4/ipc.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/svr4/ipc.c 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,713 @@ +/* + * Copyright (C) 1994 Mike Jagdis (jaggy@purplet.demon.co.uk) + * Copyright (C) 2001 Christoph Hellwig (hch@caldera.de) + * + * Massive work over with a fine tooth comb, lots of rewriting. There + * were a *lot* of bugs in this - mismatched structs that weren't + * mapped, wrong pointers etc. I've tested this version with the + * demo programs from the Wyse V/386 IPC documentation which exercise + * all the functions. I don't have any major IPC using applications + * to test it with - as far as I know... + * + * Again rewritten for Linux 2.4 - Linux 2.4 changes a lot of structures + * and the cruft this file relied on has simply changed... + * + * Original copyright etc. follows: + * + * Copyright (C) 1993,1994 Joe Portman (baron@hebron.connected.com) + * First stab at ibcs shm, sem and msg handlers + * + * NOTE: + * Please contact the author above before blindly making changes + * to this file. You will break things. + * + * 04-15-1994 JLP III + * Still no msgsys, but IPC_STAT now works for shm calls + * Corrected argument order for sys_ipc calls, to accomodate Mike's + * changes, so that we can just call sys_ipc instead of the internal + * sys_* calls for ipc functions. + * Cleaned up translation of perm structures + * tstshm for Oracle now works. + * + * 04-23-1994 JLP III + * Added in msgsys calls, Tested and working + * Added translation for IPC_SET portions of all xxxctl functions. + * Added SHM_LOCK and SHM_UNLOCK to shmsys + * + * 04-28-1994 JLP III + * Special thanks to Brad Pepers for adding in the GETALL and SETALL + * case of semaphores. (pepersb@cuug.ab.ca) + */ + +#ident "%W% %G%" + +#include +#include +#include +#include +#include +#include +#include +#include +#define __KERNEL_SYSCALLS__ +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + + +static __inline__ void +ip_to_lp(struct ibcs2_ipc_perm *ip, struct ipc_perm *lp) +{ + lp->uid = ip->uid; + lp->gid = ip->gid; + lp->cuid = ip->cuid; + lp->cgid = ip->cgid; + lp->mode = ip->mode; + lp->seq = ip->seq; + lp->key = ip->key; +} + +static __inline__ void +lp_to_ip(struct ipc_perm *lp, struct ibcs2_ipc_perm *ip) +{ + ip->uid = lp->uid; + ip->gid = lp->gid; + ip->cuid = lp->cuid; + ip->cgid = lp->cgid; + ip->mode = lp->mode; + ip->seq = lp->seq; + ip->key = lp->key; +} + +static __inline__ void +ip_to_lp_l(struct abi4_ipc_perm *ip, struct ipc_perm *lp) +{ + lp->uid = ip->uid; + lp->gid = ip->gid; + lp->cuid = ip->cuid; + lp->cgid = ip->cgid; + lp->mode = ip->mode; + lp->seq = ip->seq; + lp->key = ip->key; +} + +static __inline__ void +lp_to_ip_l(struct ipc_perm *lp, struct abi4_ipc_perm *ip) +{ + ip->uid = lp->uid; + ip->gid = lp->gid; + ip->cuid = lp->cuid; + ip->cgid = lp->cgid; + ip->mode = lp->mode; + ip->seq = lp->seq; + ip->key = lp->key; +} + +static void +isem_to_lsem(struct ibcs2_semid_ds *is, struct semid_ds *ls) +{ + ip_to_lp(&is->sem_perm, &ls->sem_perm); + + ls->sem_base = is->sem_base; + ls->sem_nsems = is->sem_nsems; + ls->sem_otime = is->sem_otime; + ls->sem_ctime = is->sem_ctime; +} + +static void +lsem_to_isem(struct semid_ds *ls, struct ibcs2_semid_ds *is) +{ + lp_to_ip(&ls->sem_perm, &is->sem_perm); + + is->sem_base = ls->sem_base; + is->sem_nsems = ls->sem_nsems; + is->sem_otime = ls->sem_otime; + is->sem_ctime = ls->sem_ctime; +} + +static void +isem_to_lsem_l(struct abi4_semid_ds *is, struct semid_ds *ls) +{ + ip_to_lp_l(&is->sem_perm, &ls->sem_perm); + + ls->sem_base = is->sem_base; + ls->sem_nsems = is->sem_nsems; + ls->sem_otime = is->sem_otime; + ls->sem_ctime = is->sem_ctime; +} + +static void +lsem_to_isem_l(struct semid_ds *ls, struct abi4_semid_ds *is) +{ + memset(is, 0, sizeof(*is)); + + lp_to_ip_l(&ls->sem_perm, &is->sem_perm); + + is->sem_base = ls->sem_base; + is->sem_nsems = ls->sem_nsems; + is->sem_otime = ls->sem_otime; + is->sem_ctime = ls->sem_ctime; +} + +static int +__ibcs2_semctl(int first, int second, int third, union semun *fourth) +{ + struct ibcs2_semid_ds is, *isp; + struct semid_ds ls; + union semun lsemun; + mm_segment_t fs; + int err; + + err = get_user(isp, (struct ibcs2_semid_ds **)&fourth->buf); + if (err) + return (err); + + err = copy_from_user(&is, isp, sizeof(is)) ? -EFAULT : 0; + if (err) + return (err); + + isem_to_lsem(&is, &ls); + lsemun.buf = &ls; + + fs = get_fs(); + set_fs(get_ds()); + err = sys_ipc(SEMCTL, first, second, third, &lsemun,0); + set_fs(fs); + + if (err < 0) + return (err); + + lsem_to_isem(&ls, &is); + return copy_to_user(isp, &is, sizeof(is)) ? -EFAULT : 0; +} + +static int +__abi4_semctl(int first, int second, int third, union semun *fourth) +{ + struct abi4_semid_ds is, *isp; + struct semid_ds ls; + union semun lsemun; + mm_segment_t fs; + int err; + + err = get_user(isp, (struct abi4_semid_ds **)&fourth->buf); + if (err) + return (err); + + err = copy_from_user(&is, isp, sizeof(is)) ? -EFAULT : 0; + if (err) + return (err); + + isem_to_lsem_l(&is, &ls); + lsemun.buf = &ls; + + fs = get_fs(); + set_fs(get_ds()); + err = sys_ipc(SEMCTL, first, second, third, &lsemun,0); + set_fs(fs); + + if (err < 0) + return (err); + + lsem_to_isem_l(&ls, &is); + return copy_to_user(isp, &is, sizeof(is)) ? -EFAULT : 0; +} + +static int +svr4_semctl(int arg1, int arg2, int arg3, union semun *arg4) +{ + int 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: + return sys_ipc(SEMCTL, arg1, arg2, cmd, arg4, 0); + 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); + } + + __abi_trace("semctl: unsupported command %d\n", arg3); + return -EINVAL; +} + +static int +svr4_semget(int arg1, int arg2, int arg3) +{ +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_API, "semget(%d, %d, %o)\n", arg1, arg2, arg3); +#endif + return sys_semget(arg1, arg2, arg3); + +} + +static int +svr4_semop(int arg1, struct sembuf *arg2, int arg3) +{ +#if defined(CONFIG_ABI_TRACE) + if (abi_traced(ABI_TRACE_API)) { + struct sembuf tmp, *tp = arg2; + int i; + + for (i = 0; i < arg3; i++) { + copy_from_user (&tmp, tp, sizeof(tmp)); + __abi_trace("semop(%d, %d, 0%o)\n", + tmp.sem_num, tmp.sem_op, + tmp.sem_flg); + tp++; + } + } +#endif + + return sys_semop(arg1, arg2, arg3); +} + +int +svr4_semsys(struct pt_regs *regp) +{ + int which, arg1, arg2, arg3; + union semun *arg4; + + which = get_syscall_parameter(regp, 0); + arg1 = get_syscall_parameter(regp, 1); + arg2 = get_syscall_parameter(regp, 2); + arg3 = get_syscall_parameter(regp, 3); + + /* + * XXX - The value for arg4 depends on how union + * passing is implement on this architecture and + * compiler. The following is *only* known to be + * right for Intel (the default else case). + */ +#ifdef __sparc__ + arg4 = (union semun *)get_syscall_parameter(regp, 4); +#else + arg4 = (union semun *)(((u_long *)regp->esp) + (5)); +#endif + + switch (which) { + case SVR4_semctl: + return svr4_semctl(arg1, arg2, arg3, arg4); + case SVR4_semget: + return svr4_semget(arg1, arg2, arg3); + case SVR4_semop: + return svr4_semop(arg1, (struct sembuf *)arg2, arg3); + } + + return -EINVAL; +} + +static void +ishm_to_lshm(struct ibcs2_shmid_ds *is, struct shmid_ds *ls) +{ + ip_to_lp(&is->shm_perm, &ls->shm_perm); + ls->shm_segsz = is->shm_segsz; + ls->shm_lpid = is->shm_lpid; + ls->shm_cpid = is->shm_cpid; + ls->shm_nattch = is->shm_nattch; + ls->shm_atime = is->shm_atime; + ls->shm_dtime = is->shm_dtime; + ls->shm_ctime = is->shm_ctime; +} + +static void +lshm_to_ishm(struct shmid_ds *ls, struct ibcs2_shmid_ds *is) +{ + lp_to_ip(&ls->shm_perm, &is->shm_perm); + is->shm_segsz = ls->shm_segsz; + is->shm_lpid = ls->shm_lpid; + is->shm_cpid = ls->shm_cpid; + is->shm_nattch = ls->shm_nattch; + is->shm_atime = ls->shm_atime; + is->shm_dtime = ls->shm_dtime; + is->shm_ctime = ls->shm_ctime; +} + +static void +ishm_to_lshm_l(struct abi4_shmid_ds *is, struct shmid_ds *ls) +{ + ip_to_lp_l(&is->shm_perm, &ls->shm_perm); + ls->shm_segsz = is->shm_segsz; + ls->shm_lpid = is->shm_lpid; + ls->shm_cpid = is->shm_cpid; + ls->shm_nattch = is->shm_nattch; + ls->shm_atime = is->shm_atime; + ls->shm_dtime = is->shm_dtime; + ls->shm_ctime = is->shm_ctime; +} + +static void +lshm_to_ishm_l(struct shmid_ds *ls, struct abi4_shmid_ds *is) +{ + memset(is, 0, sizeof(*is)); + lp_to_ip_l(&ls->shm_perm, &is->shm_perm); + is->shm_segsz = ls->shm_segsz; + is->shm_lpid = ls->shm_lpid; + is->shm_cpid = ls->shm_cpid; + is->shm_nattch = ls->shm_nattch; + is->shm_atime = ls->shm_atime; + is->shm_dtime = ls->shm_dtime; + is->shm_ctime = ls->shm_ctime; +} + +static int +svr4_shmdt(struct pt_regs *regp) +{ + caddr_t addr = (caddr_t)get_syscall_parameter(regp, 1); + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_API, "shmdt(%p)\n", addr); +#endif + return sys_shmdt(addr); +} + +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: + return sys_shmctl(arg1, SHM_LOCK, (struct shmid_ds *)arg3); + case SVR4_SHM_UNLOCK: + return sys_shmctl(arg1, SHM_UNLOCK, (struct shmid_ds *)arg3); + 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()); + err = sys_shmctl(arg1, IPC_SET, &ls); + 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()); + err = sys_shmctl(arg1, IPC_SET, &ls); + 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: + return sys_shmctl(arg1, IPC_RMID, (struct shmid_ds *)arg3); + case SVR4_IPC_STAT: + fs = get_fs(); + set_fs(get_ds()); + err = sys_shmctl(arg1, IPC_STAT, &ls); + 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()); + err = sys_shmctl(arg1, IPC_STAT, &ls); + 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); +} + +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()); + err = do_shmat(arg1, (caddr_t)arg2, arg3, &raddr); + 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 + err = sys_shmget(arg1, arg2, arg3); +#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 *)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)); + abi_trace(ABI_TRACE_API, "Error %d\n", get_result(regp)); + return 0; + } + + clear_error(regp); + set_result(regp, err); + return 0; +} + +static void +imsq_to_lmsq(struct ibcs2_msqid_ds * im, struct msqid_ds * lm) +{ + ip_to_lp(&im->msg_perm, &lm->msg_perm); + lm->msg_first = im->msg_first; + lm->msg_last = im->msg_last; + lm->msg_cbytes = im->msg_cbytes; + lm->msg_qnum = im->msg_qnum; + lm->msg_qbytes = im->msg_qbytes; + lm->msg_lspid = im->msg_lspid; + lm->msg_lrpid = im->msg_lrpid; + lm->msg_stime = im->msg_stime; + lm->msg_rtime = im->msg_rtime; + lm->msg_ctime = im->msg_ctime; +} + +static void +lmsq_to_imsq(struct msqid_ds *lm, struct ibcs2_msqid_ds *im) +{ + lp_to_ip(&lm->msg_perm, &im->msg_perm); + im->msg_first = lm->msg_first; + im->msg_last = lm->msg_last; + im->msg_cbytes = lm->msg_cbytes; + im->msg_qnum = lm->msg_qnum; + im->msg_qbytes = lm->msg_qbytes; + im->msg_lspid = lm->msg_lspid; + im->msg_lrpid = lm->msg_lrpid; + im->msg_stime = lm->msg_stime; + im->msg_rtime = lm->msg_rtime; + im->msg_ctime = lm->msg_ctime; +} + +static void +imsq_to_lmsq_l(struct abi4_msqid_ds *im, struct msqid_ds *lm) +{ + ip_to_lp_l(&im->msg_perm, &lm->msg_perm); + lm->msg_first = im->msg_first; + lm->msg_last = im->msg_last; + lm->msg_cbytes = im->msg_cbytes; + lm->msg_qnum = im->msg_qnum; + lm->msg_qbytes = im->msg_qbytes; + lm->msg_lspid = im->msg_lspid; + lm->msg_lrpid = im->msg_lrpid; + lm->msg_stime = im->msg_stime; + lm->msg_rtime = im->msg_rtime; + lm->msg_ctime = im->msg_ctime; +} + +static void +lmsq_to_imsq_l(struct msqid_ds *lm, struct abi4_msqid_ds *im) +{ + memset(im, 0, sizeof(*im)); + lp_to_ip_l(&lm->msg_perm, &im->msg_perm); + im->msg_first = lm->msg_first; + im->msg_last = lm->msg_last; + im->msg_cbytes = lm->msg_cbytes; + im->msg_qnum = lm->msg_qnum; + im->msg_qbytes = lm->msg_qbytes; + im->msg_lspid = lm->msg_lspid; + im->msg_lrpid = lm->msg_lrpid; + im->msg_stime = lm->msg_stime; + im->msg_rtime = lm->msg_rtime; + im->msg_ctime = lm->msg_ctime; +} + +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()); + err = sys_msgctl(arg1, IPC_SET, &lm); + 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()); + err = sys_msgctl(arg1, IPC_SET, &lm); + 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: + return sys_msgctl(arg1, IPC_RMID, (struct msqid_ds *)arg3); + case SVR4_IPC_STAT: + fs = get_fs(); + set_fs(get_ds()); + err = sys_msgctl(arg1, IPC_STAT, &lm); + 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()); + err = sys_msgctl(arg1, IPC_STAT, &lm); + 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: + __abi_trace("msgctl: unsupported command: %x\n", cmd); + err = -EINVAL; + } + + return (err); +} + +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: + return sys_msgget((key_t)arg1, arg2); + case SVR4_msgctl: + arg3 = get_syscall_parameter(regp, 3); + return svr4_msgctl(arg1, arg2, (caddr_t)arg3); + case SVR4_msgrcv: + arg3 = get_syscall_parameter(regp, 3); + arg4 = get_syscall_parameter(regp, 4); + arg5 = get_syscall_parameter(regp, 5); + return sys_msgrcv(arg1, (struct msgbuf *)arg2, arg3, arg4, arg5); + case SVR4_msgsnd: + arg3 = get_syscall_parameter(regp, 3); + arg4 = get_syscall_parameter(regp, 4); + err = sys_msgsnd(arg1, (struct msgbuf *)arg2, arg3, arg4); + return ((err > 0) ? 0 : err); + } + + __abi_trace("msgsys: unsupported command: %x\n", cmd); + return -EINVAL; +} + +#if defined(CONFIG_ABI_SYSCALL_MODULES) +EXPORT_SYMBOL(svr4_msgsys); +EXPORT_SYMBOL(svr4_semsys); +EXPORT_SYMBOL(svr4_shmsys); +#endif diff -Nru linux-2.6.7/abi/svr4/Makefile linux-2.6.7-abi/abi/svr4/Makefile --- linux-2.6.7/abi/svr4/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/svr4/Makefile 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,20 @@ + +svr4-y := hrtsys.o ioctl.o ipc.o mmap.o open.o svr4.o sysconf.o \ + sysfs.o sysinfo.o sysi86.o ulimit.o utsname.o stream.o \ + stat.o socksys.o signal.o misc.o socket.o statvfs.o \ + fcntl.o + +# emulations for all kinds of weird ioctls... +svr4-y += filio.o termios.o consio.o tapeio.o sockio.o + +# networking +svr4-$(CONFIG_ABI_XTI) += timod.o xti.o +svr4-$(CONFIG_ABI_SPX) += timod.o + +abi-svr4-objs += $(sort $(svr4-y)) + + +obj-$(CONFIG_ABI_SVR4) += abi-svr4.o + +abi-svr4.o: $(abi-svr4-objs) + $(LD) -r -o $@ $(abi-svr4-objs) diff -Nru linux-2.6.7/abi/svr4/misc.c linux-2.6.7-abi/abi/svr4/misc.c --- linux-2.6.7/abi/svr4/misc.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/svr4/misc.c 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,659 @@ +/* + * Copyright (C) 1993 Linus Torvalds + * Copyright (C) 2001 Caldera Deutschland GmbH + * + * Modified by Eric Youngdale to include all ibcs syscalls. + * Re-written by Drew Sullivan to handle lots more of the syscalls correctly. + */ + +#ident "%W% %G%" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include + + +MODULE_DESCRIPTION("common code for SVR3/SVR4 based personalities"); +MODULE_AUTHOR("Christoph Hellwig, partially taken from iBCS"); +MODULE_LICENSE("GPL"); + + +int +abi_time(void) +{ + return sys_time(0); +} + +int +abi_brk(unsigned long brk) +{ + unsigned long newbrk = PAGE_ALIGN(brk), oldbrk, sysbrk; + + down_read(¤t->mm->mmap_sem); + if (!brk) + goto report; + oldbrk = PAGE_ALIGN(current->mm->brk); + up_read(¤t->mm->mmap_sem); + + if (newbrk != oldbrk) { + sysbrk = sys_brk(brk); + if (PAGE_ALIGN(sysbrk) != newbrk) + return -ENOMEM; + } + return 0; + +report: + /* return non-pagealigned old brk value */ + oldbrk = current->mm->brk; + up_read(¤t->mm->mmap_sem); + return oldbrk; +} + +/* + * UNIX wants a 0-edx after fork and may have set + * the carry flag before calling fork. + */ +int +abi_fork(struct pt_regs *regs) +{ + int retval; + + regs->eflags &= ~1; + retval = do_fork(SIGCHLD, regs->esp, regs, 0, + /* parent_tidptr */NULL, /* child_tidptr */NULL); + regs->edx = 0; + return retval; +} + +/* + * Unlike Linux, UNIX does not use C calling conventions + * for pipe(). + */ +int +abi_pipe(struct pt_regs *regs) +{ + int filedes[2], retval; + + retval = do_pipe(filedes); + if (retval == 0) { + retval = filedes[0]; + regs->edx = filedes[1]; + } + return retval; +} + +/* + * Note the double value return in eax and edx. + */ +int +abi_getpid(struct pt_regs *regs) +{ + regs->edx = current->parent->pid; + return current->pid; +} + +/* + * Note the double value return in eax and edx. + */ +int +abi_getuid(struct pt_regs *regs) +{ + regs->edx = current->euid; + return current->uid; +} + +/* + * Note the double value return in eax and edx. + */ +int +abi_getgid(struct pt_regs *regs) +{ + regs->edx = current->egid; + return current->gid; +} + + + +enum { + FLAG_ZF = 0x0040, + FLAG_PF = 0x0004, + FLAG_SF = 0x0080, + FLAG_OF = 0x0800, +}; + +#define MAGIC_WAITPID_FLAG (FLAG_ZF | FLAG_PF | FLAG_SF | FLAG_OF) + +int +abi_wait(struct pt_regs * regs) +{ + mm_segment_t fs; + long result, kopt = 0; + int loc, opt; + pid_t pid; + + /* + * Xenix wait() puts status to edx and returns pid. + * + * XXX xenix should get it's own syyent table so we can + * XXX rip this cruft out. + */ + if (is_cur_personality(PER_XENIX)) { + fs = get_fs(); + set_fs(get_ds()); + result = sys_wait4(-1, &loc, 0, NULL); + set_fs(fs); + + regs->edx = loc; + return result; + } + + /* + * if ZF,PF,SF,and OF are set then it is waitpid + */ + if ((regs->eflags & MAGIC_WAITPID_FLAG) == MAGIC_WAITPID_FLAG) { + get_user(pid, ((u_long *)regs->esp)+1); + get_user(loc, ((u_long *)regs->esp)+2); + get_user(opt, ((u_long *)regs->esp)+3); + + /* + * Now translate the options from the SVr4 numbers + */ + if (opt & 0100) + kopt |= WNOHANG; + if (opt & 4) + kopt |= WUNTRACED; + + result = sys_wait4(pid, (u_int *)loc, kopt, NULL); + } else { + get_user(loc, ((u_long *)regs->esp)+1); + result = sys_wait4(-1, (u_int *)loc, WUNTRACED, NULL); + } + + if (result < 0 || !loc) + return result; + + get_user(regs->edx, (u_long *)loc); + if ((regs->edx & 0xff) == 0x7f) { + int sig; + + sig = (regs->edx >> 8) & 0xff; + if (sig < NSIGNALS) + sig = current_thread_info()->exec_domain->signal_map[sig]; + regs->edx = (regs->edx & (~0xff00)) | (sig << 8); + put_user(regs->edx, (u_long *)loc); + } else if (regs->edx && regs->edx == (regs->edx & 0xff)) { + if ((regs->edx & 0x7f) < NSIGNALS) + regs->edx = current_thread_info()->exec_domain->signal_map[regs->edx & 0x7f]; + put_user(regs->edx, (u_long *)loc); + } + return result; +} + +#if defined(CONFIG_ABI_TRACE) +/* + * Trace arguments of exec(). + * + * We show up to twenty arguments and enviroment variables. + * This could as well be sysctl configurable. + */ +static void +trace_exec(struct pt_regs *regs, char *pgm, char **argv, char **envp) +{ + char **v, *p = NULL, *q = NULL; + int i; + + q = getname(pgm); + if (IS_ERR(q)) { + __abi_trace("\tpgm: %p pointer error %ld\n", pgm, PTR_ERR(q)); + } else { + __abi_trace("\tpgm: %p \"%s\"\n", pgm, q); + putname(q); + } + + for (i = 0, v = argv; v && i < 20; v++, i++) { + if (get_user(p, v) || !p) + break; + + q = getname(p); + if (IS_ERR(q)) { + __abi_trace("\targ: %p pointer error %ld\n", + p, PTR_ERR(q)); + } else { + __abi_trace("\targ: %p \"%s\"\n", p, q); + putname(q); + } + } + + if (v && p) + __abi_trace("\targ: ...\n"); + + for (i = 0, v = envp; v && i < 20; v++, i++) { + if (get_user(p, v) || !p) + break; + + q = getname(p); + if (IS_ERR(q)) { + __abi_trace("\tenv: %p pointer error %ld\n", + p, PTR_ERR(q)); + } else { + __abi_trace("\tenv: %p \"%s\"\n", p, q); + putname(q); + } + } + + if (v && p) + __abi_trace("\tenv: ...\n"); +} +#endif + +/* + * Execute a new program. + * + * The difference from the native version is that we + * optionally trace the arguments. + */ +int +abi_exec(struct pt_regs *regs) +{ + char *pgm, **argv, **envp; + char *filename; + int error; + + get_user((u_long)pgm, ((u_long *)regs->esp)+1); + get_user((u_long)argv, ((u_long *)regs->esp)+2); + get_user((u_long)envp, ((u_long *)regs->esp)+3); + +#if defined(CONFIG_ABI_TRACE) + if (abi_traced(ABI_TRACE_API)) + trace_exec(regs, pgm, argv, envp); +#endif + + filename = getname(pgm); + if (!IS_ERR(filename)) { + error = do_execve(filename, argv, envp, regs); + putname (filename); + } else + error = PTR_ERR(filename); + return error; +} + +/* + * Yet another crufy SysV multiplexed syscall. + * This time it's all the process group and session handling. + * + * NOTE: we return EPERM on get_user failures as EFAULT is not + * a valid return value for theses calls. + */ +int +abi_procids(struct pt_regs *regs) +{ + int offset = 0, op; + + if (get_user(op, ((u_long *)regs->esp)+1)) + return -EPERM; + + /* Remap op codes for current personality if necessary. */ + switch (get_cur_personality_id()) { + case (PERID_SVR3): + case (PERID_SCOSVR3): + case (PERID_WYSEV386): + case (PERID_XENIX): + /* + * SCO at least uses an interesting library to + * syscall mapping that leaves an extra return + * address between the op code and the arguments. + * + * WTF does SCO at least mean? + * Could someone please verify this with another + * SVR3 derivate as I have none. + * --hch + */ + offset = 1; + + if (op < 0 || op > 5) + return -EINVAL; + op = "\000\001\005\003\377\377"[op]; + } + + switch (op) { + case 0: /* getpgrp */ + return process_group(current); + + case 1: /* setpgrp */ + sys_setpgid(0, 0); + return process_group(current); + + case 2: /* getsid */ + { + pid_t pid; + + if (get_user(pid, ((u_long *)regs->esp)+2 + offset)) + return -EPERM; + return sys_getsid(pid); + } + + case 3: /* setsid */ + return sys_setsid(); + + case 4: /* getpgid */ + { + pid_t pid; + + if (get_user(pid, ((u_long *)regs->esp)+2 + offset)) + return -EPERM; + return sys_getpgid(pid); + } + + case 5: /* setpgid */ + { + pid_t pid, pgid; + + if (get_user(pid, ((u_long *)regs->esp)+2 + offset)) + return -EPERM; + if (get_user(pgid, ((u_long *)regs->esp)+3 + offset)) + return -EPERM; + return sys_setpgid(pid, pgid); + } + } + + return -EINVAL; +} + + +/* + * Stupid bloody thing is trying to read a directory. + * + * Some old programs expect this to work. It works on SCO. + * To emulate it we have to map a dirent to a direct. This + * involves shrinking a long inode to a short. Fortunately + * nothing this archaic is likely to care about anything + * but the filenames of entries with non-zero inodes. + */ +int +abi_read_dir(int fd, char *buf, int count) +{ + struct file *fp; + struct old_linux_dirent *de; + mm_segment_t fs; + int error, here; + int posn = 0, reclen = 0; + + + fp = fget(fd); + if (!fp) + return -EBADF; + + error = -ENOMEM; + de = (struct old_linux_dirent *)__get_free_page(GFP_KERNEL); + if (!de) + goto out_fput; + + error = 0; + while (posn + reclen < count) { + char *p; + + /* + * Save the current position and get another dirent + */ + here = fp->f_pos; + + fs = get_fs(); + set_fs (get_ds()); + error = old_readdir(fd, de, 1); + set_fs(fs); + + if (error <= 0) + break; + + /* + * If it'll fit in the buffer save it. + * Otherwise back up so it is read next time around. + * Oh, if we're at the beginning of the buffer there's + * no chance that this entry will ever fit so don't + * copy it and don't back off - we'll just pretend it + * isn't here... + */ + + /* + * SCO (at least) handles long filenames by breaking + * them up in to 14 character chunks of which all + * but the last have the inode set to 0xffff. + * Those chunks will get aligned to a 4 byte boundary + * thus leaving two bytes in each entry for other purposes. + * + * Well, that's SCO E(A)FS. + * HTFS and DTFS should handle it better. + * --hch + */ + reclen = 16 * ((de->d_namlen + 13) / 14); + if (posn + reclen > count) { + if (posn) + sys_lseek(fd, here, 0); + continue; + } + + p = de->d_name; + + /* + * Put all but the last chunk. + */ + while (de->d_namlen > 14) { + put_user(0xffff, (u_short *)(buf+posn)); + posn += 2; + if (copy_to_user(buf+posn, p, 14)) + goto out_fault; + posn += 14; + p += 14; + de->d_namlen -= 14; + } + + /* + * Put the last chunk. Note the we have to fold a + * long inode number down to a short avoiding + * giving a zero inode number since that indicates + * an unused directory slot. Note also that the + * folding used here must match that used in stat() + * or path finding programs that do read() on + * directories will fail. + */ +#if 0 + /* + * This appears to match what SCO does for + * reads on a directory with long inodes. + */ + if ((u_long)de->d_ino > 0xfffe) { + if (put_user(0xfffe, buf+posn)) + goto out_fault; + } else { + if (put_user((short)de->d_ino, buf+posn)) + goto out_fault; + } +#else + /* + * This attempts to match the way stat and + * getdents fold long inodes to shorts. + */ + if ((u_long)de->d_ino & 0xffff ) { + if (put_user((u_long)de->d_ino & 0xffff, buf+posn)) + goto out_fault; + } else { + if (put_user(0xfffe, buf+posn)) + goto out_fault; + } +#endif + posn += 2; + if (copy_to_user(buf+posn, p, de->d_namlen)) + goto out_fault; + + /* + * Ensure that filenames that don't fill the array + * completely are null filled. + */ + for (; de->d_namlen < 14; de->d_namlen++) { + if (put_user('\0', buf+posn+de->d_namlen)) + goto out_fault; + } + posn += 14; + } + + free_page((u_long)de); + fput(fp); + + /* + * If we've put something in the buffer return the byte count + * otherwise return the error status. + */ + return (posn ? posn : error); + +out_fault: + error = -EFAULT; + free_page((u_long)de); +out_fput: + fput(fp); + return error; +} + +/* + * We could use Linux read if there wouldn't be the + * read on directory issue.. + */ +int +abi_read(int fd, char *buf, int count) +{ + int error; + + error = sys_read(fd, buf, count); + if (error == -EISDIR) + error = abi_read_dir(fd, buf, count); + return error; +} + +/* + * Linux doesn't allow trailing slashes in mkdir. + * Old UNIX apps expect it work anyway, so we have + * to get rid of them here. + */ +int +abi_mkdir(const char *fname, int mode) +{ + mm_segment_t fs; + char *tmp, *p; + int error; + + tmp = getname(fname); + if (IS_ERR(tmp)) + return PTR_ERR(tmp); + + for (p = tmp; *p; p++); + p--; + if (*p == '/') + *p = '\0'; + + fs = get_fs(); + set_fs(get_ds()); + error = sys_mkdir(tmp, mode); + set_fs(fs); + + putname(tmp); + return error; +} + +/* + * Unlike UNIX Linux doesn't allow to create + * directories using mknod. + */ +int +svr4_mknod(char *filename, svr4_o_mode_t mode, svr4_o_dev_t dev) +{ + if ((mode & 0017000) == 0040000) + return abi_mkdir(filename, mode); + return sys_mknod(filename, mode, dev); +} + +static int +svr4_do_xmknod(char *filename, svr4_mode_t mode, svr4_dev_t dev) +{ + u_int minor = (dev & 0x3ffff), major = (dev >> 18); + + if (minor > 0xff || major > 0xff) + return -EINVAL; + return svr4_mknod(filename, mode, ((major << 8) | minor)); +} + + +enum {SVR4_mknod = 1, SVR4_xmknod = 2}; + +int +svr4_xmknod(int vers, char *filename, svr4_mode_t mode, svr4_dev_t dev) +{ + switch (vers) { + case SVR4_mknod: + return svr4_mknod(filename, mode, dev); + case SVR4_xmknod: + return svr4_do_xmknod(filename, mode, dev); + } + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_API, "xmknod version %d not supported\n", vers); +#endif + return -EINVAL; +} + +int +abi_kill(int pid, int sig) +{ + int insig, outsig; + + insig = (sig & 0xff); + outsig = current_thread_info()->exec_domain->signal_map[insig]; + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_SIGNAL, "kill: %d -> %d\n", insig, outsig); +#endif + + return sys_kill(pid, outsig); +} + +#if defined(CONFIG_ABI_SYSCALL_MODULES) +EXPORT_SYMBOL(abi_brk); +EXPORT_SYMBOL(abi_exec); +EXPORT_SYMBOL(abi_fork); +EXPORT_SYMBOL(abi_getgid); +EXPORT_SYMBOL(abi_getpid); +EXPORT_SYMBOL(abi_getuid); +EXPORT_SYMBOL(abi_kill); +EXPORT_SYMBOL(abi_mkdir); +EXPORT_SYMBOL(abi_pipe); +EXPORT_SYMBOL(abi_procids); +EXPORT_SYMBOL(abi_read); +EXPORT_SYMBOL(abi_time); +EXPORT_SYMBOL(abi_wait); +EXPORT_SYMBOL(svr4_mknod); +EXPORT_SYMBOL(svr4_xmknod); +#endif diff -Nru linux-2.6.7/abi/svr4/mmap.c linux-2.6.7-abi/abi/svr4/mmap.c --- linux-2.6.7/abi/svr4/mmap.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/svr4/mmap.c 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2001 Christoph Hellwig. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ident "%W% %G%" + +/* + * Support for mmap on SVR4 and derivates. + */ +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include + + +u_long +svr4_mmap(u_long addr, size_t len, int prot, int flags, int fd, svr4_off_t off) +{ + struct file *file = NULL; + u_long mapaddr; + + if (flags & SVR4_MAP_UNIMPL) { +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_UNIMPL, + "unsupported mmap flags: 0x%x\n", flags & SVR4_MAP_UNIMPL); +#endif + flags &= ~SVR4_MAP_UNIMPL; + } + + if (!(flags & SVR4_MAP_ANONYMOUS)) { + file = fget(fd); + if (!file) + goto Ebadfd; + + flags &= ~SVR4_MAP_ANONYMOUS; + flags |= MAP_ANONYMOUS; + } + + down_write(¤t->mm->mmap_sem); + mapaddr = do_mmap(file, addr, len, prot, flags, off); + up_write(¤t->mm->mmap_sem); + + if (file) + fput(file); + return mapaddr; +Ebadfd: + return -EBADFD; +} + +#if defined(CONFIG_ABI_SYSCALL_MODULES) +EXPORT_SYMBOL(svr4_mmap); +#endif diff -Nru linux-2.6.7/abi/svr4/open.c linux-2.6.7-abi/abi/svr4/open.c --- linux-2.6.7/abi/svr4/open.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/svr4/open.c 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,318 @@ +/* + * Copyright (c) 1993 Joe Portman (baron@hebron.connected.com) + * Copyright (c) 1993, 1994 Drew Sullivan (re-worked for iBCS2) + * Copyright (c) 2000 Christoph Hellwig (rewrote lookup-related code) + */ + +#ident "%W% %G%" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include + + +static int +copy_kstatfs(struct svr4_statfs *buf, struct kstatfs *st) +{ + struct svr4_statfs ibcsstat; + + ibcsstat.f_type = st->f_type; + ibcsstat.f_bsize = st->f_bsize; + ibcsstat.f_frsize = 0; + ibcsstat.f_blocks = st->f_blocks; + ibcsstat.f_bfree = st->f_bfree; + ibcsstat.f_files = st->f_files; + ibcsstat.f_ffree = st->f_ffree; + memset(ibcsstat.f_fname, 0, sizeof(ibcsstat.f_fname)); + memset(ibcsstat.f_fpack, 0, sizeof(ibcsstat.f_fpack)); + + /* Finally, copy it to the user's buffer */ + return copy_to_user(buf, &ibcsstat, sizeof(struct svr4_statfs)); +} + +int svr4_statfs(const char * path, struct svr4_statfs * buf, int len, int fstype) +{ + struct svr4_statfs ibcsstat; + + if (len > (int)sizeof(struct svr4_statfs)) + return -EINVAL; + + if (!fstype) { + struct nameidata nd; + int error; + + error = user_path_walk(path, &nd); + if (!error) { + struct kstatfs tmp; + + error = vfs_statfs(nd.dentry->d_inode->i_sb, &tmp); + if (!error && copy_kstatfs(buf, &tmp)) + error = -EFAULT; + path_release(&nd); + } + + return error; + } + + /* + * Linux can't stat unmounted filesystems so we + * simply lie and claim 500MB of 8GB is free. Sorry. + */ + ibcsstat.f_bsize = 1024; + ibcsstat.f_frsize = 0; + ibcsstat.f_blocks = 8 * 1024 * 1024; /* 8GB */ + ibcsstat.f_bfree = 500 * 1024; /* 100MB */ + ibcsstat.f_files = 60000; + ibcsstat.f_ffree = 50000; + memset(ibcsstat.f_fname, 0, sizeof(ibcsstat.f_fname)); + memset(ibcsstat.f_fpack, 0, sizeof(ibcsstat.f_fpack)); + + /* Finally, copy it to the user's buffer */ + return copy_to_user(buf, &ibcsstat, len) ? -EFAULT : 0; +} + +int svr4_fstatfs(unsigned int fd, struct svr4_statfs * buf, int len, int fstype) +{ + struct svr4_statfs ibcsstat; + + if (len > (int)sizeof(struct svr4_statfs)) + return -EINVAL; + + if (!fstype) { + struct file * file; + struct kstatfs tmp; + int error; + + error = -EBADF; + file = fget(fd); + if (!file) + goto out; + error = vfs_statfs(file->f_dentry->d_inode->i_sb, &tmp); + if (!error && copy_kstatfs(buf, &tmp)) + error = -EFAULT; + fput(file); + +out: + return error; + } + + /* + * Linux can't stat unmounted filesystems so we + * simply lie and claim 500MB of 8GB is free. Sorry. + */ + ibcsstat.f_bsize = 1024; + ibcsstat.f_frsize = 0; + ibcsstat.f_blocks = 8 * 1024 * 1024; /* 8GB */ + ibcsstat.f_bfree = 500 * 1024; /* 100MB */ + ibcsstat.f_files = 60000; + ibcsstat.f_ffree = 50000; + memset(ibcsstat.f_fname, 0, sizeof(ibcsstat.f_fname)); + memset(ibcsstat.f_fpack, 0, sizeof(ibcsstat.f_fpack)); + + /* Finally, copy it to the user's buffer */ + return copy_to_user(buf, &ibcsstat, len) ? -EFAULT : 0; +} + +int svr4_open(const char *fname, int flag, int mode) +{ +#ifdef __sparc__ + return sys_open(fname, map_flags(flag, fl_svr4_to_linux), mode); +#else + u_long args[3]; + int error, fd; + struct file *file; + mm_segment_t old_fs; + char *p; + struct sockaddr_un addr; + + fd = sys_open(fname, map_flags(flag, fl_svr4_to_linux), mode); + if (fd < 0) + return fd; + + /* Sometimes a program may open a pathname which it expects + * to be a named pipe (or STREAMS named pipe) when the + * Linux domain equivalent is a Unix domain socket. (e.g. + * UnixWare uses a STREAMS named pipe /dev/X/Nserver.0 for + * X :0 but Linux uses a Unix domain socket /tmp/.X11-unix/X0) + * It isn't enough just to make the symlink because you cannot + * open() a socket and read/write it. If we spot the error we can + * switch to socket(), connect() and things will likely work + * as expected however. + */ + file = fget(fd); + if (!file) + return fd; /* Huh?!? */ + if (!S_ISSOCK(file->f_dentry->d_inode->i_mode)) { + fput(file); + return fd; + } + fput(file); + + sys_close(fd); + args[0] = AF_UNIX; + args[1] = SOCK_STREAM; + args[2] = 0; + old_fs = get_fs(); + set_fs(get_ds()); + fd = sys_socketcall(SYS_SOCKET, args); + set_fs(old_fs); + if (fd < 0) + return fd; + + p = getname(fname); + if (IS_ERR(p)) { + sys_close(fd); + return PTR_ERR(p); + } + if (strlen(p) >= UNIX_PATH_MAX) { + putname(p); + sys_close(fd); + return -E2BIG; + } + addr.sun_family = AF_UNIX; + strcpy(addr.sun_path, p); + putname(p); + + args[0] = fd; + args[1] = (int)&addr; + args[2] = sizeof(struct sockaddr_un); + set_fs(get_ds()); + error = sys_socketcall(SYS_CONNECT, args); + set_fs(old_fs); + if (error) { + sys_close(fd); + return error; + } + + return fd; +#endif +} + +#define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de))) +#define ROUND_UP(x) (((x)+sizeof(long)-1) & ~(sizeof(long)-1)) + +struct svr4_getdents_callback { + struct dirent * current_dir; + struct dirent * previous; + int count; + int error; +}; + +static int svr4_filldir(void * __buf, const char * name, int namlen, + loff_t offset, ino_t ino, unsigned int d_type) +{ + struct dirent * dirent; + struct svr4_getdents_callback * buf = (struct svr4_getdents_callback *) __buf; + int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1); + + buf->error = -EINVAL; /* only used if we fail.. */ + if (reclen > buf->count) + return -EINVAL; + + dirent = buf->previous; + if (dirent) + put_user(offset, &dirent->d_off); + dirent = buf->current_dir; + buf->previous = dirent; + + if (is_cur_personality_flag(PERF_SHORT_INODE)) { + /* read() on a directory only handles + * short inodes but cannot use 0 as that + * indicates an empty directory slot. + * Therefore stat() must also fold + * inode numbers avoiding 0. Which in + * turn means that getdents() must fold + * inodes avoiding 0 - if the program + * was built in a short inode environment. + * If we have short inodes in the dirent + * we also have a two byte pad so we + * can let the high word fall in the pad. + * This makes it a little more robust if + * we guessed the inode size wrong. + */ + if (!((unsigned long)dirent->d_ino & 0xffff)) + dirent->d_ino = 0xfffffffe; + } + + put_user(ino, &dirent->d_ino); + put_user(reclen, &dirent->d_reclen); + copy_to_user(dirent->d_name, name, namlen); + put_user(0, dirent->d_name + namlen); + ((char *) dirent) += reclen; + buf->current_dir = dirent; + buf->count -= reclen; + return 0; +} + + + +int svr4_getdents(int fd, char *dirent, int count) +{ + struct file * file; + struct dirent * lastdirent; + struct svr4_getdents_callback buf; + int error; + + error = -EBADF; + file = fget(fd); + if (!file) + goto out; + + buf.current_dir = (struct dirent *) dirent; + buf.previous = NULL; + buf.count = count; + buf.error = 0; + error = vfs_readdir(file, svr4_filldir, &buf); + if (error < 0) + goto out_putf; + error = buf.error; + lastdirent = buf.previous; + if (lastdirent) { + put_user(file->f_pos, &lastdirent->d_off); + error = count - buf.count; + } + +out_putf: + fput(file); + +out: + return error; +} + +#if defined(CONFIG_ABI_SYSCALL_MODULES) +EXPORT_SYMBOL(svr4_fstatfs); +EXPORT_SYMBOL(svr4_getdents); +EXPORT_SYMBOL(svr4_open); +EXPORT_SYMBOL(svr4_statfs); +#endif diff -Nru linux-2.6.7/abi/svr4/signal.c linux-2.6.7-abi/abi/svr4/signal.c --- linux-2.6.7/abi/svr4/signal.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/svr4/signal.c 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,523 @@ +/* + * signal.c - signal emulation code + * + * This module does not go through the normal processing routines for + * ibcs. The reason for this is that for most events, the return is a + * procedure address for the previous setting. This procedure address + * may be negative which is not an error. Therefore, the return processing + * for standard functions is skipped by declaring this routine as a "special" + * module for the decoder and dealing with the register settings directly. + * + * Please consider this closely if you plan on changing this mode. + * -- Al Longyear + */ + +#ident "%W% %G%" + +#include +#include +#include +#include +#include +#include +#define __KERNEL_SYSCALLS__ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + + +#define SIG_HOLD ((__sighandler_t)2) /* hold signal */ + +#include +#include + +typedef void (*pfn) (void); /* Completion function */ + +/* + * Parameters to the signal functions have a common stack frame. This + * defines the stack frame. + */ +#define SIGNAL_NUMBER(regp) get_syscall_parameter((regp), 0) +#define HIDDEN_PARAM(regp) (SIGNAL_NUMBER((regp)) & ~0xFF) +#define SECOND_PARAM(regp) get_syscall_parameter((regp), 1) +#define THIRD_PARAM(regp) ((u_long)(regp)->edx) + +/* Return a mask that includes SIG only. */ +#define __sigmask(sig) (1 << ((sig) - 1)) +#define _S(nr) (1 << ((nr) - 1)) +#define _BLOCKABLE (~(_S(IBCS_SIGKILL) | _S(IBCS_SIGSTOP))) + + +void +deactivate_signal(struct task_struct *task, int signum) +{ + spin_lock_irq(&task->sighand->siglock); + sigdelset(&task->pending.signal, signum); + recalc_sigpending(); + spin_unlock_irq(&task->sighand->siglock); +} + +/* + * Translate the signal number to the corresponding item for Linux. + */ +static __inline int +abi_mapsig(int sig) +{ + if ((u_int)sig >= NSIGNALS) + return (-1); + return (current_thread_info()->exec_domain->signal_map[sig]); +} + +/* + * Either we want this static or in a header... + */ +__inline int +abi_signo(struct pt_regs *regp, int *sigp) +{ + int value; + + value = abi_mapsig(SIGNAL_NUMBER(regp) & 0xFF); + if (value == -1) { + set_error(regp, iABI_errors(EINVAL)); + return 0; + } else { + *sigp = value; + return 1; + } +} + +/* + * Process the signal() function from iBCS + * + * This version appeared in "Advanced Programming in the Unix Environment" + * by W. Richard Stevens, page 298. + */ +void +abi_sig_handler(struct pt_regs *regp, int sig, + __sighandler_t handler, int oneshot) +{ + struct sigaction act, oact; + mm_segment_t fs; + int error; + + sigemptyset(&act.sa_mask); + act.sa_restorer = NULL; + act.sa_handler = handler; + act.sa_flags = 0; + + if (oneshot) + act.sa_flags |= SA_ONESHOT | SA_NOMASK; + + fs = get_fs(); + set_fs(get_ds()); + error = sys_rt_sigaction(sig, &act, &oact, sizeof(sigset_t)); + set_fs(fs); + + if (error < 0) { + set_error(regp, iABI_errors(-error)); + } else { + set_result(regp, (int)oact.sa_handler); + } +} + +/* + * Process the signal() function from iBCS + */ +int +abi_signal(struct pt_regs *regp) +{ + __sighandler_t vec; + int sig; + + if (abi_signo(regp, &sig)) { + vec = (__sighandler_t)SECOND_PARAM(regp); + abi_sig_handler(regp, sig, vec, 1); + } + + return 0; +} + +/* + * Process the SVR4 sigset function. + * + * This is basically the same as the signal() routine with the + * exception that it will accept a SIG_HOLD parameter. + * + * A SIG_HOLD will defer the processing of the signal until a sigrelse() + * function is called or the signal handler is set again using this function. + */ +int +abi_sigset(struct pt_regs *regp) +{ + int sig, error; + sigset_t newmask, oldmask; + __sighandler_t vec; + mm_segment_t fs; + int action; + + + if (abi_signo(regp, &sig) == 0) + return 0; + + vec = (__sighandler_t)SECOND_PARAM(regp); + action = SIG_BLOCK; + + if (vec != SIG_HOLD) { + action = SIG_UNBLOCK; + deactivate_signal(current, sig); + abi_sig_handler(regp, sig, vec, 0); + } + + /* + * Process the signal hold/unhold function. + */ + sigemptyset(&newmask); + sigaddset(&newmask, sig); + + fs = get_fs(); + set_fs(get_ds()); + error = sys_rt_sigprocmask(action, &newmask, &oldmask, + sizeof(sigset_t)); + set_fs(fs); + + if (error < 0) + set_error(regp, iABI_errors(-error)); + + return 0; +} + +/* + * Process the iBCS sighold function. + * + * Suspend the signal from future recognition. + */ +void +abi_sighold(struct pt_regs *regp) +{ + sigset_t newmask, oldmask; + int error, sig; + mm_segment_t fs; + + if (!abi_signo(regp, &sig)) + return; + + sigemptyset(&newmask); + sigaddset(&newmask, sig); + + fs = get_fs(); + set_fs(get_ds()); + error = sys_rt_sigprocmask(SIG_BLOCK, &newmask, + &oldmask, sizeof(sigset_t)); + set_fs(fs); + + if (error < 0) + set_error(regp, iABI_errors(-error)); +} + +/* + * Process the iBCS sigrelse. + * + * Re-enable the signal processing from a previously suspended + * signal. This may have been done by calling the sighold() function + * or a longjmp() during the signal processing routine. If you do a + * longjmp() function then it is expected that you will call sigrelse + * or set the handler again using sigset before going on with the program. + */ +void +abi_sigrelse(struct pt_regs *regp) +{ + sigset_t newmask, oldmask; + int error, sig; + mm_segment_t fs; + + if (!abi_signo(regp, &sig)) + return; + + sigemptyset(&newmask); + sigaddset(&newmask, sig); + + fs = get_fs(); + set_fs(get_ds()); + error = sys_rt_sigprocmask(SIG_UNBLOCK, &newmask, + &oldmask, sizeof(sigset_t)); + set_fs(fs); + + if (error < 0) + set_error(regp, iABI_errors(-error)); +} + +/* + * Process the iBCS sigignore + * + * This is basically a signal (...,SIG_IGN) call. + */ +void +abi_sigignore(struct pt_regs *regp) +{ + struct sigaction act, oact; + int error, sig; + mm_segment_t fs; + + if (!abi_signo(regp, &sig)) + return; + + sigemptyset(&act.sa_mask); + + act.sa_restorer = NULL; + act.sa_handler = SIG_IGN; + act.sa_flags = 0; + + fs = get_fs(); + set_fs(get_ds()); + error = sys_rt_sigaction(sig, &act, &oact, sizeof(sigset_t)); + set_fs(fs); + + if (error < 0) + set_error(regp, iABI_errors(-error)); +} + +/* + * Process the iBCS sigpause + * + * Wait for the signal indicated to arrive before resuming the + * processing. I do not know if the signal is processed first using + * the normal event processing before the return. If someone can + * shed some light on this then please correct this code. I block + * the signal and look for it to show up in the pending list. + */ +void +abi_sigpause(struct pt_regs *regs) +{ + old_sigset_t newset; + int error, sig; + + if (!abi_signo(regs, &sig)) + return; + newset = (~0UL) & (1UL << (sig-1)); + + if ((error = sys_sigsuspend(0, current->blocked.sig[0], newset) < 0)) + set_error(regs, iABI_errors(-error)); +} + +/* + * This is the service routine for the syscall #48 (signal funcs). + * + * Examine the request code and branch on the request to the appropriate + * function. + */ +int +abi_sigfunc(struct pt_regs *regp) +{ + int sig_type = (int)HIDDEN_PARAM(regp); + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_SIGNAL|ABI_TRACE_SIGNAL_F, + "sig%s(%ld, 0x%08lx, 0x%08lx)\n", + sig_type == 0 ? "nal" + : (sig_type == 0x100 ? "set" + : (sig_type == 0x200 ? "hold" + : (sig_type == 0x400 ? "relse" + : (sig_type == 0x800 ? "ignore" + : (sig_type == 0x1000 ? "pause" + : "???" ))))), + SIGNAL_NUMBER(regp) & 0xff, + SECOND_PARAM(regp), + THIRD_PARAM(regp)); +#endif + + regp->eflags &= ~1; + regp->eax = 0; + + switch (sig_type) { + case 0x0000: + abi_signal(regp); + break; + case 0x0100: + abi_sigset(regp); + break; + case 0x0200: + abi_sighold(regp); + break; + case 0x0400: + abi_sigrelse(regp); + break; + case 0x0800: + abi_sigignore(regp); + break; + case 0x1000: + abi_sigpause(regp); + break; + default: + set_error(regp, EINVAL); + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_SIGNAL|ABI_TRACE_SIGNAL_F, + "sigfunc(%x, %ld, %lx, %lx) unsupported\n", + sig_type, SIGNAL_NUMBER(regp), + SECOND_PARAM(regp), THIRD_PARAM(regp)); +#endif + return 0; + } + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_SIGNAL|ABI_TRACE_SIGNAL_F, + "returns %d\n", get_result(regp)); +#endif + return 0; +} + +/* + * This function is used to handle the sigaction call from SVr4 binaries. + * + * If anyone else uses this, this function needs to be modified since the + * order and size of the ibcs_sigaction structure is different in ibcs + * and the SVr4 ABI + */ +asmlinkage int +abi_sigaction(int abi_signum, const struct abi_sigaction *action, + struct abi_sigaction *oldaction) +{ + struct abi_sigaction new_sa, old_sa; + struct sigaction nsa, osa; + mm_segment_t fs; + int error, signo; + + signo = abi_mapsig(abi_signum); + if (signo == -1) + return -EINVAL; + + if (oldaction) { + error = verify_area(VERIFY_WRITE, oldaction, + sizeof(struct abi_sigaction)); + if (error) + return (-EFAULT); + } + + if (action) { + error = copy_from_user(&new_sa, action, + sizeof(struct abi_sigaction)); + if (error) + return (-EFAULT); + nsa.sa_restorer = NULL; + nsa.sa_handler = new_sa.sa_handler; + nsa.sa_mask = map_sigvec_to_kernel(new_sa.sa_mask, + current_thread_info()->exec_domain->signal_map); + if (new_sa.sa_flags & ABI_SA_ONSTACK) + nsa.sa_flags |= SA_ONSTACK; + if (new_sa.sa_flags & ABI_SA_RESTART) + nsa.sa_flags |= SA_RESTART; + if (new_sa.sa_flags & ABI_SA_NODEFER) + nsa.sa_flags |= SA_NODEFER; + if (new_sa.sa_flags & ABI_SA_RESETHAND) + nsa.sa_flags |= SA_RESETHAND; + if (new_sa.sa_flags & ABI_SA_NOCLDSTOP) + nsa.sa_flags |= SA_NOCLDSTOP; + if (new_sa.sa_flags & ABI_SA_NOCLDWAIT) + nsa.sa_flags |= SA_NOCLDWAIT; + } + + fs = get_fs(); + set_fs(get_ds()); + error = sys_rt_sigaction(signo, action ? &nsa : NULL, + oldaction ? &osa : NULL, sizeof(sigset_t)); + set_fs(fs); + + if (error || !oldaction) + return (error); + + old_sa.sa_handler = osa.sa_handler; + old_sa.sa_mask = map_sigvec_from_kernel(osa.sa_mask, + current_thread_info()->exec_domain->signal_invmap); + old_sa.sa_flags = 0; + if (osa.sa_flags & SA_ONSTACK) + old_sa.sa_flags |= ABI_SA_ONSTACK; + if (osa.sa_flags & SA_RESTART) + old_sa.sa_flags |= ABI_SA_RESTART; + if (osa.sa_flags & SA_NODEFER) + old_sa.sa_flags |= ABI_SA_NODEFER; + if (osa.sa_flags & SA_RESETHAND) + old_sa.sa_flags |= ABI_SA_RESETHAND; + if (osa.sa_flags & SA_NOCLDSTOP) + old_sa.sa_flags |= ABI_SA_NOCLDSTOP; + if (osa.sa_flags & SA_NOCLDWAIT) + old_sa.sa_flags |= ABI_SA_NOCLDWAIT; + /* + * We already did the verify_area at the beginning. + */ + __copy_to_user(oldaction, &old_sa, sizeof(struct abi_sigaction)); + return 0; +} + + +static short int howcnv[] = {SIG_SETMASK, SIG_BLOCK, SIG_UNBLOCK, SIG_SETMASK}; + +asmlinkage int +abi_sigprocmask(int how, u_long *abinset, u_long *abioset) +{ + sigset_t new_set, *nset = NULL; + sigset_t old_set, *oset = NULL; + u_long new_set_abi, old_set_abi; + mm_segment_t fs; + int error; + + if (abinset) { + get_user(new_set_abi, abinset); + new_set = map_sigvec_to_kernel(new_set_abi, + current_thread_info()->exec_domain->signal_map); + nset = &new_set; + } + + if (abioset) + oset = &old_set; + + fs = get_fs(); + set_fs(get_ds()); + error = sys_rt_sigprocmask(howcnv[how], nset, oset, sizeof(sigset_t)); + set_fs(fs); + + if (!error && abioset) { + old_set_abi = map_sigvec_from_kernel(old_set, + current_thread_info()->exec_domain->signal_invmap); + put_user(old_set_abi, abioset); + } + + return (error); +} + +int +abi_sigsuspend(struct pt_regs *regs) +{ + u_long abi_mask, *abi_maskp; + old_sigset_t mask; + + abi_maskp = (u_long *)SIGNAL_NUMBER(regs); + if (get_user(abi_mask, abi_maskp)) + return -EFAULT; + + mask = map_bitvec(abi_mask, current_thread_info()->exec_domain->signal_map); +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_SIGNAL, + "sigsuspend(mask = %lx)\n", mask); +#endif + return sys_sigsuspend(0, current->blocked.sig[0], mask); +} + +#if defined(CONFIG_ABI_SYSCALL_MODULES) +EXPORT_SYMBOL(abi_sigaction); +EXPORT_SYMBOL(abi_sigfunc); +EXPORT_SYMBOL(abi_sigprocmask); +EXPORT_SYMBOL(abi_sigsuspend); +EXPORT_SYMBOL(deactivate_signal); +#endif diff -Nru linux-2.6.7/abi/svr4/socket.c linux-2.6.7-abi/abi/svr4/socket.c --- linux-2.6.7/abi/svr4/socket.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/svr4/socket.c 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,259 @@ +/* + * Copyright (c) 1994,1996 Mike Jagdis (jaggy@purplet.demon.co.uk) + */ + +#ident "%W% %G%" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + + +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 defined(CONFIG_ABI_TRACE) + 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); + } +#endif + + 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_thread_info()->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); +} + +int +abi_do_getsockopt(unsigned long *sp) +{ + int error; + int level, optname; + char *optval; + long *optlen; + + error = verify_area(VERIFY_READ, + ((unsigned long *)sp), + 5*sizeof(long)); + if (error) + return error; + + get_user((unsigned long) level, ((unsigned long *)sp)+1); + get_user((unsigned long) optname, ((unsigned long *)sp)+2); + get_user((unsigned long) optval, ((unsigned long *)sp)+3); + get_user((unsigned long) optlen, ((unsigned long *)sp)+4); + +#if defined(CONFIG_ABI_TRACE) + if (abi_traced(ABI_TRACE_STREAMS|ABI_TRACE_SOCKSYS)) { + long l; + + get_user(l, optlen); + __abi_trace("getsockopt level=%d, optname=%d, optval=0x%08lx, " + "optlen=0x%08lx[%ld]\n", level, optname, + (u_long)optval, (u_long)optlen, l); + } +#endif + + 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_thread_info()->exec_domain->sockopt_map, optname, 0); + put_user(optname, ((unsigned long *)sp)+2); + + switch (optname) { + case SO_LINGER: { + long l; + + /* 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(l, optlen); + if (l == sizeof(int)) { + put_user(0, (long *)optval); + 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: { + unsigned long len; + error = get_user(len, optlen); + if (error) + return error; + if (len < sizeof(long)) + return -EINVAL; + + error = verify_area(VERIFY_WRITE, + (char *)optval, + sizeof(long)); + if (!error) { + put_user(0, (long *)optval); + put_user(sizeof(long), + optlen); + } + return error; + } + + case SO_ORDREL: + case SO_SNDTIMEO: + case SO_RCVTIMEO: + return -ENOPROTOOPT; + + case SO_USELOOPBACK: + case SO_SNDLOWAT: + case SO_RCVLOWAT: + case SO_IMASOCKET: { + unsigned long len; + error = get_user(len, optlen); + if (error) + return error; + if (len < sizeof(long)) + return -EINVAL; + + error = verify_area(VERIFY_WRITE, + (char *)optval, + sizeof(long)); + if (!error) { + put_user(1, (long *)optval); + put_user(sizeof(long), + optlen); + } + return error; + } + } + + 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_GETSOCKOPT, sp); +} diff -Nru linux-2.6.7/abi/svr4/sockio.c linux-2.6.7-abi/abi/svr4/sockio.c --- linux-2.6.7/abi/svr4/sockio.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/svr4/sockio.c 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,307 @@ +/* $Id$ */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include /* for socksys_fdinit */ + +#include +#include + + +/* + * Check if the inode belongs to /dev/socksys. + */ +#define IS_SOCKSYS(ip) (MAJOR((ip)->i_rdev) == SOCKSYS_MAJOR) + + +static int +i_nread(u_int fd, struct file *fp, struct inode *ip, + void *data, struct pt_regs *regs) +{ + int error; + + error = verify_area(VERIFY_WRITE, data, sizeof(u_long)); + if (error) + goto fput; + +#if defined(CONFIG_ABI_XTI) + if (ip->i_sock) { + struct T_private *ti = Priv(fp); + + if (IS_SOCKSYS(ip)) + timod_update_socket(fd, fp, regs); + + if (ti && ti->pfirst) { + put_user(ti->pfirst->length, (u_long *)data); + fput(fp); + return 1; /* at least 1... (FIXME) */ + } + } +#endif + fput(fp); + + error = sys_ioctl(fd, TIOCINQ, (long)data); + if (error == -EINVAL) + return 0; + else if (error) + return error; + + __get_user(error, (u_long *)data); + return !!error; +fput: + fput(fp); + return error; +} + +static int +i_peek(u_int fd, struct file *fp, struct inode *ip, + void *data, struct pt_regs *regs) +{ +#if !defined(CONFIG_ABI_XTI) + fput(fp); + return 0; +#else + struct T_private *ti = Priv(fp); + struct T_primsg *tp; + struct strpeek buf, *uap = data; + int error = -EFAULT; + + if (copy_from_user(&buf, uap, sizeof(buf))) + goto fput; + + error = 0; + if (!ip->i_sock) + goto fput; + + if (IS_SOCKSYS(ip)) + timod_update_socket(fd, fp, regs); + + if (!ti || !ti->pfirst) + goto fput; + tp = ti->pfirst; + + error = -EFAULT; + if (!buf.flags || buf.flags == tp->pri) { + int l; + + + + if (buf.ctl.maxlen <= tp->length) + l = buf.ctl.maxlen; + else + l = tp->length; + + if (copy_to_user(buf.ctl.buf, + ((char *)&tp->type) + ti->offset, l)) + goto fput; + + if (put_user(l, &uap->ctl.len)) + goto fput; + + if (buf.dat.maxlen >= 0 && put_user(0, &uap->dat.len)) + goto fput; + + if (put_user(tp->pri, &uap->flags)) + goto fput; + + error = 1; + } +fput: + fput(fp); + return error; +#endif /* CONFIG_ABI_XTI */ +} + +static int +i_str(u_int fd, struct file *fp, struct inode *ip, + void *data, struct pt_regs *regs) +{ + int cmd; + /* + * Unpack the ioctl data and forward as a normal + * ioctl. Timeouts are not handled (yet?). + */ + struct strioctl { + int cmd, timeout, len; + char *data; + } it, *uap = data; + + if (copy_from_user(&it, uap, sizeof(struct strioctl))) + return -EFAULT; + cmd = it.cmd >> 8; + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_STREAMS, "STREAMS I_STR ioctl(%d, 0x%08x, %p)\n", + fd, it.cmd, it.data); +#endif + +#ifdef CONFIG_ABI_XTI + if (cmd == 'T') + return timod_ioctl(regs, fd, it.cmd & 0xff, it.data, it.len, + &uap->len); +#endif + return __svr4_ioctl(regs, fd, it.cmd, it.data); +} + +int +svr4_stream_ioctl(struct pt_regs *regs, int fd, u_int cmd, caddr_t data) +{ + struct file *fp; + struct inode *ip; + int error; + + fp = fget(fd); + if (!fp) + return -EBADF; + ip = fp->f_dentry->d_inode; + + /* + * Special hack^H^Hndling for socksys fds + */ + if (ip->i_sock == 0 && IS_SOCKSYS(ip)) { + error = socksys_fdinit(fd, 0, NULL, NULL); + if (error < 0) + return error; + fput(fp); + fp = fget(fd); + if (!fp) + return -EBADF; + ip = fp->f_dentry->d_inode; + } + + switch (cmd) { + case 001: /* I_NREAD */ + return i_nread(fd, fp, ip, data, regs); + + case 017: /* I_PEEK */ + return i_peek(fd, fp, ip, data, regs); + } + + fput(fp); + + switch (cmd) { + case 010: /* I_STR */ + return i_str(fd, fp, ip, data, regs); + case 002: { /* I_PUSH */ + char *tmp; + + /* Get the name anyway to validate it. */ + tmp = getname(data); + if (IS_ERR(tmp)) + return PTR_ERR(tmp); + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_STREAMS, + "%d STREAMS I_PUSH %s\n", fd, tmp); +#endif + + putname(tmp); + return 0; + } + case 003: /* I_POP */ +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_STREAMS, "%d STREAMS I_POP\n", fd); +#endif + return 0; + + case 005: /* I_FLUSH */ + return 0; + + case 013: { /* I_FIND */ + char *tmp; + + /* Get the name anyway to validate it. */ + tmp = getname(data); + if (IS_ERR(tmp)) + return PTR_ERR(tmp); + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_STREAMS, + "%d STREAMS I_FIND %s\n", fd, tmp); +#endif +#ifdef CONFIG_ABI_XTI + if (!strcmp(tmp, "timod")) { + putname(tmp); + return 1; + } +#endif + putname(tmp); + return 0; + } + + /* FIXME: These are bogus. */ + case 011: /* I_SETSIG */ + return sys_ioctl(fd, FIOSETOWN, (long)current->pid); + case 012: /* I_GETSIG */ + return sys_ioctl(fd, FIOGETOWN, (long)data); + + case 020: /* I_FDINSERT */ +#ifdef CONFIG_ABI_XTI + return stream_fdinsert(regs, fd, + (struct strfdinsert *)data); +#else + return -EINVAL; +#endif + + case 004: /* I_LOOK */ + case 006: /* I_SRDOPT */ + case 007: /* I_GRDOPT */ + case 014: /* I_LINK */ + case 015: /* I_UNLINK */ + case 021: /* I_SENDFD */ + case 022: /* I_RECVFD */ + case 023: /* I_SWROPT */ + case 040: /* I_SETCLTIME */ + return 0; /* Lie... */ + case 042: /* I_CANPUT */ + /* + * Arg is the priority band in question. We only + * support one priority band so data must be 0. + * If the band is writable we should return 1, if + * the band is flow controlled we should return 0. + */ + if (data) + return -EINVAL; + + /* FIXME: How can we test if a write would block? */ + return 1; + + case 024: /* I_GWROPT */ + case 025: /* I_LIST */ + case 026: /* I_PLINK */ + case 027: /* I_PUNLINK */ + case 030: /* I_SETEV */ + case 031: /* I_GETEV */ + case 032: /* I_STREV */ + case 033: /* I_UNSTREV */ + case 034: /* I_FLUSHBAND */ + case 035: /* I_CKBAND */ + case 036: /* I_GETBAND */ + case 037: /* I_ATMARK */ + case 041: /* I_GETCLTIME */ + /* Unsupported - drop out. */ + break; + + default: + break; + } + + printk(KERN_ERR "iBCS: STREAMS ioctl 0%o unsupported\n", cmd); + return -EINVAL; +} + +#if defined(CONFIG_ABI_SYSCALL_MODULES) +EXPORT_SYMBOL(svr4_stream_ioctl); +#endif diff -Nru linux-2.6.7/abi/svr4/socksys.c linux-2.6.7-abi/abi/svr4/socksys.c --- linux-2.6.7/abi/svr4/socksys.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/svr4/socksys.c 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,1232 @@ +/* + * socksys.c - SVR4 /dev/socksys emulation + * + * Copyright (c) 1994-1996 Mike Jagdis (jaggy@purplet.demon.co.uk) + * Copyright (c) 2001 Caldera Deutschland GmbH + * Copyright (c) 2001 Christoph Hellwig + */ + +#ident "%W% %G%" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + + +/* + * External declarations. + */ +struct svr4_stat; + +/* + * Forward declarations. + */ +static int socksys_open(struct inode *ip, struct file *fp); +#if defined(CONFIG_ABI_XTI) +static int socksys_release(struct inode *ip, struct file *fp); +static u_int socksys_poll(struct file *fp, struct poll_table_struct *wait); +#endif +static int socksys_read(struct file *fp, char *buf, + size_t count, loff_t *ppos); +static int socksys_write(struct file *fp, const char *buf, + size_t count, loff_t *ppos); + +/* + * The socksys socket file operations. + * This gets filled in on module initialization. + */ +static struct file_operations socksys_socket_fops = { + /* NOTHING */ +}; + +/* + * File operations for the user-visible device files. + * + * While open the files are handled as sockets. + */ +static struct file_operations socksys_fops = { + owner: THIS_MODULE, + open: socksys_open, + read: socksys_read, + write: socksys_write, +#ifdef CONFIG_ABI_XTI + poll: socksys_poll, + release: socksys_release, +#endif +}; + + +void +inherit_socksys_funcs(u_int fd, int state) +{ + struct file *fp; + struct inode *ip; +#ifdef CONFIG_ABI_XTI + struct T_private *tp; +#endif + struct socket *sp; + + fp = fget(fd); + if (fp == NULL) + return; + ip = fp->f_dentry->d_inode; + + /* + * SYSV sockets are BSD like with respect to ICMP errors + * with UDP rather than RFC conforming. I think. + */ + sp = SOCKET_I(ip); /* inode -> socket */ + if (sp->sk) + sock_set_flag(sp->sk, SOCK_BSDISM); + + ip->i_mode = 0020000; /* S_IFCHR */ + ip->i_rdev = MKDEV(SOCKSYS_MAJOR, 0); + +#ifdef CONFIG_ABI_XTI + tp = kmalloc(sizeof(struct T_private), GFP_KERNEL); + if (tp) { + tp->magic = XTI_MAGIC; + tp->state = state; + tp->offset = 0; + tp->pfirst = NULL; + tp->plast = NULL; + } + fp->private_data = tp; +#endif + + fp->f_op = &socksys_socket_fops; + fput(fp); +} + +static int +spx_connect(u_int fd, int spxnum) +{ + struct sockaddr_un sun; + int newfd, err; + mm_segment_t fs; + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_SOCKSYS, + "SPX: %u choose service %d\n", fd, spxnum); +#endif + + /* + * Rather than use an explicit path to the X :0 server + * socket we should use the given number to look up a path + * name to use (we can't rely on servers registering their + * sockets either - for one thing we don't emulate that yet + * and for another thing different OS binaries do things in + * different ways but all must interoperate). + * I suggest putting the mapping in, say, /dev/spx.map/%d + * where each file is a symlink containing the path of the + * socket to use. Then we can just do a readlink() here to + * get the pathname. + * Hey, this is what we do here now! + */ + sun.sun_family = AF_UNIX; + sprintf(sun.sun_path, "/dev/spx.map/%u", spxnum); + + fs = get_fs(); + set_fs(get_ds()); + err = sys_readlink(sun.sun_path, sun.sun_path, strlen(sun.sun_path)); + set_fs(fs); + + if (err == -ENOENT) { +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_SOCKSYS, + "SPX: %u no symlink \"%s\", try X :0\n", + fd, sun.sun_path); +#endif + strcpy(sun.sun_path, "/tmp/.X11-unix/X0"); + } else if (err < 0) { +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_SOCKSYS, + "SPX: readlink failed with %d\n", err); +#endif + return (err); + } else + sun.sun_path[err] = '\0'; + + set_fs(get_ds()); + newfd = sys_socket(AF_UNIX, SOCK_STREAM, 0); + set_fs(fs); + + if (newfd < 0) { +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_SOCKSYS, + "SPX: %u got no UNIX domain socket (err=%d)\n", + fd, err); +#endif + return (newfd); + } + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_SOCKSYS, + "SPX: %u got a UNIX domain socket\n", fd); +#endif + + set_fs(get_ds()); + err = sys_connect(newfd, (struct sockaddr *)&sun, sizeof(struct sockaddr_un)); + set_fs(fs); + + if (err) { +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_SOCKSYS, + "SPX: %u connect to \"%s\" failed (err = %d)\n", + fd, sun.sun_path, err); +#endif + sys_close(newfd); + return (err); + } + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_SOCKSYS, + "SPX: %u connect to \"%s\"\n", + fd, sun.sun_path); +#endif + return (newfd); +} + +/* + * XTI to Linux protocol table. + */ +static int inet_prot[16] = { + IPPROTO_ICMP, IPPROTO_ICMP, + IPPROTO_IGMP, IPPROTO_IPIP, + IPPROTO_TCP, IPPROTO_EGP, + IPPROTO_PUP, IPPROTO_UDP, + IPPROTO_IDP, IPPROTO_RAW, +}; + +static int inet_type[16] = { + SOCK_RAW, SOCK_RAW, + SOCK_RAW, SOCK_RAW, + SOCK_STREAM, SOCK_RAW, + SOCK_RAW, SOCK_DGRAM, + SOCK_RAW, SOCK_RAW, +}; + + +static int +xti_connect(struct file *fp, u_int fd, dev_t dev) +{ + int family, type, prot = 0, i, s; + mm_segment_t fs; + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_SOCKSYS, + "XTI: %d get socket for transport end point " + "(dev = 0x%04x)\n", fd, dev); +#endif + + switch ((family = ((MINOR(dev) >> 4) & 0x0f))) { + case AF_UNIX: + type = SOCK_STREAM; + break; + case AF_INET: + i = MINOR(dev) & 0x0f; + type = inet_type[i]; + prot = inet_prot[i]; + break; + default: + type = SOCK_RAW; + break; + } + + fput(fp); + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_SOCKSYS, + "XTI: %d socket %d %d %d\n", + fd, family, type, prot); +#endif + + fs = get_fs(); + set_fs(get_ds()); + s = sys_socket(family, type, prot); + set_fs(fs); + + return (s); +} + +int +socksys_fdinit(int fd, int rw, const char *buf, int *count) +{ + struct file *fp; + struct inode *ip; + int sockfd, error = -EINVAL; + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_SOCKSYS, "socksys: fd=%d initializing\n", fd); +#endif + + fp = fget(fd); + if (!fp) + return -EBADF; + ip = fp->f_dentry->d_inode; + + /* + * Minor = 0 is the socksys device itself. No special handling + * will be needed as it is controlled by the application + * via ioctls. + */ + if (MINOR(ip->i_rdev) == 0) + goto fput; + + /* + * Minor = 1 is the spx device. This is the client side of a + * streams pipe to the X server. Under SCO and friends + * the library code messes around setting the connection + * up itself. We do it ourselves - this means we don't + * need to worry about the implementation of the server + * side (/dev/X0R - which must exist but can be a link + * to /dev/null) nor do we need to actually implement + * getmsg/putmsg. + */ + if (MINOR(ip->i_rdev) == 1) { + int unit = 1; + + /* + * It seems early spx implementations were just a + * quick hack to get X to work. They only supported + * one destination and connected automatically. + * Later versions take a single byte write, the + * value of the byte telling them which destination + * to connect to. Hence this quick hack to work + * with both. If the first write is a single byte + * it's a connect request otherwise we auto-connect + * to destination 1. + */ +#if 0 + if (rw == 1 && *count == 1) { + error = get_user(unit, buf); + if (error) + goto fput; + (*count)--; + } +#endif + + fput(fp); + + sockfd = spx_connect(fd, unit); + } else { + /* + * Otherwise the high 4 bits specify the address/protocol + * family (AF_INET, AF_UNIX etc.) and the low 4 bits determine + * the protocol (IPPROTO_IP, IPPROTO_UDP, IPPROTO_TCP etc.) + * although not using a one-to-one mapping as the minor number + * is not big enough to hold everything directly. The socket + * type is inferrred from the protocol. + */ + sockfd = xti_connect(fp, fd, ip->i_rdev); + } + + /* + * Give up if we weren't able to allocate a socket. + * There is no sense in plying our funny game without a new fd. + */ + if (sockfd < 0) + return sockfd; + + /* + * Redirect operations on the socket fd via our emulation + * handlers then swap the socket fd and the original fd, + * discarding the original fd. + */ + inherit_socksys_funcs(sockfd, TS_UNBND); + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_SOCKSYS, "XTI: %d -> %d\n", fd, sockfd); +#endif + + sys_dup2(sockfd, fd); + sys_close(sockfd); + return 1; + +fput: + fput(fp); + return error; +} + +static int +socksys_open(struct inode *ip, struct file *fp) +{ +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_SOCKSYS, + "socksys: fp=0x%p, ip=0x%p opening\n", fp, ip); +#endif + return 0; +} + +#ifdef CONFIG_ABI_XTI +static int +socksys_release(struct inode *ip, struct file *fp) +{ + int error = 0; + + /* + * Not being a socket is not an error - it is probably + * just the pseudo device transport provider. + */ + if (!ip || !ip->i_sock) + goto out; + + if (fp->private_data) { + struct T_primsg *it; + + it = ((struct T_private *)fp->private_data)->pfirst; + while (it) { + struct T_primsg *tmp = it; + it = it->next; + kfree(tmp); + } + kfree(fp->private_data); + } + error = socket_file_ops.release(ip, fp); +out: +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_SOCKSYS, "socksys: %p closed\n", fp); +#endif + return error; +} + +static u_int +socksys_poll(struct file *fp, struct poll_table_struct *wait) +{ + struct inode *ip = fp->f_dentry->d_inode; + u_int mask = 0; + + /* + * If this is a timod transport end point and there + * is a control message queued we have readable data. + */ + if (ip && ip->i_sock && MINOR(ip->i_rdev) != 1) { + if (Priv(fp) && Priv(fp)->pfirst) { + if (Priv(fp)->pfirst->pri == MSG_HIPRI) + mask |= POLLPRI; + else + mask |= POLLIN; + } + } + + return (mask | socket_file_ops.poll(fp, wait)); +} +#endif + +static int +socksys_read(struct file *fp, char *buf, size_t count, loff_t *ppos) +{ + int fd, error; + + if (fp->f_dentry->d_inode->i_sock) + BUG(); + + for (fd = 0; fd < current->files->max_fdset; fd++) { + if (fcheck(fd) == fp) { + error = socksys_fdinit(fd, 0, NULL, NULL); + if (error < 0) + return error; + fput(fp); + fp = fget(fd); + return fp->f_op->read(fp, buf, count, ppos); + } + } + + return -EINVAL; +} + +static int +socksys_write(struct file *fp, const char *buf, size_t count, loff_t *ppos) +{ + int fd, error; + + if (fp->f_dentry->d_inode->i_sock) + BUG(); + + for (fd = 0; fd < current->files->max_fdset; fd++) { + if (fcheck(fd) == fp) { + error = socksys_fdinit(fd, 1, buf, &count); + if (error < 0) + return error; + fput(fp); + fp = fget(fd); + if (count == 1) + return 1; + printk("count=%d\n", count); + return fp->f_op->write(fp, buf, count, ppos); + } + } + + return -EINVAL; +} + + +/* + * Get a socket but replace the socket file + * operations with our own so we can do the + * right thing for ioctls. + */ +static int +socksys_socket(u_long *sp) +{ + u_long x; + int fd; + + get_user(x, ((u_long *)sp)+0); + put_user(map_value(current_thread_info()->exec_domain->af_map, x, 0), sp+0); + get_user(x, ((u_long *)sp)+1); + put_user(map_value(current_thread_info()->exec_domain->socktype_map, x, 0), sp+1); + + fd = sys_socketcall(SYS_SOCKET, sp); + if (fd >= 0) + inherit_socksys_funcs(fd, TS_UNBND); + return fd; +} + +static int +socksys_accept(u_long *sp) +{ + int fd; + + fd = sys_socketcall(SYS_ACCEPT, sp); + if (fd >= 0) + inherit_socksys_funcs(fd, TS_DATA_XFER); + return fd; +} + +static int +socksys_getipdomain(u_long *sp) +{ + char *name, *p; + int error, len; + + error = get_user((u_long)name, (char *)(sp+0)); + if (error) + return error; + + get_user(len, sp+1); + if (error) + return error; + + down_read(&uts_sem); + error = verify_area(VERIFY_WRITE, name, len); + if (!error) { + --len; + for (p = system_utsname.nodename; *p && *p != '.'; p++) + ; + if (*p == '.') + p++; + else + p = system_utsname.domainname; + + if (strcmp(p, "(none)")) { + for (; *p && len > 0; p++,len--) { + __put_user(*p, name); + name++; + } + } + __put_user('\0', name); + } + up_read(&uts_sem); + return error; +} + +static int +socksys_setipdomain(u_long *sp) +{ + char *name, *p; + int error, len, togo; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + error = get_user((unsigned long) name, (char *)(sp+0)); + if (error) + return error; + + error = get_user(len, sp+1); + if (error) + return error; + + down_write(&uts_sem); + togo = __NEW_UTS_LEN; + for (p = system_utsname.nodename; *p && *p != '.'; p++,togo--) + ; + if (*p == '.') + p++,togo--; + + error = -EINVAL; + if (len <= togo) { + while (len-- > 0) { + get_user(*p, name); + p++; + name++; + } + *p = '\0'; + error = 0; + } + up_write(&uts_sem); + return error; +} + +static int +socksys_setreugid(int cmd, u_long *sp) +{ + uid_t ruid, euid; + int error; + + error = get_user(ruid, sp+0); + if (error) + return error; + + error = get_user(euid, sp+1); + if (error) + return error; + + return (cmd == SSYS_SO_SETREUID) ? + sys_setreuid16(ruid, euid) : + sys_setregid16(ruid, euid); +} + +/* + * Get a socketpair but replace the socket file + * operations with our own so we can do the + * right thing for ioctls. + */ +static int +socksys_socketpair(u_long *sp) +{ + struct file *fp; + struct inode *ip; + mm_segment_t fs; + int pairin[2], pairout[2]; + int error; + + /* + * The first two arguments are file descriptors + * of sockets which have already been opened + * and should now be connected back to back. + */ + error = get_user(pairin[0], sp+0); + if (!error) + error = get_user(pairin[1], sp+1); + if (error) + return error; + + fp = fget(pairin[0]); + if (!fp) + return -EBADF; + ip = fp->f_dentry->d_inode; + + fput(fp); /* this looks boguos */ + if (!ip || !ip->i_sock) + return -EBADF; + + + /* + * XXX Do we need to close these here? + * XXX If we fail to connect them should they be open? + */ + sys_close(pairin[0]); + sys_close(pairin[1]); + + fs = get_fs(); + set_fs(get_ds()); + error = sys_socketpair(AF_UNIX, SOCKET_I(ip)->type, 0, pairout); + set_fs(fs); + + if (error < 0) + return error; + + if (pairout[0] != pairin[0]) { + sys_dup2(pairout[0], pairin[0]); + sys_close(pairout[0]); + } + + if (pairout[1] != pairin[1]) { + sys_dup2(pairout[1], pairin[1]); + sys_close(pairout[1]); + } + + inherit_socksys_funcs(pairin[0], TS_DATA_XFER); + inherit_socksys_funcs(pairin[1], TS_DATA_XFER); + return 0; +} + +int +socksys_syscall(u_long *sp) +{ + int error, cmd; + + error = get_user(cmd, sp); + if (error) + return error; + sp++; + +#if defined(CONFIG_ABI_TRACE) + if (abi_traced(ABI_TRACE_SOCKSYS)) { + u_long a0, a1, a2, a3, a4, a5; + static const char * const cmd_map[] = { + "", "accept", "bind", "connect", "getpeername", + "getsockname", "getsockopt", "listen", "recv", + "recvfrom", "send", "sendto", "setsockopt", "shutdown", + "socket", "select", "getipdomain", "setipdomain", + "adjtime", "setreuid", "setregid", "gettimeofday", + "settimeofday", "getitimer", "setitimer", + "recvmsg", "sendmsg", "sockpair" + }; + + get_user(a0, sp+0); + get_user(a1, sp+1); + get_user(a2, sp+2); + get_user(a3, sp+3); + get_user(a4, sp+4); + get_user(a5, sp+5); + + __abi_trace("socksys: %s (%d) " + "<0x%lx,0x%lx,0x%lx,0x%lx,0x%lx,0x%lx>\n", + (cmd >= 0 && + cmd < sizeof(cmd_map) / sizeof(cmd_map[0])) + ? cmd_map[cmd] : "???", cmd, + a0, a1, a2, a3, a4, a5); + } +#endif + + switch (cmd) { + case SSYS_SO_SOCKET: + return socksys_socket(sp); + case SSYS_SO_ACCEPT: + return socksys_accept(sp); + case SSYS_SO_BIND: + return sys_socketcall(SYS_BIND, sp); + case SSYS_SO_CONNECT: + return sys_socketcall(SYS_CONNECT, sp); + case SSYS_SO_GETPEERNAME: + return sys_socketcall(SYS_GETPEERNAME, sp); + case SSYS_SO_GETSOCKNAME: + return sys_socketcall(SYS_GETSOCKNAME, sp); + case SSYS_SO_GETSOCKOPT: + return abi_do_getsockopt((u_long *)sp); + case SSYS_SO_LISTEN: + return sys_socketcall(SYS_LISTEN, sp); + case SSYS_SO_RECV: + if ((error = sys_socketcall(SYS_RECV, sp)) == -EAGAIN) + return -EWOULDBLOCK; + return error; + case SSYS_SO_RECVFROM: + if ((error = sys_socketcall(SYS_RECVFROM, sp)) == -EAGAIN) + return -EWOULDBLOCK; + return error; + case SSYS_SO_SEND: + if ((error = sys_socketcall(SYS_SEND, sp)) == -EAGAIN) + error = -EWOULDBLOCK; + return error; + case SSYS_SO_SENDTO: + if ((error = sys_socketcall(SYS_SENDTO, sp)) == -EAGAIN) + error = -EWOULDBLOCK; + return error; + case SSYS_SO_SETSOCKOPT: + return abi_do_setsockopt(sp); + case SSYS_SO_SHUTDOWN: + return sys_socketcall(SYS_SHUTDOWN, sp); + case SSYS_SO_GETIPDOMAIN: + return socksys_getipdomain(sp); + case SSYS_SO_SETIPDOMAIN: + return socksys_setipdomain(sp); + case SSYS_SO_SETREUID: + case SSYS_SO_SETREGID: + return socksys_setreugid(cmd, sp); + case SSYS_SO_GETTIME: + case SSYS_SO_SETTIME: + { + struct timeval *tv; + struct timezone *tz; + + error = get_user((unsigned long) tv, sp+0); + if (!error) + error = get_user((unsigned long) tz, sp+1); + if (error) + return error; + return (cmd == SSYS_SO_GETTIME) + ? sys_gettimeofday(tv, tz) + : sys_settimeofday(tv, tz); + } + + case SSYS_SO_GETITIMER: + { + int which; + struct itimerval *value; + + error = get_user((unsigned long) which, sp+0); + if (!error) + error = get_user((unsigned long) value, sp+1); + if (error) + return error; + return sys_getitimer(which, value); + } + case SSYS_SO_SETITIMER: + { + int which; + struct itimerval *value, *ovalue; + + error = get_user((unsigned long) which, sp+0); + if (!error) + error = get_user((unsigned long) value, sp+1); + if (!error) + error = get_user((unsigned long) ovalue, sp+2); + if (error) + return error; + return sys_setitimer(which, value, ovalue); + } + +#if BUGGY + case SSYS_SO_SELECT: + /* + * This may be wrong? I don't know how to trigger + * this case. Select seems to go via the Xenix + * select entry point. + */ + return sys_select(sp); +#endif + + case SSYS_SO_ADJTIME: + return -EINVAL; + + /* + * These appear in SCO 3.2v5. I assume that the format of + * a msghdr is identical with Linux. I have not checked. + */ + case SSYS_SO_RECVMSG: + if ((error = sys_socketcall(SYS_RECVMSG, sp)) == -EAGAIN) + error = -EWOULDBLOCK; + return error; + case SSYS_SO_SENDMSG: + if ((error = sys_socketcall(SYS_SENDMSG, sp)) == -EAGAIN) + error = -EWOULDBLOCK; + return error; + case SSYS_SO_SOCKPAIR: + return socksys_socketpair(sp); + } + + return -EINVAL; +} + +static int +socksys_getdomainname(caddr_t arg) +{ + struct domnam_args dn; + char *p; + int error; + + if (copy_from_user(&dn, arg, sizeof(struct domnam_args))) + return -EFAULT; + + down_read(&uts_sem); + error = verify_area(VERIFY_WRITE, dn.name, dn.namelen); + if (!error) { + --dn.namelen; + for (p = system_utsname.domainname; *p && dn.namelen > 0; p++) { + __put_user(*p, dn.name); + dn.name++; + dn.namelen--; + } + __put_user('\0', dn.name); + } + up_read(&uts_sem); + return error; +} + +static int +socksys_setdomainname(caddr_t arg) +{ + struct domnam_args dn; + + if (copy_from_user(&dn, arg, sizeof(struct domnam_args))) + return -EFAULT; + return sys_setdomainname(dn.name, dn.namelen); +} + +/* + * I think this was used before symlinks were added + * to the base SCO OS? + */ +static int +socksys_lstat(caddr_t arg) +{ + struct lstat_args st; + + if (copy_from_user(&st, arg, sizeof(struct lstat_args))) + return -EFAULT; + return svr4_lstat(st.fname, st.statb); +} + +static int +socksys_getfh(caddr_t arg) +{ + struct getfh_args gf; + struct nameidata nd; + int error; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + if (copy_from_user(&gf, arg, sizeof(struct getfh_args))) + return -EFAULT; + + error = verify_area(VERIFY_WRITE, gf.fhp, sizeof(fhandle_t)); + if (error) + return error; + + error = user_path_walk(gf.fname, &nd); + if (error) + return error; + + error = do_revalidate(nd.dentry); + if (!error) { + struct inode *ip = nd.dentry->d_inode; + + __put_user(ip->i_rdev, &gf.fhp->fh.fsid); + __put_user(ip->i_ino, &gf.fhp->fh.fno); + __put_user(0L, &gf.fhp->fh.fgen); + __put_user(ip->i_rdev, &gf.fhp->fh.ex_fsid); + __put_user(ip->i_ino, &gf.fhp->fh.ex_fno); + __put_user(0L, &gf.fhp->fh.ex_fgen); + error = 0; + } + path_release(&nd); + return error; +} + +static int +socksys_getpeername(int fd, caddr_t arg) +{ + struct sockaddr uaddr; + int addrlen; + mm_segment_t fs; + int error; + + addrlen = sizeof(struct sockaddr); + + error = verify_area(VERIFY_WRITE, arg, addrlen); + if (error) + return error; + + fs = get_fs(); + set_fs(get_ds()); + error = sys_getpeername(fd, &uaddr, &addrlen); + set_fs(fs); + + if (error >= 0) + copy_to_user(arg, &uaddr, addrlen); + return error; +} + +static int +socksys_getsockname(int fd, caddr_t arg) +{ + struct sockaddr uaddr; + int addrlen; + mm_segment_t fs; + int error; + + addrlen = sizeof(struct sockaddr); + + error = verify_area(VERIFY_WRITE, arg, addrlen); + if (error) + return error; + + fs = get_fs(); + set_fs(get_ds()); + error = sys_getsockname(fd, &uaddr, &addrlen); + set_fs(fs); + + if (error >= 0) + copy_to_user(arg, &uaddr, addrlen); + return error; +} + +static int +socksys_gifonep(caddr_t data) +{ + return -EOPNOTSUPP; +} + +static int +socksys_sifonep(caddr_t data) +{ +#if 0 + struct svr4_ifreq *ifr = (struct svr4_ifreq *)data; + + printk("SIOCSIFONEP (spsize = %x, spthresh = %x) not supported\n", + ifr->svr4_ifr_onepacket.spsize, + ifr->svr4_ifr_onepacket.spthresh); +#endif + return -EOPNOTSUPP; +} + +int +abi_ioctl_socksys(int fd, unsigned int cmd, caddr_t arg) +{ + int error; + + switch (cmd) { + /* + * Strictly the ip domain and nis domain are separate and + * distinct under SCO but Linux only has the one domain. + */ + case NIOCGETDOMNAM: + return socksys_getdomainname(arg); + case NIOCSETDOMNAM: + return socksys_setdomainname(arg); + case NIOCLSTAT: + return socksys_lstat(arg); + case NIOCOLDGETFH: + case NIOCGETFH: + return socksys_getfh(arg); + case NIOCNFSD: + case NIOCASYNCD: + case NIOCCLNTHAND: + case NIOCEXPORTFS: + return -EINVAL; + + case SSYS_SIOCSOCKSYS: /* Pseudo socket syscall */ + case SVR4_SIOCSOCKSYS: + return socksys_syscall((u_long *)arg); + + case SSYS_SIOCSHIWAT: /* set high watermark */ + case SVR4_SIOCSHIWAT: + case SSYS_SIOCSLOWAT: /* set low watermark */ + case SVR4_SIOCSLOWAT: + /* + * Linux doesn't support them but lie anyway + * or some things take it as fatal (why?) + * + * FIXME: actually we can do this now... + */ + return 0; + case SSYS_SIOCGHIWAT: /* get high watermark */ + case SVR4_SIOCGHIWAT: + case SSYS_SIOCGLOWAT: /* get low watermark */ + case SVR4_SIOCGLOWAT: + /* + * Linux doesn't support them but lie anyway + * or some things take it as fatal (why?) + * + * FIXME: actually we can do this now... + */ + if ((error = verify_area(VERIFY_WRITE, arg, sizeof(u_long)))) + return error; + put_user(0, (u_long *)arg); + return 0; + case SSYS_SIOCATMARK: /* at oob mark? */ + case SVR4_SIOCATMARK: + return sys_ioctl(fd, SIOCATMARK, (long)arg); + + case SSYS_SIOCSPGRP: /* set process group */ + case SVR4_SIOCSPGRP: + return sys_ioctl(fd, SIOCSPGRP, (long)arg); + case SSYS_SIOCGPGRP: /* get process group */ + case SVR4_SIOCGPGRP: + return sys_ioctl(fd, SIOCGPGRP, (long)arg); + + case FIONREAD: + case SSYS_FIONREAD: /* BSD compatibilty */ + error = sys_ioctl(fd, TIOCINQ, (long)arg); +#if defined(CONFIG_ABI_TRACE) + if (!error && abi_traced(ABI_TRACE_SOCKSYS)) { + u_long n; + + get_user(n, (u_long *)arg); + __abi_trace("socksys: %d FIONREAD " + "found %lu bytes ready\n", + fd, n); + } +#endif + return error; + case SSYS_FIONBIO: /* BSD compatibilty */ + return sys_ioctl(fd, FIONBIO, (long)arg); + case SSYS_FIOASYNC: /* BSD compatibilty */ + return sys_ioctl(fd, FIOASYNC, (long)arg); + case SSYS_SIOCADDRT: /* add route */ + case SVR4_SIOCADDRT: + return sys_ioctl(fd, SIOCADDRT, (long)arg); + case SSYS_SIOCDELRT: /* delete route */ + case SVR4_SIOCDELRT: + return sys_ioctl(fd, SIOCDELRT, (long)arg); + case SSYS_SIOCSIFADDR: /* set ifnet address */ + case SVR4_SIOCSIFADDR: + return sys_ioctl(fd, SIOCSIFADDR, (long)arg); + case SSYS_SIOCGIFADDR: /* get ifnet address */ + case SVR4_SIOCGIFADDR: + return sys_ioctl(fd, SIOCGIFADDR, (long)arg); + case SSYS_SIOCSIFDSTADDR: /* set p-p address */ + case SVR4_SIOCSIFDSTADDR: + return sys_ioctl(fd, SIOCSIFDSTADDR, (long)arg); + case SSYS_SIOCGIFDSTADDR: /* get p-p address */ + case SVR4_SIOCGIFDSTADDR: + return sys_ioctl(fd, SIOCGIFDSTADDR, (long)arg); + case SSYS_SIOCSIFFLAGS: /* set ifnet flags */ + case SVR4_SIOCSIFFLAGS: + return sys_ioctl(fd, SIOCSIFFLAGS, (long)arg); + case SSYS_SIOCGIFFLAGS: /* get ifnet flags */ + case SVR4_SIOCGIFFLAGS: +#if 0 + case SVRX_SIOCGIFFLAGS: +#endif + return sys_ioctl(fd, SIOCGIFFLAGS, (long)arg); + case SSYS_SIOCGIFCONF: /* get ifnet list */ + case SVR4_SIOCGIFCONF: +#if 0 + case SVRX_SIOCGIFCONF: +#endif + return sys_ioctl(fd, SIOCGIFCONF, (long)arg); + case SSYS_SIOCGIFBRDADDR: /* get broadcast addr */ + case SVR4_SIOCGIFBRDADDR: + return sys_ioctl(fd, SIOCGIFBRDADDR, (long)arg); + case SSYS_SIOCSIFBRDADDR: /* set broadcast addr */ + case SVR4_SIOCSIFBRDADDR: + return sys_ioctl(fd, SIOCSIFBRDADDR, (long)arg); + case SSYS_SIOCGIFNETMASK: /* get net addr mask */ + case SVR4_SIOCGIFNETMASK: + return sys_ioctl(fd, SIOCGIFNETMASK, (long)arg); + case SSYS_SIOCSIFNETMASK: /* set net addr mask */ + return sys_ioctl(fd, SIOCSIFNETMASK, (long)arg); + case SSYS_SIOCGIFMETRIC: /* get IF metric */ + case SVR4_SIOCGIFMETRIC: + return sys_ioctl(fd, SIOCGIFMETRIC, (long)arg); + case SSYS_SIOCSIFMETRIC: /* set IF metric */ + case SVR4_SIOCSIFMETRIC: + return sys_ioctl(fd, SIOCSIFMETRIC, (long)arg); + case SSYS_SIOCSARP: /* set arp entry */ + case SVR4_SIOCSARP: + return sys_ioctl(fd, SIOCSARP, (long)arg); + case SSYS_SIOCGARP: /* get arp entry */ + case SVR4_SIOCGARP: + return sys_ioctl(fd, SIOCGARP, (long)arg); + case SSYS_SIOCDARP: /* delete arp entry */ + case SVR4_SIOCDARP: + return sys_ioctl(fd, SIOCDARP, (long)arg); + case SSYS_SIOCGENADDR: /* Get ethernet addr */ + case SVR4_SIOCGENADDR: + return sys_ioctl(fd, SIOCGIFHWADDR, (long)arg); + case SSYS_SIOCSIFMTU: /* get if_mtu */ + case SVR4_SIOCSIFMTU: + return sys_ioctl(fd, SIOCSIFMTU, (long)arg); + case SSYS_SIOCGIFMTU: /* set if_mtu */ + case SVR4_SIOCGIFMTU: + return sys_ioctl(fd, SIOCGIFMTU, (long)arg); + + case SSYS_SIOCGETNAME: /* getsockname */ + case SVR4_SIOCGETNAME: + return socksys_getsockname(fd, arg); + case SSYS_SIOCGETPEER: /* getpeername */ + case SVR4_SIOCGETPEER: + return socksys_getpeername(fd, arg); + + case SSYS_IF_UNITSEL: /* set unit number */ + case SVR4_IF_UNITSEL: + case SSYS_SIOCXPROTO: /* empty proto table */ + case SVR4_SIOCXPROTO: + + case SSYS_SIOCIFDETACH: /* detach interface */ + case SVR4_SIOCIFDETACH: + case SSYS_SIOCGENPSTATS: /* get ENP stats */ + case SVR4_SIOCGENPSTATS: + + case SSYS_SIOCSIFNAME: /* set interface name */ + case SVR4_SIOCSIFNAME: + + case SSYS_SIOCPROTO: /* link proto */ + case SVR4_SIOCPROTO: + case SSYS_SIOCX25XMT: + case SVR4_SIOCX25XMT: + case SSYS_SIOCX25RCV: + case SVR4_SIOCX25RCV: + case SSYS_SIOCX25TBL: + case SVR4_SIOCX25TBL: + + case SSYS_SIOCGIFONEP: /* get one-packet params */ + return socksys_gifonep(arg); + case SSYS_SIOCSIFONEP: /* set one-packet params */ + return socksys_sifonep(arg); + + default: + printk(KERN_DEBUG "%d iBCS: socksys: %d: ioctl 0x%x with argument 0x%p requested\n", + current->pid, fd, cmd, arg); + break; + } + + return -EINVAL; +} + +static int __init +socksys_init(void) +{ + int ret; + + if ((ret = register_chrdev(SOCKSYS_MAJOR, "socksys", &socksys_fops))) { + printk(KERN_ERR "abi: unable register socksys char major\n"); + return (ret); + } + + fops_get(&socket_file_ops); + socksys_socket_fops = socket_file_ops; +#ifdef CONFIG_ABI_XTI + socksys_socket_fops.release = socksys_release; + socksys_socket_fops.poll = socksys_poll; +#endif + return (0); +} + +static void __exit +socksys_exit(void) +{ + fops_put(&socket_file_ops); + unregister_chrdev(SOCKSYS_MAJOR, "socksys"); +} + +module_init(socksys_init); +module_exit(socksys_exit); + +#if defined(CONFIG_ABI_SYSCALL_MODULES) +EXPORT_SYMBOL(abi_ioctl_socksys); +EXPORT_SYMBOL(socksys_syscall); +#endif diff -Nru linux-2.6.7/abi/svr4/stat.c linux-2.6.7-abi/abi/svr4/stat.c --- linux-2.6.7/abi/svr4/stat.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/svr4/stat.c 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,223 @@ +/* + * Copyright (c) 2001 Caldera Deutschland GmbH. + * Copyright (c) 2001 Christoph Hellwig. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ident "%W% %G%" + +/* + * SVR4 stat & friends support. + */ +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + + +enum {SVR4_stat = 1, SVR4_xstat = 2}; + +int +report_svr4_stat(struct kstat *stp, struct svr4_stat *bufp) +{ + struct svr4_stat buf; + + memset(&buf, 0, sizeof(struct svr4_stat)); + + + buf.st_dev = linux_to_svr4_o_dev_t(stp->dev); + buf.st_ino = linux_to_svr4_o_ino_t(stp->ino); + buf.st_mode = stp->mode; + buf.st_nlink = stp->nlink; + buf.st_uid = linux_to_svr4_o_uid_t(stp->uid); + buf.st_gid = linux_to_svr4_o_gid_t(stp->gid); + buf.st_rdev = linux_to_svr4_o_dev_t(stp->rdev); + + if (stp->size > MAX_NON_LFS) + return -EOVERFLOW; /* XXX: what to return for SVR4?? */ + + buf.st_size = stp->size; + + buf.st_atime = stp->atime.tv_sec; + buf.st_mtime = stp->mtime.tv_sec; + buf.st_ctime = stp->ctime.tv_sec; + + if (copy_to_user(bufp, &buf, sizeof(struct svr4_stat))) + return -EFAULT; + return 0; +} + +int +report_svr4_xstat(struct kstat *stp, struct svr4_xstat *bufp) +{ + struct svr4_xstat buf; + + memset(&buf, 0, sizeof(struct svr4_xstat)); + + + buf.st_dev = linux_to_svr4_dev_t(stp->dev); + buf.st_ino = linux_to_svr4_ino_t(stp->ino); + buf.st_mode = stp->mode; + buf.st_nlink = stp->nlink; + buf.st_uid = linux_to_svr4_uid_t(stp->uid); + buf.st_gid = linux_to_svr4_gid_t(stp->gid); + buf.st_rdev = linux_to_svr4_dev_t(stp->rdev); + + if (stp->size > MAX_NON_LFS) + return -EOVERFLOW; /* XXX: what to return for SVR4?? */ + + buf.st_size = stp->size; + + buf.st_atim.tv_sec = stp->atime.tv_sec; + buf.st_atim.tv_usec = stp->atime.tv_nsec / 1000; + buf.st_mtim.tv_sec = stp->mtime.tv_sec; + buf.st_mtim.tv_usec = stp->mtime.tv_nsec / 1000; + buf.st_ctim.tv_sec = stp->ctime.tv_sec; + buf.st_ctim.tv_usec = stp->ctime.tv_nsec / 1000; + + buf.st_blksize = stp->blksize; + buf.st_blocks = stp->blocks; + + if (copy_to_user(bufp, &buf, sizeof(struct svr4_xstat))) + return -EFAULT; + return 0; +} + +int +svr4_stat(char *filename, struct svr4_stat *bufp) +{ + struct kstat st; + int error; + + error = vfs_stat(filename, &st); + if (!error) + error = report_svr4_stat(&st, bufp); + return error; +} + +int +svr4_lstat(char *filename, struct svr4_stat *bufp) +{ + struct kstat st; + int error; + + error = vfs_lstat(filename, &st); + if (!error) + error = report_svr4_stat(&st, bufp); + return error; +} + +int +svr4_fstat(int fd, struct svr4_stat *bufp) +{ + struct kstat st; + int error; + + error = vfs_fstat(fd, &st); + if (!error) + error = report_svr4_stat(&st, bufp); + return error; +} + +int +svr4_xstat(int vers, char *filename, void *bufp) +{ + struct kstat st; + int error; + + error = vfs_stat(filename, &st); + if (error) + return error; + + switch (vers) { + case SVR4_stat: + return report_svr4_stat(&st, bufp); + case SVR4_xstat: + return report_svr4_xstat(&st, bufp); + } + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_API, "xstat version %d not supported\n", vers); +#endif + return -EINVAL; +} + +int +svr4_lxstat(int vers, char *filename, void *bufp) +{ + struct kstat st; + int error; + + error = vfs_lstat(filename, &st); + if (error) + return error; + + switch (vers) { + case SVR4_stat: + return report_svr4_stat(&st, bufp); + case SVR4_xstat: + return report_svr4_xstat(&st, bufp); + } + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_API, "lxstat version %d not supported\n", vers); +#endif + return -EINVAL; +} + +int +svr4_fxstat(int vers, int fd, void *bufp) +{ + struct kstat st; + int error; + + error = vfs_fstat(fd, &st); + if (error) + return error; + + switch (vers) { + case SVR4_stat: + return report_svr4_stat(&st, bufp); + case SVR4_xstat: + return report_svr4_xstat(&st, bufp); + } + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_API, "fxstat version %d not supported\n", vers); +#endif + return -EINVAL; +} + +#if defined(CONFIG_ABI_SYSCALL_MODULES) +EXPORT_SYMBOL(report_svr4_stat); +EXPORT_SYMBOL(report_svr4_xstat); +EXPORT_SYMBOL(svr4_fstat); +EXPORT_SYMBOL(svr4_fxstat); +EXPORT_SYMBOL(svr4_lstat); +EXPORT_SYMBOL(svr4_lxstat); +EXPORT_SYMBOL(svr4_stat); +EXPORT_SYMBOL(svr4_xstat); +#endif diff -Nru linux-2.6.7/abi/svr4/statvfs.c linux-2.6.7-abi/abi/svr4/statvfs.c --- linux-2.6.7/abi/svr4/statvfs.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/svr4/statvfs.c 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2001 Caldera Deutschland GmbH. + * Copyright (c) 2001 Christoph Hellwig. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ident "%W% %G%" + +/* + * SVR4 statvfs/fstatvfs support. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +struct svr4_statvfs { + u_int32_t f_bsize; + u_int32_t f_frsize; + u_int32_t f_blocks; + u_int32_t f_bfree; + u_int32_t f_bavail; + u_int32_t f_files; + u_int32_t f_free; + u_int32_t f_sid; + char f_basetype[16]; + u_int32_t f_flag; + u_int32_t f_namemax; + char f_fstr[32]; + u_int32_t f_filler[16]; +}; + +static int +report_statvfs(struct vfsmount *mnt, struct inode *ip, struct svr4_statvfs *bufp) +{ + struct svr4_statvfs buf; + struct kstatfs s; + int error; + + error = vfs_statfs(mnt->mnt_sb, &s); + if (error) + return error; + + memset(&buf, 0, sizeof(struct svr4_statvfs)); + + buf.f_bsize = s.f_bsize; + buf.f_frsize = s.f_bsize; + buf.f_blocks = s.f_blocks; + buf.f_bfree = s.f_bfree; + buf.f_bavail = s.f_bavail; + buf.f_files = s.f_files; + buf.f_free = s.f_ffree; + buf.f_sid = ip->i_sb->s_dev; + + /* Get the name of the filesystem */ + strcpy(buf.f_basetype, ip->i_sb->s_type->name); + + /* Check for a few flags statvfs wants but statfs doesn't have. */ + if (IS_RDONLY(ip)) + buf.f_flag |= 1; + if (mnt->mnt_flags & MNT_NOSUID) + buf.f_flag |= 2; + + buf.f_namemax = s.f_namelen; + + if (copy_to_user(bufp, &buf, sizeof(struct svr4_statvfs))) + return -EFAULT; + return 0; +} + +int +svr4_statvfs(char *filename, struct svr4_statvfs *bufp) +{ + struct nameidata nd; + int error; + + error = user_path_walk(filename, &nd); + if (!error) { + error = report_statvfs(nd.mnt, nd.dentry->d_inode, bufp); + path_release(&nd); + } + return error; +} + +int +svr4_fstatvfs(int fd, struct svr4_statvfs *bufp) +{ + struct file *fp; + int error = -EBADF; + + fp = fget(fd); + if (fp) { + error = report_statvfs(fp->f_vfsmnt, + fp->f_dentry->d_inode, bufp); + fput(fp); + } + return error; +} + +#if defined(CONFIG_ABI_SYSCALL_MODULES) +EXPORT_SYMBOL(svr4_statvfs); +EXPORT_SYMBOL(svr4_fstatvfs); +#endif diff -Nru linux-2.6.7/abi/svr4/stream.c linux-2.6.7-abi/abi/svr4/stream.c --- linux-2.6.7/abi/svr4/stream.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/svr4/stream.c 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,114 @@ +/* + * Copyright 1994,1995 Mike Jagdis (jaggy@purplet.demon.co.uk) + */ + +#ident "%W% %G%" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + + +#if !defined(CONFIG_ABI_XTI) && !defined(CONFIG_ABI_SPX) +# define timod_getmsg(fd, ino, is_pmsg, regs) 0 +# define timod_putmsg(fd, ino, is_pmsg, regs) 0 +#endif + +/* + * Check if the inode belongs to /dev/spx. + */ +#define IS_SPX(ip) ((MAJOR((ip)->i_rdev) == 30 && MINOR((ip)->i_rdev) == 1)) + + +int +svr4_getmsg(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 (ip->i_sock) + error = timod_getmsg(fd, ip, 0, regs); + fput(fp); + } + return error; +} + +int +svr4_putmsg(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 (ip->i_sock || IS_SPX(ip)) + error = timod_putmsg(fd, ip, 0, regs); + fput(fp); + } + return error; +} + +#ifdef CONFIG_ABI_XTI +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 (ip->i_sock) + error = timod_getmsg(fd, ip, 1, regs); + fput(fp); + } + 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 (ip->i_sock || IS_SPX(ip)) + error = timod_putmsg(fd, ip, 1, regs); + fput(fp); + } + return error; +} +#endif /* CONFIG_ABI_XTI */ + +#if defined(CONFIG_ABI_SYSCALL_MODULES) +EXPORT_SYMBOL(svr4_getmsg); +EXPORT_SYMBOL(svr4_getpmsg); +EXPORT_SYMBOL(svr4_putmsg); +EXPORT_SYMBOL(svr4_putpmsg); +#endif diff -Nru linux-2.6.7/abi/svr4/svr4.c linux-2.6.7-abi/abi/svr4/svr4.c --- linux-2.6.7/abi/svr4/svr4.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/svr4/svr4.c 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,332 @@ +/* + * Copyright (C) 1995 Mike Jagdis + */ + +#ident "%W% %G%" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + + +/* + * Interactive SVR4's /bin/sh calls access(... 011) but Linux returns + * EINVAL if the access mode has any other bits than 007 set. + */ + +int +svr4_access(char *path, int mode) +{ + return sys_access(path, mode & 007); +} + + +enum { + SVR4_CLD_EXITED = 1, + SVR4_CLD_KILLED = 2, + SVR4_CLD_DUMPED = 3, + SVR4_CLD_TRAPPED = 4, + SVR4_CLD_STOPPED = 5, + SVR4_CLD_CONTINUED = 6 +}; + +int +svr4_waitid(int idtype, int id, struct svr4_siginfo *infop, int options) +{ + long result, kopt; + mm_segment_t old_fs; + int pid, status; + + switch (idtype) { + case 0: /* P_PID */ + pid = id; + break; + + case 1: /* P_PGID */ + pid = -id; + break; + + case 7: /* P_ALL */ + pid = -1; + break; + + default: + return -EINVAL; + } + + if (infop) { + result = verify_area(VERIFY_WRITE, infop, + sizeof(struct svr4_siginfo)); + if (result) + return result; + } + + kopt = 0; + if (options & 0100) kopt |= WNOHANG; + if (options & 4) kopt |= WUNTRACED; + + old_fs = get_fs(); + set_fs(get_ds()); + result = sys_wait4(pid, &status, kopt, NULL); + set_fs(old_fs); + if (result < 0) + return result; + + if (infop) { + unsigned long op, st; + + put_user(current_thread_info()->exec_domain->signal_map[SIGCHLD], + &infop->si_signo); + put_user(result, + &infop->_data._proc._pid); + + if ((status & 0xff) == 0) { + /* Normal exit. */ + op = SVR4_CLD_EXITED; + st = status >> 8; + } else if ((status & 0xff) == 0x7f) { + /* Stopped. */ + st = (status & 0xff00) >> 8; + op = (st == SIGSTOP || st == SIGTSTP) + ? SVR4_CLD_STOPPED + : SVR4_CLD_CONTINUED; + st = current_thread_info()->exec_domain->signal_invmap[st]; + } else { + st = (status & 0xff00) >> 8; + op = (status & 0200) + ? SVR4_CLD_DUMPED + : SVR4_CLD_KILLED; + st = current_thread_info()->exec_domain->signal_invmap[st]; + } + put_user(op, &infop->si_code); + put_user(st, &infop->_data._proc._pdata._cld._status); + } + return 0; +} + +int +svr4_seteuid(int uid) +{ + return sys_setreuid16(-1, uid); +} + +int +svr4_setegid(int gid) +{ + return sys_setregid16(-1, gid); +} + +/* POSIX.1 names */ +#define _PC_LINK_MAX 1 +#define _PC_MAX_CANON 2 +#define _PC_MAX_INPUT 3 +#define _PC_NAME_MAX 4 +#define _PC_PATH_MAX 5 +#define _PC_PIPE_BUF 6 +#define _PC_NO_TRUNC 7 +#define _PC_VDISABLE 8 +#define _PC_CHOWN_RESTRICTED 9 +/* POSIX.4 names */ +#define _PC_ASYNC_IO 10 +#define _PC_PRIO_IO 11 +#define _PC_SYNC_IO 12 + +int +svr4_pathconf(char *path, int name) +{ + switch (name) { + case _PC_LINK_MAX: + /* Although Linux headers define values on a per + * filesystem basis there is no way to access + * these without hard coding fs information here + * so for now we use a bogus value. + */ + return LINK_MAX; + + case _PC_MAX_CANON: + return MAX_CANON; + + case _PC_MAX_INPUT: + return MAX_INPUT; + + case _PC_PATH_MAX: + return PATH_MAX; + + case _PC_PIPE_BUF: + return PIPE_BUF; + + case _PC_CHOWN_RESTRICTED: + /* We should really think about this and tell + * the truth. + */ + return 0; + + case _PC_NO_TRUNC: + /* Not sure... It could be fs dependent? */ + return 1; + + case _PC_VDISABLE: + return 1; + + case _PC_NAME_MAX: { + struct statfs buf; + char *p; + int error; + mm_segment_t old_fs; + + p = getname(path); + error = PTR_ERR(p); + if (!IS_ERR(p)) { + old_fs = get_fs(); + set_fs (get_ds()); + error = sys_statfs(p, &buf); + set_fs(old_fs); + putname(p); + if (!error) + return buf.f_namelen; + } + return error; + } + } + + return -EINVAL; +} + +int +svr4_fpathconf(int fildes, int name) +{ + switch (name) { + case _PC_LINK_MAX: + /* Although Linux headers define values on a per + * filesystem basis there is no way to access + * these without hard coding fs information here + * so for now we use a bogus value. + */ + return LINK_MAX; + + case _PC_MAX_CANON: + return MAX_CANON; + + case _PC_MAX_INPUT: + return MAX_INPUT; + + case _PC_PATH_MAX: + return PATH_MAX; + + case _PC_PIPE_BUF: + return PIPE_BUF; + + case _PC_CHOWN_RESTRICTED: + /* We should really think about this and tell + * the truth. + */ + return 0; + + case _PC_NO_TRUNC: + /* Not sure... It could be fs dependent? */ + return 1; + + case _PC_VDISABLE: + return 1; + + case _PC_NAME_MAX: { + struct statfs buf; + int error; + mm_segment_t old_fs; + + old_fs = get_fs(); + set_fs (get_ds()); + error = sys_fstatfs(fildes, &buf); + set_fs(old_fs); + if (!error) + return buf.f_namelen; + return error; + } + } + + return -EINVAL; +} + +int +svr4_sigpending(int which_routine, svr4_sigset_t *set) +{ + /* Solaris multiplexes on this one */ + /* Which routine has the actual routine that should be called */ + + switch (which_routine){ + case 1: /* sigpending */ + printk ("iBCS/Intel: sigpending not implemented\n"); + return -EINVAL; + + case 2: /* sigfillset */ + set->setbits [0] = ~0; + set->setbits [1] = 0; + set->setbits [2] = 0; + set->setbits [3] = 0; + return 0; + } + return -EINVAL; +} + +typedef void svr4_ucontext_t; + +static int +svr4_setcontext(svr4_ucontext_t *c, struct pt_regs *regs) +{ + printk (KERN_DEBUG "Getting context\n"); + return 0; +} + +static int +svr4_getcontext(svr4_ucontext_t *c, struct pt_regs *regs) +{ + printk (KERN_DEBUG "Setting context\n"); + return 0; +} + +int +svr4_context(struct pt_regs *regs) +{ + int context_fn = get_syscall_parameter (regs, 0); + struct svr4_ucontext_t *uc = (void *) get_syscall_parameter (regs, 1); + + switch (context_fn){ + case 0: /* getcontext */ + return svr4_getcontext (uc, regs); + + case 1: /* setcontext */ + return svr4_setcontext (uc, regs); + } + return -EINVAL; +} + +#if defined(CONFIG_ABI_SYSCALL_MODULES) +EXPORT_SYMBOL(svr4_context); +EXPORT_SYMBOL(svr4_fpathconf); +EXPORT_SYMBOL(svr4_pathconf); +EXPORT_SYMBOL(svr4_setegid); +EXPORT_SYMBOL(svr4_seteuid); +EXPORT_SYMBOL(svr4_sigpending); +EXPORT_SYMBOL(svr4_waitid); +#endif diff -Nru linux-2.6.7/abi/svr4/sysconf.c linux-2.6.7-abi/abi/svr4/sysconf.c --- linux-2.6.7/abi/svr4/sysconf.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/svr4/sysconf.c 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,186 @@ +/* + * sysconf.c - sysv sysconf(2) and sysconfig(2) emulation + * + * Copyright (C) 1994 Mike Jagdis (jaggy@purplet.demon.co.uk) + */ + +#ident "%W% %G%" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + + +/* The sysconf() call is supposed to give applications access to various + * kernel parameters. According to SCO's man page this a POSIX mandated + * function. Perhaps it should be moved across as a native Linux call? + * + * N.B. SCO only has sysconf in the Xenix group. Therefore this is based + * on the Xenix spec. Is SVR4 the same? Wyse Unix V.3.2.1A doesn't have + * sysconf documented at all. + * + * N.B. 0-7 are required (by who?). Other values may be defined for + * various systems but there appears no guarantee that they match across + * platforms. Thus, unless we can identify what system the executable + * was compiled for, we probably prefer to have extensions fail. Hell, + * nothing important is going to use this obscure stuff anyway... + */ +#define _SC_ARG_MAX 0 +#define _SC_CHILD_MAX 1 +#define _SC_CLK_TCK 2 +#define _SC_NGROUPS_MAX 3 +#define _SC_OPEN_MAX 4 +#define _SC_JOB_CONTROL 5 +#define _SC_SAVED_IDS 6 +#define _SC_VERSION 7 + +#define _SC_PAGESIZE 11 +#define _SCO_SC_PAGESIZE 34 + + +/* This is an SVR4 system call that is undocumented except for some + * hints in a header file. It appears to be a forerunner to the + * POSIX sysconf() call. + */ +int svr4_sysconfig(int name) +{ + switch (name) { + case _CONFIG_NGROUPS: + /* From limits.h */ + return (NGROUPS_MAX); + + case _CONFIG_CHILD_MAX: + /* From limits.h */ + return (CHILD_MAX); + + case _CONFIG_OPEN_FILES: + /* From limits.h */ + return (OPEN_MAX); + + case _CONFIG_POSIX_VER: + /* The version of the POSIX standard we conform + * to. SCO defines _POSIX_VERSION as 198808L + * sys/unistd.h. What are we? We are 199009L. + */ + return (199009L); + + case _CONFIG_PAGESIZE: + return (PAGE_SIZE); + + case _CONFIG_CLK_TCK: + return (HZ); + + case _CONFIG_XOPEN_VER: + return 4; + + case _CONFIG_NACLS_MAX: + return 0; + + case _CONFIG_NPROC: + return 4000; /* max_threads */ + + case _CONFIG_NENGINE: + case _CONFIG_NENGINE_ONLN: + return (num_online_cpus()); + + case _CONFIG_TOTAL_MEMORY: + return (max_mapnr << (PAGE_SHIFT-10)); + + case _CONFIG_USEABLE_MEMORY: + case _CONFIG_GENERAL_MEMORY: + return (max_mapnr << (PAGE_SHIFT-10)); +/* return ((unsigned long) (nr_free_pages()) << (PAGE_SHIFT-10)); */ + + case _CONFIG_DEDICATED_MEMORY: + return 0; + + case _CONFIG_NCGS_CONF: + case _CONFIG_NCGS_ONLN: + case _CONFIG_MAX_ENG_PER_CG: + return 1; /* no NUMA-Q support on Linux yet */ + /* well, there is. we lie anyway --hch */ + + case _CONFIG_CACHE_LINE: + return 32; /* XXX is there a more accurate way? */ + + case _CONFIG_KERNEL_VM: + return -EINVAL; + + case _CONFIG_ARG_MAX: + /* From limits.h */ + return (ARG_MAX); + } + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_API, "unsupported sysconfig call %d\n", name); +#endif + return -EINVAL; +} + + +int ibcs_sysconf(int name) +{ + switch (name) { + case _SC_ARG_MAX: + /* From limits.h */ + return (ARG_MAX); + + case _SC_CHILD_MAX: + /* From limits.h */ + return (CHILD_MAX); + + case _SC_CLK_TCK: + return (HZ); + + case _SC_NGROUPS_MAX: + /* From limits.h */ + return (NGROUPS_MAX); + + case _SC_OPEN_MAX: + /* From limits.h */ + return (OPEN_MAX); + + case _SC_JOB_CONTROL: + return (1); + + case _SC_SAVED_IDS: + return (1); + + case _SC_PAGESIZE: + case _SCO_SC_PAGESIZE: + return PAGE_SIZE; + + case _SC_VERSION: + /* The version of the POSIX standard we conform + * to. SCO defines _POSIX_VERSION as 198808L + * sys/unistd.h. What are we? + */ + return (198808L); + } + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_API, "unsupported sysconf call %d\n", name); +#endif + return -EINVAL; +} + +#if defined(CONFIG_ABI_SYSCALL_MODULES) +EXPORT_SYMBOL(ibcs_sysconf); +EXPORT_SYMBOL(svr4_sysconfig); +#endif diff -Nru linux-2.6.7/abi/svr4/sysfs.c linux-2.6.7-abi/abi/svr4/sysfs.c --- linux-2.6.7/abi/svr4/sysfs.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/svr4/sysfs.c 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,130 @@ +/* + * Copyright (C) 1994 Mike Jagdis (jaggy@purplet.demon.co.uk) + */ + +#ident "%W% %G%" + +#include +#include +#include +#include +#include + +#include + +/* + * The kernel sysfs() code is almost all we need but, apparently, + * the SCO (at least) sysfs() will also accept a "magic number" + * as an index argument and will return the name of the relevant + * file system. Since Linux doesn't have any concept of fs magic + * numbers outside the file system code themselves there is no + * clean way to do it in the kernel. There isn't a clean way to + * to it here either but it needs to be done somehow :-(. + */ +enum { + GETFSIND = 1, + GETFSTYP = 2, + GETNFSTYP = 3 +}; + +int +svr4_sysfs(int cmd, int arg1, int arg2) +{ + if (cmd == GETFSIND) + return sys_sysfs(cmd, arg1, arg2); + + if (cmd == GETNFSTYP) + return sys_sysfs(cmd, arg1, arg2); + + if (cmd == GETFSTYP) { + char *buf = (char *)arg2; + int error; + + if (arg1 & 0x80000000) + arg1 &= 0x0000ffff; + if (arg1 >= 0 && arg1 < sys_sysfs(GETNFSTYP,0,0)) + return sys_sysfs(cmd, arg1-1, arg2); + + /* + * Kludge alert! Hardcoded known magic numbers! + */ + switch (arg1) { + case 0xef53: case 0xffffef53: + case 0xef51: case 0xffffef51: + /* + * Some SCO programs (i.e. Informix Dynamic + * Server are using this to detect "real" + * filesystems by checking type names :-(. + * So we lie :-). + */ + if (is_cur_personality(PER_SCOSVR3)) + error = copy_to_user(buf, "HTFS", 5); + else + error = copy_to_user(buf, "ext2", 5); + break; + case 0x137d: + error = copy_to_user(buf, "ext", 4); + break; + case 0x9660: case 0xffff9660: + error = copy_to_user(buf, "iso9660", 8); + break; + case 0x4d44: + error = copy_to_user(buf, "msdos", 6); + break; + case 0x6969: + error = copy_to_user(buf, "nfs", 4); + break; + case 0x9fa0: case 0xffff9fa0: + error = copy_to_user(buf, "proc", 5); + break; + case 0xf995e849: + case 0xe849: case 0xffffe849: + error = copy_to_user(buf, "hpfs", 5); + break; + case 0x137f: /* original */ + case 0x138f: /* original + 30 char names */ + case 0x2468: /* V2 */ + case 0x2478: /* V2 + 30 char names */ + error = copy_to_user(buf, "minix", 6); + break; + case 0x564c: + error = copy_to_user(buf, "ncpfs", 6); + break; + case 0x517b: + error = copy_to_user(buf, "smbfs", 6); + break; + case 0x00011954: + error = copy_to_user(buf, "ufs", 4); + break; + case 0x012fd16d: case 0xffffd16d: + error = copy_to_user(buf, "xiafs", 6); + break; + case 0x012ff7b3+1: case 0xfffff7b3+1: + error = copy_to_user(buf, "xenix", 6); + break; + case 0x012ff7b3+2: case 0xfffff7b3+2: + case 0x012ff7b3+3: case 0xfffff7b3+3: + error = copy_to_user(buf, "sysv", 5); + break; + case 0x012ff7b3+4: case 0xfffff7b3+4: + error = copy_to_user(buf, "coherent", 9); + break; + default: + error = copy_to_user(buf, "", 1); + break; + } + + if (error) + return -EFAULT; + return 0; + } + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_API, "unsupported sysfs call %d\n", cmd); +#endif + return -EINVAL; +} + +#if defined(CONFIG_ABI_SYSCALL_MODULES) +EXPORT_SYMBOL(svr4_sysfs); +#endif diff -Nru linux-2.6.7/abi/svr4/sysi86.c linux-2.6.7-abi/abi/svr4/sysi86.c --- linux-2.6.7/abi/svr4/sysi86.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/svr4/sysi86.c 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,180 @@ +/* + * Copyright 1994,1995 Mike Jagdis + * Copyright 2002 Caldera Deutschland GmbH + */ + +#ident "%W% %G%" + +#include +#include +#include +#include +#include +#include +#include + +#include + + +/* + * The sysi86() call is used for machine specific functions. Only the + * most basic are implemented here. + */ +#define SI86SWPI 1 /* General swap functions. */ +#define SI86SYM 2 /* Get symbol table */ +#define SI86CONF 4 /* Get configuration table */ +#define SI86BOOT 5 /* Get timestamp and name of program + * booted. + */ +#define SI86DMM 7 /* Double-map data segment for + * read/write/execute support + */ +#define SI86AUTO 9 /* Was an auto-config boot done? */ +#define SI86EDT 10 /* Copy contents of EDT to user */ +#define SI86SWAP 12 /* Declare swap space */ +#define SI86FPHW 40 /* what (if any?) floating-point hardware */ +# define FP_NO 0 /* No fp at all */ +# define FP_SW 1 /* using emulator */ +# define FP_HW 2 /* using hardware */ +# define FP_287 2 /* using a 287 */ +# define FP_387 3 /* using a 387 */ +#define GRNON 52 /* set green light to solid on state */ +#define GRNFLASH 53 /* start green light flashing */ +#define STIME 54 /* set internal time */ +#define SETNAME 56 /* rename the system */ +#define RNVR 58 /* read NVRAM */ +#define WNVR 59 /* write NVRAM */ +#define RTODC 60 /* read time of day clock */ +#define CHKSER 61 /* check soft serial number */ +#define SI86NVPRT 62 /* print an xtra_nvr structure */ +#define SANUPD 63 /* sanity update of kernel buffers */ +#define SI86KSTR 64 /* make a copy of a kernel string */ +#define SI86MEM 65 /* return the memory size of system */ +#define SI86TODEMON 66 /* Transfer control to firmware. */ +#define SI86CCDEMON 67 /* Control character access to demon. */ +#define SI86CACHE 68 /* Turn cache on and off. */ +#define SI86DELMEM 69 /* Delete available memory for testing. */ +#define SI86ADDMEM 70 /* Add back deleted memory. */ +/* 71 through 74 reserved for VPIX */ +#define SI86V86 71 /* V86 system calls (see v86.h) */ +#define SI86SLTIME 72 /* Set local time correction */ +#define SI86DSCR 75 /* Set a segment or gate descriptor */ +#define RDUBLK 76 /* Read U Block */ +/* #ifdef MERGE386 */ +/* NFA entry point */ +#define SI86NFA 77 /* make nfa_sys system call */ +#define SI86VM86 81 +#define SI86VMENABLE 82 +/* #endif MERGE386 */ +#define SI86VM86 81 +#define SI86VMENABLE 82 +#define SI86LIMUSER 91 /* liscense interface */ +#define SI86RDID 92 /* ROM BIOS Machid ID */ +#define SI86RDBOOT 93 /* Bootable Non-SCSI Hard Disk */ +/* Merged Product defines */ +#define SI86SHFIL 100 /* map a file into addr space of a proc */ +#define SI86PCHRGN 101 /* make globally visible change to a region */ +#define SI86BADVISE 102 /* badvise subcommand - see below for */ + /* badvise subfunction definitions */ +#define SI86SHRGN 103 /* enable/disable XENIX small model shared */ + /* data context switching */ +#define SI86CHIDT 104 /* set user level int 0xf0, ... 0xff handlers */ +#define SI86EMULRDA 105 /* remove special emulator read access */ +#define SI86GETPIPE 106 /* return the pipe filesystem */ +#define SI86SETPIPE 107 /* set the pipe filesystem */ +#define SI86SETPIPE_NM 108 /* set the pipe filesystem -non mountable */ +#define SI86GETNPIPE 109 /* get # of pipe filesystems */ +#define SI86GETPIPE_ALL 110 /* get data on all of pipe filesystems */ +#define SI86POPPIPE 111 /* pop pipe file system off stack */ +#define SI86APM 112 /* get APM information passed by boot(HW) */ +#define SI86TIMECHG 113 /* get time before/after last timechange */ +#define SI86GETFEATURES 114 /* get os features vector */ + +/* The SI86BADVISE command is used to set Xenix behaviour. */ +#define SI86B_SET 0x0100 /* Set badvise bits */ +#define SI86B_GET 0x0200 /* Get badvise bits */ +#define SI86B_LOCK 0x0001 /* XENIX advisory locking bit */ +#define SI86B_PRE_SV 0x0008 /* follow pre-System V x.out behavior */ +#define SI86B_XOUT 0x0010 /* follow XENIX x.out behavior */ +#define SI86B_XSDSWTCH 0x0080 /* XENIX small model shared data */ + /* context switching enabled */ + +/* + * The SI86DSCR subcommand of the sysi86() system call + * sets a segment or gate descriptor in the kernel. + * The following descriptor types are accepted: + * - executable and data segments in the LDT at DPL 3 + * - a call gate in the GDT at DPL 3 that points to a segment in the LDT + * The request structure declared below is used to pass the values + * to be placed in the descriptor. A pointer to the structure is + * passed as the second argument of the system call. + * If acc1 is zero, the descriptor is cleared. + */ +struct ssd { + uint32_t sel; /* descriptor selector */ + uint32_t bo; /* segment base or gate offset */ + uint32_t ls; /* segment limit or gate selector */ + uint32_t acc1; /* access byte 5 */ + uint32_t acc2; /* access bits in byte 6 or gate count */ +}; + + +int +svr4_sysi86(int cmd, void *arg1, int arg2) +{ + switch (cmd) { + case SI86FPHW: + /* + * If we remove the 'static' from the definition + * of fpu_error in linux/init/main.c we can tell + * whether we are using hardware or software at + * least. For now let's lie... + * (actually SCO Unix 3.4 gives me -1...) + */ + return put_user(FP_387, (unsigned long *)arg1); + case STIME: + /* + * Set the system time. The argument is a long, + * sys_stime() expects a pointer to a long... + */ + return sys_stime(arg1); + case SETNAME: + /* + * The name is required to be string of no more + * than 7 characters. We don't get passed the + * length so we are depending upon the current + * implementation of sys_sethostname() here. + */ + return sys_sethostname(arg1, 7); + case SI86MEM: + { + /* + * Returns the size of physical memory. + */ + struct sysinfo i; + + si_meminfo(&i); + return (i.totalram << PAGE_SHIFT); + } + case SI86DSCR: + { + struct ssd s; + + if (copy_from_user(&s, arg1, sizeof(struct ssd))) + return -EFAULT; + + printk("SI86DSCR(%x,%x,%x,%x,%x)\n", + s.sel, s.bo, s.ls, s.acc1, s.acc2); + return -EINVAL; + } + default: +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_API, "unsupported sysi86 subcall %d\n", cmd); +#endif + return -EINVAL; + } +} + +#if defined(CONFIG_ABI_SYSCALL_MODULES) +EXPORT_SYMBOL(svr4_sysi86); +#endif diff -Nru linux-2.6.7/abi/svr4/sysinfo.c linux-2.6.7-abi/abi/svr4/sysinfo.c --- linux-2.6.7/abi/svr4/sysinfo.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/svr4/sysinfo.c 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,128 @@ +/* + * Copyright (C) 1995 Eric Youngdale + */ + +#ident "%W% %G%" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + +#define __O_SI_SYSNAME 1 /* return name of operating system */ +#define __O_SI_HOSTNAME 2 /* return name of node */ +#define SI_RELEASE 3 /* return release of operating system */ +#define SI_VERSION 4 /* return version field of utsname */ +#define __O_SI_MACHINE 5 /* return kind of machine */ +#define __O_SI_ARCHITECTURE 6 /* return instruction set arch */ +#define SI_HW_SERIAL 7 /* return hardware serial number */ +#define __O_SI_HW_PROVIDER 8 /* return hardware manufacturer */ +#define SI_SRPC_DOMAIN 9 /* return secure RPC domain */ +#define SI_INITTAB_NAME 10 /* return name of inittab file used */ +#define SI_ARCHITECTURE 100 /* return instruction set arch */ +#define SI_BUSTYPES 101 /* return list of bus types */ +#define SI_HOSTNAME 102 /* return fully-qualified node name */ +#define SI_HW_PROVIDER 103 /* return hardware manufacturer */ +#define SI_KERNEL_STAMP 104 /* return kernel generation timestamp */ +#define SI_MACHINE 105 /* return kind of machine */ +#define SI_OS_BASE 106 /* return base operating system */ +#define SI_OS_PROVIDER 107 /* return operating system provider */ +#define SI_SYSNAME 108 /* return name of operating system */ +#define SI_USER_LIMIT 109 /* return maximum number of users */ + + + +int svr4_sysinfo(int cmd, char * buf, long count) +{ + char * return_string; + static unsigned int serial_number = 0; + char buffer[16]; + int error; + int slen; + + return_string = NULL; + + switch(cmd) { + case __O_SI_SYSNAME: + case SI_SYSNAME: + return_string = system_utsname.sysname; + break; + case __O_SI_HOSTNAME: + case SI_HOSTNAME: + return_string = system_utsname.nodename; + break; + case SI_VERSION: + return_string = "2"; + break; + case SI_RELEASE: + return_string = system_utsname.release; + break; + case SI_MACHINE: + case __O_SI_MACHINE: + return_string = system_utsname.machine; + break; + case __O_SI_ARCHITECTURE: + case SI_ARCHITECTURE: + return_string = "IA32"; /* XXX: this seems wrong, the name ia32 is very new ... -- ch */ + break; + case SI_BUSTYPES: + return_string = "PCI ISA"; + break; + case __O_SI_HW_PROVIDER: + case SI_HW_PROVIDER: + return_string = "Generic AT"; + break; + case SI_KERNEL_STAMP: + return_string = UTS_VERSION; + break; + case SI_INITTAB_NAME: + return_string = "/etc/inittab"; + break; + case SI_HW_SERIAL: + if(serial_number == 0) + serial_number = 0xdeadbeef; + sprintf(buffer,"%8.8x", serial_number); + return_string = buffer; + break; + case SI_OS_BASE: + return_string = "Linux"; + break; + case SI_OS_PROVIDER: + return_string = "LBT"; /* someone's initials ? */ + break; + case SI_SRPC_DOMAIN: + return_string = system_utsname.domainname; + break; + case SI_USER_LIMIT: + /* have you seen a Linux box with more than 500000 users? */ + return_string = "500000"; + break; + default: +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_API, + "unsupported sysinfo call %d\n", cmd); +#endif + return -EINVAL; + } + + if (!return_string) + return 0; + + down_read(&uts_sem); + slen = (count < strlen(return_string) + 1 ? count : strlen(return_string) + 1); + error = copy_to_user(buf, return_string, slen); + up_read(&uts_sem); + + return error ? -EFAULT : slen; +} + +#if defined(CONFIG_ABI_SYSCALL_MODULES) +EXPORT_SYMBOL(svr4_sysinfo); +#endif diff -Nru linux-2.6.7/abi/svr4/tapeio.c linux-2.6.7-abi/abi/svr4/tapeio.c --- linux-2.6.7/abi/svr4/tapeio.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/svr4/tapeio.c 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,92 @@ +#ident "%W% %G%" + +#include +#include +#include +#include +#include + + +int +svr4_tape_ioctl(int fd, u_int cmd, caddr_t data) +{ + mm_segment_t fs; + int error; + struct mtop mtop; + + mtop.mt_count = 1; + + switch (cmd & 0xff) { + case 1: /* MT_RETEN */ + mtop.mt_op = MTRETEN; + break; + case 2: /* MT_REWIND */ + mtop.mt_op = MTREW; + break; + case 3: /* MT_ERASE */ + mtop.mt_op = MTERASE; + break; + case 4: /* MT_WFM */ + mtop.mt_op = MTWEOF; + break; + case 5: /* MT_RESET */ + mtop.mt_op = MTRESET; + break; + case 7: /* T_SFF */ + mtop.mt_op = MTFSF; + break; + case 8: /* T_SBF */ + mtop.mt_op = MTBSF; + break; + case 9: /* T_LOAD */ + mtop.mt_op = MTLOAD; + break; + case 10: /* MT_UNLOAD */ + mtop.mt_op = MTOFFL; + break; + case 15: /* T_WRBLKLEN */ + mtop.mt_op = MTLOCK; + mtop.mt_count = (int)data; + break; + case 16: /* T_PREVMV */ + mtop.mt_op = MTLOCK; + break; + case 17: /* T_ALLOMV */ + mtop.mt_op = MTUNLOCK; + break; + case 20: /* T_EOD */ + mtop.mt_op = MTEOM; + mtop.mt_count = (int)data; + break; + case 21: /* T_SSFB */ + mtop.mt_op = MTBSFM; + mtop.mt_count = (int)data; + break; + case 22: /* T_SSFF */ + mtop.mt_op = MTFSFM; + mtop.mt_count = (int)data; + break; + case 24: /* T_STD */ + mtop.mt_op = MTSETDENSITY; + mtop.mt_count = (int)data; + break; + +#if 0 + case 6: /* T_STATUS */ + case 14: /* T_RDBLKLEN */ + case 18: /* T_SBB */ + case 19: /* T_SFB */ + case 23: /* T_STS */ +#endif + default: + printk (KERN_ERR "iBCS: SYSV tape ioctl func=%d arg=%x unsupported\n", + cmd & 0xff, (int)data); + return -EINVAL; + } + + fs = get_fs(); + set_fs(get_ds()); + error = sys_ioctl(fd, MTIOCTOP, (long)&mtop); + set_fs (fs); + return (error); +} diff -Nru linux-2.6.7/abi/svr4/termios.c linux-2.6.7-abi/abi/svr4/termios.c --- linux-2.6.7/abi/svr4/termios.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/svr4/termios.c 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,982 @@ +#ident "%W% %G%" + +#include +#include +#include +#include +#include + +#include +#include + + +static int +svr_to_linux_termio(int fd, int op, struct svr_termio *it) +{ + struct termio t; + mm_segment_t fs; + char eof; + u_short lflag; + int error; + + error = verify_area(VERIFY_READ, it, sizeof(struct svr_termio)); + if (error) + return (error); + + fs = get_fs(); + set_fs(get_ds()); + error = sys_ioctl(fd, TCGETA, (long)&t); + set_fs(fs); + + if (error) + return (error); + + /* Save things we may need later. */ + eof = t.c_cc[4]; + lflag = t.c_lflag; + + /* Copy the entire structure then fix up as necessary. */ + copy_from_user(&t, it, sizeof(struct svr_termio)); + + /* If ICANON isn't set then we've been given VMIN in place + * of VEOF. + */ + if (!(t.c_lflag & 0000002)) { + t.c_cc[6] = t.c_cc[4]; + t.c_cc[4] = eof; + } + + if (t.c_cflag & 0100000) /* CRTSFL - SCO only? */ + t.c_cflag |= CRTSCTS; + t.c_cflag &= ~0170000; /* LOBLK|CTSFLOW|RTSFLOW|CRTSFL */ + + set_fs(get_ds()); + error = sys_ioctl(fd, op, (long)&t); + set_fs(fs); + + return (error); +} + +static int +linux_to_svr_termio(int fd, struct svr_termio *it) +{ + struct termio t; + mm_segment_t fs; + int error; + + error = verify_area(VERIFY_WRITE, it, sizeof(struct svr_termio)); + if (error) + return (error); + + fs = get_fs(); + set_fs(get_ds()); + error = sys_ioctl(fd, TCGETA, (long)&t); + set_fs(fs); + + if (error) + return (error); + + /* If ICANON isn't set then we substitute VEOF with VMIN. */ + if (!(t.c_lflag & 0000002)) + t.c_cc[4] = t.c_cc[6]; + + /* Copy to the user supplied structure. */ + copy_to_user(it, &t, sizeof(struct svr_termio)); + + return (error); +} + +static int +svr4_to_linux_termios(int fd, int op, struct svr4_termios *it) +{ + struct termios t; + mm_segment_t fs; + u_short lflag, r; + char svr4_cc[SVR4_NCCS]; + int error; + + error = verify_area(VERIFY_READ, it, sizeof(struct svr4_termios)); + if (error) + return (error); + + fs = get_fs(); + set_fs(get_ds()); + error = sys_ioctl(fd, TCGETS, (long)&t); + set_fs(fs); + + if (error) + return (error); + + __get_user(t.c_iflag, &it->c_iflag); + t.c_iflag &= ~0100000; /* DOSMODE */ + + __get_user(t.c_oflag, &it->c_oflag); + __get_user(t.c_cflag, &it->c_cflag); + + if (t.c_cflag & 0100000) /* CRTSFL - SCO only? */ + t.c_cflag |= CRTSCTS; + + t.c_cflag &= ~0170000; /* LOBLK|CTSFLOW|RTSFLOW|CRTSFL */ + + lflag = t.c_lflag; + t.c_lflag &= ~0100777; + __get_user(r, &it->c_lflag); + t.c_lflag |= r; + + if ((t.c_lflag & 0100000)) + sys_ioctl(fd, TIOCEXCL, 0); + else + sys_ioctl(fd, TIOCNXCL, 0); + + t.c_lflag &= ~0100000; + t.c_lflag |= (t.c_lflag & 0000400) << 7; /* Move IEXTEN */ + t.c_lflag &= ~0000400; + t.c_lflag |= (t.c_lflag & 0001000) >> 1; /* Move TOSTOP */ + t.c_lflag &= ~0001000; + t.c_lflag |= (lflag & 0001000); /* Restore ECHOCTL */ + + copy_from_user(svr4_cc, &it->c_cc, SVR4_NCCS); + t.c_cc[0] = svr4_cc[0]; + t.c_cc[1] = svr4_cc[1]; + t.c_cc[2] = svr4_cc[2]; + t.c_cc[3] = svr4_cc[3]; + t.c_cc[7] = svr4_cc[7]; + t.c_cc[8] = svr4_cc[8]; + t.c_cc[9] = svr4_cc[9]; + t.c_cc[10] = svr4_cc[10]; + t.c_cc[12] = svr4_cc[12]; + t.c_cc[13] = svr4_cc[13]; + t.c_cc[14] = svr4_cc[14]; + t.c_cc[15] = svr4_cc[15]; + t.c_cc[16] = svr4_cc[16]; + + if (t.c_lflag & ICANON) { + t.c_cc[4] = svr4_cc[4]; + t.c_cc[11] = svr4_cc[5]; + } else { + t.c_cc[5] = svr4_cc[5]; + t.c_cc[6] = svr4_cc[4]; + t.c_cc[11] = svr4_cc[6]; + } + + set_fs(get_ds()); + error = sys_ioctl(fd, op, (long)&t); + set_fs(fs); + + return (error); +} + +static int +linux_to_svr4_termios(int fd, int op, struct svr4_termios *it) +{ + struct termios t; + char svr4_cc[SVR4_NCCS]; + mm_segment_t fs; + int error; + + error = verify_area(VERIFY_WRITE, it, sizeof(struct svr4_termios)); + if (error) + return (error); + + fs = get_fs(); + set_fs(get_ds()); + error = sys_ioctl(fd, op, (long)&t); + set_fs(fs); + + if (error) + return (error); + + put_user(t.c_iflag & 0017777, &it->c_iflag); + put_user(t.c_oflag & 0177777, &it->c_oflag); + + if (t.c_cflag & CRTSCTS) + t.c_cflag |= 0100000; /* CRTSFL - SCO only? */ + put_user(t.c_cflag & 0177777, &it->c_cflag); + + t.c_lflag &= ~0001000; + t.c_lflag |= (t.c_lflag & 0000400) << 1; + t.c_lflag &= ~0000400; + t.c_lflag |= (t.c_lflag & 0100000) >> 7; + t.c_lflag &= ~0100000; + put_user(t.c_lflag & 0001777, &it->c_lflag); + + svr4_cc[0] = t.c_cc[0]; + svr4_cc[1] = t.c_cc[1]; + svr4_cc[2] = t.c_cc[2]; + svr4_cc[3] = t.c_cc[3]; + svr4_cc[6] = t.c_cc[16]; + svr4_cc[7] = t.c_cc[7]; + svr4_cc[8] = t.c_cc[8]; + svr4_cc[9] = t.c_cc[9]; + svr4_cc[10] = t.c_cc[10]; + svr4_cc[11] = t.c_cc[10]; + svr4_cc[12] = t.c_cc[12]; + svr4_cc[13] = t.c_cc[13]; + svr4_cc[14] = t.c_cc[14]; + svr4_cc[15] = t.c_cc[15]; + + if (t.c_lflag & ICANON) { + svr4_cc[4] = t.c_cc[4]; + svr4_cc[5] = t.c_cc[11]; + } else { + svr4_cc[4] = t.c_cc[6]; + svr4_cc[5] = t.c_cc[5]; + } + + copy_to_user(&it->c_cc, svr4_cc, SVR4_NCCS); + + return (error); +} + +int +svr4_term_ioctl(int fd, u_int cmd, caddr_t data) +{ + switch (cmd) { + case 1: /* TCGETA (TIOC|1) */ + return linux_to_svr_termio(fd, + (struct svr_termio *)data); + case 2: /* TCSETA (TIOC|2) */ + return svr_to_linux_termio(fd, TCSETA, + (struct svr_termio *)data); + case 3: /* TCSETAW (TIOC|3) */ + return svr_to_linux_termio(fd, TCSETAW, + (struct svr_termio *)data); + case 4: /* TCSETAF (TIOC|4) */ + return svr_to_linux_termio(fd, TCSETAF, + (struct svr_termio *)data); + case 5: /* TCSBRK (TIOC|5) */ + return sys_ioctl(fd, TCSBRK, (long)data); + case 6: /* TCXONC (TIOC|6) */ + return sys_ioctl(fd, TCXONC, (long)data); + case 7: /* TCFLSH (TIOC|7) */ + return sys_ioctl(fd, TCFLSH, (long)data); + /* This group appear in SVR4 but not SVR3 (SCO). */ + case 8: /* TIOCKBON */ + case 9: /* TIOCKBOF */ + case 10: /* KBENABLED */ + return -EINVAL; + + /* This set is used by SVR4 for termios ioctls. */ + case 13: /* TCGETS */ + return linux_to_svr4_termios(fd, TCGETS, + (struct svr4_termios *)data); + case 14: /* TCSETS */ + return svr4_to_linux_termios(fd, TCSETS, + (struct svr4_termios *)data); + case 15: /* TCSETSW */ + return svr4_to_linux_termios(fd, TCSETSW, + (struct svr4_termios *)data); + case 16: /* TCSETSF */ + return svr4_to_linux_termios(fd, TCSETSF, + (struct svr4_termios *)data); + + /* These two are specific to ISC. */ + case 20: /* TCSETPGRP (TIOC|20) set pgrp of tty */ + return sys_ioctl(fd, TIOCSPGRP, (long)data); + case 21: /* TCGETPGRP (TIOC|21) get pgrp of tty */ + return sys_ioctl(fd, TIOCGPGRP, (long)data); + + case 34: /* TCGETSC (TIOC|34) ioctl for scancodes */ + return 0x04; /* Translates scancode to ascii */ + case 35: /* TCSETSC (TIOC|35) ioctl for scancodes */ + return 0; + + case 103: /* TIOCSWINSZ (TIOC|103) */ + return sys_ioctl(fd, TIOCSWINSZ, (long)data); + case 104: /* TIOCGWINSZ (TIOC|104) */ + return sys_ioctl(fd, TIOCGWINSZ, (long)data); + + case 118: /* TIOCSPGRP (TIOC|118) set pgrp of tty */ + return sys_ioctl(fd, TIOCSPGRP, (long)data); + case 119: /* TIOCGPGRP (TIOC|119) get pgrp of tty */ + return sys_ioctl(fd, TIOCGPGRP, (long)data); + + case 32: /* TCDSET (TIOC|32) */ + case 33: /* RTS_TOG (TIOC|33) 386 - "RTS" toggle define 8A1 protocol */ + + case 120: /* TIOSETSAK (TIOC|120) set SAK sequence for tty */ + case 121: /* TIOGETSAK (TIOC|121) get SAK sequence for tty */ + printk(KERN_ERR "iBCS: termio ioctl %d unimplemented\n", cmd); + return -EINVAL; + } + + printk(KERN_ERR "iBCS: termio ioctl %d unsupported\n", cmd); + return -EINVAL; +} + +struct termiox { + unsigned short x_hflag; + unsigned short x_cflag; + unsigned short x_rflag[5]; + unsigned short x_sflag; +}; + +#define RTSXOFF 0x0001 +#define CTSXON 0x0002 + +int +svr4_termiox_ioctl(int fd, u_int cmd, caddr_t data) +{ + struct termios t; + struct termiox tx; + mm_segment_t fs; + int error; + + if (cmd < 1 || cmd > 4) + return -EINVAL; + + error = verify_area(cmd == 1 ? VERIFY_WRITE : VERIFY_READ, + data, sizeof(struct termiox)); + if (error) + return (error); + + fs = get_fs(); + set_fs(get_ds()); + error = sys_ioctl(fd, TCGETS, (long)&t); + set_fs(fs); + + if (error) + return (error); + + if (cmd == 1) { /* TCGETX */ + memset(&tx, '\0', sizeof(struct termiox)); + if (t.c_cflag & CRTSCTS) + tx.x_hflag = RTSXOFF|CTSXON; + copy_to_user(data, &tx, sizeof(struct termiox)); + return 0; + } + + copy_from_user(&tx, data, sizeof(struct termiox)); + if ((tx.x_hflag != 0 && tx.x_hflag != (RTSXOFF|CTSXON)) + || tx.x_cflag || tx.x_rflag[0] || tx.x_rflag[1] + || tx.x_rflag[2] || tx.x_rflag[3] || tx.x_rflag[4] + || tx.x_sflag) + return -EINVAL; + + if (tx.x_hflag) + t.c_cflag |= CRTSCTS; + else + t.c_cflag &= (~CRTSCTS); + + fs = get_fs(); + set_fs(get_ds()); + switch (cmd) { + case 2: /* TCSETX */ + error = sys_ioctl(fd, TCSETS, (long)&t); + break; + case 3: /* TCSETXW */ + error = sys_ioctl(fd, TCSETSW, (long)&t); + break; + case 4: /* TCSETXF */ + error = sys_ioctl(fd, TCSETSF, (long)&t); + break; + } + set_fs(fs); + return (error); +} + +#define BSD_NCCS 20 +struct bsd_termios { + unsigned long c_iflag; + unsigned long c_oflag; + unsigned long c_cflag; + unsigned long c_lflag; + unsigned char c_cc[BSD_NCCS]; + long c_ispeed; + long c_ospeed; +}; +static unsigned long speed_map[] = { + 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, + 4800, 9600, 19200, 38400 +}; + +static unsigned long +bsd_to_linux_speed(unsigned long s) +{ + unsigned int i; + +#ifdef B57600 + if (s == 57600) + return B57600; +#endif +#ifdef B115200 + if (s == 115200) + return B115200; +#endif + + for (i=0; ic_iflag); + t.c_iflag = (t.c_iflag & ~0xc00) + | ((t.c_iflag & 0x400) << 1) + | ((t.c_iflag & 0x800) >> 1); + + get_user(temp, &it->c_oflag); + t.c_oflag = (t.c_oflag & ~0x1805) + | (temp & 9) + | ((temp & 2) << 1) + | ((temp & 4) << 10) + | ((temp & 4) << 9); + + get_user(temp, &it->c_cflag); + t.c_cflag = (t.c_cflag & ~0xfff) + | ((temp & 0xff00) >> 4); + if (t.c_cflag & 0x30000) + t.c_cflag |= 020000000000; + t.c_cflag |= bsd_to_linux_speed(({long s; get_user(s, &it->c_ospeed); s;})) + | (bsd_to_linux_speed(({long s; get_user(s, &it->c_ispeed); s;})) << 16); + + get_user(temp, &it->c_lflag); + t.c_lflag = (t.c_lflag & ~0157663) + | ((temp & 1) << 12) + | ((temp & 0x46) << 3) + | ((temp & 0x420) << 5) + | ((temp & 0x180) >> 7) + | ((temp & 0x400000) >> 14) + | ((temp & 0x2800000) >> 11) + | ((temp & 0x80000000) >> 24); + + copy_from_user(bsd_cc, &it->c_cc, BSD_NCCS); + t.c_cc[VEOF] = bsd_cc[0]; + t.c_cc[VEOL] = bsd_cc[1]; + t.c_cc[VEOL2] = bsd_cc[2]; + t.c_cc[VERASE] = bsd_cc[3]; + t.c_cc[VWERASE] = bsd_cc[4]; + t.c_cc[VKILL] = bsd_cc[5]; + t.c_cc[VREPRINT] = bsd_cc[6]; + t.c_cc[VSWTC] = bsd_cc[7]; + t.c_cc[VINTR] = bsd_cc[8]; + t.c_cc[VQUIT] = bsd_cc[9]; + t.c_cc[VSUSP] = bsd_cc[10]; +/* t.c_cc[VDSUSP] = bsd_cc[11];*/ + t.c_cc[VSTART] = bsd_cc[12]; + t.c_cc[VSTOP] = bsd_cc[13]; + t.c_cc[VLNEXT] = bsd_cc[14]; + t.c_cc[VDISCARD] = bsd_cc[15]; + t.c_cc[VMIN] = bsd_cc[16]; + t.c_cc[VTIME] = bsd_cc[17]; +/* t.c_cc[VSTATUS] = bsd_cc[18];*/ + + set_fs(get_ds()); + error = sys_ioctl(fd, op, (long)&t); + set_fs(old_fs); + + return error; +} + + +static int +linux_to_bsd_termios(int fd, int op, struct bsd_termios *it) +{ + struct termios t; + char bsd_cc[BSD_NCCS]; + mm_segment_t old_fs; + int error; + + error = verify_area(VERIFY_WRITE, it, sizeof(struct bsd_termios)); + if (error) + return error; + + old_fs = get_fs(); + set_fs(get_ds()); + error = sys_ioctl(fd, op, (long)&t); + set_fs(old_fs); + if (error) + return error; + + put_user((t.c_iflag & 0777) + | ((t.c_iflag & 02000) >> 1) + | ((t.c_iflag & 010000) >> 2) + | ((t.c_iflag & 020000) >> 4), + &it->c_iflag); + + put_user((t.c_oflag & 1) + | ((t.c_oflag & 04) >> 1) + | ((t.c_oflag & 014000) == 014000 ? 4 : 0), + &it->c_oflag); + + put_user((t.c_cflag & ~020000007777) + | ((t.c_cflag & 0xff0) << 4) + | ((t.c_cflag & 020000000000) ? 0x30000 : 0), + &it->c_cflag); + + put_user(linux_to_bsd_speed(t.c_cflag & CBAUD), &it->c_ospeed); + if ((t.c_cflag & CIBAUD) != 0) + put_user(linux_to_bsd_speed((t.c_cflag & CIBAUD) >> 16), + &it->c_ispeed); + else + put_user(linux_to_bsd_speed(t.c_cflag & CBAUD), + &it->c_ispeed); + + put_user((t.c_lflag & 07777626010) + | ((t.c_lflag & 03) << 7) + | ((t.c_lflag & 01160) >> 3) + | ((t.c_lflag & 0400) << 14) + | ((t.c_lflag & 02000) >> 4) + | ((t.c_lflag & 04000) >> 11) + | ((t.c_lflag & 010000) << 11) + | ((t.c_lflag & 040000) << 15) + | ((t.c_lflag & 0100000) >> 5), + &it->c_lflag); + + bsd_cc[0] = t.c_cc[VEOF]; + bsd_cc[1] = t.c_cc[VEOL]; + bsd_cc[2] = t.c_cc[VEOL2]; + bsd_cc[3] = t.c_cc[VERASE]; + bsd_cc[4] = t.c_cc[VWERASE]; + bsd_cc[5] = t.c_cc[VKILL]; + bsd_cc[6] = t.c_cc[VREPRINT]; + bsd_cc[7] = t.c_cc[VSWTC]; + bsd_cc[8] = t.c_cc[VINTR]; + bsd_cc[9] = t.c_cc[VQUIT]; + bsd_cc[10] = t.c_cc[VSUSP]; + bsd_cc[11] = t.c_cc[VSUSP]; + bsd_cc[12] = t.c_cc[VSTART]; + bsd_cc[13] = t.c_cc[VSTOP]; + bsd_cc[14] = t.c_cc[VLNEXT]; + bsd_cc[15] = t.c_cc[VDISCARD]; + bsd_cc[16] = t.c_cc[VMIN]; + bsd_cc[17] = t.c_cc[VTIME]; + bsd_cc[18] = 0; /* t.c_cc[VSTATUS]; */ + bsd_cc[19] = 0; + + copy_to_user(&it->c_cc, bsd_cc, BSD_NCCS); + + return error; +} + + + + +struct v7_sgttyb { + unsigned char sg_ispeed; + unsigned char sg_ospeed; + unsigned char sg_erase; + unsigned char sg_kill; + int sg_flags; +}; + +struct v7_tchars { + char t_intrc; + char t_quitc; + char t_startc; + char t_stopc; + char t_eofc; + char t_brkc; +}; + +struct v7_ltchars { + char t_suspc; + char t_dsuspc; + char t_rprntc; + char t_flushc; + char t_werasc; + char t_lnextc; +}; + + +int bsd_ioctl_termios(int fd, unsigned int func, void *data) +{ + switch (func & 0xff) { + case 0: { /* TIOCGETD */ + unsigned long ldisc; + mm_segment_t old_fs; + int error; + + error = verify_area(VERIFY_WRITE, data, + sizeof(unsigned short)); + if (error) + return error; + + old_fs = get_fs(); + set_fs(get_ds()); + error = sys_ioctl(fd, TIOCGETD, (long)&ldisc); + set_fs(old_fs); + if (!error) + put_user(ldisc, (unsigned short *)data); + return error; + } + case 1: { /* TIOCSETD */ + unsigned long ldisc; + mm_segment_t old_fs; + int error; + + error = verify_area(VERIFY_READ, data, + sizeof(unsigned short)); + if (error) + return error; + + get_user(ldisc, (unsigned short *)data); + old_fs = get_fs(); + set_fs(get_ds()); + error = sys_ioctl(fd, TIOCSETD, (long)&ldisc); + set_fs(old_fs); + return error; + } + + case 2: { /* TIOCHPCL */ + int error; + mm_segment_t old_fs; + struct termios t; + + old_fs = get_fs(); + set_fs(get_ds()); + error = sys_ioctl(fd, TCGETS, (long)&t); + set_fs(old_fs); + if (error) + return error; + + if (data) + t.c_cflag |= HUPCL; + else + t.c_cflag &= ~HUPCL; + + old_fs = get_fs(); + set_fs(get_ds()); + error = sys_ioctl(fd, TCSETS, (long)&t); + set_fs(old_fs); + return error; + } + + case 8: { /* TIOCGETP */ + int error; + mm_segment_t old_fs; + struct termios t; + struct v7_sgttyb sg; + + error = verify_area(VERIFY_WRITE, data, sizeof(sg)); + if (error) + return error; + + old_fs = get_fs(); + set_fs(get_ds()); + error = sys_ioctl(fd, TCGETS, (long)&t); + set_fs(old_fs); + if (error) + return error; + + sg.sg_ispeed = sg.sg_ospeed = 0; + sg.sg_erase = t.c_cc[VERASE]; + sg.sg_kill = t.c_cc[VKILL]; + sg.sg_flags = + /* Old - became TANDEM instead. + * ((t.c_cflag & HUPCL) >> 10) + * | + */ +/* O_ODDP */ ((t.c_cflag & PARODD) >> 3) +/* O_EVENP */ | ((t.c_cflag & PARENB) >> 1) +/* LITOUT */ | ((t.c_cflag & OPOST) ? 0 : 0x200000) +/* O_CRMOD */ | ((t.c_oflag & ONLCR) << 2) +/* O_NL1|O_VTDELAY */ | (t.c_oflag & (NL1|VTDLY)) +/* O_TBDELAY */ | ((t.c_oflag & TABDLY) ? 02000 : 0) +/* O_CRDELAY */ | ((t.c_oflag & CRDLY) << 3) +/* O_BSDELAY */ | ((t.c_oflag & BSDLY) << 2) +/* O_ECHO|O_LCASE */ | (t.c_lflag & (XCASE|ECHO)) + | ((t.c_lflag & ICANON) +/* O_CBREAK or O_RAW */ ? 0 : ((t.c_lflag & ISIG) ? 0x02 : 0x20)) + /* Incomplete... */ + ; + + copy_to_user(data, &sg, sizeof(sg)); + return 0; + } + + case 9: /* TIOCSETP */ + case 10: { /* TIOCSETN */ + int error; + mm_segment_t old_fs; + struct termios t; + struct v7_sgttyb sg; + + error = verify_area(VERIFY_READ, data, sizeof(sg)); + if (error) + return error; + copy_from_user(&sg, data, sizeof(sg)); + + old_fs = get_fs(); + set_fs(get_ds()); + error = sys_ioctl(fd, TCGETS, (long)&t); + set_fs(old_fs); + if (error) + return error; + + t.c_cc[VERASE] = sg.sg_erase; + t.c_cc[VKILL] = sg.sg_kill; + t.c_iflag = ICRNL | IXON; + t.c_oflag = 0; + t.c_lflag = ISIG | ICANON; + if (sg.sg_flags & 0x02) /* O_CBREAK */ + t.c_lflag &= (~ICANON); + if (sg.sg_flags & 0x08) /* O_ECHO */ + t.c_lflag |= ECHO|ECHOE|ECHOK|ECHOCTL|ECHOKE|IEXTEN; + if (sg.sg_flags & 0x10) /* O_CRMOD */ + t.c_oflag |= OPOST|ONLCR; + if (sg.sg_flags & 0x20) { /* O_RAW */ + t.c_iflag = 0; + t.c_lflag &= ~(ISIG|ICANON); + } + if (sg.sg_flags & 0x200000) /* LITOUT */ + t.c_oflag &= (~OPOST); + if (!(t.c_lflag & ICANON)) { + t.c_cc[VMIN] = 1; + t.c_cc[VTIME] = 0; + } + + old_fs = get_fs(); + set_fs(get_ds()); + error = sys_ioctl(fd, TCSETS, (long)&t); + set_fs(old_fs); + return error; + } + + case 17: { /* TIOCSETC */ + int error; + mm_segment_t old_fs; + struct termios t; + struct v7_tchars tc; + + error = verify_area(VERIFY_READ, data, sizeof(tc)); + if (error) + return error; + copy_from_user(&tc, data, sizeof(tc)); + + old_fs = get_fs(); + set_fs(get_ds()); + error = sys_ioctl(fd, TCGETS, (long)&t); + set_fs(old_fs); + if (error) + return error; + + t.c_cc[VINTR] = tc.t_intrc; + t.c_cc[VQUIT] = tc.t_quitc; + t.c_cc[VSTART] = tc.t_startc; + t.c_cc[VSTOP] = tc.t_stopc; + t.c_cc[VEOF] = tc.t_eofc; + t.c_cc[VEOL2] = tc.t_brkc; + + old_fs = get_fs(); + set_fs(get_ds()); + error = sys_ioctl(fd, TCSETS, (long)&t); + set_fs(old_fs); + return error; + } + + case 18: { /* TIOCGETC */ + int error; + mm_segment_t old_fs; + struct termios t; + struct v7_tchars tc; + + error = verify_area(VERIFY_WRITE, data, sizeof(tc)); + if (error) + return error; + + old_fs = get_fs(); + set_fs(get_ds()); + error = sys_ioctl(fd, TCGETS, (long)&t); + set_fs(old_fs); + if (error) + return error; + + tc.t_intrc = t.c_cc[VINTR]; + tc.t_quitc = t.c_cc[VQUIT]; + tc.t_startc = t.c_cc[VSTART]; + tc.t_stopc = t.c_cc[VSTOP]; + tc.t_eofc = t.c_cc[VEOF]; + tc.t_brkc = t.c_cc[VEOL2]; + + copy_to_user(data, &tc, sizeof(tc)); + return 0; + } + + case 116: { /* TIOCGLTC */ + int error; + mm_segment_t old_fs; + struct termios t; + struct v7_ltchars tc; + + error = verify_area(VERIFY_WRITE, data, sizeof(tc)); + if (error) + return error; + + old_fs = get_fs(); + set_fs(get_ds()); + error = sys_ioctl(fd, TCGETS, (long)&t); + set_fs(old_fs); + if (error) + return error; + + tc.t_suspc = t.c_cc[VSUSP]; + tc.t_dsuspc = t.c_cc[VSUSP]; + tc.t_rprntc = t.c_cc[VREPRINT]; + tc.t_flushc = t.c_cc[VEOL2]; + tc.t_werasc = t.c_cc[VWERASE]; + tc.t_lnextc = t.c_cc[VLNEXT]; + + copy_to_user(data, &tc, sizeof(tc)); + return 0; + } + + case 117: { /* TIOCSLTC */ + int error; + mm_segment_t old_fs; + struct termios t; + struct v7_ltchars tc; + + error = verify_area(VERIFY_READ, data, sizeof(tc)); + if (error) + return error; + copy_from_user(&tc, data, sizeof(tc)); + + old_fs = get_fs(); + set_fs(get_ds()); + error = sys_ioctl(fd, TCGETS, (long)&t); + set_fs(old_fs); + if (error) + return error; + + t.c_cc[VSUSP] = tc.t_suspc; + t.c_cc[VEOL2] = tc.t_dsuspc; + t.c_cc[VREPRINT] = tc.t_rprntc; + t.c_cc[VEOL2] = tc.t_flushc; + t.c_cc[VWERASE] = tc.t_werasc; + t.c_cc[VLNEXT] = tc.t_lnextc; + + old_fs = get_fs(); + set_fs(get_ds()); + error = sys_ioctl(fd, TCSETS, (long)&t); + set_fs(old_fs); + return error; + } + + case 13: /* TIOEXCL */ + return sys_ioctl(fd, TIOCEXCL, (long)data); + + case 14: /* TIOCNXCL */ + return sys_ioctl(fd, TIOCNXCL, (long)data); + + case 16: /* TIOCFLUSH */ + return sys_ioctl(fd, TCFLSH, (long)data); + + + /* ISC (maybe SVR4 in general?) has some extensions over + * the sgtty stuff. So do later BSDs. Needless to say they + * both have different extensions. + */ + case 20: /* TCSETPGRP (TIOC|20) set pgrp of tty */ + return bsd_to_linux_termios(fd, TCSETS, data); + + case 21: /* TCGETPGRP (TIOC|21) get pgrp of tty */ + return bsd_to_linux_termios(fd, TCSETSW, data); + + case 19: /* TIOCGETA */ + return linux_to_bsd_termios(fd, TCGETS, data); + + case 22: /* TIOCSETAF */ + return bsd_to_linux_termios(fd, TCSETSF, data); + + case 26: /* TIOCGETD */ + return sys_ioctl(fd, TIOCGETD, (long)data); + + case 27: /* TIOCSETD */ + return sys_ioctl(fd, TIOCSETD, (long)data); + + case 97: /* TIOCSCTTY */ + return sys_ioctl(fd, TIOCSCTTY, (long)data); + + case 103: /* TIOCSWINSZ */ + return sys_ioctl(fd, TIOCSWINSZ, (long)data); + + case 104: /* TIOCGWINSZ */ + return sys_ioctl(fd, TIOCGWINSZ, (long)data); + + case 113: /* TIOCNOTTY */ + return sys_ioctl(fd, TIOCNOTTY, (long)data); + + case 118: /* TIOCSPGRP */ + return sys_ioctl(fd, TIOCSPGRP, (long)data); + + case 119: /* TIOCGPGRP */ + return sys_ioctl(fd, TIOCGPGRP, (long)data); + + case 123: /* TIOCSBRK */ + return sys_ioctl(fd, TCSBRK, (long)data); + + case 124: /* TIOCLGET */ + case 125: /* TIOCLSET */ + return 0; + + + case 3: /* TIOCMODG */ + case 4: /* TIOCMODS */ + case 94: /* TIOCDRAIN */ + case 95: /* TIOCSIG */ + case 96: /* TIOCEXT */ + case 98: /* TIOCCONS */ + case 102: /* TIOCUCNTL */ + case 105: /* TIOCREMOTE */ + case 106: /* TIOCMGET */ + case 107: /* TIOCMBIC */ + case 108: /* TIOCMBIS */ + case 109: /* TIOCMSET */ + case 110: /* TIOCSTART */ + case 111: /* TIOCSTOP */ + case 112: /* TIOCPKT */ + case 114: /* TIOCSTI */ + case 115: /* TIOCOUTQ */ + case 120: /* TIOCCDTR */ + case 121: /* TIOCSDTR */ + case 122: /* TIOCCBRK */ + break; + } + + printk(KERN_ERR "BSD/V7: terminal ioctl 0x%08lx unsupported\n", + (unsigned long)func); + return -EINVAL; +} + +#if defined(CONFIG_ABI_SYSCALL_MODULES) +EXPORT_SYMBOL(bsd_ioctl_termios); +EXPORT_SYMBOL(svr4_term_ioctl); +#endif diff -Nru linux-2.6.7/abi/svr4/timod.c linux-2.6.7-abi/abi/svr4/timod.c --- linux-2.6.7/abi/svr4/timod.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/svr4/timod.c 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,200 @@ +/* + * Copyright 1995, 1996 Mike Jagdis (jaggy@purplet.demon.co.uk) + */ + +#ident "%W% %G%" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include +#include + + +/* + * Check if the inode belongs to /dev/socksys. + */ +#define IS_SOCKSYS(ip) (MAJOR((ip)->i_rdev) == SOCKSYS_MAJOR) + + +int +timod_getmsg(int fd, struct inode *ip, int pmsg, struct pt_regs *regs) +{ + struct strbuf ctl, *ctlp, dat, *datp; + int flags, *flagsp, *bandp; + int error; + + ctlp = (struct strbuf *)get_syscall_parameter(regs, 1); + datp = (struct strbuf *)get_syscall_parameter(regs, 2); + + if (pmsg) { + bandp = (int *)get_syscall_parameter(regs, 3); + flagsp = (int *)get_syscall_parameter(regs, 4); + } else + flagsp = (int *)get_syscall_parameter (regs, 3); + + if (ctlp) { + if (copy_from_user(&ctl, ctlp, sizeof(ctl))) + return -EFAULT; + if ((error = put_user(-1, &ctlp->len))) + return error; + } else + ctl.maxlen = -1; + + if (datp) { + if (copy_from_user(&dat, datp, sizeof(dat))) + return -EFAULT; + if ((error = put_user(-1, &datp->len))) + return error; + } else + dat.maxlen = -1; + + if ((error = get_user(flags, flagsp))) + return error; + +#ifdef CONFIG_ABI_SPX + if (IS_SOCKSYS(ip) && MINOR(ip->i_rdev) == 1) { + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_STREAMS, + "SPX: getmsg offers descriptor %d\n", fd); +#endif + + if ((error = put_user(fd, ctl.buf))) + return error; + if ((error = put_user(4, &ctlp->len))) + return error; + + return 0; + } +#endif /* CONFIG_ABI_SPX */ + +#ifdef CONFIG_ABI_XTI + if (flags == 0 || flags == MSG_HIPRI || + flags == MSG_ANY || flags == MSG_BAND) { + struct file *fp; + + fp = fget(fd); + error = do_getmsg(fd, regs, ctl.buf, ctl.maxlen, &ctlp->len, + dat.buf, dat.maxlen, &datp->len, &flags); + fput(fp); + + if (error >= 0) + error = put_user(flags, flagsp); + return error; + } + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_STREAMS, + "XTI: getmsg flags value bad (%d) for %d\n", + flags, fd); +#endif /* CONFIG_ABI_TRACE */ +#endif /* CONFIG_ABI_XTI */ + return -EINVAL; +} + + +int +timod_putmsg(int fd, struct inode *ip, int pmsg, struct pt_regs *regs) +{ + struct strbuf ctl, *ctlp, dat, *datp; + int flags, band; + int error; + + ctlp = (struct strbuf *)get_syscall_parameter(regs, 1); + datp = (struct strbuf *)get_syscall_parameter(regs, 2); + if (pmsg) { + band = get_syscall_parameter(regs, 3); + flags = get_syscall_parameter(regs, 4); + } else + flags = get_syscall_parameter(regs, 3); + + if (ctlp) { + if (copy_from_user(&ctl, ctlp, sizeof(ctl))) + return -EFAULT; + if (ctl.len < 0 && flags) + return -EINVAL; + } else { + ctl.len = 0; + ctl.buf = NULL; + } + + if (datp) { + if (copy_from_user(&dat, datp, sizeof(dat))) + return -EFAULT; + } else { + dat.len = 0; + dat.buf = NULL; + } + +#ifdef CONFIG_ABI_SPX + if (IS_SOCKSYS(ip) && MINOR(ip->i_rdev) == 1) { + int newfd; + + if (ctl.len != 4) + return -EIO; + + error = get_user(newfd, ctl.buf); + if (error) + return error; + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_STREAMS, + "SPX: putmsg on %d dups descriptor %d\n", + fd, newfd); +#endif + error = sys_dup2(newfd, fd); + + return (error < 0 ? error : 0); + } +#endif /* CONFIG_ABI_SPX */ + +#ifdef CONFIG_ABI_XTI + return do_putmsg(fd, regs, ctl.buf, ctl.len, + dat.buf, dat.len, flags); +#endif + return -EINVAL; +} + +int +stream_fdinsert(struct pt_regs *regs, int fd, struct strfdinsert *arg) +{ + struct strfdinsert sfd; + + if (copy_from_user(&sfd, arg, sizeof(sfd))) + return -EFAULT; + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_STREAMS, + "%u fdinsert: flags=%ld, fildes=%u, offset=%d\n", + fd, sfd.flags, sfd.fildes, sfd.offset); +#endif +#ifdef CONFIG_ABI_XTI + return do_putmsg(fd, regs, sfd.ctlbuf.buf, sfd.ctlbuf.len, + sfd.datbuf.buf, sfd.datbuf.len, sfd.fildes); +#else + return -EINVAL; +#endif +} diff -Nru linux-2.6.7/abi/svr4/ulimit.c linux-2.6.7-abi/abi/svr4/ulimit.c --- linux-2.6.7/abi/svr4/ulimit.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/svr4/ulimit.c 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,154 @@ +/* + * Copyright (C) 1993 Joe Portman (baron@hebron.connected.com) + * First stab at ulimit + * + * April 9 1994, corrected file size passed to/from setrlimit/getrlimit + * -- Graham Adams (gadams@ddrive.demon.co.uk) + * + */ + +#ident "%W% %G%" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + +/* + * Arguments to ulimit - it's one of the stupid multipled calls... + */ +#define U_GETFSIZE (1) /* get max file size in blocks */ +#define U_SETFSIZE (2) /* set max file size in blocks */ +#define U_GETMEMLIM (3) /* get process size limit */ +#define U_GETMAXOPEN (4) /* get max open files for this process */ +#define U_GTXTOFF (64) /* get text offset */ + +/* + * Define nominal block size parameters. + */ +#define ULIM_BLOCKSIZE_BITS 9 /* block size = 512 */ +#define ULIM_MAX_BLOCKSIZE (INT_MAX >> ULIM_BLOCKSIZE_BITS) + + +int +svr4_ulimit (int cmd, int val) +{ + switch (cmd) { + case U_GETFSIZE: + return (current->rlim[RLIMIT_FSIZE].rlim_cur) >> ULIM_BLOCKSIZE_BITS; + + case U_SETFSIZE: + if ((val > ULIM_MAX_BLOCKSIZE) || (val < 0)) + return -ERANGE; + val <<= ULIM_BLOCKSIZE_BITS; + if (val > current->rlim[RLIMIT_FSIZE].rlim_max) { + if (!capable(CAP_SYS_RESOURCE)) + return -EPERM; + current->rlim[RLIMIT_FSIZE].rlim_max = val; + } + current->rlim[RLIMIT_FSIZE].rlim_cur = val; + return 0; + + case U_GETMEMLIM: + return current->rlim[RLIMIT_DATA].rlim_cur; + + case U_GETMAXOPEN: + return current->rlim[RLIMIT_NOFILE].rlim_cur; + + default: +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_API, "unsupported ulimit call %d\n", cmd); +#endif + return -EINVAL; + } +} + +/* + * getrlimit/setrlimit args. + */ +#define U_RLIMIT_CPU 0 +#define U_RLIMIT_FSIZE 1 +#define U_RLIMIT_DATA 2 +#define U_RLIMIT_STACK 3 +#define U_RLIMIT_CORE 4 +#define U_RLIMIT_NOFILE 5 +#define U_RLIMIT_AS 6 + + +int +svr4_getrlimit(int cmd, void *val) +{ + switch (cmd) { + case U_RLIMIT_CPU: + cmd = RLIMIT_CPU; + break; + case U_RLIMIT_FSIZE: + cmd = RLIMIT_FSIZE; + break; + case U_RLIMIT_DATA: + cmd = RLIMIT_DATA; + break; + case U_RLIMIT_STACK: + cmd = RLIMIT_STACK; + break; + case U_RLIMIT_CORE: + cmd = RLIMIT_CORE; + break; + case U_RLIMIT_NOFILE: + cmd = RLIMIT_NOFILE; + break; + case U_RLIMIT_AS: + cmd = RLIMIT_AS; + break; + default: + return -EINVAL; + } + + return sys_getrlimit(cmd, val); +} + +int +svr4_setrlimit(int cmd, void *val) +{ + switch (cmd) { + case U_RLIMIT_CPU: + cmd = RLIMIT_CPU; + break; + case U_RLIMIT_FSIZE: + cmd = RLIMIT_FSIZE; + break; + case U_RLIMIT_DATA: + cmd = RLIMIT_DATA; + break; + case U_RLIMIT_STACK: + cmd = RLIMIT_STACK; + break; + case U_RLIMIT_CORE: + cmd = RLIMIT_CORE; + break; + case U_RLIMIT_NOFILE: + cmd = RLIMIT_NOFILE; + break; + case U_RLIMIT_AS: + cmd = RLIMIT_AS; + break; + default: + return -EINVAL; + } + + return sys_getrlimit(cmd, val); +} + +#if defined(CONFIG_ABI_SYSCALL_MODULES) +EXPORT_SYMBOL(svr4_getrlimit); +EXPORT_SYMBOL(svr4_setrlimit); +EXPORT_SYMBOL(svr4_ulimit); +#endif diff -Nru linux-2.6.7/abi/svr4/utsname.c linux-2.6.7-abi/abi/svr4/utsname.c --- linux-2.6.7/abi/svr4/utsname.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/svr4/utsname.c 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,87 @@ +/* + * Copyright (C) 1994 Mike Jagdis (jaggy@purplet.demon.co.uk) + * Copyright (C) 1994 Eric Youngdale. + */ + +#ident "%W% %G%" + +#include +#include +#include +#include +#include + + +struct v7_utsname { + char sysname[9]; + char nodename[9]; + char release[9]; + char version[9]; + char machine[9]; +}; + +#define SVR4_NMLN 257 +struct svr4_utsname { + char sysname[SVR4_NMLN]; + char nodename[SVR4_NMLN]; + char release[SVR4_NMLN]; + char version[SVR4_NMLN]; + char machine[SVR4_NMLN]; +}; + + +#define set_utsfield(to, from, dotchop) \ + { \ + char *p; \ + int i, len = (sizeof(to) > sizeof(from) ? sizeof(from) : sizeof(to)); \ + __copy_to_user(to, from, len); \ + if (dotchop) \ + for (p=from,i=0; *p && *p != '.' && --len; p++,i++); \ + else \ + i = len - 1; \ + __put_user('\0', to+i); \ + } + + +int v7_utsname(unsigned long addr) +{ + int error; + struct v7_utsname *it = (struct v7_utsname *)addr; + + down_read(&uts_sem); + error = verify_area(VERIFY_WRITE, it, sizeof (struct v7_utsname)); + if (!error) { + set_utsfield(it->sysname, system_utsname.nodename, 1); + set_utsfield(it->nodename, system_utsname.nodename, 1); + set_utsfield(it->release, system_utsname.release, 0); + set_utsfield(it->version, system_utsname.version, 0); + set_utsfield(it->machine, system_utsname.machine, 0); + } + up_read(&uts_sem); + + return error; +} + +int abi_utsname(unsigned long addr) +{ + int error; + struct svr4_utsname *it = (struct svr4_utsname *)addr; + + down_read(&uts_sem); + error = verify_area(VERIFY_WRITE, it, sizeof (struct svr4_utsname)); + if (!error) { + set_utsfield(it->sysname, system_utsname.sysname, 0); + set_utsfield(it->nodename, system_utsname.nodename, 0); + set_utsfield(it->release, system_utsname.release, 0); + set_utsfield(it->version, system_utsname.version, 0); + set_utsfield(it->machine, system_utsname.machine, 0); + } + up_read(&uts_sem); + + return error; +} + +#if defined(CONFIG_ABI_SYSCALL_MODULES) +EXPORT_SYMBOL(abi_utsname); +EXPORT_SYMBOL(v7_utsname); +#endif diff -Nru linux-2.6.7/abi/svr4/xti.c linux-2.6.7-abi/abi/svr4/xti.c --- linux-2.6.7/abi/svr4/xti.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/svr4/xti.c 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,1572 @@ +/* + * Copyright 1995, 1996 Mike Jagdis (jaggy@purplet.demon.co.uk) + */ + +#ident "%W% %G%" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include /* for socksys_fdinit */ + +#include +#include +#include + + +/* + * This is because TLI and XTI options buffers are incompatible and there + * is no clear way to detect which format we are dealing with here. + * Existing systems appear to have TLI options management implemented + * but return TNOTSUPPORT for XTI requests. + */ +#if defined(CONFIG_ABI_XTI_OPTMGMT) && defined(CONFIG_ABI_TLI_OPTMGMT) +# error "unable to support _both_ TLI and XTI option management" +#endif + + +#if defined(CONFIG_ABI_TRACE) +static char *const xti_tab[] = { + "T_CONN_REQ", "T_CONN_RES", + "T_DISCON_REQ", "T_DATA_REQ", + "T_EXDATA_REQ", "T_INFO_REQ", + "T_BIND_REQ", "T_UNBIND_REQ", + "T_UNITDATA_REQ", "T_OPTMGMT_REQ", + "T_ORDREL_REQ","T_CONN_IND", + "T_CONN_CON", "T_DISCON_IND", + "T_DATA_IND", "T_EXDATA_IND", + "T_INFO_ACK", "T_BIND_ACK", + "T_ERROR_ACK","T_OK_ACK", + "T_UNITDATA_IND", "T_UDERROR_IND", + "T_OPTMGMT_ACK", "T_ORDREL_IND" +}; +static char xti_unknown[] = ""; + +static char * +xti_prim(int n) +{ + if (n < 0 || n >= ARRAY_SIZE(xti_tab)) + return xti_unknown; + return xti_tab[n]; +} +#endif + + +#define timod_mkctl(len) kmalloc(sizeof(struct T_primsg)-sizeof(long)+len, \ + GFP_KERNEL) + + +static void +timod_socket_wakeup(struct file *fp) +{ + struct socket *sock; + + sock = SOCKET_I(fp->f_dentry->d_inode); + wake_up_interruptible(&sock->wait); + + read_lock(&sock->sk->sk_callback_lock); + if (sock->fasync_list && !test_bit(SOCK_ASYNC_WAITDATA, &sock->flags)) + __kill_fasync(sock->fasync_list, SIGIO, POLL_IN); + read_unlock(&sock->sk->sk_callback_lock); +} + + +static void +timod_ok(int fd, int prim) +{ + struct file *fp; + struct T_primsg *it; + struct T_ok_ack *ok; + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_STREAMS, "TI: %u ok ack prim=%d\n", fd, prim); +#endif + + fp = fcheck(fd); + it = timod_mkctl(sizeof(struct T_ok_ack)); + if (!it) + return; + + ok = (struct T_ok_ack *)&it->type; + ok->PRIM_type = T_OK_ACK; + ok->CORRECT_prim = prim; + + it->pri = MSG_HIPRI; + it->length = sizeof(struct T_ok_ack); + it->next = Priv(fp)->pfirst; + + Priv(fp)->pfirst = it; + if (!Priv(fp)->plast) + Priv(fp)->plast = it; + timod_socket_wakeup(fp); +} + +static void +timod_error(int fd, int prim, int terr, int uerr) +{ + struct file *fp; + struct T_primsg *it; + struct T_error_ack *err; + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_STREAMS, "TI: %u error prim=%d, TLI=%d, UNIX=%d\n", + fd, prim, terr, uerr); +#endif + + fp = fcheck(fd); + it = timod_mkctl(sizeof(struct T_error_ack)); + if (!it) + return; + + err = (struct T_error_ack *)&it->type; + err->PRIM_type = T_ERROR_ACK; + err->ERROR_prim = prim; + err->TLI_error = terr; + err->UNIX_error = iABI_errors(uerr); + + it->pri = MSG_HIPRI; + it->length = sizeof(struct T_error_ack); + it->next = Priv(fp)->pfirst; + + Priv(fp)->pfirst = it; + if (!Priv(fp)->plast) + Priv(fp)->plast = it; + timod_socket_wakeup(fp); +} + + +#if defined(CONFIG_ABI_XTI_OPTMGMT) || defined(CONFIG_ABI_TLI_OPTMGMT) +/* + * 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_long old_esp, *tsp; + int is_tli, error, failed; + int ret_len, ret_space; + + if (opt_buf && opt_len > 0) { + error = verify_area(VERIFY_READ, opt_buf, opt_len); + if (error) + return error; + } + + /* + * FIXME: + * We should be able to detect the difference between + * TLI and XTI requests at run time? + */ + is_tli = CONFIG_ABI_TLI_OPTMGMT; + + 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 *)(regs->esp - ret_space); + ret_len = 0; + + old_esp = regs->esp; + regs->esp -= ret_space + 6*sizeof(long); + tsp = (unsigned long *)(regs->esp); + error = verify_area(VERIFY_WRITE, tsp, 6*sizeof(long)); + if (error) { + regs->esp = old_esp; + return error; + } + + 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 + + copy_from_user(&opt, opt_buf, sizeof(struct opthdr)); + + /* Idiot check... */ + if (opt.len > opt_len) { + failed = TBADOPT; + break; + } + + if (abi_traced(ABI_TRACE_STREAMS)) { + unsigned long v; + get_user(v, (unsigned long *)(opt_buf+sizeof(struct opthdr))); +#if defined(CONFIG_ABI_TRACE) + __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. */ + error = verify_area(VERIFY_WRITE, ret_buf, sizeof(struct opthdr)); + if (error) { + 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((int)(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((int)(ret_buf+sizeof(struct opthdr)), tsp+3); + put_user((int)(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); + copy_to_user(ret_buf, &opt, sizeof(opt)); + 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)) { + struct t_opthdr opt; + + copy_from_user(&opt, opt_buf, sizeof(struct t_opthdr)); + if (opt.len > opt_len) { + failed = 1; + break; + } + + if (abi_traced(ABI_TRACE_STREAMS)) { + unsigned long v; + get_user(v, (unsigned long *)(opt_buf+sizeof(struct t_opthdr))); +#if defined(CONFIG_ABI_TRACE) + __abi_trace("XTI 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 (verify_area(VERIFY_WRITE, ret_buf, sizeof(struct t_opthdr))) { + failed = 1; + break; + } + + /* Flag values: + * T_NEGOTIATE means try and set it. + * T_CHECK means see if we could set it. + * (so we just set it for now) + * T_DEFAULT means get the default value. + * (return the current for now) + * T_CURRENT means get the current value (SCO xti.h has + * no T_CURRENT???). + */ + error = 0; + if (flag == T_NEGOTIATE || flag == T_CHECK) { + put_user(fd, tsp); + put_user(opt.level, tsp+1); + put_user(opt.name, tsp+2); + put_user((int)(opt_buf+sizeof(struct t_opthdr)), tsp+3); + put_user(opt.len-sizeof(struct t_opthdr), tsp+4); + error = abi_do_setsockopt(tsp); + } + if (!error) { + put_user(fd, tsp); + put_user(opt.level, tsp+1); + put_user(opt.name, tsp+2); + put_user((int)(ret_buf+sizeof(struct t_opthdr)), tsp+3); + put_user((int)(tsp+5), tsp+4); + put_user(ret_space, tsp+5); + error = abi_do_getsockopt(tsp); + if (!error) { + int len; + get_user(len, tsp+5); + /* FIXME: opt.status should be set... */ + copy_to_user(ret_buf, &opt, sizeof(opt)); + put_user(len+sizeof(struct t_opthdr), + &((struct t_opthdr *)opt_buf)->len); + ret_space -= sizeof(struct t_opthdr) + len; + ret_len += sizeof(struct t_opthdr) + len; + ret_buf += sizeof(struct t_opthdr) + len; + } + } + + failed |= error; + opt_len -= opt.len; + opt_buf += opt.len; + } +#endif /* CONFIG_ABI_XTI_OPTMGMT */ + +#if 0 + /* If there is left over data the supplied options buffer was + * formatted incorrectly. But we might have done some work so + * we must fall through and return an acknowledgement I think. + */ + if (opt_len) { + regs->esp = old_esp; + return -EINVAL; + } +#endif + + if (do_ret) { + struct T_primsg *it; + + if (failed) { + timod_error(fd, T_OPTMGMT_REQ, failed, -error); + regs->esp = old_esp; + return 0; + } + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_STREAMS, + "optmgmt returns %d bytes, failed=%d\n", + ret_len, failed); +#endif + + /* Convert the return buffer in the user stack to a + * T_OPTMGMT_ACK + * message and queue it. + */ + it = timod_mkctl(sizeof(struct T_optmgmt_ack) + ret_len); + if (it) { + struct T_optmgmt_ack *ack + = (struct T_optmgmt_ack *)&it->type; + ack->PRIM_type = T_OPTMGMT_ACK; + ack->OPT_length = ret_len; + ack->OPT_offset = sizeof(struct T_optmgmt_ack); + ack->MGMT_flags = (failed ? T_FAILURE : flag); + copy_from_user(((char *)ack)+sizeof(struct T_optmgmt_ack), + ret_base, ret_len); + it->pri = MSG_HIPRI; + it->length = sizeof(struct T_optmgmt_ack) + ret_len; + it->next = Priv(fp)->pfirst; + Priv(fp)->pfirst = it; + if (!Priv(fp)->plast) + Priv(fp)->plast = it; + timod_socket_wakeup(fp); + } + } + + regs->esp = old_esp; + return 0; +} + +#else /* no CONFIG_ABI_XTI_OPTMGMT or CONFIG_ABI_TLI_OPTMGMT */ + +static int +timod_optmgmt(int fd, struct pt_regs * regs, int flag, + char * opt_buf, int opt_len, int do_ret) +{ + return -EINVAL; +} + +#endif /* CONFIG_ABI_XTI_OPTMGMT or CONFIG_ABI_TLI_OPTMGMT */ + +#define T_PRIV(fp) Priv(fp) + +int +timod_update_socket(int fd, struct file * fp, struct pt_regs * regs) +{ + struct socket * sock; + struct T_private * priv; + struct T_primsg * it; + struct T_conn_ind * ind; + u_long old_esp, * tsp, alen; + u_short oldflags; + int error = 0; + + sock = SOCKET_I(fp->f_dentry->d_inode); + priv = T_PRIV(fp); + + /* + * If this a SOCK_STREAM and is in the TS_WRES_CIND state + * we are supposed to be looking for an incoming connection. + */ + if (sock->type != SOCK_STREAM || priv->state != TS_WRES_CIND) + goto out; + + old_esp = regs->esp; + regs->esp -= 1024; + tsp = (unsigned long *)regs->esp; + error = verify_area(VERIFY_WRITE, tsp, + 3*sizeof(long)+sizeof(struct sockaddr)); + if (error) { + regs->esp = old_esp; + goto out; + } + + put_user(fd, tsp); + put_user((unsigned long)(tsp+4), tsp+1); + put_user((unsigned long)(tsp+3), tsp+2); + put_user(sizeof(struct sockaddr), tsp+3); + + /* + * We don't want to block in the accept(). Any + * blocking necessary must be handled earlier. + */ + oldflags = fp->f_flags; + fp->f_flags |= O_NONBLOCK; + error = sys_socketcall(SYS_ACCEPT, tsp); + fp->f_flags = oldflags; + + if (error < 0) + goto out_set; + + /* The new fd needs to be fixed up + * with the iBCS file functions and a + * timod state block. + */ + inherit_socksys_funcs(error, TS_DATA_XFER); + + /* Generate a T_CONN_IND and queue it. */ + get_user(alen, tsp+3); + it = timod_mkctl(sizeof(struct T_conn_ind) + alen); + if (!it) { + /* Oops, just drop the connection I guess. */ + sys_close(error); + goto out_set; + } + + ind = (struct T_conn_ind *)&it->type; + ind->PRIM_type = T_CONN_IND; + ind->SRC_length = alen; + ind->SRC_offset = sizeof(struct T_conn_ind); + ind->OPT_length = ind->OPT_offset = 0; + ind->SEQ_number = error; + + copy_from_user(((char *)ind)+sizeof(struct T_conn_ind), tsp+4, alen); +#if 0 + it->pri = MSG_HIPRI; +#endif + it->length = sizeof(struct T_conn_ind) + alen; + it->next = Priv(fp)->pfirst; + Priv(fp)->pfirst = it; + if (!Priv(fp)->plast) + Priv(fp)->plast = it; + timod_socket_wakeup(fp); + +out_set: + regs->esp = old_esp; +out: + return (error); +} + + +int +do_getmsg(int fd, struct pt_regs *regs, char *ctl_buf, + int ctl_maxlen, int *ctl_len, char *dat_buf, + int dat_maxlen, int *dat_len, int *flags_p) +{ + int error; + long old_esp; + unsigned long *tsp; + unsigned short oldflags; + struct T_unitdata_ind udi; + struct file *filep; + + /* + * It may not be obvious but we are always holding an fget(fd) + * at this point so we can use fcheck(fd) rather than fget...fput. + */ + filep = fcheck(fd); + + if (!Priv(filep) && Priv(filep)->magic != XTI_MAGIC) { + printk("putmsg on non-STREAMS fd %d by %s\n",fd, current->comm); + return -EINVAL; + } + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_STREAMS, + "getmsg %d, 0x%lx[%d], 0x%lx[%d], %x\n", + fd, (u_long)ctl_buf, ctl_maxlen, + (u_long)dat_buf, dat_maxlen, *flags_p); +#endif + + /* + * We need some user space to build syscall argument vectors + * later. Set it up now and page it in if necessary. This will + * avoid (most?) potential blocking after the select(). + */ + old_esp = regs->esp; + regs->esp -= 1024; + tsp = (unsigned long *)regs->esp; + error = verify_area(VERIFY_WRITE, tsp, 6*sizeof(long)); + regs->esp = old_esp; + if (error) + return error; + + /* + * If the TEP is not non-blocking we must test for + * something to do. We don't necessarily know what order + * events will be happening on the socket so we have to + * watch for evrything at once. + * N.B. If we weren't asked for data we should only be looking + * for connection requests. There are socket type issues to + * consider here. + */ + if (!(filep->f_flags & O_NONBLOCK)) { + struct poll_wqueues wait_queue; + poll_table *wait; + unsigned long mask = (POLLIN | POLLRDNORM | POLLHUP | POLLERR); + + if (*flags_p == MSG_HIPRI) + mask |= POLLPRI; + + poll_initwait(&wait_queue); + wait = &wait_queue.pt; + + /* + * N.B. We need to be sure to recheck after a schedule() + * so that when we proceed it is because there is + * something to do and nothing else can get there + * before us. + */ + while (!(filep->f_op->poll(filep, wait) & mask) + && !signal_pending(current)) { + current->state = TASK_INTERRUPTIBLE; + wait = NULL; + schedule(); + } + + current->state = TASK_RUNNING; + poll_freewait(&wait_queue); + + if (signal_pending(current)) + return -EINTR; + } + + if (ctl_maxlen >= 0 && !Priv(filep)->pfirst) + timod_update_socket(fd, filep, regs); + + /* + * If we were asked for a control part and there is an outstanding + * message queued as a result of some other operation we'll + * return that. + */ + if (ctl_maxlen >= 0 && Priv(filep)->pfirst) { + int l = ctl_maxlen <= Priv(filep)->pfirst->length + ? ctl_maxlen : Priv(filep)->pfirst->length; + error = verify_area(VERIFY_WRITE, ctl_buf, l); + if (error) + return error; + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_STREAMS, + "priority message %ld %s\n", + Priv(filep)->pfirst->type, + xti_prim(Priv(filep)->pfirst->type)); +#endif + + copy_to_user(ctl_buf, ((char *)&Priv(filep)->pfirst->type) + + Priv(filep)->offset, l); + put_user(l, ctl_len); + if (dat_maxlen >= 0) + put_user(0, dat_len); + *flags_p = Priv(filep)->pfirst->pri; + Priv(filep)->pfirst->length -= l; + +#if defined(CONFIG_ABI_TRACE) + if (abi_traced(ABI_TRACE_STREAMS) && ctl_buf && l > 0) { + int i = -1; + + for (i = 0; i < l && i < 64; i += 4) { + u_long v; + + get_user(v, (u_long *)(ctl_buf + i)); + __abi_trace("ctl: 0x%08lx\n", v); + } + if (i != l) + __abi_trace("ctl: ...\n"); + } +#endif + + if (Priv(filep)->pfirst->length) { + Priv(filep)->offset += l; + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_STREAMS, + "MORECTL %d bytes", + Priv(filep)->pfirst->length); +#endif + return MORECTL; + } else { + struct T_primsg *it = Priv(filep)->pfirst; + Priv(filep)->pfirst = it->next; + if (!Priv(filep)->pfirst) + Priv(filep)->plast = NULL; + kfree(it); + Priv(filep)->offset = 0; + return 0; + } + } + + *flags_p = 0; + + /* If we weren't asked for data there is nothing more to do. */ + if (dat_maxlen <= 0) { + if (dat_maxlen == 0) + put_user(0, dat_len); + if (ctl_maxlen >= 0) + put_user(0, ctl_len); + return -EAGAIN; + } + + /* If the select() slept we may have had our temp space paged + * out. The re-verify_area is only really needed for pre-486 + * chips which don't handle write faults from kernel mode. + */ + regs->esp = (unsigned long)tsp; + error = verify_area(VERIFY_WRITE, tsp, 6*sizeof(long)); + if (error) { + regs->esp = old_esp; + return error; + } + put_user(fd, tsp); + put_user((unsigned long)dat_buf, tsp+1); + put_user((dat_maxlen < 0 ? 0 : dat_maxlen), tsp+2); + put_user(0, tsp+3); + if (ctl_maxlen > (int)sizeof(udi) && Priv(filep)->state == TS_IDLE) { + put_user((unsigned long)ctl_buf+sizeof(udi), tsp+4); + put_user(ctl_maxlen-sizeof(udi), ctl_len); + put_user((int)ctl_len, tsp+5); + } else { + put_user(0, tsp+4); + put_user(0, ctl_len); + put_user((int)ctl_len, tsp+5); + } + + /* We don't want to block in the recvfrom(). Any blocking is + * handled by the select stuff above. + */ + oldflags = filep->f_flags; + filep->f_flags |= O_NONBLOCK; + error = sys_socketcall(SYS_RECVFROM, tsp); + filep->f_flags = oldflags; + + regs->esp = old_esp; + if (error < 0) + return error; + if (error + && ctl_maxlen > (int)sizeof(udi) + && Priv(filep)->state == TS_IDLE) { + udi.PRIM_type = T_UNITDATA_IND; + get_user(udi.SRC_length, ctl_len); + udi.SRC_offset = sizeof(udi); + udi.OPT_length = udi.OPT_offset = 0; + copy_to_user(ctl_buf, &udi, (int)sizeof(udi)); + put_user(sizeof(udi)+udi.SRC_length, ctl_len); +#if 0 +#if defined(CONFIG_ABI_TRACE) + if (abi_traced(ABI_TRACE_STREAMS) && + ctl_buf && udi.SRC_length > 0) { + char * buf = ctl_buf + sizeof(udi); + int i = -1; + + for (i = 0; i < udi.SRC_length && + i < 64; i += 4) { + u_long v; + + get_user(v, (u_long *)(buf+i)); + __abi_trace("dat: 0x%08lx\n", v); + } + if (i != udi.SRC_length) + __abi_trace("dat: ...\n"); + } +#endif +#endif + } else { + put_user(0, ctl_len); + } + put_user(error, dat_len); + + return 0; +} + + +int +do_putmsg(int fd, struct pt_regs *regs, char *ctl_buf, int ctl_len, + char *dat_buf, int dat_len, int flags) +{ + struct file *filep; + int error, terror; + unsigned long cmd; + + /* It may not be obvious but we are always holding an fget(fd) + * at this point so we can use fcheck(fd) rather than fget...fput. + */ + filep = fcheck(fd); + + if (!Priv(filep) && Priv(filep)->magic != XTI_MAGIC) { + printk("putmsg on non-STREAMS fd %d by %s\n",fd, current->comm); + return -EINVAL; + } + +#if defined(CONFIG_ABI_TRACE) + if (abi_traced(ABI_TRACE_STREAMS)) { + u_long v; + __abi_trace("putmsg %d, 0x%lx[%d], 0x%lx[%d], %x\n", + fd, (u_long)ctl_buf, ctl_len, + (u_long)dat_buf, dat_len, flags); + + get_user(v, ctl_buf); + __abi_trace("putmsg prim: %ld %s\n", v, xti_prim(v)); + + if (ctl_buf && ctl_len > 0) { + int i = -1; + + for (i = 0; i < ctl_len && i < 64; i += 4) { + u_long v; + + get_user(v, (u_long *)(ctl_buf + i)); + __abi_trace("ctl: 0x%08lx\n", v); + } + if (i != ctl_len) + __abi_trace("ctl: ...\n"); + } + + if (dat_buf && dat_len > 0) { + int i = -1; + + for (i = 0; i < dat_len && i < 64; i += 4) { + u_long v; + + get_user(v, (u_long *)(dat_buf + i)); + __abi_trace("dat: 0x%08lx\n", v); + } + if (i != dat_len) + __abi_trace("dat: ..."); + } + } +#endif + + error = get_user(cmd, (unsigned long *)ctl_buf); + if (error) + return error; + + switch (cmd) { + case T_BIND_REQ: { + struct T_bind_req req; + long old_esp; + unsigned long *tsp; + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_STREAMS, "%u bind req\n", fd); +#endif + error = verify_area(VERIFY_READ, ctl_buf, sizeof(req)); + if (error) + return error; + + if (Priv(filep)->state != TS_UNBND) { + timod_error(fd, T_BIND_REQ, TOUTSTATE, 0); + return 0; + } + + old_esp = regs->esp; + regs->esp -= 1024; + tsp = (unsigned long *)(regs->esp); + error = verify_area(VERIFY_WRITE, tsp, 3*sizeof(long)); + if (error) { + timod_error(fd, T_BIND_REQ, TSYSERR, -error); + regs->esp = old_esp; + return 0; + } + + copy_from_user(&req, ctl_buf, sizeof(req)); + if (req.ADDR_offset && req.ADDR_length) { + struct sockaddr_in *sin; + unsigned short family; + +#if 1 /* Wheee... Kludge time... */ + sin = (struct sockaddr_in *)(ctl_buf + + req.ADDR_offset); + get_user(family, &sin->sin_family); + + /* Sybase seems to have set up the address + * struct with sa->sa_family = htons(AF_?) + * which is bollocks. I have no idea why it + * apparently works on SCO?!? + */ + if (family && !(family & 0x00ff)) + put_user(ntohs(family), &sin->sin_family); +#endif + + put_user(fd, tsp); + put_user((unsigned long)ctl_buf + + req.ADDR_offset, tsp+1); + /* For TLI/XTI the length may be the 8 *used* + * bytes, for (IP?) sockets it must be the 16 + * *total* bytes in a sockaddr_in. + */ + put_user(req.ADDR_length == 8 + ? 16 : req.ADDR_length, + tsp+2); + error = sys_socketcall(SYS_BIND, tsp); + + if (!error) { + if (req.CONIND_number) { + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_STREAMS, + "%u listen backlog=%lu\n", + fd, req.CONIND_number); +#endif + + put_user(fd, tsp); + put_user(req.CONIND_number, tsp+1); + sys_socketcall(SYS_LISTEN, tsp); + Priv(filep)->state = TS_WRES_CIND; + } else { + Priv(filep)->state = TS_IDLE; + } + } + } else { + error = 0; + } + + regs->esp = old_esp; + + if (!error) { + struct T_primsg *it; + it = timod_mkctl(ctl_len); + if (it) { + struct T_bind_ack *ack = (struct T_bind_ack *)&it->type; + copy_from_user(ack, ctl_buf, ctl_len); + ack->PRIM_type = T_BIND_ACK; + it->pri = MSG_HIPRI; + it->length = ctl_len; + it->next = NULL; + timod_ok(fd, T_BIND_REQ); + Priv(filep)->plast->next = it; + Priv(filep)->plast = it; + return 0; + } + } + switch (error) { + case -EINVAL: + terror = TOUTSTATE; + error = 0; + break; + case -EACCES: + terror = TACCES; + error = 0; + break; + case -EADDRNOTAVAIL: + case -EADDRINUSE: + terror = TNOADDR; + error = 0; + break; + default: + terror = TSYSERR; + break; + } + timod_error(fd, T_BIND_REQ, terror, -error); + return 0; + } + case T_CONN_RES: { + struct T_conn_res *res = (struct T_conn_res *)ctl_buf; + unsigned int conn_fd; + + error = get_user(conn_fd, &res->SEQ_number); + if (error) + return error; + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_STREAMS, + "%u accept: conn fd=%u, use fd=%u\n", + fd, conn_fd, flags); +#endif + + if (conn_fd != flags) { + error = sys_dup2(conn_fd, flags); + sys_close(conn_fd); + if (error < 0) + return error; + } + timod_ok(fd, T_CONN_RES); + return 0; + } + case T_CONN_REQ: { + struct T_conn_req req; + long old_esp; + unsigned short oldflags; + unsigned long *tsp; + struct T_primsg *it; + struct sockaddr_in *sin; + unsigned short family; + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_STREAMS, "%u connect req\n", fd); +#endif + error = verify_area(VERIFY_READ, ctl_buf, sizeof(req)); + if (error) + return error; + + if (Priv(filep)->state != TS_UNBND + && Priv(filep)->state != TS_IDLE) { + timod_error(fd, T_CONN_REQ, TOUTSTATE, 0); + return 0; + } + + old_esp = regs->esp; + regs->esp -= 1024; + tsp = (unsigned long *)(regs->esp); + error = verify_area(VERIFY_WRITE, tsp, 3*sizeof(long)); + if (error) { + timod_error(fd, T_CONN_REQ, TSYSERR, -error); + regs->esp = old_esp; + return 0; + } + copy_from_user(&req, ctl_buf, sizeof(req)); + put_user(fd, tsp); + put_user((unsigned long)ctl_buf + req.DEST_offset, tsp+1); + /* For TLI/XTI the length may be the 8 *used* + * bytes, for (IP?) sockets it must be the 16 + * *total* bytes in a sockaddr_in. + */ + put_user(req.DEST_length == 8 + ? 16 : req.DEST_length, + tsp+2); + +#if 1 /* Wheee... Kludge time... */ + sin = (struct sockaddr_in *)(ctl_buf + + req.DEST_offset); + get_user(family, &sin->sin_family); + + /* Sybase seems to have set up the address + * struct with sa->sa_family = htons(AF_?) + * which is bollocks. I have no idea why it + * apparently works on SCO?!? + */ + if (family && !(family & 0x00ff)) { + family = ntohs(family); + put_user(family, &sin->sin_family); + } + + /* Sheesh... ISC telnet seems to give the port + * number low byte first as I expected but the + * X programs seem to be giving high byte first. + * One is broken of course but clearly both + * should work. No, I don't understand this + * either but I can at least try... + * A better solution would be for you to change + * the definition of xserver0 in ISC's /etc/services + * but then it wouldn't work out of the box... + */ + if (is_cur_personality(PER_SVR4) && family == AF_INET) { + get_user(family, &sin->sin_port); + if (family == 0x1770) + put_user(htons(family), + &sin->sin_port); + } +#endif + /* FIXME: We should honour non-blocking mode + * here but that means that the select probe + * needs to know that if select returns ok and + * we are in T_OUTCON we have a connection + * completion. This isn't so bad but the real + * problem is that the connection acknowledgement + * is supposed to contain the destination + * address. + */ + oldflags = filep->f_flags; + filep->f_flags &= ~O_NONBLOCK; + error = sys_socketcall(SYS_CONNECT, tsp); + filep->f_flags = oldflags; + regs->esp = old_esp; + + if (!error) { + struct T_conn_con *con; + + it = timod_mkctl(ctl_len); + if (!it) + return -ENOMEM; + it->length = ctl_len; + con = (struct T_conn_con *)&it->type; + copy_from_user(con, ctl_buf, ctl_len); + con->PRIM_type = T_CONN_CON; + Priv(filep)->state = TS_DATA_XFER; + } else { + struct T_discon_ind *dis; + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_STREAMS, + "%u connect failed (errno=%d)\n", + fd, error); +#endif + + it = timod_mkctl(sizeof(struct T_discon_ind)); + if (!it) + return -ENOMEM; + it->length = sizeof(struct T_discon_ind); + dis = (struct T_discon_ind *)&it->type; + dis->PRIM_type = T_DISCON_IND; + dis->DISCON_reason = iABI_errors(-error); + dis->SEQ_number = 0; + } + timod_ok(fd, T_CONN_REQ); + it->pri = 0; + it->next = NULL; + Priv(filep)->plast->next = it; + Priv(filep)->plast = it; + return 0; + } + + case T_DISCON_REQ: { + struct T_discon_req *req; + + req = (struct T_discon_req *)ctl_buf; + error = get_user(fd, &req->SEQ_number); + if (error) + return error; + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_STREAMS, "disconnect %u\n", fd); +#endif + /* Fall through... */ + } + case T_ORDREL_REQ: { + sys_close(fd); + return 0; + } + + case T_DATA_REQ: { + long old_esp; + unsigned long *tsp; + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_STREAMS, "%u data req\n", fd); +#endif + + if (Priv(filep)->state != TS_DATA_XFER) { + return 0; + } + + old_esp = regs->esp; + regs->esp -= 1024; + tsp = (unsigned long *)(regs->esp); + error = verify_area(VERIFY_WRITE, tsp, 6*sizeof(long)); + if (error) { + regs->esp = old_esp; + return 0; + } + put_user(fd, tsp); + put_user((unsigned long)dat_buf, tsp+1); + put_user(dat_len, tsp+2); + put_user(0, tsp+3); + error = sys_socketcall(SYS_SEND, tsp); + regs->esp = old_esp; + return error; + } + + case T_UNITDATA_REQ: { + struct T_unitdata_req req; + long old_esp; + unsigned long *tsp; + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_STREAMS, "%u unitdata req\n", fd); +#endif + error = verify_area(VERIFY_READ, ctl_buf, sizeof(req)); + if (error) + return error; + + if (Priv(filep)->state != TS_IDLE + && Priv(filep)->state != TS_DATA_XFER) { + timod_error(fd, T_UNITDATA_REQ, TOUTSTATE, 0); + return 0; + } + + old_esp = regs->esp; + regs->esp -= 1024; + tsp = (unsigned long *)(regs->esp); + error = verify_area(VERIFY_WRITE, tsp, 6*sizeof(long)); + if (error) { + timod_error(fd, T_UNITDATA_REQ, TSYSERR, -error); + regs->esp = old_esp; + return 0; + } + put_user(fd, tsp); + put_user((unsigned long)dat_buf, tsp+1); + put_user(dat_len, tsp+2); + put_user(0, tsp+3); + copy_from_user(&req, ctl_buf, sizeof(req)); + if (req.DEST_length > 0) { + put_user((unsigned long)(ctl_buf+req.DEST_offset), tsp+4); + put_user(req.DEST_length, tsp+5); + error = sys_socketcall(SYS_SENDTO, tsp); + regs->esp = old_esp; + return error; + } + error = sys_socketcall(SYS_SEND, tsp); + regs->esp = old_esp; + return error; + } + + case T_UNBIND_REQ: + Priv(filep)->state = TS_UNBND; + timod_ok(fd, T_UNBIND_REQ); + return 0; + + case T_OPTMGMT_REQ: { + struct T_optmgmt_req req; + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_STREAMS, "%u optmgmt req\n", fd); +#endif + error = verify_area(VERIFY_READ, ctl_buf, sizeof(req)); + if (error) + return error; + copy_from_user(&req, ctl_buf, sizeof(req)); + + return timod_optmgmt(fd, regs, req.MGMT_flags, + req.OPT_offset > 0 + ? ctl_buf+req.OPT_offset + : NULL, + req.OPT_length, + 1); + } + } + +#if defined(CONFIG_ABI_TRACE) + if (abi_traced(ABI_TRACE_STREAMS)) + { + + if (ctl_buf && ctl_len > 0) { + int i; + + for (i = 0; i < ctl_len && i < 32; i += 4) { + u_long v; + + get_user(v, (u_long *)(ctl_buf + i)); + __abi_trace("ctl: 0x%08lx\n", v); + } + if (i != ctl_len) + __abi_trace("ctl: ...\n"); + } + if (dat_buf && dat_len > 0) { + int i; + for (i = 0; i < dat_len && i < 32; i += 4) { + u_long v; + + get_user(v, (u_long *)(dat_buf + i)); + __abi_trace("dat: 0x%08lx\n", v); + } + if (i != dat_len) + __abi_trace("dat: ...\n"); + } + } +#endif + return -EINVAL; +} + +/* this function needs to be cleaned up badly. --hch */ +int +timod_ioctl(struct pt_regs *regs, + int fd, unsigned int func, void *arg, int len, int *len_p) +{ + struct file *filep; + struct inode *ino; + int error; + + func &= 0xff; + + filep = fget(fd); + if (!filep) + return TBADF; + + error = verify_area(VERIFY_WRITE, len_p, sizeof(int)); + if (error) { + fput(filep); + return (-error << 8) | TSYSERR; + } + + ino = filep->f_dentry->d_inode; + + /* SCO/SVR3 starts at 100, ISC/SVR4 starts at 140. */ + switch (func >= 140 ? func-140 : func-100) { + case 0: /* TI_GETINFO */ + { + struct T_info_ack it; + unsigned long v; + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_STREAMS, "%u getinfo\n", fd); +#endif + /* The pre-SVR4 T_info_ack structure didn't have + * the PROVIDER_flag on the end. + */ + error = verify_area(VERIFY_WRITE, arg, + func == 140 + ? sizeof(struct T_info_ack) + : sizeof(struct T_info_ack)-sizeof(long)); + if (error) { + fput(filep); + return (-error << 8) | TSYSERR; + } + + __get_user(v, &((struct T_info_req *)arg)->PRIM_type); + if (v != T_INFO_REQ) { + fput(filep); + return (EINVAL << 8) | TSYSERR; + } + + it.PRIM_type = T_INFO_ACK; + it.CURRENT_state = Priv(filep)->state; + it.CDATA_size = -2; + it.DDATA_size = -2; + it.OPT_size = -1; + it.TIDU_size = 16384; + switch ((MINOR(ino->i_rdev)>>4) & 0x0f) { + case AF_UNIX: + it.ADDR_size = sizeof(struct sockaddr_un); + break; + case AF_INET: + it.ADDR_size = sizeof(struct sockaddr_in); + break; + default: + /* Uh... dunno... play safe(?) */ + it.ADDR_size = 1024; + break; + } + switch (SOCKET_I(ino)->type) { + case SOCK_STREAM: + it.ETSDU_size = 1; + it.TSDU_size = 0; + it.SERV_type = 2; + break; + default: + it.ETSDU_size = -2; + it.TSDU_size = 16384; + it.SERV_type = 3; + break; + } + + fput(filep); + + /* The pre-SVR4 T_info_ack structure didn't have + * the PROVIDER_flag on the end. + */ + if (func == 140) { + it.PROVIDER_flag = 0; + copy_to_user(arg, &it, sizeof(it)); + put_user(sizeof(it), len_p); + return 0; + } + copy_to_user(arg, &it, sizeof(it)-sizeof(long)); + put_user(sizeof(it)-sizeof(long), len_p); + return 0; + } + + case 2: /* TI_BIND */ + { + int i; + long prim; + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_STREAMS, "%u bind\n", fd); +#endif + error = do_putmsg(fd, regs, arg, len, + NULL, -1, 0); + if (error) { + fput(filep); + return (-error << 8) | TSYSERR; + } + + /* Get the response. This should be either + * T_OK_ACK or T_ERROR_ACK. + */ + i = MSG_HIPRI; + error = do_getmsg(fd, regs, + arg, len, len_p, + NULL, -1, NULL, + &i); + if (error) { + fput(filep); + return (-error << 8) | TSYSERR; + } + + get_user(prim, (unsigned long *)arg); + if (prim == T_ERROR_ACK) { + unsigned long a, b; + fput(filep); + get_user(a, ((unsigned long *)arg)+3); + get_user(b, ((unsigned long *)arg)+2); + return (a << 8) | b; + } + if (prim != T_OK_ACK) { + fput(filep); + return TBADSEQ; + } + + /* Get the response to the bind request. */ + i = MSG_HIPRI; + error = do_getmsg(fd, regs, + arg, len, len_p, + NULL, -1, NULL, + &i); + fput(filep); + if (error) + return (-error << 8) | TSYSERR; + + return 0; + } + + case 3: /* TI_UNBIND */ + if (Priv(filep)->state != TS_IDLE) { + fput(filep); + return TOUTSTATE; + } + Priv(filep)->state = TS_UNBND; + fput(filep); + return 0; + + case 1: { /* TI_OPTMGMT */ +#if defined(CONFIG_ABI_XTI_OPTMGMT) || defined(CONFIG_ABI_TLI_OPTMGMT) + int i; + long prim; + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_STREAMS, "%u optmgmt\n", fd); +#endif + error = do_putmsg(fd, regs, arg, len, + NULL, -1, 0); + if (error) { + fput(filep); + return (-error << 8) | TSYSERR; + } + + /* Get the response to the optmgmt request. */ + i = MSG_HIPRI; + error = do_getmsg(fd, regs, + arg, len, len_p, + NULL, -1, NULL, + &i); + if (error > 0) { + /* If there is excess data in the response + * our buffer is too small which implies + * the application is broken. SO_LINGER + * is a common fault. Because it works + * on other systems we attempt to recover + * by discarding the excess. + */ + struct T_primsg *it = Priv(filep)->pfirst; + Priv(filep)->pfirst = it->next; + if (!Priv(filep)->pfirst) + Priv(filep)->plast = NULL; + kfree(it); + Priv(filep)->offset = 0; + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_STREAMS, + "excess discarded\n"); +#endif + } + + fput(filep); + + if (error < 0) + return (-error << 8) | TSYSERR; + + __get_user(prim, (unsigned long *)arg); + if (prim == T_ERROR_ACK) { + unsigned long a, b; + __get_user(a, ((unsigned long *)arg)+3); + __get_user(b, ((unsigned long *)arg)+2); + return (a << 8) | b; + } + + return 0; +#else /* no CONFIG_ABI_XTI_OPTMGMT or CONFIG_ABI_TLI_OPTMGMT */ + fput(filep); + return TNOTSUPPORT; +#endif /* CONFIG_ABI_XTI_OPTMGMT or CONFIG_ABI_TLI_OPTMGMT */ + } + + case 4: /* TI_GETMYNAME */ + case 5: /* TI_SETPEERNAME */ + case 6: /* TI_GETMYNAME */ + case 7: /* TI_SETPEERNAME */ + break; + } + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_STREAMS, + "STREAMS timod op %d not supported\n", func); +#endif + fput(filep); + return TNOTSUPPORT; +} + + +int +svr4_sockmod_ioctl(int fd, u_int cmd, caddr_t data) +{ + struct file *fp; + struct inode *ip; + int error; + + fp = fget(fd); + if (!fp) + return (TBADF); + + ip = fp->f_dentry->d_inode; + if (MAJOR(ip->i_rdev) == SOCKSYS_MAJOR) { + error = socksys_fdinit(fd, 0, NULL, NULL); + if (error < 0) + return -error; + fput(fp); + fp = fget(fd); + if (!fp) + return TBADF; + ip = fp->f_dentry->d_inode; + } + + switch (cmd) { + case 101: { /* SI_GETUDATA */ + struct { + int tidusize, addrsize, optsize, etsdusize; + int servtype, so_state, so_options; + } *it = (void *)data; + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_STREAMS, "%u getudata\n", fd); +#endif + error = verify_area(VERIFY_WRITE, it, sizeof(*it)); + if (error) { + fput(fp); + return (-error << 8) | TSYSERR; + } + + __put_user(16384, &it->tidusize); + __put_user(sizeof(struct sockaddr), &it->addrsize); + __put_user(-1, &it->optsize); + __put_user(0, &it->so_state); + __put_user(0, &it->so_options); + + switch (SOCKET_I(ip)->type) { + case SOCK_STREAM: + __put_user(1, &it->etsdusize); + __put_user(2, &it->servtype); + break; + default: + __put_user(-2, &it->etsdusize); + __put_user(3, &it->servtype); + break; + } + fput(fp); + return 0; + } + + case 102: /* SI_SHUTDOWN */ + case 103: /* SI_LISTEN */ + case 104: /* SI_SETMYNAME */ + case 105: /* SI_SETPEERNAME */ + case 106: /* SI_GETINTRANSIT */ + case 107: /* SI_TCL_LINK */ + case 108: /* SI_TCL_UNLINK */ + break; + } + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_STREAMS, + "STREAMS sockmod op %d not supported\n", cmd); +#endif + fput(fp); + return TNOTSUPPORT; +} + +#if defined(CONFIG_ABI_SYSCALL_MODULES) +EXPORT_SYMBOL(svr4_sockmod_ioctl); +#endif diff -Nru linux-2.6.7/abi/util/Makefile linux-2.6.7-abi/abi/util/Makefile --- linux-2.6.7/abi/util/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/util/Makefile 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,7 @@ + +abi-util-objs := stat.o plist.o + +obj-$(CONFIG_ABI_UTIL) += abi-util.o + +abi-util.o: $(abi-util-objs) + $(LD) -r -o $@ $(abi-util-objs) diff -Nru linux-2.6.7/abi/util/plist.c linux-2.6.7-abi/abi/util/plist.c --- linux-2.6.7/abi/util/plist.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/util/plist.c 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,69 @@ +#ident "%W% %G%" + +#include +#include +#include /* needed by putname macro */ +#include /* needed by current-> in __abi_trace() macro */ +#include + +#include + + +#if defined(CONFIG_ABI_TRACE) +static void +print_string(char *buf, char *str) +{ + char *tmp; + + tmp = getname(str); + if (!IS_ERR(tmp)) { + /* we are debugging, we don't need to see it all */ + tmp[80] = '\0'; + sprintf(buf, "\"%s\"", tmp); + putname(tmp); + } +} + +void plist(char *name, char *args, int *list) +{ + char buf[512], *p = buf; + + buf[0] = '\0'; + while (*args) { + switch (*args++) { + case 'd': + sprintf(p, "%d", *list++); + break; + case 'o': + sprintf(p, "0%o", *list++); + break; + case 'p': + sprintf(p, "%p", (void *)(*list++)); + break; + case '?': + case 'x': + sprintf(p, "0x%x", *list++); + break; + case 's': + print_string(p, (char *)(*list++)); + break; + default: + sprintf(p, "?%c%c?", '%', args[-1]); + break; + } + + while (*p) + ++p; + if (*args) { + *p++ = ','; + *p++ = ' '; + *p = '\0'; + } + } + __abi_trace("%s(%s)\n", name, buf); +} + +#if CONFIG_ABI_LCALL7 == m +EXPORT_SYMBOL(plist); +#endif +#endif /* CONFIG_ABI_TRACE */ diff -Nru linux-2.6.7/abi/util/stat.c linux-2.6.7-abi/abi/util/stat.c --- linux-2.6.7/abi/util/stat.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/util/stat.c 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,146 @@ +/* + * Mostly ripped from Al Viro's stat-a-AC9-10 patch, 2001 Christoph Hellwig. + */ + +#ident "%W% %G%" + +#include /* needed to shut up modprobe */ +#include +#include +#include +#include +#include + +#include +#include + + +MODULE_DESCRIPTION("Linux-ABI helper routines"); +MODULE_AUTHOR("Christoph Hellwig, ripped from kernel sources/patches"); +MODULE_LICENSE("GPL"); + +#if 0 /* LINUXABI_OBSOLETE */ +int getattr_full(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) +{ + struct inode *inode = dentry->d_inode; + stat->dev = inode->i_rdev; + stat->ino = inode->i_ino; + stat->mode = inode->i_mode; + stat->nlink = inode->i_nlink; + stat->uid = inode->i_uid; + stat->gid = inode->i_gid; + stat->rdev = inode->i_rdev; + stat->atime = inode->i_atime; + stat->mtime = inode->i_mtime; + stat->ctime = inode->i_ctime; + stat->size = inode->i_size; + stat->blocks = inode->i_blocks; + stat->blksize = inode->i_blksize; + return 0; +} + +/* + * Use minix fs values for the number of direct and indirect blocks. The + * count is now exact for the minix fs except that it counts zero blocks. + * Everything is in units of BLOCK_SIZE until the assignment to + * stat->blksize. + */ +int getattr_minix(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) +{ + struct inode *inode = dentry->d_inode; + unsigned int blocks, indirect; + + stat->dev = inode->i_rdev; + stat->ino = inode->i_ino; + stat->mode = inode->i_mode; + stat->nlink = inode->i_nlink; + stat->uid = inode->i_uid; + stat->gid = inode->i_gid; + stat->rdev = inode->i_rdev; + stat->atime = inode->i_atime; + stat->mtime = inode->i_mtime; + stat->ctime = inode->i_ctime; + stat->size = inode->i_size; +#define D_B 7 +#define I_B (BLOCK_SIZE / sizeof(unsigned short)) + + blocks = (stat->size + BLOCK_SIZE - 1) >> BLOCK_SIZE_BITS; + if (blocks > D_B) { + indirect = (blocks - D_B + I_B - 1) / I_B; + blocks += indirect; + if (indirect > 1) { + indirect = (indirect - 1 + I_B - 1) / I_B; + blocks += indirect; + if (indirect > 1) + blocks++; + } + } + stat->blocks = (BLOCK_SIZE / 512) * blocks; + stat->blksize = BLOCK_SIZE; + return 0; +} + +int vfs_stat(char *filename, struct kstat *stat) +{ + struct nameidata nd; + int error; + + error = user_path_walk(filename, &nd); + if (error) + return error; + + error = do_revalidate(nd.dentry); + if (!error) { + struct inode *inode = nd.dentry->d_inode; + if (!inode->i_blksize) + error = getattr_minix(nd.mnt, nd.dentry, stat); + else + error = getattr_full(nd.mnt, nd.dentry, stat); + path_release(&nd); + } + + return error; +} + +int vfs_lstat(char *filename, struct kstat *stat) +{ + struct nameidata nd; + int error; + + error = user_path_walk_link(filename, &nd); + if (error) + return error; + + error = do_revalidate(nd.dentry); + if (!error) { + struct inode *inode = nd.dentry->d_inode; + if (!inode->i_blksize) + error = getattr_minix(nd.mnt, nd.dentry, stat); + else + error = getattr_full(nd.mnt, nd.dentry, stat); + path_release(&nd); + } + + return error; +} + +int vfs_fstat(int fd, struct kstat *stat) +{ + struct file *file = fget(fd); + int error; + + if (!file) + return -EBADF; + + error = do_revalidate(file->f_dentry); + if (!error) { + struct inode *inode = file->f_dentry->d_inode; + if (!inode->i_blksize) + error = getattr_minix(file->f_vfsmnt, file->f_dentry, stat); + else + error = getattr_full(file->f_vfsmnt, file->f_dentry, stat); + fput(file); + } + return error; +} +#endif diff -Nru linux-2.6.7/abi/uw7/access.c linux-2.6.7-abi/abi/uw7/access.c --- linux-2.6.7/abi/uw7/access.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/uw7/access.c 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,75 @@ +/* + * abi/uw7/access.c - support for UnixWare access(2) system call. + * + * We handle the non-POSIX EFF_ONLY_OK/EX_OK flags. + * This software is under GPL. + */ + +#include +#include +#include +#include +#include +#include + +#include + + +#undef DEBUG + +#ifdef DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif + +#define UW7_R_OK 004 +#define UW7_W_OK 002 +#define UW7_X_OK 001 +#define UW7_F_OK 000 +#define UW7_EFF_ONLY_OK 010 +#define UW7_EX_OK 020 + +#define UW7_MODE_MSK (UW7_R_OK|UW7_W_OK|UW7_X_OK|UW7_F_OK|UW7_EFF_ONLY_OK|UW7_EX_OK) + +int uw7_access(char * filename, int mode) +{ + struct nameidata nd; + int error; + + DBG(KERN_ERR "UW7[%d]: access(%p,%o)\n", current->pid, filename, mode); + + if (mode & ~UW7_MODE_MSK) + return -EINVAL; + + if (mode & UW7_EX_OK) { + error = user_path_walk(filename, &nd); + if (!error) { + error = do_revalidate(nd.dentry); + if (error) { + path_release(&nd); + return -EIO; + } + if (!S_ISREG(nd.dentry->d_inode->i_mode)) { + path_release(&nd); + return -EACCES; + } + path_release(&nd); + } + mode &= ~UW7_EX_OK; + mode |= UW7_X_OK; + } + if (mode & UW7_EFF_ONLY_OK) { + uid_t old_uid = current->uid, old_gid = current->gid; + + current->uid = current->euid; + current->gid = current->egid; + mode &= ~UW7_EFF_ONLY_OK; + error = sys_access(filename, mode); + current->uid = old_uid; + current->gid = old_gid; + } else + error = sys_access(filename, mode); + + return error; +} diff -Nru linux-2.6.7/abi/uw7/context.c linux-2.6.7-abi/abi/uw7/context.c --- linux-2.6.7/abi/uw7/context.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/uw7/context.c 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,98 @@ +/* + * abi/uw7/context.c + * + * This software is under GPL + */ + + +#include +#include +#define __KERNEL_SYSCALLS__ +#include +#include +#include + +#include +#include + + +int +uw7_sigaltstack(const uw7_stack_t *uw7_ss, uw7_stack_t *uw7_oss) +{ + stack_t ss, oss, *ssp = NULL, *ossp = NULL; + int error; + mm_segment_t old_fs; + + if (uw7_ss) { + error = verify_area(VERIFY_READ, uw7_ss, sizeof(uw7_stack_t)); + if (error) + return error; + __get_user(ss.ss_sp, &uw7_ss->ss_sp); + __get_user(ss.ss_size, &uw7_ss->ss_size); + __get_user(ss.ss_flags, &uw7_ss->ss_flags); + ssp = &ss; + } + + if (uw7_oss) { + error = verify_area(VERIFY_WRITE, uw7_oss, sizeof(uw7_stack_t)); + if (error) + return error; + __get_user(oss.ss_sp, &uw7_oss->ss_sp); + __get_user(oss.ss_size, &uw7_oss->ss_size); + __get_user(oss.ss_flags, &uw7_oss->ss_flags); + ossp = &oss; + } + + old_fs = get_fs(); + set_fs(get_ds()); + error = sys_sigaltstack(ssp, ossp); + set_fs(old_fs); + + if (ossp) { + __put_user(ossp->ss_sp, &uw7_oss->ss_sp); + __put_user(ossp->ss_size, &uw7_oss->ss_size); + __put_user(ossp->ss_flags, &uw7_oss->ss_flags); + } + return error; +} + +static int +getcontext(uw7_context_t * uc, struct pt_regs * regs) +{ + uw7_context_t tmp = { 0 }; + + return copy_to_user(uc, &tmp, sizeof(uw7_context_t)) ? -EFAULT : 0; +} + +static int +getxcontext(uw7_context_t * uc, struct pt_regs * regs) +{ + return 0; +} + +static int +setcontext(uw7_context_t * uc, struct pt_regs * regs) +{ + if (!uc) /* SVR4 says setcontext(NULL) => exit(0) */ + sys_exit(0); + return 0; +} + +int +uw7_context(struct pt_regs * regs) +{ + int fcn = get_syscall_parameter(regs, 0); + uw7_context_t * uc = (uw7_context_t *) get_syscall_parameter(regs, 1); + + switch (fcn) { + case UW7_GETCONTEXT: + return getcontext(uc, regs); + + case UW7_GETXCONTEXT: + return getxcontext(uc, regs); + + case UW7_SETCONTEXT: + return setcontext(uc, regs); + } + return -EINVAL; +} diff -Nru linux-2.6.7/abi/uw7/ioctl.c linux-2.6.7-abi/abi/uw7/ioctl.c --- linux-2.6.7/abi/uw7/ioctl.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/uw7/ioctl.c 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,220 @@ +/* + * abi/uw7/ioctl.c - Support for UnixWare 7.x ioctl(2) system call. + * + * This module provides a function uw7_ioctl() which is called indirectly + * via uw7_funcs[] array, see abi/uw7/funcs.c. + * This software is under GPL + */ + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + + +#undef DEBUG + +#ifdef DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif + + +static int tioc_tcgets(int fd, struct uw7_termios * tios); +static int tioc_tcsets(int fd, int lnx_cmd, struct uw7_termios * tios); +static int ioctl_T(int fd, unsigned int cmd, void * arg); + + +int uw7_ioctl(struct pt_regs * regs) +{ + int fd; + unsigned int cmd, class; + void * arg; + + fd = (int)get_syscall_parameter(regs, 0); + cmd = (unsigned int)get_syscall_parameter(regs, 1); + arg = (void *)get_syscall_parameter(regs, 2); + class = cmd >> 8; + + switch (class) { + case 'T': + return ioctl_T(fd, cmd, arg); + default: + return __svr4_ioctl(regs, fd, cmd, arg); + } +} + +static int tioc_tcsets(int fd, int lnx_cmd, struct uw7_termios * tios) +{ + struct termios t; + struct uw7_termios tmp = {0, }; + mm_segment_t old_fs; + int error; + + DBG(KERN_ERR "UW7[%d]: tioc_tcsets(%d,%x,%p)\n", + current->pid, fd, lnx_cmd, tios); + + error = verify_area(VERIFY_READ, tios, sizeof(struct uw7_termios)); + if (error) + return error; + + old_fs = get_fs(); + set_fs(get_ds()); + error = sys_ioctl(fd, TCGETS, (long)&t); + set_fs(old_fs); + if (error) + return error; + + if (copy_from_user(&tmp, tios, sizeof(struct uw7_termios))) + return -EFAULT; + t.c_iflag = tmp.c_iflag & ~UW7_DOSMODE; + t.c_oflag = tmp.c_oflag; + t.c_cflag = tmp.c_cflag; + t.c_lflag = tmp.c_lflag & ~UW7_DEFECHO; + if (tmp.c_lflag & UW7_FLUSHO) + t.c_lflag |= FLUSHO; + else + t.c_lflag &= ~FLUSHO; + + DBG(KERN_ERR + "UW7[%d]: iflag: %lx->%lx, oflag: %lx->%lx, cflag: %lx->%lx, lflag: %lx->%lx\n", + current->pid, tmp.c_iflag, t.c_iflag, tmp.c_oflag, t.c_oflag, + tmp.c_cflag, t.c_cflag, tmp.c_lflag, t.c_lflag); + + t.c_cc[VINTR] = tmp.c_cc[UW7_VINTR]; + t.c_cc[VQUIT] = tmp.c_cc[UW7_VQUIT]; + t.c_cc[VERASE] = tmp.c_cc[UW7_VERASE]; + t.c_cc[VKILL] = tmp.c_cc[UW7_VKILL]; + t.c_cc[VEOL2] = tmp.c_cc[UW7_VEOL2]; + t.c_cc[VSWTC] = tmp.c_cc[UW7_VSWTCH]; + t.c_cc[VSTART] = tmp.c_cc[UW7_VSTART]; + t.c_cc[VSTOP] = tmp.c_cc[UW7_VSTOP]; + t.c_cc[VSUSP] = tmp.c_cc[UW7_VSUSP]; + t.c_cc[VREPRINT] = tmp.c_cc[UW7_VREPRINT]; + t.c_cc[VDISCARD] = tmp.c_cc[UW7_VDISCARD]; + t.c_cc[VWERASE] = tmp.c_cc[UW7_VWERASE]; + t.c_cc[VLNEXT] = tmp.c_cc[UW7_VLNEXT]; + if (t.c_lflag & ICANON) { + t.c_cc[VEOF] = tmp.c_cc[UW7_VEOF]; + t.c_cc[VEOL] = tmp.c_cc[UW7_VEOL]; + } else { + t.c_cc[VMIN] = tmp.c_cc[UW7_VMIN]; + t.c_cc[VTIME] = tmp.c_cc[UW7_VTIME]; + t.c_cc[VEOL] = tmp.c_cc[UW7_VEOL2]; + } + + + DBG(KERN_ERR + "UW7[%d]: " + "VINTR: %x->%x, VQUIT: %x->%x, VERASE: %x->%x, VKILL: %x->%x\n" + "VEOL2: %x->%x\n", + current->pid, tmp.c_cc[UW7_VINTR], t.c_cc[VINTR], + tmp.c_cc[UW7_VQUIT], t.c_cc[VQUIT], + tmp.c_cc[UW7_VERASE], t.c_cc[VERASE], + tmp.c_cc[UW7_VKILL], t.c_cc[VKILL], + tmp.c_cc[UW7_VEOL2], t.c_cc[VEOL2]); + + old_fs = get_fs(); + set_fs(get_ds()); + error = sys_ioctl(fd, lnx_cmd, (long)&t); + set_fs(old_fs); + return error; +} + +static int tioc_tcgets(int fd, struct uw7_termios * tios) +{ + struct termios t; + struct uw7_termios tmp = { 0 }; + mm_segment_t old_fs; + int error; + + DBG(KERN_ERR "UW7[%d]: tioc_tcgets(%d,%p)\n", current->pid, fd, tios); + + old_fs = get_fs(); + set_fs(get_ds()); + error = sys_ioctl(fd, TCGETS, (long)&t); + set_fs(old_fs); + if (error) + return error; + + tmp.c_iflag = UW7_IFLAG_MSK & (t.c_iflag & ~UW7_DOSMODE); + tmp.c_oflag = UW7_OFLAG_MSK & t.c_oflag; + tmp.c_cflag = UW7_CFLAG_MSK & t.c_cflag; + tmp.c_lflag = UW7_LFLAG_MSK & (t.c_lflag & ~UW7_DEFECHO); + if (t.c_lflag & FLUSHO) + tmp.c_lflag |= UW7_FLUSHO; + else + tmp.c_lflag &= ~UW7_FLUSHO; + + DBG(KERN_ERR + "UW7[%d]: iflag: %lx->%lx, oflag: %lx->%lx, cflag: %lx->%lx, lflag: %lx->%lx\n", + current->pid, tmp.c_iflag, t.c_iflag, tmp.c_oflag, t.c_oflag, + tmp.c_cflag, t.c_cflag, tmp.c_lflag, t.c_lflag); + + if (t.c_lflag & ICANON) { + tmp.c_cc[UW7_VEOF] = t.c_cc[VEOF]; + tmp.c_cc[UW7_VEOL] = t.c_cc[VEOL]; + } else { + tmp.c_cc[UW7_VMIN] = t.c_cc[VMIN]; + tmp.c_cc[UW7_VTIME] = t.c_cc[VTIME]; + } + + tmp.c_cc[UW7_VINTR] = t.c_cc[VINTR]; + tmp.c_cc[UW7_VQUIT] = t.c_cc[VQUIT]; + tmp.c_cc[UW7_VERASE] = t.c_cc[VERASE]; + tmp.c_cc[UW7_VKILL] = t.c_cc[VKILL]; + tmp.c_cc[UW7_VEOL2] = t.c_cc[VEOL2]; + tmp.c_cc[UW7_VSWTCH] = t.c_cc[VSWTC]; + tmp.c_cc[UW7_VSTART] = t.c_cc[VSTART]; + tmp.c_cc[UW7_VSTOP] = t.c_cc[VSTOP]; + tmp.c_cc[UW7_VSUSP] = tmp.c_cc[UW7_VDSUSP] = t.c_cc[VSUSP]; + tmp.c_cc[UW7_VREPRINT] = t.c_cc[VREPRINT]; + tmp.c_cc[UW7_VDISCARD] = t.c_cc[VDISCARD]; + tmp.c_cc[UW7_VWERASE] = t.c_cc[VWERASE]; + tmp.c_cc[UW7_VLNEXT] = t.c_cc[VLNEXT]; + + return copy_to_user(tios, &tmp, sizeof(struct uw7_termios)) ? -EFAULT : 0; +} + +static int ioctl_T(int fd, unsigned int cmd, void * arg) +{ + DBG(KERN_ERR "ioctl_T(%d,%x,%p)\n", fd, cmd, arg); + + switch (cmd) { + case UW7_TCSBRK: + return sys_ioctl(fd, TCSBRK, (long)arg); + + case UW7_TCXONC: + return sys_ioctl(fd, TCXONC, (long)arg); + + case UW7_TCFLSH: + return sys_ioctl(fd, TCFLSH, (long)arg); + + case UW7_TIOCSWINSZ: + return sys_ioctl(fd, TIOCSWINSZ, (long)arg); + + case UW7_TIOCGWINSZ: + return sys_ioctl(fd, TIOCGWINSZ, (long)arg); + + case UW7_TCGETS: + return tioc_tcgets(fd, arg); + + case UW7_TCSETS: + return tioc_tcsets(fd, TCSETS, arg); + + case UW7_TCSETSW: + return tioc_tcsets(fd, TCSETSW, arg); + + case UW7_TCSETSF: + return tioc_tcsets(fd, TCSETSF, arg); + } + return -EINVAL; +} diff -Nru linux-2.6.7/abi/uw7/lfs.c linux-2.6.7-abi/abi/uw7/lfs.c --- linux-2.6.7/abi/uw7/lfs.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/uw7/lfs.c 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,241 @@ +/* + * Copyright (c) 1999 Tigran Aivazian. + * Copyright (c) 2001 Christoph Hellwig. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ident "%W% %G%" + +/* + * Support for the UnixWare 7.x LFS (Large File Summit) syscalls. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + + +/* + * The UnixWare 7 truncate64/fruncate64 syscalls are the same as in + * Linux, but we can't easily handle long long syscall parameters for + * lcall7, thus we have to fake two 32bit arguments instead. + * + * XXX: if do_sys_truncate/do_sys_ftruncate in fs/open.c were exported + * we could get rid of one function call. + */ +int +uw7_truncate64(const char *filename, u_int len, u_int len_hi) +{ + return sys_truncate64(filename, (len | (loff_t)len_hi << 32)); +} + +int +uw7_ftruncate64(int fd, u_int len, u_int len_hi) +{ + return sys_ftruncate64(fd, (len | (loff_t)len_hi << 32)); +} + +/* + * The SVR4 statvfs is basically our statfs, but of course only + * basically .... + */ +static int +cp_uw7_statvfs64(struct super_block *sbp, struct kstatfs *srcp, + struct uw7_statvfs64 *dstp) +{ + struct uw7_statvfs64 tmp; + + memset(&tmp, 0, sizeof(struct uw7_statvfs64)); + + tmp.f_bsize = srcp->f_bsize; + tmp.f_frsize = srcp->f_bsize; + tmp.f_blocks = srcp->f_blocks; + tmp.f_bfree = srcp->f_bfree; + tmp.f_bavail = srcp->f_bavail; + tmp.f_files = srcp->f_files; + tmp.f_ffree = srcp->f_ffree; + tmp.f_favail = srcp->f_ffree; + tmp.f_fsid = sbp->s_dev; + + strcpy(tmp.f_basetype, sbp->s_type->name); + + tmp.f_namemax = srcp->f_namelen; + + if (copy_to_user(dstp, &tmp, sizeof(struct uw7_statvfs64))) + return -EFAULT; + return 0; +} + +int +uw7_statvfs64(char *filename, struct uw7_statvfs64 *stvfsp) +{ + struct nameidata nd; + int error; + + error = user_path_walk(filename, &nd); + if (!error) { + struct super_block *sbp = nd.dentry->d_inode->i_sb; + struct kstatfs tmp; + + error = vfs_statfs(sbp, &tmp); + if (!error && cp_uw7_statvfs64(sbp, &tmp, stvfsp)) + error = -EFAULT; + path_release(&nd); + } + + return (error); +} + + +int +uw7_fstatvfs64(int fd, struct uw7_statvfs64 *stvfsp) +{ + struct file *fp; + int error = -EBADF; + + fp = fget(fd); + if (fp) { + struct super_block *sbp = fp->f_dentry->d_inode->i_sb; + struct kstatfs tmp; + + error = vfs_statfs(sbp, &tmp); + if (!error && cp_uw7_statvfs64(sbp, &tmp, stvfsp)) + error = -EFAULT; + fput(fp); + } + + return (error); +} + +static __inline__ int +uw7_rlim64_to_user(int resource, struct uw7_rlim64 *rlimp) +{ + struct rlimit *lxrlim = current->rlim + resource; + struct uw7_rlim64 rlim; + + rlim.rlim_cur = lxrlim->rlim_cur; + rlim.rlim_max = lxrlim->rlim_max; + + if (copy_to_user(rlimp, &rlim, sizeof(struct uw7_rlim64))) + return -EFAULT; + return 0; +} + +int +uw7_getrlimit64(int resource, struct uw7_rlim64 *rlimp) +{ + if (resource > ARRAY_SIZE(uw7_to_linux_rlimit)) + return -EINVAL; + + return (uw7_rlim64_to_user(uw7_to_linux_rlimit[resource], rlimp)); +} + +static __inline__ int +uw7_check_rlimit64(int resource, const struct uw7_rlim64 *rlimp, + struct rlimit *lxrlimp) +{ + if ((rlimp->rlim_cur > RLIM_INFINITY) || + (rlimp->rlim_max > RLIM_INFINITY)) + return -EPERM; /* XXX: actually this is wrong */ + + if (((rlimp->rlim_cur > lxrlimp->rlim_max) || + (rlimp->rlim_max > lxrlimp->rlim_max)) && + !capable(CAP_SYS_RESOURCE)) + return -EPERM; + + if (resource == RLIMIT_NOFILE && + (rlimp->rlim_cur > NR_OPEN || rlimp->rlim_max > NR_OPEN)) + return -EPERM; + + return 0; +} + +int +uw7_setrlimit64(int resource, const struct uw7_rlim64 *rlimp) +{ + struct rlimit *lxrlim = current->rlim + resource; + struct uw7_rlim64 rlim; + + if (resource > ARRAY_SIZE(uw7_to_linux_rlimit)) + return -EINVAL; + if (copy_from_user(&rlim, rlimp, sizeof(struct uw7_rlim64))) + return -EFAULT; + if (uw7_check_rlimit64(resource, &rlim, lxrlim)) + return -EPERM; + + /* XXX: this is non-atomic. */ + lxrlim->rlim_cur = rlim.rlim_cur; + lxrlim->rlim_max = rlim.rlim_max; + + return 0; +} + +/* + * 64bit lseek for UnixWare. + */ +int +uw7_lseek64(int fd, u_int off, u_int off_hi, int orig) +{ + loff_t result; + int err; + + if (off_hi == (u_int)-1) + off_hi = 0; + + err = sys_llseek(fd, (off_t) off_hi, off, &result, orig); + if (err) + return err; + return (long)result; /* XXX: how does UnixWare return large results? */ +} + +/* + * The UnixWare 7 pread64/pwrite64 syscalls are the same as in Linux, + * but we can't easily handle long long syscall parameters for lcall7, + * thus we have to fake two 32bit arguments instead. + */ +ssize_t +uw7_pread64(int fd, char *bufp, int count, u_int pos, u_int pos_hi) +{ + return sys_pread64(fd, bufp, count, (pos | (loff_t)pos_hi << 32)); +} + +ssize_t +uw7_pwrite64(int fd, char *bufp, int count, u_int pos, u_int pos_hi) +{ + return sys_pwrite64(fd, bufp, count, (pos | (loff_t)pos_hi << 32)); +} + +/* + * Unlike Linux UnixWare 7 does not simply add O_LARGEFILE to flags in + * libc, so we have to do it. + * We call sys_open directly as sys_creat is just yet another wrapper. + */ +#define UW7_CREAT64_FLAGS \ + (O_LARGEFILE | O_CREAT | O_WRONLY | O_TRUNC) +int +uw7_creat64(const char *filename, int mode) +{ + return sys_open(filename, UW7_CREAT64_FLAGS, mode); +} diff -Nru linux-2.6.7/abi/uw7/mac.c linux-2.6.7-abi/abi/uw7/mac.c --- linux-2.6.7/abi/uw7/mac.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/uw7/mac.c 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,41 @@ +/* + * abi/uw7/mac.c - mldmode(2) and friends. + * + * This software is under GPL + */ + +#include +#include + +#undef DEBUG + +#ifdef DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif + +#define UW7_MLD_REAL 1 +#define UW7_MLD_VIRT 0 +#define UW7_MLD_QUERY 2 + +int uw7_mldmode(int mldmode) +{ + switch (mldmode) { + case UW7_MLD_REAL: + DBG(KERN_ERR "UW7[%d]: mldmode(MLD_REAL)\n", current->pid); + break; + + case UW7_MLD_VIRT: + DBG(KERN_ERR "UW7[%d]: mldmode(MLD_VIRT)\n", current->pid); + break; + + case UW7_MLD_QUERY: + DBG(KERN_ERR "UW7[%d]: mldmode(MLD_QUERY)\n", current->pid); + return UW7_MLD_REAL; + + default: + return -EINVAL; + } + return 0; +} diff -Nru linux-2.6.7/abi/uw7/Makefile linux-2.6.7-abi/abi/uw7/Makefile --- linux-2.6.7/abi/uw7/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/uw7/Makefile 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,8 @@ + +abi-uw7-objs := access.o context.o ioctl.o lfs.o mac.o \ + misc.o mmap.o stat.o sysent.o + +obj-$(CONFIG_ABI_UW7) += abi-uw7.o + +abi-uw7.o: $(abi-uw7-objs) + $(LD) -r -o $@ $(abi-uw7-objs) diff -Nru linux-2.6.7/abi/uw7/misc.c linux-2.6.7-abi/abi/uw7/misc.c --- linux-2.6.7/abi/uw7/misc.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/uw7/misc.c 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,66 @@ +/* + * abi/uw7/misc.c - various UW7 system calls. + * + * This software is under GPL + */ + +#include +#include +#include +#include +#include +#include + + +int uw7_sleep(int seconds) +{ + struct timespec t; + mm_segment_t old_fs; + int error; + + t.tv_sec = seconds; + t.tv_nsec = 0; + old_fs = get_fs(); + set_fs(get_ds()); + error = sys_nanosleep(&t, NULL); + set_fs(old_fs); + return error; +} + +#define UW7_MAXUID 60002 + +int uw7_seteuid(int uid) +{ + if (uid < 0 || uid > UW7_MAXUID) + return -EINVAL; + return sys_setreuid16(-1, uid); +} + +int uw7_setegid(int gid) +{ + if (gid < 0 || gid > UW7_MAXUID) + return -EINVAL; + return sys_setreuid16(-1, gid); +} + +/* can't call sys_pread64() directly because off is 32bit on UW7 */ +int uw7_pread(unsigned int fd, char * buf, int count, long off) +{ + return sys_pread64(fd, buf, count, (loff_t)off); +} + +/* can't call sys_pwrite64() directly because off is 32bit on UW7 */ +int uw7_pwrite(unsigned int fd, char * buf, int count, long off) +{ + return sys_pwrite64(fd, buf, count, (loff_t)off); +} + +int uw7_stty(int fd, int cmd) +{ + return -EIO; +} + +int uw7_gtty(int fd, int cmd) +{ + return -EIO; +} diff -Nru linux-2.6.7/abi/uw7/mmap.c linux-2.6.7-abi/abi/uw7/mmap.c --- linux-2.6.7/abi/uw7/mmap.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/uw7/mmap.c 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,71 @@ +/* + * Copyright (c) 1999 Tigran Aivazian. + * Copyright (c) 2001 Christoph Hellwig. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ident "%W% %G%" + +/* + * Support for mmap on UnixWare 7. + */ +#include +#include +#include +#include + +#include + + +/* the other MAP_XXX values are the same as on Linux/i386 */ +#define UW7_MAP_ANONYMOUS 0x100 + +int +uw7_mmap64(u_long addr, size_t len, int prot, int flags, + int fd, u_int off, u_int off_hi) +{ + loff_t off64 = (off | ((loff_t)off_hi << 32)); + u_long pgoff = (off64 >> PAGE_SHIFT); + int error = -EBADF; + struct file *fp = NULL; + + if ((off64 + PAGE_ALIGN(len)) < off64) + return -EINVAL; + + if (!(off64 & ~PAGE_MASK)) + return -EINVAL; + + if (flags & UW7_MAP_ANONYMOUS) { + flags |= MAP_ANONYMOUS; + flags &= ~UW7_MAP_ANONYMOUS; + } + + flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); + if (!(flags & MAP_ANONYMOUS)) { + if (!(fp = fget(fd))) + goto out; + } + + down_write(¤t->mm->mmap_sem); + error = do_mmap_pgoff(fp, addr, len, prot, flags, pgoff); + up_write(¤t->mm->mmap_sem); + + if (fp) + fput(fp); +out: + return (error); +} diff -Nru linux-2.6.7/abi/uw7/stat.c linux-2.6.7-abi/abi/uw7/stat.c --- linux-2.6.7/abi/uw7/stat.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/uw7/stat.c 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2001 Christoph Hellwig. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * aint32_t with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ident "%W% %G%" + +/* + * UnixWare 7.x xstat support. + */ +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + + +enum {SVR4_stat = 1, SVR4_xstat = 2, UW7_stat64 = 4}; + +int +report_uw7_stat64(struct kstat *stp, struct uw7_stat64 *bufp) +{ + struct uw7_stat64 buf; + + memset(&buf, 0, sizeof(struct uw7_stat64)); + + buf.st_dev = linux_to_uw7_dev_t(stp->dev); + buf.st_ino = linux_to_uw7_ino_t(stp->ino); + buf.st_mode = stp->mode; + buf.st_nlink = stp->nlink; + buf.st_uid = linux_to_uw7_uid_t(stp->uid); + buf.st_gid = linux_to_uw7_gid_t(stp->gid); + buf.st_rdev = linux_to_uw7_dev_t(stp->rdev); + buf.st_size = stp->size; + + buf.st_atime.tv_sec = stp->atime.tv_sec; + buf.st_mtime.tv_sec = stp->mtime.tv_sec; + buf.st_ctime.tv_sec = stp->ctime.tv_sec; + + buf.st_blksize = stp->blksize; + buf.st_blocks = stp->blocks; + + strcpy(buf.st_fstype, "ext2"); + + if (copy_to_user(bufp, &buf, sizeof(struct uw7_stat64))) + return -EFAULT; + return 0; +} + +int +uw7_xstat(int vers, char *filename, void *bufp) +{ + struct kstat st; + int error; + + error = vfs_stat(filename, &st); + if (error) + return error; + + switch (vers) { + case SVR4_stat: + return report_svr4_stat(&st, bufp); + case SVR4_xstat: + return report_svr4_xstat(&st, bufp); + case UW7_stat64: + return report_uw7_stat64(&st, bufp); + } + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_API, "xstat version %d not supported\n", vers); +#endif + return -EINVAL; +} + +int +uw7_lxstat(int vers, char *filename, void *bufp) +{ + struct kstat st; + int error; + + error = vfs_lstat(filename, &st); + if (error) + return error; + + switch (vers) { + case SVR4_stat: + return report_svr4_stat(&st, bufp); + case SVR4_xstat: + return report_svr4_xstat(&st, bufp); + case UW7_stat64: + return report_uw7_stat64(&st, bufp); + } + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_API, "lxstat version %d not supported\n", vers); +#endif + return -EINVAL; +} + +int +uw7_fxstat(int vers, int fd, void *bufp) +{ + struct kstat st; + int error; + + error = vfs_fstat(fd, &st); + if (error) + return error; + + switch (vers) { + case SVR4_stat: + return report_svr4_stat(&st, bufp); + case SVR4_xstat: + return report_svr4_xstat(&st, bufp); + case UW7_stat64: + return report_uw7_stat64(&st, bufp); + } + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_API, "fxstat version %d not supported\n", vers); +#endif + return -EINVAL; +} diff -Nru linux-2.6.7/abi/uw7/sysent.c linux-2.6.7-abi/abi/uw7/sysent.c --- linux-2.6.7/abi/uw7/sysent.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/uw7/sysent.c 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,478 @@ +/* + * Copyright (c) 1999 Tigran Aivazian. + * Copyright (c) 2000, 2001 Christoph Hellwig. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ident "%W% %G%" + +/* + * UnixWare 7/OpenUnix 8 personality switch. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include + +MODULE_DESCRIPTION("UnixWare7/OpenUnix8 personality"); +MODULE_AUTHOR("Tigran Aivazian, Christoph Hellwig"); +MODULE_LICENSE("GPL"); + + +/* + * We could remove some of the long identity mapped runs but at the + * expense of extra comparisons for each mapping at run time... + */ +static u_char uw7_err_table[] = { +/* 0 - 9 */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, +/* 10 - 19 */ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, +/* 20 - 29 */ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, +/* 30 - 39 */ 30, 31, 32, 33, 34, 45, 78, 46, 89, 93, +/* 40 - 49 */ 90, 90, 35, 36, 37, 38, 39, 40, 41, 42, +/* 50 - 59 */ 43, 44, 50, 51, 52, 53, 54, 55, 56, 57, +/* 60 - 69 */ 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, +/* 70 - 79 */ 70, 71, 74, 76, 77, 79, 80, 81, 82, 83, +/* 80 - 89 */ 84, 85, 86, 87, 88, 91, 92, 94, 95, 96, +/* 90 - 99 */ 97, 98, 99, 120, 121, 122, 123, 124, 125, 126, +/* 100 - 109 */ 127, 128, 129, 130, 131, 132, 133, 134, 143, 144, +/* 110 - 119 */ 145, 146, 147, 148, 149, 150, 22, 135, 137, 138, +/* 120 - 122 */ 139, 140, 28 +}; + +/* + * Map Linux RESTART* values (512,513,514) to EINTR + */ +static u_char lnx_err_table[] = { +/* 512 - 514 */ EINTR, EINTR, EINTR +}; + +struct map_segment uw7_err_map[] = { + { 0, 0+sizeof(uw7_err_table)-1, uw7_err_table }, + { 512, 512+sizeof(lnx_err_table)-1, lnx_err_table }, + { -1 } +}; + +static long linux_to_uw7_signals[NSIGNALS+1] = { +/* 0 - 3 */ 0, IBCS_SIGHUP, IBCS_SIGINT, IBCS_SIGQUIT, +/* 4 - 7 */ IBCS_SIGILL, IBCS_SIGTRAP, IBCS_SIGABRT, -1, +/* 8 - 11 */ IBCS_SIGFPE, IBCS_SIGKILL, IBCS_SIGUSR1, IBCS_SIGSEGV, +/* 12 - 15 */ IBCS_SIGUSR2, IBCS_SIGPIPE, IBCS_SIGALRM, IBCS_SIGTERM, +/* 16 - 19 */ IBCS_SIGSEGV, IBCS_SIGCHLD, IBCS_SIGCONT, IBCS_SIGSTOP, +/* 20 - 23 */ IBCS_SIGTSTP, IBCS_SIGTTIN, IBCS_SIGTTOU, IBCS_SIGURG, +/* 24 - 27 */ IBCS_SIGGXCPU, IBCS_SIGGXFSZ, IBCS_SIGVTALRM, IBCS_SIGPROF, +/* 28 - 31 */ IBCS_SIGWINCH, IBCS_SIGIO, IBCS_SIGPWR, -1, +/* 32 */ -1 +}; + +static long uw7_to_linux_signals[NSIGNALS+1] = { +/* 0 - 3 */ 0, SIGHUP, SIGINT, SIGQUIT, +/* 4 - 7 */ SIGILL, SIGTRAP, SIGIOT, SIGUNUSED, +/* 8 - 11 */ SIGFPE, SIGKILL, SIGUNUSED, SIGSEGV, +/* 12 - 15 */ SIGUNUSED, SIGPIPE, SIGALRM, SIGTERM, +/* 16 - 19 */ SIGUSR1, SIGUSR2, SIGCHLD, SIGPWR, +/* 20 - 23 */ SIGWINCH, SIGURG, SIGPOLL, SIGSTOP, +/* 24 - 27 */ SIGTSTP, SIGCONT, SIGTTIN, SIGTTOU, +/* 28 - 31 */ SIGVTALRM, SIGPROF, SIGXCPU, SIGXFSZ, +/* 32 */ -1 +}; + +static char uw7_socktype[] = { + SOCK_STREAM, + SOCK_DGRAM, + 0, + SOCK_RAW, + SOCK_RDM, + SOCK_SEQPACKET +}; + +static struct map_segment uw7_socktype_map[] = { + { 1, 6, uw7_socktype }, + { -1 } +}; + +static struct map_segment uw7_sockopt_map[] = { + { 0x0001, 0x0001, (char *)SO_DEBUG }, + { 0x0002, 0x0002, (char *)__SO_ACCEPTCON }, + { 0x0004, 0x0004, (char *)SO_REUSEADDR }, + { 0x0008, 0x0008, (char *)SO_KEEPALIVE }, + { 0x0010, 0x0010, (char *)SO_DONTROUTE }, + { 0x0020, 0x0020, (char *)SO_BROADCAST }, + { 0x0040, 0x0040, (char *)SO_USELOOPBACK }, + { 0x0080, 0x0080, (char *)SO_LINGER }, + { 0x0100, 0x0100, (char *)SO_OOBINLINE }, + { 0x0200, 0x0200, (char *)SO_ORDREL }, + { 0x0400, 0x0400, (char *)SO_IMASOCKET }, + { 0x1001, 0x1001, (char *)SO_SNDBUF }, + { 0x1002, 0x1002, (char *)SO_RCVBUF }, + { 0x1003, 0x1003, (char *)SO_SNDLOWAT }, + { 0x1004, 0x1004, (char *)SO_RCVLOWAT }, + { 0x1005, 0x1005, (char *)SO_SNDTIMEO }, + { 0x1006, 0x1006, (char *)SO_RCVTIMEO }, + { 0x1007, 0x1007, (char *)SO_ERROR }, + { 0x1008, 0x1008, (char *)SO_TYPE }, + { 0x1009, 0x1009, (char *)SO_PROTOTYPE }, + { -1 } +}; + +static struct map_segment uw7_af_map[] = { + { 0, 2, NULL }, + { -1 } +}; + + +static struct sysent uw7_syscall_table[] = { +/* 0 */ { abi_syscall, Fast, "syscall", "" }, +/* 2 */ { sys_exit, 1, "exit", "d" }, +/* 3 */ { abi_fork, Spl, "fork", "" }, +/* 4 */ { abi_read, 3, "read", "dpd" }, +/* 5 */ { sys_write, 3, "write", "dpd" }, +/* 6 */ { svr4_open, 3, "open", "soo" }, +/* 7 */ { sys_close, 1, "close", "d" }, +/* 8 */ { abi_wait, Spl, "wait", "xxx" }, +/* 9 */ { sys_creat, 2, "creat", "so" }, +/* 10 */ { sys_link, 2, "link", "ss" }, +/* 11 */ { sys_unlink, 1, "unlink", "s" }, +/* 12 */ { abi_exec, Spl, "exec", "sxx" }, +/* 13 */ { sys_chdir, 1, "chdir", "s" }, +/* 14 */ { abi_time, 0, "time", "" }, +/* 15 */ { svr4_mknod, 3, "mknod", "soo" }, +/* 16 */ { sys_chmod, 2, "chmod", "so" }, +/* 17 */ { sys_chown, 3, "chown", "sdd" }, +/* 18 */ { abi_brk, 1, "brk/break", "x" }, +/* 19 */ { svr4_stat, 2, "stat", "sp" }, +/* 21 */ { sys_lseek, 3, "seek/lseek", "ddd" }, +/* 20 */ { abi_getpid, Spl, "getpid", "" }, +/* 21 */ { 0, Ukn, "mount", "" }, +/* 22 */ { sys_umount, 1, "umount", "s" }, +/* 23 */ { sys_setuid, 1, "setuid", "d" }, +/* 24 */ { abi_getuid, Spl, "getuid", "" }, +/* 25 */ { sys_stime, 1, "stime", "d" }, +/* 26 */ { 0, 4, "ptrace", "" }, +/* 27 */ { sys_alarm, 1, "alarm", "d" }, +/* 28 */ { svr4_fstat, 2, "fstat", "dp" }, +/* 21 */ { sys_pause, 0, "pause", "" }, +/* 30 */ { sys_utime, 2, "utime", "xx" }, +/* 31 */ { uw7_stty, 2, "stty", "dd" }, +/* 32 */ { uw7_gtty, 2, "gtty", "dd" }, +/* 33 */ { uw7_access, 2, "access", "so" }, +/* 34 */ { sys_nice, 1, "nice", "d" }, +/* 35 */ { svr4_statfs, 4, "statfs", "spdd" }, +/* 36 */ { sys_sync, 0, "sync", "" }, +/* 37 */ { abi_kill, 2, "kill", "dd" }, +/* 38 */ { svr4_fstatfs, 4, "fstatfs", "dpdd" }, +/* 39 */ { abi_procids, Spl, "procids", "d" }, +/* 40 */ { 0, Ukn, "cxenix", "" }, +/* 41 */ { sys_dup, 1, "dup", "d" }, +/* 42 */ { abi_pipe, Spl, "pipe", "" }, +/* 43 */ { sys_times, 1, "times", "p" }, +/* 44 */ { 0, 4, "", "" }, +/* 45 */ { 0, Ukn, "plock", "" }, +/* 46 */ { sys_setgid, 1, "setgid", "d" }, +/* 47 */ { abi_getgid, Spl, "getgid", "" }, +/* 48 */ { abi_sigfunc, Fast, "sigfunc", "xxx" }, +/* 49 */ { svr4_msgsys, Spl, "msgsys", "dxddd" }, +/* 50 */ { svr4_sysi86, 3, "sysi86/sys3b", "d" }, +/* 51 */ { sys_acct, 1, "acct/sysacct", "x" }, +/* 52 */ { svr4_shmsys, Fast, "shmsys", "ddxo" }, +/* 53 */ { svr4_semsys, Spl, "semsys", "dddx" }, +/* 54 */ { uw7_ioctl, Spl, "ioctl", "dxx" }, +/* 55 */ { 0, 3, "uadmin", "xxx" }, +/* 56 */ { 0, Ukn, "unimpl/exch", "" }, +/* 57 */ { v7_utsname, 1, "utsys", "x" }, +/* 58 */ { sys_fsync, 1, "fsync", "d" }, +/* 59 */ { abi_exec, Spl, "execv", "spp" }, +/* 60 */ { sys_umask, 1, "umask", "o" }, +/* 61 */ { sys_chroot, 1, "chroot", "s" }, +/* 62 */ { svr4_fcntl, 3, "fcntl", "dxx" }, +/* 63 */ { svr4_ulimit, 2, "ulimit", "xx" }, + +/* + * 64-69 were reserved for the UNIX PC, and are now use for NUMA calls. + */ +/* 64 */ { 0, Ukn, "cg_ids", "" }, +/* 65 */ { 0, Ukn, "cg_processors","" }, +/* 66 */ { 0, Ukn, "cg_info", "" }, +/* 67 */ { 0, Ukn, "cg_bind", "" }, +/* 68 */ { 0, Ukn, "cg_current", "" }, +/* 69 */ { 0, Ukn, "cg_memloc", "" }, +/* 70 */ { 0, Ukn, "unimpl/advfs", "" }, +/* 71 */ { 0, Ukn, "unimpl/unadvfs","" }, +/* 72 */ { 0, Ukn, "unimpl/rmount","" }, +/* 73 */ { 0, Ukn, "unimpl/rumount","" }, +/* 74 */ { 0, Ukn, "unimpl/rfstart","" }, +/* 75 */ { 0, Ukn, "unimpl 75", "" }, +/* 76 */ { 0, Ukn, "unimpl/rdebug","" }, +/* 77 */ { 0, Ukn, "unimpl/rfstop","" }, +/* 78 */ { 0, Ukn, "rfsys", "" }, +/* 89 */ { sys_rmdir, 1, "rmdir", "s" }, +/* 80 */ { sys_mkdir, 2, "mkdir", "so" }, +/* 81 */ { svr4_getdents, 3, "getdents", "dxd" }, +/* 82 */ { 0, Ukn, "unimpl/libattach","" }, +/* 83 */ { 0, Ukn, "unimpl/libdetach","" }, +/* 84 */ { svr4_sysfs, 3, "sysfs", "dxx" }, +/* 85 */ { svr4_getmsg, Spl, "getmsg", "dxxx" }, +/* 86 */ { svr4_putmsg, Spl, "putmsg", "dxxd" }, +/* 87 */ { sys_poll, 3, "poll", "xdd" }, +/* 88 */ { svr4_lstat, 2, "lstat", "sp" }, +/* 89 */ { sys_symlink, 2, "symlink", "ss" }, +/* 90 */ { sys_readlink, 3, "readlink", "spd" }, +/* 91 */ { sys_setgroups, 2, "setgroups", "dp" }, +/* 92 */ { sys_getgroups, 2, "getgroups", "dp" }, +/* 93 */ { sys_fchmod, 2, "fchmod", "do" }, +/* 94 */ { sys_fchown, 3, "fchown", "ddd" }, +/* 95 */ { abi_sigprocmask, 3, "sigprocmask", "dxx" }, +/* 96 */ { abi_sigsuspend, Spl, "sigsuspend", "x" }, +/* 97 */ { uw7_sigaltstack, 2, "sigaltstack", "xx" }, +/* 98 */ { abi_sigaction, 3, "sigaction", "dxx" }, +/* 99 */ { svr4_sigpending, 2, "sigpending", "dp" }, +/* 100 */ { uw7_context, Spl, "ucontext", "" }, +/* 101 */ { 0, Ukn, "evsys", "" }, +/* 102 */ { 0, Ukn, "evtrapret", "" }, +/* 103 */ { svr4_statvfs, 2, "statvfs", "sp" }, +/* 104 */ { svr4_fstatvfs, 2, "fstatvfs", "dp" }, +/* 105 */ { 0, Ukn, "reserved 105", "" }, +/* 106 */ { 0, Ukn, "nfssys", "" }, +/* 107 */ { svr4_waitid, 4, "waitid", "ddxd" }, +/* 108 */ { 0, 3, "sigsendsys", "ddd" }, +/* 109 */ { svr4_hrtsys, Spl, "hrtsys", "xxx" }, +/* 110 */ { 0, 3, "acancel", "dxd" }, +/* 111 */ { 0, Ukn, "async", "" }, +/* 112 */ { 0, Ukn, "priocntlsys", "" }, +/* 113 */ { svr4_pathconf, 2, "pathconf", "sd" }, +/* 114 */ { 0, 3, "mincore", "xdx" }, +/* 115 */ { svr4_mmap, 6, "mmap", "xxxxdx"}, +/* 116 */ { sys_mprotect, 3, "mprotect", "xdx" }, +/* 117 */ { sys_munmap, 2, "munmap", "xd" }, +/* 118 */ { svr4_fpathconf, 2, "fpathconf", "dd" }, +/* 119 */ { abi_fork, Spl, "vfork", "" }, +/* 120 */ { sys_fchdir, 1, "fchdir", "d" }, +/* 121 */ { sys_readv, 3, "readv", "dxd" }, +/* 122 */ { sys_writev, 3, "writev", "dxd" }, +/* 123 */ { uw7_xstat, 3, "xstat", "dsx" }, +/* 124 */ { uw7_lxstat, 3, "lxstat", "dsx" }, +/* 125 */ { uw7_fxstat, 3, "fxstat", "ddx" }, +/* 126 */ { svr4_xmknod, 4, "xmknod", "dsox" }, +/* 127 */ { 0, Spl, "syslocal", "d" }, +/* 128 */ { svr4_getrlimit, 2, "setrlimit", "dx" }, +/* 129 */ { svr4_setrlimit, 2, "getrlimit", "dx" }, +/* 130 */ { sys_lchown, 3, "lchown", "sdd" }, +/* 131 */ { 0, Ukn, "memcntl", "" }, +#if defined(CONFIG_ABI_XTI) +/* 132 */ { svr4_getpmsg, 5, "getpmsg", "dxxxx" }, +/* 133 */ { svr4_putpmsg, 5, "putpmsg", "dxxdd" }, +#else +/* 132 */ { 0, 5, "getpmsg", "dxxxx" }, +/* 133 */ { 0, 5, "putpmsg", "dxxdd" }, +#endif +/* 134 */ { sys_rename, 2, "rename", "ss" }, +/* 135 */ { abi_utsname, 1, "uname", "x" }, +/* 136 */ { uw7_setegid, 1, "setegid", "d" }, +/* 137 */ { svr4_sysconfig, 1, "sysconfig", "d" }, +/* 138 */ { 0, Ukn, "adjtime", "" }, +/* 139 */ { svr4_sysinfo, 3, "systeminfo", "dsd" }, +/* 140 */ { socksys_syscall, 1, "socksys_syscall","x" }, +/* 141 */ { uw7_seteuid, 1, "seteuid", "d" }, +/* 142 */ { 0, Ukn, "unimpl 142", "" }, +/* 143 */ { 0, Ukn, "keyctl", "" }, +/* 144 */ { 0, 2, "secsys", "dx" }, +/* 145 */ { 0, 4, "filepriv", "sdxd" }, +/* 146 */ { 0, 3, "procpriv", "dxd" }, +/* 147 */ { 0, 3, "devstat", "sdx" }, +/* 148 */ { 0, 5, "aclipc", "ddddx" }, +/* 149 */ { 0, 3, "fdevstat", "ddx" }, +/* 150 */ { 0, 3, "flvlfile", "ddx" }, +/* 151 */ { 0, 3, "lvlfile", "sdx" }, +/* 152 */ { 0, Ukn, "sendv", "" }, +/* 153 */ { 0, 2, "lvlequal", "xx" }, +/* 154 */ { 0, 2, "lvlproc", "dx" }, +/* 155 */ { 0, Ukn, "unimpl 155", "" }, +/* 156 */ { 0, 4, "lvlipc", "dddx" }, +/* 157 */ { 0, 4, "acl", "sddx" }, +/* 158 */ { 0, Ukn, "auditevt", "" }, +/* 159 */ { 0, Ukn, "auditctl", "" }, +/* 160 */ { 0, Ukn, "auditdmp", "" }, +/* 161 */ { 0, Ukn, "auditlog", "" }, +/* 162 */ { 0, Ukn, "auditbuf", "" }, +/* 163 */ { 0, 2, "lvldom", "xx" }, +/* 164 */ { 0, Ukn, "lvlvfs", "" }, +/* 165 */ { 0, 2, "mkmld", "so" }, +/* 166 */ { uw7_mldmode, 1, "mldmode", "d" }, +/* 167 */ { 0, 2, "secadvise", "xx" }, +/* 168 */ { 0, Ukn, "online", "" }, +/* 169 */ { sys_setitimer, 3, "setitimer", "dxx" }, +/* 170 */ { sys_getitimer, 2, "getitimer", "dx" }, +/* 171 */ { sys_gettimeofday, 2, "gettimeofday", "xx" }, +/* 172 */ { sys_settimeofday, 2, "settimeofday", "xx" }, +/* 173 */ { 0, Ukn, "lwpcreate", "" }, +/* 174 */ { 0, Ukn, "lwpexit", "" }, +/* 175 */ { 0, Ukn, "lwpwait", "" }, +/* 176 */ { 0, Ukn, "lwpself", "" }, +/* 177 */ { 0, Ukn, "lwpinfo", "" }, +/* 178 */ { 0, Ukn, "lwpprivate", "" }, +/* 179 */ { 0, Ukn, "processorbind","" }, +/* 180 */ { 0, Ukn, "processorexbind","" }, +/* 181 */ { 0, Ukn, "unimpl 181", "" }, +/* 182 */ { 0, Ukn, "sendv64", "" }, +/* 183 */ { 0, Ukn, "prepblock", "" }, +/* 184 */ { 0, Ukn, "block", "" }, +/* 185 */ { 0, Ukn, "rdblock", "" }, +/* 186 */ { 0, Ukn, "unblock", "" }, +/* 187 */ { 0, Ukn, "cancelblock", "" }, +/* 188 */ { 0, Ukn, "unimpl 188", "" }, +/* 189 */ { uw7_pread, 4, "pread", "dsdd" }, +/* 190 */ { uw7_pwrite, 4, "pwrite", "dsdd" }, +/* 191 */ { sys_truncate, 2, "truncate", "sd" }, +/* 192 */ { sys_ftruncate, 2, "ftruncate", "dd" }, +/* 193 */ { 0, Ukn, "lwpkill", "" }, +/* 194 */ { 0, Ukn, "sigwait", "" }, +/* 195 */ { abi_fork, Spl, "fork1", "" }, +/* 196 */ { abi_fork, Spl, "forkall", "" }, + +/* + * 197-202 are for loadable kernel module support. + */ +/* 197 */ { 0, Ukn, "modload", "" }, +/* 198 */ { 0, Ukn, "moduload", "" }, +/* 199 */ { 0, Ukn, "modpath", "" }, +/* 200 */ { 0, Ukn, "modstat", "" }, +/* 201 */ { 0, Ukn, "modadm", "" }, +/* 202 */ { 0, Ukn, "getksym", "" }, + +/* 203 */ { 0, Ukn, "lwpsuspend", "" }, +/* 204 */ { 0, Ukn, "lwpcontinue", "" }, +/* 205 */ { 0, Ukn, "priocntllst", "" }, +/* 206 */ { uw7_sleep, 1, "sleep", "d" }, + +/* + * 207-209 are for post/wait synchronisation. + */ +/* 207 */ { 0, Ukn, "lwp_sema_wait","" }, +/* 208 */ { 0, Ukn, "lwp_sema_post","" }, +/* 209 */ { 0, Ukn, "lwp_sema_trywait","" }, + +/* 210 */ { 0, Ukn, "reserved 210", "" }, +/* 211 */ { 0, Ukn, "unused 211", "" }, +/* 212 */ { 0, Ukn, "unused 212", "" }, +/* 213 */ { 0, Ukn, "unused 213", "" }, +/* 214 */ { 0, Ukn, "unused 214", "" }, +/* 215 */ { 0, Ukn, "unused 215", "" }, + +/* + * 216-226 are for LFS (Large File Summit) support + */ +/* 216 */ { uw7_fstatvfs64, 2, "fstatvfs64", "dp" }, +/* 217 */ { uw7_statvfs64, 2, "statvfs64", "sp" }, +/* 218 */ { uw7_ftruncate64, 3, "ftruncate64", "sdd" }, +/* 219 */ { uw7_truncate64, 3, "truncate64", "ddd" }, +/* 220 */ { uw7_getrlimit64, 2, "getrlimit64", "dp" }, +/* 221 */ { uw7_setrlimit64, 2, "setrlimit64", "dp" }, +/* 222 */ { uw7_lseek64, 4, "lseek64", "dddd" }, +/* 223 */ { uw7_mmap64, 7, "mmap64", "xxxxdxx"}, +/* 224 */ { uw7_pread64, 5, "pread64", "dsddd" }, +/* 225 */ { uw7_pwrite64, 5, "pwrite64", "dsddd" }, +/* 226 */ { uw7_creat64, 2, "creat64", "so" }, + +/* 227 */ { 0, Ukn, "dshmsys", "" }, +/* 228 */ { 0, Ukn, "invlpg", "" }, + +/* + * 229-234 are used for SSI clustering (Nonstop cluster) + */ +/* 229 */ { 0, Ukn, "rfork1", "" }, +/* 230 */ { 0, Ukn, "rforkall", "" }, +/* 231 */ { 0, Ukn, "rexecve", "" }, +/* 232 */ { 0, Ukn, "migrate", "" }, +/* 233 */ { 0, Ukn, "kill3", "" }, +/* 234 */ { 0, Ukn, "ssisys", "" }, + +/* + * 235-248 are for kernel-based sockets (Yeah, SVR5 finally got sockets) + */ +/* 235 */ { 0, Ukn, "xaccept", "" }, +/* 236 */ { 0, Ukn, "xbind", "" }, +/* 237 */ { 0, Ukn, "xbindresvport","" }, +/* 238 */ { 0, Ukn, "xconnect", "" }, +/* 239 */ { 0, Ukn, "xgetsockaddr", "" }, +/* 240 */ { 0, Ukn, "xgetsockopt", "" }, +/* 241 */ { 0, Ukn, "xlisten", "" }, +/* 242 */ { 0, Ukn, "xrecvmsg", "" }, +/* 243 */ { 0, Ukn, "xsendmsg", "" }, +/* 244 */ { 0, Ukn, "xsetsockaddr", "" }, +/* 245 */ { 0, Ukn, "xsetsockopt", "" }, +/* 246 */ { 0, Ukn, "xshutdown", "" }, +/* 247 */ { 0, Ukn, "xsocket", "" }, +/* 248 */ { 0, Ukn, "xsocketpair", "" }, + +/* 249 */ { 0, Ukn, "unused 249", "" }, +/* 250 */ { 0, Ukn, "unused 250", "" }, +}; + + +static void +uw7_lcall7(int segment, struct pt_regs *regs) +{ + int sysno = regs->eax & 0xff; + + if (sysno >= ARRAY_SIZE(uw7_syscall_table)) + set_error(regs, iABI_errors(-EINVAL)); + else + lcall7_dispatch(regs, &uw7_syscall_table[sysno], 1); +} + +static struct exec_domain uw7_exec_domain = { + name: "UnixWare 7", + handler: uw7_lcall7, + pers_low: 14 /* PER_UW7 */, + pers_high: 14 /* PER_UW7 */, + signal_map: uw7_to_linux_signals, + signal_invmap: linux_to_uw7_signals, + err_map: uw7_err_map, + socktype_map: uw7_socktype_map, + sockopt_map: uw7_sockopt_map, + af_map: uw7_af_map, + module: THIS_MODULE +}; + +static int __init +init_uw7(void) +{ + return register_exec_domain(&uw7_exec_domain); +} + +static void __exit +cleanup_uw7(void) +{ + unregister_exec_domain(&uw7_exec_domain); +} + +module_init(init_uw7); +module_exit(cleanup_uw7); diff -Nru linux-2.6.7/abi/wyse/Makefile linux-2.6.7-abi/abi/wyse/Makefile --- linux-2.6.7/abi/wyse/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/wyse/Makefile 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,7 @@ + +abi-wyse-objs := sysent.o ptrace.o socket.o + +obj-$(CONFIG_ABI_WYSE) += abi-wyse.o + +abi-wyse.o: $(abi-wyse-objs) + $(LD) -r -o $@ $(abi-wyse-objs) diff -Nru linux-2.6.7/abi/wyse/ptrace.c linux-2.6.7-abi/abi/wyse/ptrace.c --- linux-2.6.7/abi/wyse/ptrace.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/wyse/ptrace.c 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,113 @@ +/* + * ptrace.c - Wyse V/386 ptrace(2) support. + * + * Copyright (c) 1995 Mike Jagdis (jaggy@purplet.demon.co.uk) + */ + +#ident "%W% %G%" + +/* + * This file is nearly identical to abi/sco/ptrace.c, please keep it in sync. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#define __KERNEL_SYSCALLS__ +#include + +#include + +#include +#include + + +#define NREGS 19 +#define U(X) ((unsigned long)&((struct user *)0)->X) + + +static unsigned long wysev386_to_linux_reg[NREGS] = { + U(regs.es), U(regs.ds), U(regs.edi), U(regs.esi), + U(regs.ebp), U(regs.esp), + U(regs.ebx), U(regs.edx), U(regs.ecx), U(regs.eax), + U(signal /* Trap */), + U(reserved /* ERR */), + U(regs.eip), U(regs.cs), + U(regs.eflags), + U(regs.esp /* UESP */), + U(regs.ss), + U(regs.fs), U(regs.gs) +}; + +static const char *regnam[] = { + "EBX", "ECX", "EDX", "ESI", "EDI", "EBP", "EAX", + "DS", "ES", "FS", "GS", "ORIG_EAX", "EIP", "CS", + "EFL", "UESP", "SS" +}; + + +int +wyse_ptrace(int req, int pid, u_long addr, u_long data) +{ + u_long res; + + /* + * Slight variations between iBCS and Linux codes. + */ + if (req == PTRACE_ATTACH) + req = 10; + else if (req == PTRACE_DETACH) + req = 11; + + if (req == 3 || req == 6) { + /* get offset of u_ar0 */ + if (addr == 0x1292) + return 0x4000; + + /* remap access to the registers. */ + if ((addr & 0xff00) == 0x4000) { /* Registers */ + addr = (addr & 0xff) >> 2; + if (addr > NREGS) + return -EIO; + addr = wysev386_to_linux_reg[addr]; + if (addr == -1) + return -EIO; + } + } + + if (req == 7 && data > 0) { + if (data > NSIGNALS) + return -EIO; + data = current_thread_info()->exec_domain->signal_map[data]; + } + + if (req == 1 || req == 2 || req == 3) { + mm_segment_t old_fs = get_fs(); + int error; + + set_fs(get_ds()); + error = sys_ptrace(req, pid, addr, (long)&res); + set_fs(old_fs); + + if (error) + return (error); + } + +#if defined(CONFIG_ABI_TRACE) + if (req == 3 || req == 6) { + abi_trace(ABI_TRACE_API, "%ld [%s] = 0x%08lx\n", + addr >> 2, (addr >> 2) < ARRAY_SIZE(regnam) ? + regnam[addr >> 2] : "???", + req == 3 ? res : data); + } +#endif + + if (req == 1 || req == 2 || req == 3) + return (res); + + return sys_ptrace(req, pid, addr, data); +} diff -Nru linux-2.6.7/abi/wyse/socket.c linux-2.6.7-abi/abi/wyse/socket.c --- linux-2.6.7/abi/wyse/socket.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/wyse/socket.c 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,307 @@ +/* + * Copyright (c) 1994,1996 Mike Jagdis. + * Copyright (c) 2001 Christoph Hellwig. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ident "%W% %G%" + +/* + * BSD-style socket support for Wyse/V386. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + + +int wyse_gethostname(char *name, int len) +{ + int error; + char *p; + + down_read(&uts_sem); + error = verify_area(VERIFY_WRITE, name, len); + if (!error) { + --len; + for (p = system_utsname.nodename; *p && len; p++,len--) { + __put_user(*p, name); + name++; + } + __put_user('\0', name); + } + up_read(&uts_sem); + return error; +} + +int wyse_getdomainname(char *name, int len) +{ + int error; + char *p; + + down_read(&uts_sem); + error = verify_area(VERIFY_WRITE, name, len); + if (!error) { + --len; + for (p = system_utsname.domainname; *p && len; p++,len--) { + __put_user(*p, name); + name++; + } + __put_user('\0', name); + } + up_read(&uts_sem); + return error; +} + +int wyse_wait3(int *loc) +{ + pid_t pid; + int res; + + pid = sys_wait4(-1, loc, WNOHANG, 0); + if (!loc) + return pid; + + get_user(res, (unsigned long *)loc); + + if ((res & 0xff) == 0x7f) { + int sig = (res >> 8) & 0xff; + + sig = current_thread_info()->exec_domain->signal_map[sig]; + res = (res & (~0xff00)) | (sig << 8); + put_user(res, (unsigned long *)loc); + } else if (res && res == (res & 0xff)) { + res = current_thread_info()->exec_domain->signal_map[res & 0x7f]; + put_user(res, (unsigned long *)loc); + } + + return pid; +} + +int wyse_socket(int family, int type, int protocol) +{ + family = map_value(current_thread_info()->exec_domain->af_map, family, 0); + type = map_value(current_thread_info()->exec_domain->socktype_map, family, 0); + + return sys_socket(family, type, protocol); +} + +int wyse_setsockopt(int fd, int level, int optname, char *optval, int optlen) +{ + switch (level) { + case 0: /* IPPROTO_IP aka SOL_IP */ + if (--optname == 0) + optname = 4; + if (optname > 4) { + optname += 24; + if (optname <= 33) + optname--; + if (optname < 32 || optname > 36) + return -EINVAL; + break; + } + case 0xffff: + level = SOL_SOCKET; + optname = map_value(current_thread_info()->exec_domain->sockopt_map, optname, 0); + switch (optname) { + case SO_LINGER: + /* + * SO_LINGER takes a struct linger as the argument + * but some code uses an int and expects to get + * away without an error. Sigh... + */ + 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: + break; + } + default: + /* + * XXX We assume everything else uses the same level and + * XXX option numbers. This is true for IPPROTO_TCP(/SOL_TCP) + * XXX and TCP_NDELAY but is known to be incorrect for other + * XXX potential options :-(. + */ + break; + } + + return sys_setsockopt(fd, level, optname, optval, optlen); +} + +int wyse_getsockopt(int fd, int level, int optname, char *optval, int *optlen) +{ + unsigned int len; + int val; + + if (get_user(len,optlen)) + return -EFAULT; + if (len < 0) + return -EINVAL; + + switch (level) { + case 0: /* IPPROTO_IP aka SOL_IP */ + if (--optname == 0) + optname = 4; + if (optname > 4) { + optname += 24; + if (optname <= 33) + optname--; + if (optname < 32 || optname > 36) + return -EINVAL; + break; + } + case 0xffff: + level = SOL_SOCKET; + optname = map_value(current_thread_info()->exec_domain->sockopt_map, optname, 0); + switch (optname) { + case SO_LINGER: + /* + * SO_LINGER takes a struct linger as the argument + * but some code uses an int and expects to get + * away without an error. Sigh... + */ + if (len != sizeof(int)) + goto native; + + val = 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: + val = 0; + break; + + 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: + val = 1; + break; + default: + goto native; + } + + if (len > sizeof(int)) + len = sizeof(int); + if (copy_to_user(optval, &val, len)) + return -EFAULT; + if (put_user(len, optlen)) + return -EFAULT; + return 0; + + default: + /* + * XXX We assume everything else uses the same level and + * XXX option numbers. This is true for IPPROTO_TCP(/SOL_TCP) + * XXX and TCP_NDELAY but is known to be incorrect for other + * XXX potential options :-(. + */ + break; + } + +native: + return sys_getsockopt(fd, level, optname, optval, optlen); +} + +int wyse_recvfrom(int fd, void *buff, size_t size, unsigned flags, + struct sockaddr *addr, int *addr_len) +{ + int error; + + error = sys_recvfrom(fd, buff, size, flags, addr, addr_len); + if (error == -EAGAIN) + error = -EWOULDBLOCK; + return error; +} + +int wyse_recv(int fd, void *buff, size_t size, unsigned flags) +{ + int error; + + error = sys_recvfrom(fd, buff, size, flags, NULL, NULL); + if (error == -EAGAIN) + error = -EWOULDBLOCK; + return error; +} + +int wyse_sendto(int fd, void *buff, size_t len, unsigned flags, + struct sockaddr *addr, int addr_len) +{ + int error; + + error = sys_sendto(fd, buff, len, flags, addr, addr_len); + if (error == -EAGAIN) + error = -EWOULDBLOCK; + return error; +} + +int wyse_send(int fd, void *buff, size_t len, unsigned flags) +{ + int error; + + error = sys_sendto(fd, buff, len, flags, NULL, 0); + if (error == -EAGAIN) + error = -EWOULDBLOCK; + return error; +} diff -Nru linux-2.6.7/abi/wyse/sysent.c linux-2.6.7-abi/abi/wyse/sysent.c --- linux-2.6.7/abi/wyse/sysent.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/wyse/sysent.c 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,394 @@ +/* + * Copyright (c) 2001 Christoph Hellwig. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ident "%W% %G%" + +/* + * Wyse/V386 personality switch. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include + + +MODULE_DESCRIPTION("Wyse/V386 personality"); +MODULE_AUTHOR("Christoph Hellwig, partially taken from iBCS"); +MODULE_LICENSE("GPL"); + + +/* + * local functions + */ +static void wyse_class_nfs(struct pt_regs *); +static void wyse_class_tcp(struct pt_regs *); + + +/* + * local variables + */ +static u_char wyse_err_table[] = { + /* 0 - 9 */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + /* 10 - 19 */ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + /* 20 - 29 */ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + /* 30 - 39 */ 30, 31, 32, 33, 34, 45, 78, 46, 228, 46, + /* 40 - 49 */ 22, 231, 227, 200, 37, 38, 39, 40, 41, 42, + /* 50 - 59 */ 43, 44, 50, 51, 52, 53, 54, 55, 56, 57, + /* 60 - 69 */ 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + /* 70 - 79 */ 70, 71, 74, 76, 77, 22, 80, 81, 82, 83, + /* 80 - 89 */ 84, 85, 86, 87, 22, 4, 22, 233, 203, 204, + /* 90 - 99 */ 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, + /* 100 - 109 */ 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + /* 110 - 119 */ 225, 226, 229, 230, 202, 201, 237, 135, 137, 138, + /* 120 - 122 */ 139, 140, 234 +}; + +/* + * Map Linux RESTART* values (512,513,514) to EINTR + */ +static u_char lnx_err_table[] = { + /* 512 - 514 */ EINTR, EINTR, EINTR +}; + +static struct map_segment wyse_err_map[] = { + { 0, 0 + sizeof(wyse_err_table) - 1, wyse_err_table }, + { 512, 512 + sizeof(lnx_err_table) - 1, lnx_err_table }, + { -1 } +}; + +static long linux_to_wyse_signals[NSIGNALS+1] = { +/* 0 - 3 */ 0, IBCS_SIGHUP, IBCS_SIGINT, IBCS_SIGQUIT, +/* 4 - 7 */ IBCS_SIGILL, IBCS_SIGTRAP, IBCS_SIGABRT, -1, +/* 8 - 11 */ IBCS_SIGFPE, IBCS_SIGKILL, IBCS_SIGUSR1, IBCS_SIGSEGV, +/* 12 - 15 */ IBCS_SIGUSR2, IBCS_SIGPIPE, IBCS_SIGALRM, IBCS_SIGTERM, +/* 16 - 19 */ IBCS_SIGSEGV, IBCS_SIGCHLD, IBCS_SIGCONT, IBCS_SIGSTOP, +/* 20 - 23 */ IBCS_SIGTSTP, IBCS_SIGTTIN, IBCS_SIGTTOU, IBCS_SIGURG, +/* 24 - 27 */ IBCS_SIGGXCPU, IBCS_SIGGXFSZ, IBCS_SIGVTALRM, IBCS_SIGPROF, +/* 28 - 31 */ IBCS_SIGWINCH, IBCS_SIGIO, IBCS_SIGPWR, -1, +/* 32 */ -1 +}; + +static long wyse_to_linux_signals[NSIGNALS+1] = { +/* 0 - 3 */ 0, SIGHUP, SIGINT, SIGQUIT, +/* 4 - 7 */ SIGILL, SIGTRAP, SIGIOT, SIGUNUSED, +/* 8 - 11 */ SIGFPE, SIGKILL, SIGUNUSED, SIGSEGV, +/* 12 - 15 */ SIGUNUSED, SIGPIPE, SIGALRM, SIGTERM, +/* 16 - 19 */ SIGUSR1, SIGUSR2, SIGCHLD, SIGPWR, +/* 20 - 23 */ SIGWINCH, SIGURG, SIGPOLL, SIGSTOP, +/* 24 - 27 */ SIGTSTP, SIGCONT, SIGTTIN, SIGTTOU, +/* 28 - 31 */ SIGVTALRM, SIGPROF, SIGXCPU, SIGXFSZ, +/* 32 */ -1 +}; + +static char wyse_socktype[] = { + SOCK_STREAM, + SOCK_DGRAM, + 0, + SOCK_RAW, + SOCK_RDM, + SOCK_SEQPACKET +}; + +static struct map_segment wyse_socktype_map[] = { + { 1, 6, wyse_socktype }, + { -1 } +}; + +static struct map_segment wyse_sockopt_map[] = { + { 0x0001, 0x0001, (char *)SO_DEBUG }, + { 0x0002, 0x0002, (char *)__SO_ACCEPTCON }, + { 0x0004, 0x0004, (char *)SO_REUSEADDR }, + { 0x0008, 0x0008, (char *)SO_KEEPALIVE }, + { 0x0010, 0x0010, (char *)SO_DONTROUTE }, + { 0x0020, 0x0020, (char *)SO_BROADCAST }, + { 0x0040, 0x0040, (char *)SO_USELOOPBACK }, + { 0x0080, 0x0080, (char *)SO_LINGER }, + { 0x0100, 0x0100, (char *)SO_OOBINLINE }, + { 0x0200, 0x0200, (char *)SO_ORDREL }, + { 0x0400, 0x0400, (char *)SO_IMASOCKET }, + { 0x1001, 0x1001, (char *)SO_SNDBUF }, + { 0x1002, 0x1002, (char *)SO_RCVBUF }, + { 0x1003, 0x1003, (char *)SO_SNDLOWAT }, + { 0x1004, 0x1004, (char *)SO_RCVLOWAT }, + { 0x1005, 0x1005, (char *)SO_SNDTIMEO }, + { 0x1006, 0x1006, (char *)SO_RCVTIMEO }, + { 0x1007, 0x1007, (char *)SO_ERROR }, + { 0x1008, 0x1008, (char *)SO_TYPE }, + { 0x1009, 0x1009, (char *)SO_PROTOTYPE }, + { -1 } +}; + +static struct map_segment wyse_af_map[] = { + { 0, 2, NULL }, + { -1 } +}; + + +static struct sysent wyse_nfscall_table[] = { +/* 0 */ { 0, Ukn, "nfs_svc", "" }, +/* 1 */ { 0, Ukn, "async_daemon", "" }, +/* 2 */ { 0, Ukn, "nfs_getfh", "" }, +/* 3 */ { 0, Ukn, "nfsmount", "" }, +}; + +static struct sysent wyse_tcpcall_table[] = { +/* 0 */ { sys_select, 5, "select", "dxxxx" }, +/* 1 */ { wyse_socket, 3, "socket", "ddd" }, +/* 2 */ { sys_connect, 3, "connect", "dxd" }, +/* 3 */ { sys_accept, 3, "accept", "dxx" }, +/* 4 */ { wyse_send, 4, "send", "dxdd" }, +/* 5 */ { wyse_recv, 4, "recv", "dxdd" }, +/* 6 */ { sys_bind, 3, "bind", "dxd" }, +/* 7 */ { wyse_setsockopt, 5, "setsockopt", "dddxx" }, +/* 8 */ { sys_listen, 2, "listen", "dd" }, +/* 9 */ { 0, 3, "recvmsg", "dxd" }, +/* 10 */ { 0, 3, "sendmsg", "dxd" }, +/* 11 */ { wyse_getsockopt, 5, "getsockopt", "dddxx" }, +/* 12 */ { wyse_recvfrom, 6, "recvfrom", "dxddxd"}, +/* 13 */ { wyse_sendto, 6, "sendto", "dxddxd"}, +/* 14 */ { sys_shutdown, 2, "shutdown", "dd" }, +/* 15 */ { sys_socketpair, 4, "socketpair", "dddx" }, +/* 16 */ { 0, Ukn, "trace", "" }, +/* 17 */ { sys_getpeername, 3, "getpeername", "dxx" }, +/* 18 */ { sys_getsockname, Spl, "getsockname", "dxx" }, +/* 19 */ { wyse_wait3, 1, "wait3", "x" }, +}; + + +static struct sysent wyse_syscall_table[] = { +/* 0 */ { abi_syscall, Fast, "syscall", "" }, +/* 1 */ { sys_exit, 1, "exit", "d" }, +/* 2 */ { abi_fork, Spl, "fork", "" }, +/* 3 */ { abi_read, 3, "read", "dpd" }, +/* 4 */ { sys_write, 3, "write", "dpd" }, +/* 5 */ { svr4_open, 3, "open", "soo" }, +/* 6 */ { sys_close, 1, "close", "d" }, +/* 7 */ { abi_wait, Spl, "wait", "xxx" }, +/* 8 */ { sys_creat, 2, "creat", "so" }, +/* 9 */ { sys_link, 2, "link", "ss" }, +/* 10 */ { sys_unlink, 1, "unlink", "s" }, +/* 11 */ { abi_exec, Spl, "exec", "sxx" }, +/* 12 */ { sys_chdir, 1, "chdir", "s" }, +/* 13 */ { abi_time, 0, "time", "" }, +/* 14 */ { svr4_mknod, 3, "mknod", "soo" }, +/* 15 */ { sys_chmod, 2, "chmod", "so" }, +/* 16 */ { sys_chown, 3, "chown", "sdd" }, +/* 17 */ { abi_brk, 1, "brk/break", "x" }, +/* 18 */ { svr4_stat, 2, "stat", "sp" }, +/* 19 */ { sys_lseek, 3, "seek/lseek", "ddd" }, +/* 20 */ { abi_getpid, Spl, "getpid", "" }, +/* 21 */ { 0, Ukn, "mount", "" }, +/* 22 */ { sys_umount, 1, "umount", "s" }, +/* 23 */ { sys_setuid, 1, "setuid", "d" }, +/* 24 */ { abi_getuid, Spl, "getuid", "" }, +/* 25 */ { sys_stime, 1, "stime", "d" }, +/* 26 */ { wyse_ptrace, 4, "ptrace", "xdxx" }, +/* 27 */ { sys_alarm, 1, "alarm", "d" }, +/* 28 */ { svr4_fstat, 2, "fstat", "dp" }, +/* 29 */ { sys_pause, 0, "pause", "" }, +/* 30 */ { sys_utime, 2, "utime", "xx" }, +/* 31 */ { 0, Ukn, "stty", "" }, /* 31 */ +/* 32 */ { 0, Ukn, "gtty", "" }, +/* 33 */ { sys_access, 2, "access", "so" }, +/* 34 */ { sys_nice, 1, "nice", "d" }, +/* 35 */ { svr4_statfs, 4, "statfs", "spdd" }, +/* 36 */ { sys_sync, 0, "sync", "" }, +/* 37 */ { abi_kill, 2, "kill", "dd" }, +/* 38 */ { svr4_fstatfs, 4, "fstatfs", "dpdd" }, +/* 39 */ { abi_procids, Spl, "procids", "d" }, +/* 40 */ { 0, Ukn, "cxenix", "" }, +/* 41 */ { sys_dup, 1, "dup", "d" }, +/* 42 */ { abi_pipe, Spl, "pipe", "" }, +/* 43 */ { sys_times, 1, "times", "p" }, +/* 44 */ { 0, 4, "prof", "xxxx" }, +/* 45 */ { 0, Ukn, "lock/plock", "" }, +/* 46 */ { sys_setgid, 1, "setgid", "d" }, +/* 47 */ { abi_getgid, Spl, "getgid", "" }, +/* 48 */ { abi_sigfunc, Fast, "sigfunc", "xxx" }, +/* 49 */ { svr4_msgsys, Spl, "msgsys", "dxddd" }, +/* 50 */ { svr4_sysi86, 3, "sysi86/sys3b", "d" }, +/* 51 */ { sys_acct, 1, "acct/sysacct", "x" }, +/* 52 */ { svr4_shmsys, Fast, "shmsys", "ddxo" }, +/* 53 */ { svr4_semsys, Spl, "semsys", "dddx" }, +/* 54 */ { svr4_ioctl, Spl, "ioctl", "dxx" }, +/* 55 */ { 0, 3, "uadmin", "xxx" }, +/* 56 */ { 0, Ukn, "?", "" }, +/* 57 */ { v7_utsname, 1, "utsys", "x" }, +/* 58 */ { sys_fsync, 1, "fsync", "d" }, +/* 59 */ { abi_exec, Spl, "execv", "spp" }, +/* 60 */ { sys_umask, 1, "umask", "o" }, +/* 61 */ { sys_chroot, 1, "chroot", "s" }, +/* 62 */ { svr4_fcntl, 3, "fcntl", "dxx" }, +/* 63 */ { svr4_ulimit, 2, "ulimit", "xx" }, +/* 64 */ { 0, Ukn, "?", "" }, +/* 65 */ { 0, Ukn, "?", "" }, +/* 66 */ { 0, Ukn, "?", "" }, +/* 67 */ { 0, Ukn, "?", "" }, +/* 68 */ { 0, Ukn, "?", "" }, +/* 69 */ { 0, Ukn, "?", "" }, +/* 70 */ { 0, Ukn, "advfs", "" }, +/* 71 */ { 0, Ukn, "unadvfs", "" }, +/* 72 */ { 0, Ukn, "rmount", "" }, +/* 73 */ { 0, Ukn, "rumount", "" }, +/* 74 */ { 0, Ukn, "rfstart", "" }, +/* 75 */ { 0, Ukn, "?", "" }, +/* 76 */ { 0, Ukn, "rdebug", "" }, +/* 77 */ { 0, Ukn, "rfstop", "" }, +/* 78 */ { 0, Ukn, "rfsys", "" }, +/* 79 */ { sys_rmdir, 1, "rmdir", "s" }, +/* 80 */ { abi_mkdir, 2, "mkdir", "so" }, +/* 81 */ { svr4_getdents, 3, "getdents", "dxd" }, +/* 82 */ { 0, Ukn, "libattach", "" }, +/* 83 */ { 0, Ukn, "libdetach", "" }, +/* 84 */ { svr4_sysfs, 3, "sysfs", "dxx" }, +/* 85 */ { svr4_getmsg, Spl, "getmsg", "dxxx" }, +/* 86 */ { svr4_putmsg, Spl, "putmsg", "dxxd" }, +/* 87 */ { sys_poll, 3, "poll", "xdd" }, +/* 88 */ { 0, Ukn, "nosys88", "" }, +/* 89 */ { 0, Ukn, "nosys89", "" }, +/* 90 */ { 0, Ukn, "nosys90", "" }, +/* 91 */ { 0, Ukn, "nosys91", "" }, +/* 92 */ { 0, Ukn, "nosys92", "" }, +/* 93 */ { 0, Ukn, "nosys93", "" }, +/* 94 */ { 0, Ukn, "nosys94", "" }, +/* 95 */ { 0, Ukn, "nosys95", "" }, +/* 96 */ { 0, Ukn, "nosys96", "" }, +/* 97 */ { 0, Ukn, "nosys97", "" }, +/* 98 */ { 0, Ukn, "nosys98", "" }, +/* 99 */ { 0, Ukn, "nosys99", "" }, +/* 100 */ { 0, Ukn, "nosys100", "" }, +/* 101 */ { 0, Ukn, "nosys101", "" }, +/* 102 */ { 0, Ukn, "nosys102", "" }, +/* 103 */ { 0, Ukn, "nosys103", "" }, +/* 104 */ { 0, Ukn, "nosys104", "" }, +/* 105 */ { 0, Ukn, "nosys105", "" }, +/* 106 */ { 0, Ukn, "nosys106", "" }, +/* 107 */ { 0, Ukn, "nosys107", "" }, +/* 108 */ { 0, Ukn, "nosys108", "" }, +/* 109 */ { 0, Ukn, "nosys109", "" }, +/* 110 */ { 0, Ukn, "nosys110", "" }, +/* 111 */ { 0, Ukn, "nosys111", "" }, +/* 112 */ { 0, Ukn, "nosys112", "" }, +/* 113 */ { 0, Ukn, "nosys113", "" }, +/* 114 */ { 0, Ukn, "nosys114", "" }, +/* 115 */ { 0, Ukn, "nosys115", "" }, +/* 116 */ { 0, Ukn, "nosys116", "" }, +/* 117 */ { 0, Ukn, "nosys117", "" }, +/* 118 */ { 0, Ukn, "nosys118", "" }, +/* 119 */ { 0, Ukn, "nosys119", "" }, +/* 120 */ { 0, Ukn, "nosys120", "" }, +/* 121 */ { 0, Ukn, "nosys121", "" }, +/* 122 */ { 0, Ukn, "nosys122", "" }, +/* 123 */ { 0, Ukn, "nosys123", "" }, +/* 124 */ { 0, Ukn, "nosys124", "" }, +/* 125 */ { 0, Ukn, "nosys125", "" }, +/* 126 */ { 0, Ukn, "nosys126", "" }, +/* 127 */ { 0, Ukn, "nosys127", "" }, +/* 128 */ { svr4_lstat, 2, "lstat", "sp" }, +/* 129 */ { sys_readlink, 3, "readlink", "spd" }, +/* 130 */ { sys_symlink, 2, "symlink", "ss" }, +/* 131 */ { wyse_class_tcp, Fast, "", "" }, +/* 132 */ { wyse_class_nfs, Fast, "", "" }, +/* 133 */ { wyse_gethostname, 2, "gethostname", "xd" }, +/* 134 */ { sys_sethostname, 2, "sethostname", "sd" }, +/* 135 */ { wyse_getdomainname, 2, "getdomainname","xd" }, +/* 136 */ { sys_setdomainname, 2, "setdomainname","sd" }, +/* 137 */ { 0, Ukn, "?", "" }, +/* 138 */ { sys_setreuid, 2, "setreuid", "dd" }, +/* 139 */ { sys_setregid, 2, "setregid", "dd" }, +}; + +static void +wyse_class_nfs(struct pt_regs *regs) +{ + + int sysno = regs->eax >> 8; + + if (sysno >= ARRAY_SIZE(wyse_nfscall_table)) + set_error(regs, iABI_errors(-EINVAL)); + else + lcall7_dispatch(regs, &wyse_nfscall_table[sysno], 1); +} + +static void +wyse_class_tcp(struct pt_regs *regs) +{ + int sysno = regs->eax >> 8; + + if (sysno >= ARRAY_SIZE(wyse_tcpcall_table)) + set_error(regs, iABI_errors(-EINVAL)); + else + lcall7_dispatch(regs, &wyse_tcpcall_table[sysno], 1); +} + +static void +wyse_lcall7(int segment, struct pt_regs *regs) +{ + int sysno = regs->eax & 0xff; + + if (sysno >= ARRAY_SIZE(wyse_syscall_table)) + set_error(regs, iABI_errors(-EINVAL)); + else + lcall7_dispatch(regs, &wyse_syscall_table[sysno], 1); +} + +static struct exec_domain wyse_exec_domain = { + name: "Wyse/386", + handler: wyse_lcall7, + pers_low: 4 /* PER_WYSEV386 */, + pers_high: 4 /* PER_WYSEV386 */, + signal_map: wyse_to_linux_signals, + signal_invmap: linux_to_wyse_signals, + err_map: wyse_err_map, + socktype_map: wyse_socktype_map, + sockopt_map: wyse_sockopt_map, + af_map: wyse_af_map, + module: THIS_MODULE +}; + + +static int __init +wyse_module_init(void) +{ + return register_exec_domain(&wyse_exec_domain); +} + +static void __exit +wyse_module_exit(void) +{ + unregister_exec_domain(&wyse_exec_domain); +} + +module_init(wyse_module_init); +module_exit(wyse_module_exit); diff -Nru linux-2.6.7/abi/wyse/syslocal.c linux-2.6.7-abi/abi/wyse/syslocal.c --- linux-2.6.7/abi/wyse/syslocal.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/abi/wyse/syslocal.c 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,55 @@ +/* + * Copyright (C) 1994 Mike Jagdis (jaggy@purplet.demon.co.uk) + */ + +#ident "%W% %G%" + +#include +#include +#include + +#include + + +/* + * The syslocal() call is used for machine specific functions. For + * instance on a Wyse 9000 it give information and control of the + * available processors. + */ +#define SL_ONLINE 0 /* Turn processor online */ +#define SL_OFFLINE 1 /* Turn processor offline */ +#define SL_QUERY 2 /* Query processor status */ +#define SL_NENG 3 /* Return No. of processors configured */ +#define SL_AFFINITY 4 /* processor binding */ +#define SL_CMC_STAT 7 /* gather CMC performance counters info */ +#define SL_KACC 8 /* make kernel data readable by user */ +#define SL_MACHTYPE 9 /* return machine type (MP/AT) */ +#define SL_BOOTNAME 10 /* return name of booted kernel */ +#define SL_BOOTDEV 11 /* return type of booted device */ +#define SL_UQUERY 12 /* query user status */ + +#define SL_MACH_MP 0 +#define SL_MACH_AT 1 +#define SL_MACH_EISA 2 +#define SL_MACH_EMP 3 + + +int +wyse_syslocal(struct pt_regs *regp) +{ + int cmd = get_syscall_parameter(regp, 0); + + switch (cmd) { + case SL_QUERY: + return 0; + case SL_NENG: + return 1; + case SL_MACHTYPE: + return (EISA_bus ? SL_MACH_EISA : SL_MACH_AT); + } + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_UNIMPL, "unsupported syslocal call %d\n", cmd); +#endif + return -EINVAL; +} diff -Nru linux-2.6.7/arch/i386/kernel/i386_ksyms.c linux-2.6.7-abi/arch/i386/kernel/i386_ksyms.c --- linux-2.6.7/arch/i386/kernel/i386_ksyms.c 2004-06-16 07:20:26.000000000 +0200 +++ linux-2.6.7-abi/arch/i386/kernel/i386_ksyms.c 2004-07-22 17:44:21.000000000 +0200 @@ -16,6 +16,9 @@ #include #include #include +#define __KERNEL_SYSCALLS__ +#include +#include #include #include @@ -206,3 +209,8 @@ #endif EXPORT_SYMBOL(csum_partial); + +EXPORT_SYMBOL(sys_modify_ldt); +EXPORT_SYMBOL(sys_ptrace); +EXPORT_SYMBOL(sys_ipc); +EXPORT_SYMBOL(sys_pause); diff -Nru linux-2.6.7/arch/i386/kernel/lcall7.c linux-2.6.7-abi/arch/i386/kernel/lcall7.c --- linux-2.6.7/arch/i386/kernel/lcall7.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/arch/i386/kernel/lcall7.c 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2000,2001 Christoph Hellwig. + * Copyright (c) 2001 Caldera Deutschland GmbH. + * All rights resered. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ident "%W% %G%" + +/* + * Lowlevel handler for lcall7-based syscalls. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +MODULE_AUTHOR("Christoph Hellwig"); +MODULE_DESCRIPTION("Lowlevel handler for lcall7-based syscalls"); +MODULE_LICENSE("GPL"); + + +static void get_args(int args[], struct pt_regs *regs, int of, int n) +{ + int i; + + for (i = 0; i < n; i++) + get_user(args[i], ((unsigned long *)regs->esp) + (i+of)); +} + +/* + * lcall7_syscall - indirect syscall for the lcall7 entry point + * + * @regs: saved user registers + * + * This function implements syscall(2) in kernelspace for the lcall7- + * based personalities. + */ + +int lcall7_syscall(struct pt_regs *regs) +{ + __get_user(regs->eax, ((unsigned long *)regs->esp)+1); + + ++regs->esp; + current_thread_info()->exec_domain->handler(-1,regs); + --regs->esp; + + return 0; +} + +/** + * lcall7_dispatch - handle lcall7-based syscall entry + * + * @regs: saved user registers + * @ap: syscall table entry + * @off: argument offset + * + * This function handles lcall7-based syscalls after the personality- + * specific rountine selected the right syscall table entry. + */ + +void lcall7_dispatch(struct pt_regs *regs, struct sysent *ap, int off) +{ + short nargs = ap->se_nargs; + int args[8], error; + + if (!ap->se_syscall) /* XXX kludge XXX */ + nargs = Unimpl; + + if (nargs <= ARRAY_SIZE(args)) + get_args(args, regs, off, nargs); + +#if defined(CONFIG_ABI_TRACE) + if (abi_traced(ABI_TRACE_API)) { + if (nargs == Spl) + get_args(args, regs, off, strlen(ap->se_args)); + plist(ap->se_name, ap->se_args, args); + } +#endif + + switch (nargs) { + case Fast: + SYSCALL_PREGS(ap->se_syscall, regs); + goto show_signals; + case Spl: + error = SYSCALL_PREGS(ap->se_syscall, regs); + break; + case 0: + error = SYSCALL_VOID(ap->se_syscall); + break; + case 1: + error = SYSCALL_1ARG(ap->se_syscall, args); + break; + case 2: + error = SYSCALL_2ARG(ap->se_syscall, args); + break; + case 3: + error = SYSCALL_3ARG(ap->se_syscall, args); + break; + case 4: + error = SYSCALL_4ARG(ap->se_syscall, args); + break; + case 5: + error = SYSCALL_5ARG(ap->se_syscall, args); + break; + case 6: + error = SYSCALL_6ARG(ap->se_syscall, args); + break; + case 7: + error = SYSCALL_7ARG(ap->se_syscall, args); + break; + default: +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_UNIMPL, + "Unsupported ABI function 0x%lx (%s)\n", + regs->eax, ap->se_name); +#endif + error = -ENOSYS; + } + + if (error > -ENOIOCTLCMD && error < 0) { + set_error(regs, iABI_errors(-error)); + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_API, + "%s error return %d/%ld\n", + ap->se_name, error, regs->eax); +#endif + } else { + clear_error(regs); + set_result(regs, error); + +#if defined(CONFIG_ABI_TRACE) + abi_trace(ABI_TRACE_API, + "%s returns %ld (edx:%ld)\n", + ap->se_name, regs->eax, regs->edx); +#endif + } + +show_signals: +#if defined(CONFIG_ABI_TRACE) + if (signal_pending(current) && abi_traced(ABI_TRACE_SIGNAL)) { + unsigned long signr; + + signr = current->pending.signal.sig[0] & + ~current->blocked.sig[0]; + + __asm__("bsf %1,%0\n\t" + :"=r" (signr) + :"0" (signr)); + + __abi_trace("SIGNAL %lu, queued 0x%08lx\n", + signr+1, current->pending.signal.sig[0]); + } +#endif + return; +} + +#if defined(CONFIG_ABI_SYSCALL_MODULES) +EXPORT_SYMBOL(lcall7_syscall); +EXPORT_SYMBOL(lcall7_dispatch); +#endif diff -Nru linux-2.6.7/arch/i386/kernel/Makefile linux-2.6.7-abi/arch/i386/kernel/Makefile --- linux-2.6.7/arch/i386/kernel/Makefile 2004-06-16 07:19:01.000000000 +0200 +++ linux-2.6.7-abi/arch/i386/kernel/Makefile 2004-07-22 17:44:21.000000000 +0200 @@ -25,6 +25,7 @@ obj-$(CONFIG_X86_IO_APIC) += io_apic.o obj-$(CONFIG_X86_NUMAQ) += numaq.o obj-$(CONFIG_X86_SUMMIT_NUMA) += summit.o +obj-$(CONFIG_ABI_LCALL7) += lcall7.o obj-$(CONFIG_MODULES) += module.o obj-y += sysenter.o vsyscall.o obj-$(CONFIG_ACPI_SRAT) += srat.o diff -Nru linux-2.6.7/arch/i386/kernel/traps.c linux-2.6.7-abi/arch/i386/kernel/traps.c --- linux-2.6.7/arch/i386/kernel/traps.c 2004-06-16 07:19:01.000000000 +0200 +++ linux-2.6.7-abi/arch/i386/kernel/traps.c 2004-07-22 17:44:21.000000000 +0200 @@ -588,6 +588,26 @@ __asm__ __volatile__("movl %%db6,%0" : "=r" (condition)); + /* + * Entering the kernel via lcall7 or lcall27 does not clear the TF bit. + * Leaving it set in kernel code will stop the machine. The first + * instructions of lcall7 and lcall27 in entry.S save the CPU flags. + * The saved flags should have the TF bit set, so we ignore this trap. + */ + if (regs->eip == (unsigned long) &lcall7 || + regs->eip == (unsigned long) &lcall27) + return; + + /* + * After having saved the flags, TF will fire the single step trap + * again. This time TF should be cleared. It will be restored by the + * iret instruction returning to user mode. This way, the very next + * instruction after lcall in the user programm will not be stopped at. + */ + if (regs->eip - 1 == (unsigned long) &lcall7 || /* pushfl is a one-byte op */ + regs->eip - 1 == (unsigned long) &lcall27) + goto clear_TF; + /* It's safe to allow irq's after DR6 has been saved */ if (regs->eflags & X86_EFLAGS_IF) local_irq_enable(); diff -Nru linux-2.6.7/arch/ia64/ia32/ia32priv.h linux-2.6.7-abi/arch/ia64/ia32/ia32priv.h --- linux-2.6.7/arch/ia64/ia32/ia32priv.h 2004-06-16 07:20:19.000000000 +0200 +++ linux-2.6.7-abi/arch/ia64/ia32/ia32priv.h 2004-07-22 17:44:21.000000000 +0200 @@ -332,7 +332,7 @@ #ifdef __KERNEL__ # define SET_PERSONALITY(EX,IBCS2) \ - (current->personality = (IBCS2) ? PER_SVR4 : PER_LINUX) + (is_cur_personality((IBCS2)) ? PER_SVR4 : PER_LINUX) #endif #define IA32_EFLAG 0x200 diff -Nru linux-2.6.7/arch/parisc/kernel/signal.c linux-2.6.7-abi/arch/parisc/kernel/signal.c --- linux-2.6.7/arch/parisc/kernel/signal.c 2004-06-16 07:20:19.000000000 +0200 +++ linux-2.6.7-abi/arch/parisc/kernel/signal.c 2004-07-22 17:44:21.000000000 +0200 @@ -75,7 +75,7 @@ #ifdef __LP64__ compat_sigset_t newset32; - if(personality(current->personality) == PER_LINUX32){ + if(is_cur_personality_id(PERID_LINUX32)){ /* XXX: Don't preclude handling different sized sigset_t's. */ if (sigsetsize != sizeof(compat_sigset_t)) return -EINVAL; @@ -152,7 +152,7 @@ compat_sigset_t compat_set; struct compat_rt_sigframe * compat_frame; - if(personality(current->personality) == PER_LINUX32) + if(is_cur_personality_id(PERID_LINUX32)) sigframe_size = PARISC_RT_SIGFRAME_SIZE32; #endif @@ -165,7 +165,7 @@ #ifdef __LP64__ compat_frame = (struct compat_rt_sigframe *)frame; - if(personality(current->personality) == PER_LINUX32){ + if(is_cur_personality_id(PERID_LINUX32)){ DBG(2,"sys_rt_sigreturn: ELF32 process.\n"); if (__copy_from_user(&compat_set, &compat_frame->uc.uc_sigmask, sizeof(compat_set))) goto give_sigsegv; @@ -185,7 +185,7 @@ /* Good thing we saved the old gr[30], eh? */ #ifdef __LP64__ - if(personality(current->personality) == PER_LINUX32){ + if(is_cur_personality_id(PERID_LINUX32)){ DBG(1,"sys_rt_sigreturn: compat_frame->uc.uc_mcontext 0x%p\n", &compat_frame->uc.uc_mcontext); // FIXME: Load upper half from register file @@ -315,7 +315,7 @@ compat_frame = (struct compat_rt_sigframe *)frame; - if(personality(current->personality) == PER_LINUX32) { + if(is_personality_id(PERID_LINUX32)) { DBG(1,"setup_rt_frame: frame->info = 0x%p\n", &compat_frame->info); err |= compat_copy_siginfo_to_user(&compat_frame->info, info); DBG(1,"SETUP_RT_FRAME: 1\n"); @@ -392,7 +392,7 @@ haddr = A(ka->sa.sa_handler); /* The sa_handler may be a pointer to a function descriptor */ #ifdef __LP64__ - if(personality(current->personality) == PER_LINUX32) { + if(is_cur_personality_id(PERID_LINUX32)) { #endif if (haddr & PA_PLABEL_FDESC) { Elf32_Fdesc fdesc; @@ -427,19 +427,19 @@ */ sigframe_size = PARISC_RT_SIGFRAME_SIZE; #ifdef __LP64__ - if(personality(current->personality) == PER_LINUX32) + if(is_cur_personality_id(PERID_LINUX32)) sigframe_size = PARISC_RT_SIGFRAME_SIZE32; #endif if (in_syscall) { regs->gr[31] = haddr; #ifdef __LP64__ - if(personality(current->personality) == PER_LINUX) + if(is_cur_personality_id(PERID_LINUX)) sigframe_size |= 1; #endif } else { unsigned long psw = USER_PSW; #ifdef __LP64__ - if(personality(current->personality) == PER_LINUX) + if(is_cur_personality_id(PERID_LINUX)) psw |= PSW_W; #endif @@ -452,7 +452,7 @@ regs->gr[26] = sig; /* signal number */ #ifdef __LP64__ - if(personality(current->personality) == PER_LINUX32){ + if(is_cur_personality_id(PERID_LINUX32)){ regs->gr[25] = A(&compat_frame->info); /* siginfo pointer */ regs->gr[24] = A(&compat_frame->uc); /* ucontext pointer */ } else diff -Nru linux-2.6.7/arch/x86_64/ia32/sys_ia32.c linux-2.6.7-abi/arch/x86_64/ia32/sys_ia32.c --- linux-2.6.7/arch/x86_64/ia32/sys_ia32.c 2004-06-16 07:19:22.000000000 +0200 +++ linux-2.6.7-abi/arch/x86_64/ia32/sys_ia32.c 2004-07-22 17:44:21.000000000 +0200 @@ -924,12 +924,15 @@ sys32_personality(unsigned long personality) { int ret; - if (personality(current->personality) == PER_LINUX32 && + + if (is_personality_id(PERID_LINUX32) && personality == PER_LINUX) personality = PER_LINUX32; ret = sys_personality(personality); + if (ret == PER_LINUX32) ret = PER_LINUX; + return ret; } @@ -1077,7 +1080,7 @@ __put_user(0,name->version+__OLD_UTS_LEN); { char *arch = "x86_64"; - if (personality(current->personality) == PER_LINUX32) + if (is_cur_personality_id(PERID_LINUX32)) arch = "i686"; __copy_to_user(&name->machine,arch,strlen(arch)+1); @@ -1098,7 +1101,7 @@ down_read(&uts_sem); err=copy_to_user(name, &system_utsname, sizeof (*name)); up_read(&uts_sem); - if (personality(current->personality) == PER_LINUX32) + if (is_cur_personality_id(PERID_LINUX32)) err |= copy_to_user(&name->machine, "i686", 5); return err?-EFAULT:0; } diff -Nru linux-2.6.7/arch/x86_64/kernel/sys_x86_64.c linux-2.6.7-abi/arch/x86_64/kernel/sys_x86_64.c --- linux-2.6.7/arch/x86_64/kernel/sys_x86_64.c 2004-06-16 07:19:37.000000000 +0200 +++ linux-2.6.7-abi/arch/x86_64/kernel/sys_x86_64.c 2004-07-22 17:44:21.000000000 +0200 @@ -148,7 +148,7 @@ down_read(&uts_sem); err = copy_to_user(name, &system_utsname, sizeof (*name)); up_read(&uts_sem); - if (personality(current->personality) == PER_LINUX32) + if (is_cur_personality_id(PERID_LINUX32)) err |= copy_to_user(&name->machine, "i686", 5); return err ? -EFAULT : 0; } diff -Nru linux-2.6.7/Documentation/abi/00-INDEX linux-2.6.7-abi/Documentation/abi/00-INDEX --- linux-2.6.7/Documentation/abi/00-INDEX 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/Documentation/abi/00-INDEX 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,30 @@ +00-INDEX + - this file +COMPAT + - a list of software that has run succesfull under iBCS +CREDITS + - a list of people that have contributed to linux-abi or iBCS +ChangeLog + - changelog of linux-abi +ChangeLog.ibcs + - changelog of the iBCS project (up to 1998) +Error.map + - mapping of error codes from Linux to various personalities +HINTS + - FAQ-style Q&A +Local-X + - help on local X interfaces +Notes.Signal + - some notes on signal handling +Personality + - an introduction into Linux personality support +README.first + - read this first! +Syscall.map + - the syscall mapping for certain personalities +TODO.ibcs + - things to be done, leftovers from iBCS +autoload.txt + - autoloading personality modules under Linux-ABI +modules.txt + - a brief overview of the Linux-ABI modules diff -Nru linux-2.6.7/Documentation/abi/autoload.txt linux-2.6.7-abi/Documentation/abi/autoload.txt --- linux-2.6.7/Documentation/abi/autoload.txt 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/Documentation/abi/autoload.txt 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,49 @@ +Autoloading personality modules under Linux-ABI +2001-July-19 +Christoph Hellwig, + +Linux-ABI can automatically load binary format modules (see modules.txt +for information on what binary format modules are). This file explains +how to setup a system to automatically load the binary format modules +on demand. + +Automatic module loading is done in Linux using a facility called 'kmod' +which is - unlike the name suggests - _not_ a system daemon, but a kernel- +facility to make userspace upcalls to te module loading program 'modprobe'. + +Linux-ABI uses the function request_module that is exported by kmod to +request modules for personalities that are currently not available but +requested by one of the binary fomrat detection heuristics. For a missing +personality, request_module is called for the module-string + + personality- + +To get the right modules loaded you have to alias these string to the +actually wanted modules in /etc/modules.conf. To do that you have to know +which personality number maps to what module. Here is a table for the +personalities supported by Linux-ABI: + + + personalities module + ----------------------------------- + 1,2,5,7 abi-ibcs + 3 abi-sco + 4 abi-wyse + 13 abi-solaris + 14 abi-uw7 + +Below is an example snipplet from modules.conf for such a setup: + +------------------- snip -------------------- + +alias personality-1 abi-ibcs +alias personality-2 abi-ibcs +alias personality-3 abi-sco +alias personality-4 abi-wyse +alias personality-5 abi-ibcs +alias personality-7 abi-ibcs +alias personality-13 abi-solaris +alias personality-14 abi-uw7 + +------------------- snip -------------------- + diff -Nru linux-2.6.7/Documentation/abi/ChangeLog linux-2.6.7-abi/Documentation/abi/ChangeLog --- linux-2.6.7/Documentation/abi/ChangeLog 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/Documentation/abi/ChangeLog 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,135 @@ +2002-01-03 Christoph Hellwig + + linux-abi­2.4.17.0 + + * rework/cleanup lcall7 syscall handling + * make sure x.out sections aren't loaded into illegal areas + * fix SVR4 mmap() to always assume post-SunOS4 behaviour + +2001-11-24 Christoph Hellwig + + linux-abi-2.4.15.0 + + * simplify wyse socket handling, use native syscalls directly where + possibles else use normal calling conventions + * fix compilation for non-i386 machines (Olaf Hering) + * fix alignment checks in binfmt_xout (based on patch by Joerg Ahrens) + * rewrite abi_brk: fix (theoretical) races, check for page alignment + * don't try to take a non-existant lock in xnx_nap, cleanup xnx_nap. + * fix value reported by sysi86(SI86MEM). + +2001-11-18 Christoph Hellwig + + linux-abi 2.4.14.0 + + * small binfmt_xout bugfixes (Joerg Ahrens) + * move isc into it's own personality + * make all personalities independant of abi-ibcs + * merge socket handling into abi-wyse + +2001-10-22 Christoph Hellwig + + linux-abi 2.4.12.0 + + * big mmap rewrite + | correctly check for flags in svr4_mmap + | use svr4_mmap for the UnixWare personality as well + | OpenServer has it's own implementation now as it supports + rather different flags than SVR4 & derivates + * more header cleanups - all helper routines are now in abi/util/*.h + +2001-10-04 Christoph Hellwig + + linux-abi 2.4.10.0 + + * add MODULE_DESCRIPTION/MODULE_AUTHOR/MODULE_LICENSE tags + * don't use alternate prefix for directories (David Mosberger) + * fix non-modular buil + * cleanup stat handling + | use Alexander Viro's kstat concept + | all emulations now have their own xstat implementations + | fixed overflows + * add full-fledged types.h headers for all peronalities + +2001-08-06 Christoph Hellwig + + linux-abi 2.4.9.0 + + * fix missing solaris socket exports + * move Xenix support from ibcs to sco module, + make unconditional + * UnixWare LFS fixes + * make the actual code work on the Alan Cox tree + +2001-08-06 Christoph Hellwig + + linux-abi 2.4.7.0 + + * some final polishing for segmented 286 x.out binaries (Joerg Ahrens) + * fix SPX handling (again) + * fix setpgrp and cleanup procids while we're at it + * update SCO syscall table to match OSR506a + +2001-07-19 Christoph Hellwig + + linux-abi 2.4.6.1 + + * rewritten /dev/socksys handling + * fix more non-x86 breakage (Olaf Hering) + * port solaris native sockets from sparc64 + * add sysctl support for runtime-tweaking + * add cxenix to the ibcs sysent table for Xenix/386 (Jürgen Günther) + * (re)add support for segmented x.out binaries (Joerg Ahrens) + | I probably broke it while rebasing against -CURRENT + * reject IRIX binaries on mips32 (David Woodhouse) + +2001-07-09 Christoph Hellwig + + linux-abi 2.4.6.0 + + * svr4/signal.c typo fix + * make cxenix debug printk's less verbose (Christian Lademann) + * misc small bugfixes (Christian Lademann) + * compile fixes for !CONFIG_ABI on non-x86 architectures + +2001-06-18 Christoph Hellwig + + linux-abi 2.4.5.1 + + * rewrite of abi_sigsuspend() to make it work as expected + * fix cxenix syscall table + * actually initialize socksys + +2001-06-09 Christoph Hellwig + + linux-abi 2.4.5.0 + + * rewrite of kernel exec_domain support + * make faking of SCO utsname information configurable + * get rid of SYS() and sysfunc_p (Arjan van de Ven) + * fix socket families (Stephan Springl) + * fix SCO signal mapping (Stephan Springl) + * fix SCO (and Wyse) error mapping + * continued source tree restructuring + +2001-04-31 Christoph Hellwig + + linux-abi 2.4.4.0 + + * disable tracing by default + * rewrite of the SYSV IPC code + * add support for SCO OpenServer 5 ELF binaries + * fix an error in binfmt_coff that does not clear the return value + * provide generic template macros for stat and friends + * start of source tree reorganization + +2001-03-30 Christoph Hellwig + + linux-abi 2.4.3.0 + + * fix shared library support for COFF + * x.out is now supported (again) + * redo setting of personality based on ELF headers + * get rid of CONFIG_ABI_TRACE (and a lot of nasty ifdefs) + * added documentation, mostly from iBCS + diff -Nru linux-2.6.7/Documentation/abi/ChangeLog.ibcs linux-2.6.7-abi/Documentation/abi/ChangeLog.ibcs --- linux-2.6.7/Documentation/abi/ChangeLog.ibcs 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/Documentation/abi/ChangeLog.ibcs 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,2769 @@ +Thu Nov 5 21:45:41 GMT 1998 + + * Fixed the bug that lets reads and writes on /dev/socksys + take out the kernel. + -- Mike + + * Added a kludge around for Sybase isql which appears to + have initialised a struct sockaddr using: + sa.sa_family = htons(AF_INET); + I guess this works on SCO? + -- Mike + + +Sat Oct 31 14:15:44 GMT 1998 + + * Documentation update. + + * If we are doing a T_BIND_REQ with a null address we can + ignore the connection backlog. Listening makes no sense + but some software seems to set it 1 for the hell of it. + -- Mike + + +Tue Oct 20 20:34:20 BST 1998 + + * Changed the debug messages printed when exec tracing + sees a pointer error on an arg or env entry. It may not + be a "real" error. It could be that we just cannot get + a free page or perhaps the entry is too long for getname(). + Whatever, we do not really care at this point anyway. + -- Mike + + +Sat Oct 17 20:24:59 BST 1998 + + * Documentation update for today's release. + -- Mike + + +Thu Oct 15 21:39:16 BST 1998 + + * When checking personality only look at the base personality + and ignore the flags. There is at least one case I can + think of, PER_SHORT_INODE, where the personality should + be considered the same even when the flags are different. + -- Mike + + * Added the location of the kernel source as an option + in the CONFIG. Hopefully this will make it a little + more obvious that iBCS is *dependant* on the kernel. + -- Mike + + * Set SO_BSDCOMPAT on sockets. SYSV has BSD handling of + ICMP errors on UDP sockets rather than RFC conformance. + I think... + -- Mike + + +Wed Oct 14 22:50:48 BST 1998 + + * When using some user stack as temporary work space we + only leave 1k between the work space and the real user + stack. This is because Informix Dynamic Server uses + threads with limited stack space and the idea of dropping + 16k below what would normally be touched on a SCO system + worries me a bit. + -- Mike + + +Sun Oct 11 11:58:58 BST 1998 + + * Changed the Tools Makefile to install mkmnttab in + /usr/bin. Informix Dynamic Server _requires_ a + valid /etc/mnttab. + -- Mike + + +Sun Oct 11 11:44:58 BST 1998 + + * When doing an I_PEEK or I_NREAD STREAMS ioctl we have + to do a probe on sockets in case we need to generate + a control message (e.g. T_CONN_IND) which should then + be offered. This also allows T_CONN_IND messages to be + returned in several MORECTL divided pieces should it + ever be necessary. This is required by Informix Dynamic + Server which does a poll then I_PEEK on a listening + socket before actually picking up the connection. Dynamic + Server is system call hell :-). + -- Mike + + * When we do a timod operation via an ioctl there seems + to be no way to cope if the returned message is larger + than the original request. We can't expect the app to + come back for the extra and returning MORECTL to the + app seems to confuse things. Therefore we just discard + the excess. This case is required when an app (e.g. + Informix Dynamic Server) tries to set SO_LINGER using + an int instead of a struct linger via an ioctl. + -- Mike + + * Added some debug to the poll handler so we can see what + is being polled. + -- Mike + + * More debug message changes. + -- Mike + + * Wrap SO_LINGER handling so we can survive if an int is + passed instead of s struct linger. It seems that other + systems do not do such robust error checking as Linux. + Note that if an int is passed we probably do not do what + other systems would but at least we don't give unexpected + errors to broken applications. + -- Mike + + +Sat Oct 10 15:58:29 BST 1998 + + * Added an entry to Doc/HINTS noting the the Informix + Dynamic Server install requires an /etc/mnttab. + -- Mike + + * Wrong option length being passed through to setsockopt() + from the TLI/XTI optmgmt routine. + -- Mike + + * When stating files only map "ext2" to "HTFS" for SCO + programs - and then only if the filesystem name really + was "ext2". + -- Mike + + * SCO has a different value for the _SC_PAGESIZE argument + to sysconf() than SVR4. Informix wants it to work. + -- Mike + + * Hmmm, Informix Dynamic Server may or may not be looking + at the major number on a socket. (I _think_ it does + sometimes). It definitely checks that sockets have + S_IFCHR set in their file modes though... + -- Mike + + * Changed some debug messages to make it easier to read + logs when more than one iBCS handled process is running. + -- Mike + + * If we get a STREAMS ioctl on a file descriptor only + initialize the socksys handler on it if it is not + already a socket but does belong to the socksys device. + -- Mike + + +Thu Oct 8 21:20:43 BST 1998 + + * When punting a pseudo device transport provider to a + socket copy the device numbers between the inodes. This + is because Informix Dynamic Server stats the pseudo + device node (/dev/socksys) then stats the socket it + gets and compares the major numbers. Sheesh... + -- Mike + + * If socksys_close gets something that is not a socket + it is probably the original pseudo device which was + opened just for an ioctl or two. This is not an error. + -- Mike + + * Some programs, notably the Informix Dynamic Server + install program compare the filesystem name from a + stat or sysfs against their own hard coded list of + known "real" filesystems. Hence we call "ext2" "HTFS" + instead for SCO processes. + -- Mike + + * Informix DS also checks the release part of the utsname + data to make sure it says "3.2v5.0.0". So now the + utsname struct looks even more like SCO. + -- Mike + + * Only dump the ctl part of messages in timod if + tracing is enabled. + -- Mike + + * SCO has statvfs in the same place as SVR4 but they have + added a field slap bang in the middle of the struct to + allow some inodes to be reserved for root in much the + same way that some blocks may be reserved. + -- Mike + + +Thu Oct 8 20:48:46 BST 1998 + + * On timod bind and connect the size of the address is + allowed to be the _used_ bytes whereas the underlying + socket functions require the _total_ bytes. This is + a problem for Sybase. + -- Mike + + +Sun Aug 30 21:49:46 BST 1998 + + * Changed socksys.c to handle new file_operations struct + in kernel 2.1.119 and later. + -- Mike + + +Sat Aug 22 19:57:01 BST 1998 + + * Fixes and additions to user pointer checking in ipc.c + -- Mike + + * Changed some more KERN_ERRs to KERN_DEBUGs in the + STREAMS ioctl support. + -- Mike + + +Fri Aug 21 20:24:32 BST 1998 + + * Somehow fchdir had been missed from the main iBCS call + map even though it had been put in the BSD map. Oops. + -- Mike + + +Wed Aug 19 23:12:47 BST 1998 + + * ALPHA 2.1 release number 2... + -- Mike + + +Wed Aug 19 20:43:09 BST 1998 + + * Avoid calling rt_sigaction if the mapped signal number + is -1. It is not strictly necessary but why bother? + -- Mike + + * Added David Bruce's updated x286emul. + -- Mike + + +Mon Aug 17 21:29:53 BST 1998 + + * Avoid calling fput with a NULL file pointer. + -- Mike + + +Sun Aug 16 17:32:20 BST 1998 + + * Fix to copy_{to,from}_user return checking. In many + cases we do not care because they are behind verify_area + checks but in some we do - and copy_{to,from}_user + returns the number of bytes _uncopied_. + -- Mike + + +Sat Aug 15 23:39:42 BST 1998 + + * Change the flock handling to bounce the flock struct + through kernel space rather than using an in place + modification. The assumptions we were making about + segment registers seem to have become invalid at some + point. We could go to put_user(get_user()) but moving + the whole struct is probably more robust. Which is + faster? I dunno... + -- Mike + + +Sat Aug 15 22:30:41 BST 1998 + + * Changes to signal functions. Previous code confused old and + new sigsets and could have lead to memory corruption and + was likely the cause of signals getting blocked unexpectedly. + Now we use the rt_sig* and new sigset interface to the + kernel exclusively (in a few years the old stuff may be + removed). This does means that a non-Linux program may + now operate on signals >32 which may not have existed + (and therefore would have errored) in the native environment. + This may be considered a bug or a feature as appropriate... + -- Mike + + +Mon Jul 20 22:23:14 BST 1998 + + * ALPHA 2.1 release... + -- Mike + + +Mon Jul 20 20:55:47 BST 1998 + + * Added support for I_FDINSERT in the STREAMS/TLI message + protocol handling. This allows TLI server code to work + using a _real_ libnsl_s (tested briefly) but will break + server code using my replacement libnsl_s until I update + it. (It should probably use an I_FDINSERT simply so it + can still run under SYSV if ever necessary.) + -- Mike + + * Use TIOCINQ instead of FIONREAD in the STREAMS ioctl handler. + FIONREAD isn't actually supported on sockets. The socksys + code already had this right. + -- Mike + + * Do the MOD_INC, MOD_DEC calls for sockets in the inherit + and release handling only to reduce the opportunity for, + ah, "oversights". + -- Mike + + +Thu Jul 16 22:11:48 BST 1998 + + * Finally got round to adding a GNU CopyLeft! + -- Mike + + * Set up an XTI/TLI private state struct on all sockets at + the same time we plug our own file operations in. This + costs a small amount of extra memory per socket. However + this is strictly correct (although unlikely to be actually + _required_ by anything). It also allows us to set up TEPs + created by XTI/TLI listen/accept easily so they have a + chance of working. + -- Mike + + * XTI/TLI fixes: + Do not auto-listen in getmsg() - listen() after connect() + appears to crash some 2.1 kernels(?). + Change the probe for activity in getmsg() to use the + new poll handler directly. + Handle listening TEPs slightly better. + -- Mike + + * Changed a stray KERN_ERR to KERN_DEBUG in ioctl.c + -- Mike + + +Fri Jul 3 23:20:37 BST 1998 + + * Fixed the initial set up of the argument and environment + lists which were broken during the change to 2.1 style + user memory access. + -- Mike + + +Mon Jun 29 22:50:11 BST 1998 + + * Put kernel_version definition back in emulate.c + -- Mike + + * Change loaders to set start_text, end_text, start_data, + end_data, start_brk, brk fully. + -- Mike + + +Thu Jun 25 21:18:11 BST 1998 + + * Added support for the "fat" IPC structures which use + 32 bit uids, gids etc. + -- Mike + + +Wed Jun 24 21:30:09 BST 1998 + + * Change suser() checks to use the new capable() calls. + -- Mike + + * Changed the CONFIG default to NOT support Xenix 286. It + is an ever increasing build problem. It needs a volunteer + to rewrite it. + -- Mike + + * Add locking around system_utsname data using the uts_sem. + -- Mike + + * Changed to use dentry stuff. Use fget()/fput() to get + file pointers rather than accessing task fd tables + directly. Use poll interface for SYSV poll and timod + blocking checks. Use lock_kernel()/unlock_kernel() + around stat routines and other namei stuff. Use dput() + to release dentries obtained with namei(). Other + incidental fixes to what went before as I noticed them. + -- Mike + + +Tue Jun 9 20:02:56 BST 1998 + + * More changes for new module conventions. + -- Mike + + * Changed signal stuff to new conventions. + -- Mike + + * Changed getname() calling convention. + -- Mike + + * Changed fs type to mm_segment_t. + -- Mike + + * Changed user VM accesses to use new conventions. + -- Mike + + +Sat Jun 6 20:30:00 BST 1998 + + * Changed to new module conventions. + -- Mike + + +Thu May 28 22:30:45 BST 1998 + + * Removed VM_STACK_FLAGS tests. + -- Mike + + * Remove VM_GROWSDOWN tests. + -- Mike + + * Removed MAP_EXECUTABLE tests. + -- Mike + + * Removed MAP_DENYWRITE tests. + -- Mike + + * Removed STACK_TOP tests. + -- Mike + + * Removed FORKNOEXEC tests. + -- Mike + + * Removed INIT_MM tests. + -- Mike + + +Mon May 18 22:49:56 BST 1998 + + * Fixed xnx_rdchk() return value. + -- Mike + + * The serial number returned in the SCO utsname struct + can now be set with sco_serial="..." as a module + option. Some program apparently want to find a real, + believable serial number there. This should be documented + somewhere other than here I guess... + -- Mike + + +Mon May 18 22:03:49 BST 1998 + + * A class 't' ioctl with no arg type stuff in the top + word is either an SVR4 tape ioctl a Coherent BSD-ish + termios ioctl. + -- Mike + + +Mon Feb 2 22:57:45 GMT 1998 + + * Other relatively minor changes to allow compilation + under glibc (specifically 2.0.6 but it shouldn't + matter). + -- Mike + + * Added an explicit -I flag to search /usr/src/linux/include + since glibc doesn't necessarily require the kernel + includes to be symlinked under /usr/include. + -- Mike + + * The personality defaults in binfmt_coff should probably + select short inodes on the assumption that newer stuff + is likely to be built as ELF anyway. I hope. + -- Mike + + +Wed Nov 19 19:28:07 GMT/BST 1997 + + * Attempt to work around problems with sign extension + when programs believe that the fs magic in a sysfs() + call is short rather than long. + -- Mike + + * Added IPPROTO_IP/SOL_IP option name mapping for + {get,set}sockopt. This is correct for SCO OS5 and + hopefully for other SYSV derived Unices. Note that + SCO OS5 ping still doesn't work because it uses an + unsigned char for the IP_TTL value whereas Linux + wants an int - and it objects to getting an error + return. Apparently POSIX 1003g says IP_TTL should + be an unsigned char so OS5, or at least its ping, + is at fault. This probably isn't worth hacking + around unless someone _really_ needs it. + -- Mike + + +Wed Nov 12 22:28:19 GMT/BST 1997 + + * Added the SCO-ish syscall shortcut to the socksys + networking code. + -- Mike + + +Fri Nov 7 20:13:05 GMT/BST 1997 + + * Oops, I installed the SCO signal tables in the old + personality mapping but forgot to create a specific + SCO personality using them. + -- Mike + + +Thu Nov 6 08:04:37 GMT/BST 1997 + + * No, it really should be USR1 for URG under SCO, not + USR2. This is according to the SCO Network Programmer's + documentation. The previous problem was because + confusion between the SVR4 and SCO/SVR3 requirements + prevented a SCO program from registering a handler + for the right signal, I think. + -- Mike + + +Wed Nov 5 14:23:22 GMT/BST 1997 + + * Created a new signal mapping for SCO and mapped + Linux SIGURG to SCO SIGUSR2. Also changed the + plain ibcs mapping for SIGURG back to IBCS_SIGURG. + Previously I had SIGURG mapped to SIGUSR1 for + what my subconscious says was a good reason but + I can't figure out where I got it from. The USR2 + mapping is according to Peter Brueckner - and if + it works for him... + -- Mike + + +Wed Nov 5 09:14:27 GMT/BST 1997 + + * Repair the STREAMS based socket code. The new socket + hashing in 2.0.30 and beyond means the old code no + longer works. We now delay replacing the fd with + a socket until the first read, write or ioctl. Since + the open has completed at this stage and the fd is + fully initialized we can then use dup() to do the + fd switch, which should always work. As a side effect + this allows us to auto-connect an SPX pipe to X :0 + if the first operation is other than a single character + write - which should allow us to handle v. old SVR3 + X programs side by side with their more modern, and + common, multi-SPX pipe descendants. + This does mean that some error returns from an + open of a TLI special file might be delayed until + the first operation, however a) these are unlikely + to occur (they are things like no such protocol) + and b) most opens of such files are hidden in + functions like t_open() anyway so if there is a + problem a simple fix to libnsl to check the first + ioctl is all that is needed. + -- Mike + + * sysfs() used to enumerate available filesystems seems + to be 0 based on Linux but 1 based on SYSV. + -- Mike + + +Sun Oct 12 00:18:33 GMT/BST 1997 + * Ioctls on the NFS pseudo device need to go via the + emulation code rather than the native ioctl handler. + -- Mike + + +Sat Aug 16 14:56:24 GMT/BST 1997 + + * Changed the use of errno in a prototype in ibcs.h to + avoid possible conflict with an SMP errno definition + which could get inherited from an include file if we + aren't careful. + -- Mike + + +Sat Jul 12 01:00:00 GMT/BST 1997 + + * Added Xenix locking() modes 5, 6, 7 as per patch from + David Bruce (there were others + too). I rewrote it to be a bit cleaner but I haven't + tested it (it's late...). Some one will tell me I guess. + -- Mike + +Fri Jul 11 22:27:13 GMT/BST 1997 + + * Added more console ioctl traps to discourage programs + from trying to do funky stuff with the console without + logging unsupported ioctl messages. + -- Mike + + * sysfs() can, apparently, map an fs magic number to + an fs name. We do this outside the kernel sysfs() + because there seems no clean way to do it. We simply + have a list of known magic numbers hard coded :-(. + -- Mike + + * Implemented sysconfig(). This is appears to be the SVR4 + forerunner to the POSIX sysconf(). + -- Mike + + +Tue May 13 20:52:05 GMT/BST 1997 + + * Hand off xmknod calls via ibcs_mknod so that we can + create a directory if that is what the flags imply. + I have not tested to see if xmknod is allowed to create + directories - I just noticed it in passing. + -- Mike + + * Added SCO's F_GETHFDO (get highest fd open) fcntl. This is + used by /bin/csh on SCO OS5 to save a few syscalls. + -- Mike + + +Tue May 13 00:10:09 GMT/BST 1997 + + * More changes to handle long/short inode environments + plus more explanation in the code. Are we having fun yet? + -- Mike + + +Sat May 10 15:19:39 GMT/BST 1997 + + * Added socketpair() to the socksys emulation. This is + as implemented by SCO OpenServer 5. + -- Mike + + * Change binfmt_coff.c to recognise programs compiled for + SCO OpenServer 5, programs compiled for SCO 3.2.4 and + programs compiled under SCO OpenServer 5 but with + compatibility for ODT3.0. Why? Well, sometimes we + should be giving long inodes in returns from getdents, + sometimes short inodes. We don't just want to mask + off the high part because that can lead to some + things becoming invisible. We don't want that. + -- Mike + + +Fri May 9 23:29:37 GMT/BST 1997 + + * Added some more tape ioctls. + -- Mike + + +Wed Apr 16 23:12:37 GMT/BST 1997 + + * Fix memory leaks in poll.c and change ENOMEM return + to EAGAIN. + -- Mike + + +Tue Mar 11 21:29:15 GMT/BST 1997 + + * Add {get,set}rlimit to the SYSV personalities. + -- Mike + + +Fri Mar 7 21:04:24 GMT/BST 1997 + + * Only build x286emul if EMU_X286 is enabled in CONFIG. There + are many insallations which appear to either not have the + a.out compiler support or have it installed incorrectly. + -- Mike + + +Tue Feb 18 22:04:39 GMT/BST 1997 + + * Removed unnecessary and incorrect includes. + -- Mike + + +Wed Feb 12 22:03:13 GMT/BST 1997 + + * Documentation updates for release. + -- Mike + + +Mon Feb 10 22:36:27 GMT/BST 1997 + + * Dammit! The inode folding in stat() and getdents() was + out of step _again_ :-(. + -- Mike + + +Sun Jan 5 17:20:20 GMT/BST 1997 + + * sysconf(_SC_CLK_TCK) should return the value of HZ. + -- Mike + + * Small clarification to README concerning shared libraries. + -- Mike + + * Removed the bit about UnixWare X binaries not working from + Doc/HINTS. Now we have STREAMS/TLI emulation this is no + longer true (and hasn't been for a while). + -- Mike + + +Sat Jan 4 19:31:26 GMT/BST 1997 + + * If we open() something that is really a socket we close + it and reopen it using socket(), connect(). This allows + a Unix domain socket to look like a named pipe which + enables more SYSV X clients to connect to a local X + server using the local method (with suitable symlinks + to map the pathnames). + -- Mike + + +Fri Jan 3 22:39:15 GMT/BST 1997 + + * Added a (simplistic) implementation of the I_CANPUT SVR4 + STREAMS ioctl. + -- Mike + + * Changed CONFIG.i386 to note that a correct setting of SMP + is now necessary. + -- Mike + + +Wed Oct 2 16:28:39 GMT/BST 1996 + + * Intercept mknod() and allow it to create directories. Linux + doesn't allow this but SYSV does. (What about BSD?) + -- Mike + + +Wed Oct 2 15:56:57 GMT/BST 1996 + + * Separated out the spx connect code so we can support old, + single connection spx implementations once we know how to + recognise them. + -- Mike + +Wed Oct 2 15:54:45 GMT/BST 1996 + + * At some stage I add some binfmt_elf.c changes that were + made to the kernel ELF loader in some 2.0.x patch. I forget + which now but no one should be using the iBCS ELF loader + currently anyway. + -- Mike + + +Fri Aug 23 15:42:04 GMT/BST 1996 + + * Moved svr4sig to the right place. + -- Mike + + * Moved error message strings to a separate file so they can + be shared by emulate.c and solaris.c. + -- Mike + + * CONFIG files now define ARCH to be the CPU architecture. This + is used to ensure that architecture specific files are only + used when necessary. + -- Mike + + * Changed the getdents routine in open.c to use the same + rules for folding 32 bit inodes to 16 as stat and read. + -- Mike + + +Mon Aug 19 13:33:42 GMT/BST 1996 + + * Correct IPC problem introduced with Sparc changes. + -- Mike + + +Fri Aug 9 13:27:49 GMT/BST 1996 + + * Fix the inode swapping for /dev/spx and XTI/TLI transports. + -- Mike + + * If a COFF binary doesn't have a .comment section we have no + way to tell what personality we should be using. Switch to + SCO anyway - odds on it is. + -- Mike + + +Wed Aug 7 14:22:11 GMT/BST 1996 + + * On SCO at least lseek on a character or block device + returns 0 not -ESPIPE. + -- C.A. Lademann + + * Some problems with /dev/spx and TLI end point handling that + could leak descriptors, memory and leave the lists of file + locks in an inconsistent state. Not to mention the fact that + the socket data in an inode also contains a pointer back to + the process' file structure. I _think_ I have this sorted + out now... + -- Mike + + * Sparc changes broke select. While I was at it I changed it + to use the newselect Linux call as well. If we build without + tracing we'll save a few more bytes of code now too. + -- Mike + + +Wed Jul 31 14:16:38 GMT/BST 1996 + + * Map EAGAIN to EWOULDBLOCK for recv*() and send*() syscalls. + Linux seems to return EAGAIN. X/Open allows either EAGAIN + or EWOULDBLOCK. SVR4 and Wyse V/386 specify EWOULDBLOCK in + their man pages. SCO doesn't admit to non-blocking possibilities + in their man pages but some code seems to expect only + EWOULDBLOCK. + -- Mike + + +Mon Jul 29 16:58:11 GMT/BST 1996 + + * Added a CONFIG option for SMP. This is enabled by default. + I don't think this is a problem for non-SMP systems? + -- Mike + + * Minor change to the SCO error map. + -- Mike + + +Fri Jul 26 09:13:43 GMT/BST 1996 + + * Updated README and RELEASE + -- Mike + + * Merged Sparc patches from: + Miguel de Icaza + -- Mike + + +Thu Jul 4 12:24:06 GMT/BST 1996 + + * The default is now *not* to build a versioned module. I got + too many questions about why it wouldn't compile. + -- Mike + + * Fix to binfmt_xout.c when Xenix 286 is emulation is not + configured. + -- Mike + + +Fri Jun 14 13:36:18 GMT/BST 1996 + + * Added code to explicitly fail the SCO LD?MAP ioctls used + for channel mapping. + -- Mike + + +Thu Jun 6 17:21:00 GMT/BST 1996 + + * Cleaned up Stephans SCO tape ioctls and added the + corresponding SVR4 versions (untested). + -- Mike + + +Wed Jun 5 10:47:24 GMT/BST 1996 + + * Rewritten the Xenix locking() syscall. The previous one + was crap. + -- Mike + + * Change the read on directory emulation to fold long inodes + to shorts in the same way as stat and getdents. This may + help old programs that use stat and read to do a getcwd + rather than a stat and getdents. + -- Mike + + * Use __get_free_page instead of get_free_page in getdents + since we don't need the buffer cleared initially (I think). + -- Mike + + +Sat Jun 1 09:50:30 MET DST 1996 + * Added some tape ioctrls for SCO to iBCSemul/ioctl.c. + -- Stephan + + +Fri May 31 08:44:51 GMT/BST 1996 + + * Move bsdioctl.c to the main group of source files from + than the BSD specifics. Just about everything else has + BSD style sgtty stuff and some seemingly modern code + actually depends on it (e.g. ISC SVR4 telnet)! + -- Mike + + * Add CONFIG option to build a versioned module. + -- Mike + + * Install the modules in /lib/modules/`uname -r`/misc for + compatibility with the modules tools. + -- Mike + + * If the requested connection indications in a bind request + is greater than zero do a listen() if the bind is successful. + We still also do a listen() if the program selects() on + a bound but unconnected stream. This may help some broken + programs. It may also break some broken programs. It's + debatable whether this should now be in or out. + -- Mike + + * The bit vector mapping used for converting vectors of + signal flags had an off by one error. The signal maps + themselves were also one entry short. + -- Mike + + * At some stage I changed the I_SETOWN STREAMS ioctl but + never committed it? + -- Mike + + +Thu May 9 12:51:10 GMT/BST 1996 + + * Change to install in /lib/modules/`uname -r`/misc instead + of /usr/lib/modules for compatibility with the way the + modules tools have gone. + -- Mike + + +Thu Apr 25 12:34:06 GMT/BST 1996 + + * Use the CONIND_number in a T_BIND_REQ to decide whether + or not we should listen() on the socket. + -- Mike + + +Mon Apr 22 15:42:47 GMT/BST 1996 + + * Added a simple loader that will attempt to pass scripts + that start with ":" and things that look like simple text + to /bin/sh. Hopefully this isn't going to conflict with + magic for other needed formats... + -- Mike + + +Fri Mar 29 17:11:35 GMT/BST 1996 + + * Committing the all new TLI/XTI options handling. Note that + TLI and XTI option handling is mutually exclusive at the + moment. The default is to enable TLI options handling since + that is what existing SVR3/4 systems use. I haven't found + one that actually handles X/Open format (they use the + TNOTSUPPORT cop out) so I don't know how the stack is + told to use XTI format instead of TLI. + Note that only SOL_SOCKET/* and SOL_TCP/TCP_NDELAY are + known to work to any extent at the moment. Others may (or + may not need mapping) but I can't find the motivation to + wade through the headers and create yet another table of + magic numbers. Hopefully everyone just nicked the BSD + reference code... + -- Mike + + * Some more 1.3.7x changes related to process accounting + (fork but no exec etc.). + -- Mike + + +Wed Mar 20 13:36:07 GMT/BST 1996 + + * I seem to have forgotten to add a comment about merging + changes from mid 1.3.7x kernels. + -- Mike + + +Wed Feb 28 14:53:00 GMT/BST 1996 + + * Fix to shared library loader in binfmt_aout.c from kernel + patch 1.3.69. + -- Mike + + +Wed Jan 24 09:58:34 GMT/BST 1996 + + * Implemented I_PEEK. + -- Mike + + * Changed I_NREAD to understand that control messages constitute + queued data. + -- Mike + + +Fri Jan 19 11:57:20 GMT/BST 1996 + + * Make the socket level connect in timod.c happen synchronously + always. Allowing the async possibility is a little harder. + -- Mike + + +Thu Jan 18 16:06:13 GMT/BST 1996 + + * Added (some of) the intial framework for option management. + This is documented by X/Open but many XTI stacks don't + seem to implement it. Certainly the man page for t_optmgmt + in SCO OS5 says it isn't yet implemented. There do seem + to be programs out there that make options requests though. + Unfortunately I don't have one right now so this is currently + disabled and MAY CAUSE KERNEL FAULTS. I don't know... + -- Mike + + +Tue Jan 16 12:35:21 GMT/BST 1996 + + * Added a slight change to mmap.c. The SVR4 headers describe + a slight change in functionality which is specified with + a special flag that is supposedly set by the C library + interface. I haven't actually seen this flag set by the + SVR4 dynamic loader (which is the only mmapper I've seen) + and things seem to work with or without this change. It + may not be necessary at all? + -- Mike + + +Fri Jan 12 14:56:38 GMT/BST 1996 + + * Remove trace flag from context() in the callmaps. SVR4's + /bin/sh seems to use it but doesn't care if it fails. + -- Mike + + * Added the SCO OS5 SI86GETFEATURES request to sysi86(). OS5 + uses this to establish what "features" are available when + a program starts (i.e. in crt*.o). Currently we just return + the same vector as OS5 itself. I haven't found what the + flags mean - but one of them indicates xstat extensions + which I have added to iBCS. + -- Mike + + * Change .comment parsers in binfmt_coff.c and binfmt_elf.c + so we only grab a single page (asking for two contiguous + pages is antisocial) and then roll through the comment + section in stages. + -- Mike + + * Fixes to binfmt_elf.c and binfmt_aout.c so they compile + and load with 1.3 kernels. + -- Mike + + +Tue Jan 9 14:29:49 GMT/BST 1996 + + * Add a kludge to the TLI connect code. For some reason, under + ISC SVR4, telnet seems to gve the port number in network + byte order ok but the X programs give it in host byte order. + One of them is wrong but presumably both work on ISC (I don't + have the hardware to actually install it). We kludge around + it here by checking if we are SVR4, AF_INET, port 6000 (host + order) and, if so, change it to port 6000 (network order). + This will break anything that wants to make an outgoing + call to port 28695. There are probably other things that + expect incorrect port numbers to work but there seems to + be no easy solution here. + -- Mike + + +Fri Jan 5 13:34:43 GMT/BST 1996 + + * First draft of code to handle select/poll on transport end + points correctly. This isn't well tested but should be good + enough to support normal timod usage. + -- Mike + + +Thu Jan 4 13:52:25 GMT/BST 1996 + + * TLI changes to get error returns from connects correctly. + -- Mike + + +Wed Jan 3 17:06:07 GMT/BST 1996 + + * Added a manual page in the Doc directory. This is not + installed by default. + -- Mike + + * Fixed a problem in the .comment parsers in binfmt_elf.c + and binfmt_coff.c where a number of pages was passed to + __get_free_pages() instead of a binary power. This has + been in release versions of binfmt_coff.c for a long + time but exactly one person has reported anything that + might be attributable to it. Strange, since the bug should + have manifested itself as insidious memory leakage and + corruption... + -- Mike + + +Wed Jan 3 12:16:47 GMT/BST 1996 + + * Removed all kernel patches in the Patches directory. None + should be need for kernels 1.3.50 (or earlier?) and onwards. + None should be essential for 1.2.13 - although some capability + is lost notably SCO OpenServer 5 ELF binaries (if the kernel + ELF loader is present) and BSD a.out binaries. + -- Mike + + * Another fix to termio[s] ioctls to get the control character + settings right for SVR4. Previously this was just copied + from the SCO mapping and just never got changed. + -- Mike + + +Thu Dec 14 10:41:36 GMT 1995 + + * Added basic getpmsg/putpmsg support. It doesn't do anything + with bands but we don't have anyway to use them. + -- Mike + + +Tue Dec 12 09:38:01 GMT 1995 + + * First commit of the major TLI rewrite for Eric Sixt. This + should be enough for normal TCP & UDP clients. It may be + sufficient for servers as well but this is untested so far. + The client stuff has been tested with SCO cu, ISC telnet + and custom test code down to the getmsg/putmsg level. A shared + libnsl_s is also included. This has the functions needed for + clients but lacks some needed for servers currently. It has + been tested on a real SCO system. It could be done better + (and should be) but for now we are interested in making existing + programs work rather than handling all the error conditions + by the book. The library uses SVR3 shared library tools and + needs to be built on an SVR3 system (I used SCO). + Included is a rewrite of the /dev/spx kludging (the old didn't + work if TLI was enabled). This now allows connections to other + than /tmp/.X11-unix/X0 (if configured) so you can run multiple + X servers on the VCs and display SCO X programs on all of them. + The major/minor numbers used for the emulation devices have + (necessarily) changed. The top level Makefile will (re)create + them on a "make install" or "make devices". + Oh yeah, I built stubs for other libraries as well (specifically + SCO/SecureWare protlib_s) but don't expect it to have any real + support. If programs _really_ need stuff from there they are + like to have reduced or completely broken functionality on + Linux! + The script I used to generate the skeleton APIs for the + shared libraries is libs/mkltab if anyone feels the urge to + look at other libraries... + -- Mike + + * Removed the old quota compile option. It isn't compatible with + the quota stuff in 1.3.46 and would only cause confusion. This + means you can't use iBCS if you have the old quota patches + in a pre-1.3.46 kernel. Tough :-). + -- Mike + + +Mon Dec 11 15:14:46 GMT 1995 + + * Map I_SETSIG/I_GETSIG to FIOSETOWN/FIOGETOWN and pray... + -- Mike + + * Fixed possible memory leak in COFF & ELF personality recognition + when the offset/size of the .comments section is invalid. This + could leak when the .comments section exists but is zero bytes + long I think. + -- Mike + + +Wed Dec 6 11:31:27 GMT 1995 + + * A stat of a file must give an inode that matches what we get + from a read of the directory since code that figures out cwd + needs the inodes to match. Mind you, if there are several inode + numbers greater than 65534 in the directory we are going to get + some strange paths. I don't know if this is fixable properly at + all? + -- Mike + + * Yes it is. We just mask off the high word to get the short + inode number for the stat structure. + -- Mike + + +Thu Nov 30 16:21:32 GMT 1995 + + * Fix the SVR4 additions to the V7 terminal ioctls. Add handling + of TIOC[GS]ETD. Have TIOCL[GS]ET trivially succeed (I can't + find the documentation for the arguments). + -- Mike + + +Wed Nov 29 12:57:42 GMT 1995 + + * Changed the guesswork svr4_waitsys to implement the correct + waitid syscall. + -- Mike + + * Enable the i486-linuxaout option in x286emul/Makefile by + default. There seem to be significant numbers of people + using ELF compilers now. This may be a mistake... + -- Mike + + * Fixes to sigsuspend and sigpause in signal.c. The previous + invocations of the Linux sigsuspend syscall were wrong and + liable to lead to random freeze ups of programs which used + sigsuspend() or sigpause(). + -- Mike + + +Fri Nov 24 11:03:01 GMT 1995 + + * Interactive SVR4 seems to be overloading the BSD termio + ioctls with its own. + -- Mike + + * The SVR4 procid subcodes don't match the SCO ones. Or, at + least, I seem to remember I got the orignal set from SCO + and UnixWare and Interactive SVR4 are different (but match + each other). + -- Mike + + +Thu Nov 23 17:21:56 GMT 1995 + + * Interactive SVR4's /bin/sh calls access(..., 011) but Linux + returns EINVAL if the access mode has any other bits than + 007 set. So we have to wrap it and mask it :-(. + -- Mike + + +Wed Nov 22 10:11:49 GMT 1995 + + * Change to binfmt_elf.c to set total_vm value introduced in + kernel 1.3.43. + -- Mike + + +Thu Nov 16 15:02:58 GMT 1995 + + * Added support for SCO OpenServer 5 binaries using .comment + section parsing as with COFF. + Built a BSD capable a.out loader as part of iBCS. + The iBCS ELF loader is only used for recognised (using + .comments) binaries if the standard ELF loader is configured + in the kernel iBCS is built against. If the ELF loader is + not configured in the kernel iBCS is built against the iBCS + ELF loader is used for all ELF binaries. This prevents the + iBCS module from becoming un-unloadable on ELF based Linux + systems. + Similarly the iBCS a.out loader tries to avoid dealing + with anything other than BSD binaries for the same reasons. + This requires a kernel 1.3.42 or greater to allow iBCS + to insert its loaders into the list before the standard + kernel ones. Kernels 1.3.39(~) to 1.3.41 have some support + but there are bugs which will likely prevent you running + *anything* as soon as iBCS is loaded. Mea culpa. Tough. + -- Mike + + +Thu Nov 16 11:00:08 GMT 1995 + + * Minor clean up in binfmt_coff.c and fix a minor bug in + parse_comments that caused it to miss checking a string + if there was a zero length string in among. + -- Mike + + +Fri Nov 10 12:22:05 GMT 1995 + + * Changes for latest module bogosities (~1.3.38). We need to + define __NO_VERSION__ to avoid linux/module.h putting + a kernel_version in *every* damn file. + -- Mike + + +Tue Nov 7 10:55:05 GMT 1995 + + * When stealing temp space from the stack we have to actually + move esp down and then restore it as the 1.3.x kernels add + a check to trap out of bounds stack accesses. This is not + tested but I think it only affects the TLI emulation code + which is disabled by default. + -- Mike + + +Mon Oct 9 11:22:29 BST 1995 + + * Use kernel readv/writev if available. + -- Mike + + +Thu Sep 14 12:21:48 BST 1995 + + * Changed references to current->sigaction to allow for the + changes in kernel patch 1.3.26 which allow sharing of signal + state between clone processes. + -- Mike + + +Mon Sep 4 10:04:22 BST 1995 + Originally: Wed Aug 2 09:57:56 GMT 1995 + + * Removed Xenix interrupt bug, created wait() workaround + for INFORMIX-SQL and built the locking() to fcntl() + mapping. + -- Peter + + +Wed Aug 30 09:19:54 BST 1995 + + * Merged kernel patch for binfmt_elf.c from 1.3.21 which sets + EDX to zero on process start up. See the comment in the code + for reasons. + -- Mike + + +Tue Aug 29 08:44:50 BST 1995 + + * Workaround. Local X won't work because a putmsg occurs + after we have already swapped the open descriptor for a + Unix domain socket. We either need to peek at socket + internals or actually implement the messages for passing + file descriptors. This quick fix enables local X connections + if we build without XTI support. + -- Mike + + +Tue Aug 8 11:36:41 BST 1995 + + * Fix streams kludging so local X works again (should do + anyway - it's untested as yet due to hard disk collapse. + Hopefully someone will tell me if it doesn't work.) + -- Mike + + +Mon Jul 31 13:25:58 BST 1995 + + * Changes to allow compilation in the presence of a kernel + built with the quota patches. + -- Dimitrios Mpougoulias + + +Tue Jul 18 09:01:53 BST 1995 + + * Fixed timod getinfo ioctl. This functionality should move + into the message handling as bind has. + -- Mike + + +Mon Jul 17 10:16:43 BST 1995 + + * Added handling of BSD-ish sgtty ioctls. For some reason the + SVR4 network programs such as telnet have been modified to + pushd the ttold STREAMS modules and use sgtty calls instead + of simply using termio[s]. Don't blame me! :-) + -- Mike + + * Restructuring of timod.c complete. Timod ioctls now use + message routines to avoid duplicating code. + -- Mike + + +Wed Jul 12 14:44:30 BST 1995 + + * Made debug output in binfmt_coff.c less verbose. We only + really care about matched comment strings. If we dump them + all here we overrun the kernel message buffer and miss + interesting stuff when the program actually starts running. + -- Mike + + * Changed __get_free_pages in binfmt_coff.c to give the extra + argument required in 1.3 kernels. + -- Mike + + +Tue Jul 4 11:48:27 BST 1995 + + * Restructure timod.c ready to rewrite timod_ioctl to use + putmsg/getmsg rather than reimplementing the same message + protocol again. + -- Mike + + +Mon Jul 3 13:41:49 BST 1995 + + * Initial TLI support for outgoing TCP and UDP. Merged BSD/Wyse + socket ioctl handling with the socksys handler. Fixed (some) + bugs in poll() emulation. Devices in /dev/inet have changed + to support TLI access. See README for details. + -- Mike + + +Tue Jun 27 09:00:02 BST 1995 + + * Don't export symbols from iBCS. I'm not sure when register_symtab + was introduced so we only drop our symbol table in 1.3 + and later. + -- Mike + + * Added missing brackets in binfmt_elf.c as per kernel + patch 1.3.4. + -- Mike + + +Thu Jun 22 13:09:49 BST 1995 + + * Big step forward with TLI. I now seem to understand what is + happening when and have enough to do the initial open and + get info requests. This may one day actually work... + -- Mike + + * Trap EUC ioctls and return EINVAL. We don't do EUC :-). + -- Mike + + * Changes for the 1.3 development kernel. This compiles but is + as yet untested. It still seems ok with 1.2.10. + -- Mike + + +Wed Jun 14 09:15:39 BST 1995 + + * Added Eric's protection mapping fixes to binfmt_elf.c + from 1.2.10. + -- Mike + + +Fri Jun 9 12:31:53 BST 1995 + + * Linux can't stat unmounted filesystems but SCO can (by + specifying the pathname/fd of a block device and the + filesystem type. Linux will just stat the filesystem + that the device node is on (i.e. the root filesystem). + There isn't much we can do about it. I just lie and + claim there is 100MB free of 1GB. I hope this won't + cause too much grief... + -- Mike + + +Thu May 18 12:06:50 BST 1995 + + * When trying to get an IP domain name don't try the utsname + domainname if it is "(none)". If we get that far we have to + give in and return a blank domain name. + -- Mike + + +Wed May 17 10:15:42 BST 1995 + + * Recheck the socket functions when accept returns a new socket. + This is pedantic at this stage since we must have had a + socket initially and the current kernel code isn't likely + to handle removal and reloading of in use modules. iBCS + can handle this happening to it though :-). + -- Mike + + * Fix timod faking to correctly return an error if given an + invalid file descriptor rather than trying to dereference + a null pointer in kernel mode. + -- Mike + + +Tue Apr 25 11:35:43 BST 1995 + + * If nap() is given a zero timeout return immediately rather + than blocking indefinitely. Ensure that SIGALRM is not ignored + during the pause or we never get woken up by the timeout. + -- Mike + + +Mon Apr 24 09:21:30 BST 1995 + + * Various documentation updates from Eric. + -- Mike + + +Fri Apr 21 14:34:25 BST 1995 + + * Fixes to IPC. Now it really *should* work... + -- Mike + + +Thu Apr 13 14:03:45 BST 1995 + + * Tidy up documentation ready for new release. + -- Mike + + +Wed Apr 12 11:07:52 BST 1995 + + * Moved to an ELF development system with a GCC 2.6.4 snapshot. + This pointed out a few signed/unsigned mismatches so I + fixed them. We also have to ensure that x286emul is built + as a QMAGIC a.out because it won't work any other way. It + isn't likely to work any other way unless someone pays for + for it to be done - it isn't what you might call a "sexy" + project... + -- Mike + + +Wed Apr 12 08:53:22 BST 1995 + + * Added the kernel patch to handle statically linked SVR4 ELF + binaries to the Patches directory since it doesn't seem to + have made any of the 1.2.x patches yet. + -- Mike + + +Tue Mar 28 09:55:38 BST 1995 + + * Made the ISC specific stuff optional via CONFIG. + -- Mike + + * 1. INTERACTIVE UNIX signal numbers are different from IBCS2. + I added new signalmaps and exec_domains. + 2. setpgrp does not deattach the controlling terminal. + Try the setpgrp test program included here after the patch + on real SCO or xxxx and Linux/IBCS2. + 3. sigset behavior is incorrect. Test program also included. + Short description: signal handlers registered whith sigset + should run with the signal blocked, and after return + the handler must be restored, so sa_flags = 0 + is the correct setting. + Calling sigset should remove the signal from the + blocked set. + -- Remete Gabor + + +Fri Mar 24 10:20:57 GMT 1995 + + * Set the fragment size to zero for [f]statfs() just to be + pedantic (SCO does this). + -- Mike + + +Tue Mar 21 10:24:14 GMT 1995 + + * Fixes to 286 overlay and x.out loader by Don Camp + . + -- Mike + + * New code for SVR4 {get,set}groups since SVR4 uses longs + for gids whereas Linux uses shorts. + -- Mike + + +Mon Mar 20 17:06:23 GMT 1995 + + * Added code for waitsys(). This is guesswork at this stage + but appears sufficient for ISC 4.0 ksh to do something + reasonable in the simplest case. + -- Mike + + +Tue Mar 14 09:44:13 GMT 1995 + + * Initial implementation of ptrace. This allows programs + (SCO and Wyse V/386 programs) to access a process' + registers but actual tracing semantics will be difficult + to make functional. + -- Mike + + * Alter emulate return to allow return of numbers > 2^^31 + which don't fall in the error code space. + -- Mike + + * Added signal mapping to wait() syscalls. + -- Mike + + * Updated the main README with the vger mailing list details + and a few other tidy ups. + -- Mike + + +Thu Mar 9 10:10:53 GMT 1995 + + * Added a load more system calls to the SVR4 tables (these + match UnixWare at least I think). Some of these may work, + some are just marked to shut up run time warnings. + -- Mike + + * Increased the size of the buffer used for parsing comment + sections in binfmt_coff.c to 8k (from 1k). There are + programs out there that need it. + -- Mike + + +Tue Mar 7 16:12:36 GMT 1995 + + * More XLI/TLI changes - mostly fixes. + -- Mike + + * Added basic handling of the termiox extension used by SVR4 + to give access to hardware flow control. Only RTS & CTS + or nothing is allowed because that's all Linux does. The + same comments as below apply to the status of this. + -- Mike + + * Rework ioctl handling for termios. SCO uses short in a termios + structure, SVR4 uses longs. The bit shuffling used for SVR4 is + the same as for SCO - there are known to be some slight + differences but these are not believed to be critical for + most things. A large amount of guesswork went in to this. + One day I may be able to test it... + -- Mike + + +Mon Mar 6 12:31:05 GMT 1995 + + * Added a -DMODULE to iBCSemul/Makefile to make new style kernel + modules work. + -- Mike + + +Fri Mar 3 15:04:14 GMT 1995 + + * Patches from Eric. (Use Eric's [f]statvfs instead of mine). + -- Mike + + +Thu Mar 2 11:46:03 GMT 1995 + + * Fixed a silly in the handling of SO_IMASOCKET and SO_PROTOTYPE + plus added a check on the given buffer length. + -- Mike + + * Fixed a silly in the sockopt.inc options mapping. + -- Mike + + +Wed Mar 1 14:20:06 GMT 1995 + + * Added SVR4 console keyboard mapping and termcap/terminfo + options to the PROD.Patches directory. + -- Mike + + +Mon Feb 27 13:30:17 GMT 1995 + + * Added simpleminded implementation of [f]statvfs(). + -- Mike + + * [f]statfs() now respects the length argument to allow for + older/smartass code which uses a smaller buffer size. + -- Mike + + +Fri Feb 17 10:33:23 GMT 1995 + + * More tidy up, a little more work on TLI/XTI (still nowhere + near usable), fixed the signal debugging messages so it + makes more sense. + -- Mike + + +Thu Feb 2 12:45:25 GMT 1995 + + * Changed the BSD termio ioctl handler to recognise the fact + that some provide V7 compatibility and may be invoked from + non-BSD binaries - possibly without BSD size encoding. + -- Mike + + * Changes for 1.1.88. More definitions moved around in the + Linux header files :-). + -- Mike + + +Fri Jan 27 10:12:51 GMT 1995 + + * Also mapped new Linux SIGIO to iBCS SIGIO and changed Linux + SIGURG to map to SIGUSR1 as documented in SCO's TCP/IP + programmer's guide. Is SVR4 the same? How badly do we care? + -- Mike + + * Had to add a new personality for Xenix binaries since they + have a different number for SIGPOLL - sigh... + -- Mike + + +Mon Jan 23 15:34:01 GMT 1995 + + * Changes to includes for 1.1.84. + -- Mike + + * Change to binfmt_elf.c from kernel patch 1.1.84. + -- Mike + + +Tue Jan 17 17:10:25 GMT 1995 + + * Added tracing of argument and environment vectors passed + to exec(). + -- Mike + + +Mon Jan 16 11:34:58 GMT 1995 + + * Change socksys.c for 1.1.81. There doesn't seem to be a + convenient define to test but I intended to roll out + most of the "magic" define testing for 1.2 to clean + things up. + -- Mike + + * Ensure the segment registers are correctly set up when we + exec a new program - the LDT we may have been using before + no longer exists. + -- Mike + + +Fri Jan 6 11:32:52 GMT 1995 + + * Fixed a problem where the Xenix 286 emultor wasn't getting + the correct return and error codes from lcall7s. + -- Mike + + * Added support for exec() in the Xenix 286 emulator. + -- Mike + + * Made the spin-before-launch trap in binfmt_xout.c settable + via a trace option, "xout-block". This is used to attach + gdb to a 286 process to debug the emulator. + -- Mike + + * Fixed a problem with binfmt_xout.c setting the wrong intial + brk value for impure segmented binaries. The checks for brk + collisions with mapped space were failing brk changes. Before + the brk checks were introduced I image we simply trashed + text or data... + -- Mike + + +Thu Jan 5 11:21:51 GMT 1995 + + * Added some debug to the STREAMS I_PUSH and I_POP. Also made + them succeed without actually doing anything. We may be able + to work round some instances of STREAMS usage one day... + -- Mike + + +Wed Jan 4 11:17:14 GMT 1995 + + * Change yesterday's mkdir to use getname()/putname() to + fetch the pathname from user space. I hadn't realised + these were already in ksyms.c (although how long have they + been there? This breaks compatibility with older versions + of the kernel I guess). + -- Mike + + * Implement the NIOC ioctls for getting file handles since + Oracle's TCP server seems to be wanting to do this for some + reason (why???). This is a simple implementation that simply + fills in the device number of the filesystem and the inode + number of the file. This seems to agree with what SCO is + doing. I don't know what the "exported" fields are or should be. + -- Mike + + +Tue Jan 3 14:31:13 GMT 1995 + + * POSIX says that a pathname ending with a '/' means the current + directory whereas SYSV drops the trailing slash. This is only + a problem with mkdir() I think. + -- Mike + + +Fri Dec 16 16:25:44 GMT 1994 + + * Added basic support for Wyse V/386 MPX syslocal(). + -- Mike + + +Fri Dec 9 09:14:04 GMT 1994 + + * Changed eaccess() again. We should always set the uid/gid + rather than fsuid/fsgid since the Linux access() call is + getting fsuid/fsgid from the current uid/gid. + -- Mike + + * Don't bother trying to read x.out segments which have no + data in the executable. + -- Mike + + +Thu Dec 8 11:51:06 GMT 1994 + + * Only include if hasn't + defined KERNEL_DS. The header in the linux subdirectory + was obsoleted in 1.1.69. + -- Mike + + +Fri Dec 2 13:50:03 GMT 1994 + + * Force QMAGIC format when building x286emul. + -- Mike + + * Patches for 1.1.69. + -- Mike + + +Thu Dec 1 13:50:37 GMT 1994 + + * Binfmt_xout.c now checks the trace flag to see if debug messages + should be produced. Trace now has an "xout" option. Trace is + now a Linux binary which uses a personality() syscall to enable + emulation so the iBCS trace syscall becomes accessible. + -- Mike + + * Changed binfmt_xout.c to use 0x1020 as the entry point for + the x286emul kludge overlay. This is the expected value + for a QMAGIC binary which is the default with the newest + compiler. Really I think uselib() should return something + useful but I haven't decided what. + -- Mike + + * Made the schedule() trap (so gdb can be attached before the + process starts running) in binfmt_xout.c a CONFIG option + controlled by the XOUT_TRACE setting. + -- Mike + + * Moved the configuration for the optional items out of Makefile + and into CONFIG. + -- Mike + + +Wed Nov 30 17:08:05 GMT 1994 + + * Fixed a nasty bug in binfmt_coff.c where an extra page was + being allocated in the bss causing brk() checks in 1.1.64 + and later to fail _in_certain_circumstances_. + -- Mike + + +Wed Nov 30 13:58:46 GMT 1994 + + * Added support for unpacking ioctls passed via the STREAMS + interface and forwarding them to the file descriptor. With + a slight change to socksys so that devices with minor 2 get + an anonymous dgram socket immediately they are opened this + allows many more network programs to work. Thanks to an old + piece of code from Chip Rosenthal for revealing how it all + worked - it isn't in the documentation :-). + -- Mike + + +Wed Nov 30 11:27:56 GMT 1994 + + * Fixed handling of brk and BSD sbrk so error returns are + handled correctly. + + +Mon Nov 28 10:48:25 GMT 1994 + + * When doing an IPC_STAT on a semaphore force the semaphore + number to be zero as the kernel code erroneously checks + it. + -- Mike + + +Fri Nov 25 14:26:41 GMT 1994 + + * Massive rework of ipc.c. The previous one was buggy as hell. + This one works with all the demo programs from the Wyse V/386 + IPC documentation. Hopefully someone is going to test it with + some *real* applications! + -- Mike + + +Tue Nov 22 09:11:46 GMT 1994 + + * Change the TTYDEVTYPE ioctl to say we on a pseudo terminal + rather than a console. Anything calling this is likely to + want to try fancy stuff like mapping the console memory + and playing with I/O ports if it thinks we are on a console. + -- Mike + + +Tue Nov 22 09:07:04 GMT 1994 + + * Allow direct usage of 57600 and 115200 serial speeds from + the BSD domain with kernels 1.1.65 and later. + The mask-and-merge for iBCS<->Linux termios should be checked + as we tend to try and preserve unmappable bits where there + is no other conflict. In 99% of cases we won't see a problem + though... + -- Mike + + +Mon Nov 21 10:05:19 GMT 1994 + + * Slight change to previous patch. Confusion over which struct + size we should be using for the verify_area plus we need to + do a VERIFY_WRITE as we will rewrite the data before returning. + -- Mike + + * Changes to ipc.c for reading structures from user space. + -- Roberto Bagnara + + +Thu Nov 17 15:24:23 GMT 1994 + + * Some of the unused KD ioctls were removed from Linux 1.1.64 + (or was it 63?). Changed vtkd.c accordingly. + -- Mike + + +Fri Nov 11 14:15:09 GMT 1994 + + * Moved the x286emul overlay to /usr/lib instead of /lib. There + is no real need for this to be on the root filesystem. + -- Mike + + +Mon Nov 7 13:51:55 GMT 1994 + + * Added a version of the BSD exec.c patch for Linux 1.1.62. + -- Mike + + * Extended SCO keyboard mapping for new kbd. + -- Mike + + +Tue Nov 1 10:57:18 GMT 1994 + + * Changed the personality test in the BSD kernel patch. Apparently + FreeBSD uses a machtype of 134 so it's safer to test for Linux + rather than BSD. + -- Mike + + +Fri Oct 28 11:25:43 GMT 1994 + + * General clean up of the configuration options in the Makefile + and elsewhere. It is now possible to choose which loaders are + included and whether or not BSD or Xenix 286 emulation is + required. + -- Mike + + * Added the x286emul overlay library. This is still very alpha + but SCO's /bin/masm seems to do the things expected of it :-). + -- Mike + + +Wed Oct 5 17:00:13 BST 1994 + + * Fleshed out the F_CHSIZE and F_RDCHK fcntls. I still don't + know if these are ever used from the user layer. + -- Mike + + +Tue Oct 4 13:17:32 BST 1994 + + * Fixed the BSD termios mappings. This _looks_ ok from the + point of view of the NetBSD stty. + -- Mike + + +Fri Sep 23 11:08:31 BST 1994 + + * Add SCO ODT version of CorelDraw to COMPAT file. + -- Doug Ledford + + +Thu Sep 22 09:25:04 BST 1994 + + * Added the phone numbers of McGraw Hill's order desk to the + README file. + -- Mike + + * chsize() was causing a segment error. The callmap entry punted + to a Linux system call but the argument count was not negative + resulting in a call to a bad function pointer. + -- Mike + + * Linux doesn't have the l_sysid field in struct flock so we need + to slide the l_pid field down a word after doing a locking + fcntl. + -- Mike + + +Tue Sep 20 10:31:01 BST 1994 + + * Added a simplistic implementation of writev since BSD seems + so keen to use it as much as possible. + -- Mike + + * Fixed the x.out loader (mostly). This requires a minor patch + to the kernel. Expect this to be put in to the kernel itself + sometime after 1.1.51. Segment support is still buggy and + therefore disabled. If programs assume they know what segments + exist it they are broken anyway! + -- Mike + + +Wed Sep 14 11:24:18 BST 1994 + + * Added extra fcntl code 14 (used by SVR4 for GETLCK). + -- Mike + + +Tue Sep 6 10:58:49 BST 1994 + + * Added setting of fsuid/fsgid to the loaders and changed the + eaccess() function in xnx.c to flip fsuid/fsgid rather than + uid/gid. If you were having problems with setuid/setgid iBCS + binaries this is likely to help. + -- Mike + + +Mon Sep 5 15:07:06 BST 1994 + + * Fixed the bad initialisation of howcnv in signal.c. + -- Mike + + +Fri Sep 2 11:01:26 BST 1994 + + * Added a little program to the Tools subdirectory which will + restamp old binaries with the Linux machine type rather than + zero which is used by BSD. Once this is done you can reliably + distinguish between BSD and Linux binaries (the current Linux + linker will set the correct machine type on all new binaries). + -- Mike + + * Updated the BSD patch. + -- Mike + + * Changed binfmt_coff to avoid passing meaningless MAP_DENYWRITE + and MAP_EXECUTABLE flags to mmap when we are not actually + mapping from a file. It would probably never be a problem... + -- Mike + + +Tue Aug 23 17:21:45 BST 1994 + + * Added my device trace stub in case anyone needs to investigate + and emulate some special device. + -- Mike + + +Wed Aug 17 14:06:34 BST 1994 + + * Added an extern definition of the formats list needed by + the 1.0.x hooks. Presumably this went AWOL at some stage? + -- Mike + + +Fri Aug 12 09:52:38 BST 1994 + + * Slight change to the socksys major allocation. Removed + redundant error message. + -- Mike + + +Wed Aug 10 08:57:32 BST 1994 + + * Added the spelling corrections from the 1.1.42 kernel patch. + -- Mike + + +Fri Aug 5 10:05:14 BST 1994 + + * Added Scott Michel's SCO multiscreen patches. + -- Mike + + * More changes to loaders for latest kernel changes. + -- Mike + + +Wed Jul 27 10:59:14 BST 1994 + + * Changes for 1.1.36 vm/mprotect. + -- Mike + + +Tue Jul 26 14:20:27 BST 1994 + + * Tidied up the system call maps a little. ISC is now handled + by the same maps as SCO. + -- Mike + + +Wed Jul 20 12:39:55 BST 1994 + + * Removed the lock.patch. This is in the latest kernels. + -- Mike + + * Changed the socksys/SCO utsname stuff to do the right thing + if we have the hostname set to the fqdn and the domainname + set to the NIS domain. If hostname is not an fqdn we assume + we are using the domainname == IP domain convention. + -- Mike + + +Wed Jun 29 13:34:34 BST 1994 + + * Revised the lock.patch to fix the unlock problem and allow + locks on devices. This should go to Linus (and probably has). + -- Mike + + * Removed the kernel 1.1.20 patch. This isn't needed as of + 1.1.22. + -- Mike + + +Mon Jun 27 09:26:24 BST 1994 + + * Can't use select() for nap() since the Linux select system + call expects to pull its arguments from the user stack. + Rewritten nap() using itimers. + -- Mike + + * More fixes from Eric for 1.0 compatibility. + -- Mike + + +Fri Jun 24 09:37:50 BST 1994 + + * Added a bit about time zones to the HINTS file. + -- Mike + + * First draft of BSD termios mapping. Still buggy. Needs + work to be useful. + -- Mike + + * Fixed BSD getdirentries() to align dirents on long word + boundaries. 'ls' now works and 'tcsh' finds and executes + commands successfully. + -- Mike + + * ibcs_exit should be listed in callmap.inc with arg count 1 + not -1. + -- Mike + +Thu Jun 23 09:48:43 BST 1994 + + * Lots more BSD-ish stuff. Commit now for release since there is + confusion over versions at the moment. + -- Mike + + * List Xess MOTIF spreadsheet in COMPAT file. + -- Michael K.Johnson + + * When slurping in mis-aligned COFF binaries we shouldn't be + aligning the file offset and virtual address to a page + boundary! + -- Mike + + * Merged Eric's latest patches for 1.0 compatibility and Linux + ELF capability. This was done by hand. I think it's perfect... + -- Mike + + +Wed Jun 22 14:28:38 BST 1994 + + * Many sigsuspend entries in the callmap had argumetn counts + of 1 instead of Spl. This caused kernel faults. + -- Mike + + * Implemented the ioctls for the pseudo nfs device which under + SCO is used to get/set the NIS domain. You need to link + /dev/nfsd to /dev/socksys. + -- Mike + + * The socksys getdomainname() was doing the same write null to + kernel space instead of user space as the wysev386 version. + -- Mike + + +Tue Jun 21 08:54:34 BST 1994 + + * Use the map_bitvec() function (added as part of the BSD changes) + in signal.c. Note that there were quite a few mapping bugs in + the old code. I think I got them all but few would have been + triggered by my SCO and Wyse stuff. + -- Mike + + * Snapshot BSD stuff again ready for release. + -- Mike + + * binfmt_coff.c and binfmt_xout.c should be using mmap(NULL,...) + instead of zeromap_page_range as this will create the vm area + descriptor as well as mapping the pages. This is needed for + the verify_area() in 1.1.20 which has tighter checks than + previous versions. + -- Mike + + * Map stack region as a GROWSDOWN vm area in binfmt_elf.c + -- Mike + + +Fri Jun 17 16:42:59 BST 1994 + + * Major and on going work to add BSD support (optional - see the + Makefile). I'm committing this now so I have a current tree + ready for release when Linus goes to 1.1.20. + -- Mike + + * Wyse get{host,domain}name were using direct assignment to add + a trailing null instead of put_fs_byte(). Oops... + -- Mike + + * Changes for execution domain support which will be in the main + kernel as of 1.1.20. This allows easy registration of lcall7 + handlers, binary loaders etc. for different personalities. + -- Mike + + +Fri Jun 10 10:12:55 BST 1994 + + * Added patch file for kernel locking from Niklas Hallqvist + . This (or something very similar) should + end up in the kernel at some stage. + -- Mike + + * Merged Eric's changes for 1.0 compatibilty - or rather didn't. + After playing with diff for quite a while I finally realised + we'd both done exactly the same changes :-). However Eric + has tested them... + -- Mike + + * Added Brandon's iBCS trace binary from Eric's 1.0 compatibility + release. + -- Mike + + +Thu Jun 9 10:22:56 BST 1994 + + * Mapped msgsys to ibcs_msgsys in callmap.inc. It existed, we + just didn't admit it before :-). + -- Mike + + +Tue Jun 7 08:50:34 BST 1994 + + * Sorted out some more ioctl stuff and added a handler for the + STREAMS ioctl set. This is needed for I_NREAD (number of + characters readable). Some SYSV X libraries contain implicit + assumptions that the X connection is via a STREAM and use + I_NREAD in preference to BSD/socket FIONREAD. + -- Mike + + * Oh, Jeez... The changes made for the official kernel patches + completely shafted the 1.0 compatibility. I've remerged the + previous code with the new code - there may still be some + things that need pulling back though. At this point I don't + have a 1.0 kernel tree around to test against. + -- Mike + + * If a COFF program is not correctly aligned disable demand + paging and resort to slurping the whole lot in at start up. + -- Mike + + * Added missing -I../include to the Tools Makefile. + -- Mike + + +Fri Jun 3 11:53:21 BST 1994 + + * Added my virtual system tools. A virtualised SCO 3.2.4 + system is usable for real work for me... + -- Mike + + * Added the synchronous ioctl set. This conflicts with the + SCO 3.2.x (x < 4) ioctl for getting the video map so it should + be dependent on the file descriptor it is applied to but since + we don't currently support either... + -- Mike + + +Thu Jun 2 17:02:26 BST 1994 + + * Added support for FIORDCHK ioctl. SCO says it's there for + "backward compatibility" but the system programs still + seem to use it (notably ksh). + -- Mike + + +Tue May 31 13:39:34 BST 1994 + + * Patches to sysfs.c for 1.0.x compatibility from Tor with + some extra clean up. + -- Mike + + +Fri May 27 09:15:21 BST 1994 + + * Ensure we set up signal() handlers as SA_ONESHOT and sigaction() + handlers as sticky - similar to patch from Remete Gabor. + -- Mike + + * Added the SCO cxenix sigaction extensions. Barely tested... + -- Mike + + * Added the cxenix {get,set}itimer calls discovered on SCO by + Brandon. Currently these are directly mapped to the Linux + syscalls. They are undocumented by SCO (as far as we know) + and untested by us (for now). + -- Mike + + +Thu May 26 11:58:18 BST 1994 + + * Don't include the 0.0.0.0 to localhost address mapping if we + are building for 1.1.15+. This is mapped in the kernel as of + 1.1.6 and since we don't support 1.1 kernels before 15... + -- Mike + + * Type of signal map vectors should be unsigned long not int. + -- Mike + + * Allow tracing to be compiled in to the COFF loader and turned + on and off with the Tools/trace program. + -- Mike + + * Signal maps moved out to maps/signal.inc. The only special + mapping that happens is for ISC which has a problem with + Oracle sending SIGSTOP to its backend when SIGSTOP doesn't + appear to be defined for ISC. We just map SIGSTOP to 0 so + it appears to work but does nothing. + -- Mike + + * Changes for 1.1.15. This will not work with kernels between + 1.1.10 and 1.1.14 inclusive - guaranteed. It should still + work with the 1.0.x series but has not been tested recently. + It probably works against 1.1.0 to 1.1.13 inclusive but that + is purely coincidence - you shouldn't be using old 1.1.x + kernels as it's a development series. + -- Mike + + +Tue May 24 17:27:54 1994 Eric Youngdale (eric@tantalus) + + * binfmt_xout.c: Use linux_binfmt struct, register_binfmt, + unregister_binfmt as in pl14. + + * binfmt_elf.c, binfmt_xout.c: Likewise. + + * signals.c: Make signals[] and lsignals[] global variables. + + * ibcs/include/ibcs.h: Add prototypes for signals[] and lsignals[]. + + +Tue May 24 10:37:01 BST 1994 + + * Added map entries for the ISC personality to all the maps + files. Must be more careful adding personalities. + -- Mike + + * Added Oracle to the COMPAT file. + -- Mike + + * Remember the problem with interrupting an Informix 4GL program + causing it to go psycho because of I/O errors from the tty? + Well, this doesn't happen with the new tty drivers in 1.1.13. + I never found why it happened... + -- Mike + + * Noted that the 1.1.11 kernel patches are still ok with 1.1.13. + -- Mike + + +Mon May 23 08:50:21 BST 1994 + + * Mapped ISC sysconf() to the existing Xenix sysconf(). This + looks right but isn't checked at all. + -- Mike + + * Added ISC TCSETPGRP and TCGETPGRP ioctl traps. + -- Mike + + +Thu May 19 09:26:34 BST 1994 + + * Added a bug hunting section to the README. + -- Mike + + * Always access the socket layer by picking up the file operations + from an open socket descriptor. This removes the need for + kernel socket functions to be global and should be friendlier + towards a loadable socket layer one day. + -- Mike + + +Mon May 16 10:20:38 BST 1994 + + * Always access system calls via the system call table regardless + of whether we are using a loadable module or linking directly + to the kernel. This allows other things to be loadable too. + -- Mike + + +Wed May 11 13:52:12 BST 1994 + + * Added a tip on how to fix X font problems to the HINTS file. + Other "soft" changes welcome. Does anyone read the ChangeLog? + -- Mike + + * Introduced the PROD.Patches directory and put the WP install + fixes in there. Documented in COMPAT and README. + -- Mike + + * Added some hints on incompatible shell behaviour. + -- Mike + + +Mon May 9 11:07:52 BST 1994 + + * Updated the 1.1 patch file for 1.1.11. + -- Mike + + * Additions for Interactive 4.0 + -- Karl Kiniger (ki@kretz.co.at) + + +Fri May 6 12:03:00 BST 1994 + + * Merged old sysfs.c with the new sysfs.c. The code will now + work against any kernel - 1.0, 1.1, 1.1.9, 1.1.10... + -- Mike + + +Thu May 5 10:39:52 BST 1994 + + * Reworked for compatibility with 1.1.10. Kernel patches + are *not* updated yet. We expect the kernel changes to go + in to the official distribution any time now... + -- Mike + + +Tue May 3 12:03:31 BST 1994 + + * Joe/Brad's IPC additions. + + +Fri Apr 29 10:06:10 BST 1994 + + * Updated the README to explain the difference between sysfs.c + and sysfs.c.old + -- Mike + + +Wed Apr 27 11:38:52 BST 1994 + + * Added mapping of chsize() to ftruncate(). Implemented nap() + using select(). + -- Mike + + * Further fix to termios mapping for iexten and tostop. + -- Mike + + * Updated the 1.1.? patch. New ksyms.c with fewer symbols plus + removed all the socket patches. Sockfunc.h is no longer + required. The 1.0 patch isn't updated but the extra cruft + that's in there now shouldn't be any problem. + -- Mike + + +Tue Apr 26 11:49:07 BST 1994 + + * Removed references to linux/sockfunc.h. We seem to have run + out of internal socket functions to put in it finally. + -- Mike + + * Removed use of socki_lookup(). This just wraps some checks + around inode->i_socket. We assume the socket layer is stable + by now... + -- Mike + + * Access [gs]etsockopt via the socketcall interface. + -- Mike + + * If we have to use our own CFLAGS look in the include directory + above in case we have been dropped in to the kernel. + -- Eric + + * Grab socket file operations when we create a socket rather + than linking against them directly. Similar to Eric's + changes but different... + -- Mike + + +Fri Apr 22 11:10:18 BST 1994 + + * The 'x' class of ioctls are back to being termios rather + than termio. The problem was that the field size in iBCS + termios and Linux termios is different. + -- Mike + + * Added iBCS <-> Linux termios mapping. This is untested and + probably imperfect at this stage but nothing crashes with + this code... + -- Mike + + * The iBCS time() syscall doesn't take an argument, the save, + if any, is handled in the interface library. + -- Mike + + * Updated the 1.1 kernel patch to be against 1.1.8. It won't + work with anything less than 1.1.8 but then if you are + playing with 1.1 you should be playing with the latest... + This involves a change in the way sysfs() works. If you + are using 1.0 and have applications that call sysfs() + (practically none do) then you need to build with sysfs.c.old. + -- Mike + + * The Linux kernel 1.1.8 replaces the static file_systems + table with a linked list ready for loadable file systems. + Naturally, I was ready for this... :-( + -- Mike + + +Thu Apr 21 10:34:34 BST 1994 + + * sysfs.c should be including linux/string.h to get the + inline string functions rather than needing library + functions. + -- Mike + + * Added code to map between Linux termio structs and SCO/iBCS + termio structs. There are slight differences. Mapping needs + to be done for termios structs too. Anything that uses termios + at this stage is likely to ge a nasty shock! + -- Mike + + +Tue Apr 19 22:56:55 1994 Eric Youngdale (eric@esp22) + + * ibcs.h: Put declaration of sys_call_table outside of ifdef. + (So can be compiled into kernel instead as a module). + + +Tue Apr 19 10:21:17 BST 1994 + + * It looks as though the 'x' class of ioctls should be termio + ioctls rather than termios. At least this is the case as far + as SCO 3.2.4 stty appears to be concerned. + -- Mike + + * Avoid copying the entire lock structure backwards and forwards + just to increment one field in open.c. There could be a problem + here - SCO has a sysid field *before* the pid field but only + if _XOPEN_SOURCE or _POSIX_SOURCE is defined at compile time. + There appears to be no obvious way to know what is being used??? + -- Mike + + +Mon Apr 18 08:49:37 BST 1994 + + * There appear to odd little niceties involved with SYSV which + depend on system configuration and the way users do things. + Added a HINTS file with known problems/workarounds. + -- Mike + + * Changed some annoying KERN_ERRs to KERN_DEBUGs in signal.c + -- Mike + + * Watch out for (mis)use of INADDR_ANY instead of localhost + (primarily by syslog() code?) and replace it with the + localhost address. We should perhaps do this for sendto() + as well? (Eric spotted this one on CorelDraw but it's a + problem with the standard libsocket.c) + -- Mike + + * Processes should be allowed to reduce their file size + limit but only increase it if they have root privileges. + -- Mike + + * Fixed the bug in [f]statfs where the first two arguments + to memcpt_tofs() were exchanged (spotted by Eric). + -- Mike + + * SCO seems to like utsys (v7_utsname) to return the same + thing for sysname and nodename fields just like the SCO + extended utsname structure has. The SVR4 (abi_utsname) + return is unknown at this time. + -- Mike + + * Removed comments on IPC from README. It *is* fixed? + -- Mike + + * Fix IPC which was broken by syscall changes. Also fix + structure mappings. + -- Joseph L. Portman III + + +Thu Apr 14 11:27:24 BST 1994 + + * At some stage SCO managed to build some of their binaries + with the copyright comment string in quotes so we have a + new recognition string in the COFF loader. (Seen in uname + on a 3.2.2 system). + -- Mike + + * If we have tracing compiled in then only give unsupported + syscall messages if we are tracing the API or the syscall + in question. This allows us to quieten unsupported but + unimportant syscalls. + -- Mike + + * Comment on the IPC limitations in the README file. + -- Mike + + * Added implementation of xnx_pathconf(). Actually it doesn't + look as if we really need it. The Microsoft C compiler seems + to be misusing it anyway and doesn't even care that it gets + an error. + -- Mike + + +Wed Apr 13 09:14:50 BST 1994 + + * Added handling of TIOC[GS]PGRP. + -- Mike + + * Added implementation of xnx_eaccess(). This is currently + simpleminded because Linux access() is. My eaccess() may + even be wrong. + -- Mike + + * When tracing signal delivery we shouldn't be clearing the + signal flag after reporting it or the signal is never actually + delivered. I copied the assembler from the kernel and forgot + to deleted an opcode... + -- Mike + + * Signal 0 should have been identity mapped so kill 0 works. + -- Brandon S. Allbery (kf8nh@kf8nh.ampr.org) (bsa@kf8nh.wariat.org) + +Tue Apr 12 14:30:25 BST 1994 + + * Corrected file size passed to/from setrlimit/getrlimit + -- Graham Adams (gadams@ddrive.demon.co.uk) + + +Tue Apr 12 11:16:45 BST 1994 + + * Added support for an obscure SCO extension that is used + to get SCO's extended utsname information. + -- Mike + + * Changed ipc.c to always go via the ipc syscall rather than + direct to internal functions. This should survive if ipc + isn't in the kernel. It should even do sensible things if + the ipc module is loaded/unloaded on us. + -- Mike + + * Initial changes to access system calls via sys_call_table + -- Mike + + +05 April 1994 + + * Eric's pre-release fixes. + + +Wed Mar 30 22:35:28 1994 Eric Youngdale (eric@esp22) + + * ioctl.c: Change 'F' to 'f' for SVr4 FIONREAD ioctl. + + * Makefile: Add svr4.c. + + * svr4.c: New file (sort of - it got lost in shuffle before). + + * include/ibcs/ibcs.h: Include prototypes for abi_uname. + + * maps/callmap.inc: Insert abi_uname in syscall number 135. + Add sys_rename in slot 134 (emacs v18 requires this). + + +Tue Mar 29 23:32:35 1994 Eric Youngdale (eric@esp22) + + * Makefile: Fix so that we do not need uname. Use symbol from + .config instead. + + * README: Update a bit. + + +28 March 1994 + + * Preparation for release: + Tidy up documentation and create CREDITS file from the old + ToDo list. + -- Mike + + +27 March 1994 + + * Preparation for release: + Move headers into a subdirectory. + Move maps into a subdirectory. + -- Mike + + +25 March 1994 + + * Changed the COFF loader so that if the filesystem doesn't + support mmap we read in the whole lot initially and let + it page to swap if necessary. This is already in the x.out + loader, it should go in the ELF loader too at some point. + -- Mike + + +24 March 1994 + + * Added a loader for x.out i386 small model binaries - i.e 386 + Xenix programs. <=286, non-small model binaries are not + supported and not likely to be in the near future. + -- Mike + + +Wed Mar 23 23:12:54 1994 Eric Youngdale (eric@esp22) + + * Add ioctl for 0x4004667f (FIONREAD) (used by SVr4). + + * map.h (map_segment.map): Make unsigned. + + * hrtsys.c: New file implementing parts of the hrtsys syscall. + + +02 March 1994 + + * Add socket value mappings. This meant a general move round + to tidy things up and group map functions/tables. + There is a new kernel patch in the Patches directory called + net.patch which gives us access to the sock_*sockopts + functions directly. + -- Mike + + +28 February 1994 + + * Implementation of poll(). + -- Eric + + +25 February 1994 + + * Pedantic change to call maps so that IBCS_function contains + a void * instead of a function pointer - we cast it as + necessary later in emulate.c. The warnings were annoying me. + + * Moved struct abi_sigaction from signal.c to abi4.h so it is + available for prototype declarations. Changed prototype for + abi_sigsuspend to correspond to implementation in signal.c. + -- Mike + + * Reversed out Eric's earlier signal patches and added new ones. + -- Mike + + * Updated trace code and trace control program to be useful. + Control of tracing individual functions is still not there + yet - perhaps another day. + Default trace mode is now none (i.e. only functions with + the trace flag set are traced). Use the trace program to + change the trace level. + -- Mike + + * File modes (open/fcntl flags) are different between Linux and + iBCS so we need to map between them. Open also requires this + so fcntl.c is now merged with open.c. Failure to set and reset + non-blocking mode was what was breaking Unipox. + -- Mike + + * Signal handling function changes to map to and from the Linux + signal set and sigaction flags correctly. + -- Eric + + +24 February 1994 + + * Added code to the emulate() function to let us know when we + are about to process a signal on exit from the syscall. + -- Mike + + * Implemented proctl() as a no-op. It's not really relevent + under Linux. + -- Mike + + * Added argument count and type for eaccess() + -- Mike + + * Have emulate.c return -ENOSYS for unimplemented system calls + rather than zero. + -- Mike + + * Added Eric's patches to waitpid. + + * Created the ChangeLog! diff -Nru linux-2.6.7/Documentation/abi/COMPAT linux-2.6.7-abi/Documentation/abi/COMPAT --- linux-2.6.7/Documentation/abi/COMPAT 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/Documentation/abi/COMPAT 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,181 @@ +C: This file contains details of programs that have been run under +C: Linux using the iBCS emulator. An entry here is no guarantee that +C: the program works 100% but does indicate that the major elements +C: of the program have been unable to exercise bugs in the emulator +C: unless otherwise noted. +C: +C: An entry in this file does not necessarily indicate that the vendor +C: or anyone else actually supports the package under Linux unless +C: there is a specific entry to that effect. +C: +C: Please add to this file - new entries, other releases, amendments +C: to existing entries etc. +C: +C: The layout of this file is intended to be both easy to browse and +C: easy to parse, allowing it to be formatted into documents in the +C: future. This hasn't happened yet though and might never happen :-). +C: +C: Key: +C: C = Comment +C: V = Vendor +C: S = Support details +C: O = Operating system compiled for +C: P = Product +C: R = Release(s) known to work +C: L = Libraries required +C: D = Description +C: N = Notes +C: T = Tester + +V: Applied Information Systems, Inc. (info@ais.com) +O: SCO +P: Xess (MOTIF Spreadsheet) +R: current +L: statically linked +N: A save-disabled demo is available in ftp.uu.net:/vendor/ais/ +N: Get three files: README, gen.tar, and sco.tar. +N: Don't add a .Z or .gz to the end of the filenames; the files +N: inside are compressed. ~300K of online documentation is in +N: gen.tar. +N: If anyone decides to actually *buy* this product, *please* +N: mention that you will be running it under Linux. I promise +N: you that you will still get technical support (the majority +N: of our technical support staff run Linux at home) -- but if +N: enough people buy the product asking for a Linux version, my +N: employer will be willing to make the investment. Pass the +N: word on if you want to see a native-mode, high-quality +N: spreadsheet for Linux as much as I do... +N: michaelkjohnson +T: Michael K.Johnson + +V: Corel +O: SCO ODT +P: CorelDraw! 3.0 and friends. +R: 3.0 +N: Requires X11, no character versions of these apps. +N: Everything seems to be statically linked, no extra libs +N: necessary. I had a few problems with my .xmodmap file +N: since CorelDraw wants all of the lower function keys to +N: be mapped to functions in the CorelDraw program. Uses a +N: networked license manager, it worked fine. My programs +N: did not install properly due to an install bug. The dir. +N: that contains the washes.3fx file and others must be hand +N: changed to mode 777 for CorelChart to work (This from +N: Corel tech support). +T: Doug Ledford + +V: Informix +O: SCO +P: Informix SQL Standard Engine +R: 4.00 & 5.01 +L: /shlib/libc_s +T: Mike Jagdis + +V: Informix +O: SCO +P: Informix SQL Online Dynamic Server +R: 7.20.UD5 +T: Mike Jagdis + +P: Informix INET +R: ??? +N: INET is reputed to work too but I can't remember who +N: said that... +T: ??? + +V: IXI +O: SCO +P: X.desktop +R: ??? +L: /shlib/libnsl_s +N: The version of X.desktop tested is that shipped with +N: Uniplex Windows. Functionality is at least enough to +N: support Uniplex Windows. +T: Mike Jagdis + +V: Oracle +O: Interactive +P: Oracle +R: V6 +L: /shlib/libnsl_s +T: Remete Gabor + +V: Soft-Tek +O: SCO +P: Tactician Plus (character and X) +R: 3.0 +T: Brandon S. Allbery + +V: SPSS Inc. +O: SCO +P: SPSS 5.0 for SCO UNIX +L: Motif, if you want to use the GUI +D: Statistical Package for the Social Sciences +N: SCO's cpio is not compatible with GNU's -- I had to dd all +N: floppys onto my hd and to concatenate them into one file. +N: I couldn't test the GUI since I had no Motif available. +T: Joerg Rade + +V: Uniplex Limited +O: SCO +P: Uniplex / Uniplex Windows +R: 7.02 +L: statically linked (Uniplex Windows requires libnsl_s) +N: Uniplex Windows is implemented using a version of IXI +N: X.desktop. It is this that requires libnsl_s. +T: Mike Jagdis + +V: V-Systems, Inc. +O: SCO +P: VSI*FAX (FxServer, FxScript, FxVision) (character and X) +R: FxServer 2.0.19, FxScript 1.1.05, FxVision 1.0.16 +L: Statically linked +N: Needs localhost in the X server's access control list +N: even when using a local X connection. +N: This has not been tested with a modem connected as I +N: don't have a Multitech... +T: Mike Jagdis + +V: ViaCrypt +O: SCO +P: ViaCrypt PGP +R: 2.4 +T: Mark C. Henderson + +V: WordPerfect Corporation +O: SCO +P: WordPerfect (character and X) +R: 5.1 +L: Statically linked +N: Installation under Linux may require changes to some of +N: the WP install scripts. See the PROD.Patches/WP file +N: for details. +N: +N: WP uses a network license manager. +N: +N: For some reason WP use a partition floppy device rather +N: than the full block device. Linux does not have this so +N: you need to use dd to skip the first cylinder (track?) +N: when loading the floppies under Linux. See the HINTS +N: file for details. +N: +N: Fonts appear corrupt. See the HINTS file for a cure. +T: Mike Jagdis + +V: Z-Code Inc +O: SCO +P: Z-Mail +R: 3.2 +L: Statically linked - Motif based. +N: Installation scripts work correctly. +N: +N: ZMail can use a network license manager or a license file. +N: Both are known to work. +N: +N: ZMail is a GUI-based mail program. +N: +N: You can download the binaries for ZMail via anonymous ftp +N: ftp@ncd.com +N: You will have to contact Z-Code to obtain an evaluation +N: license if you wish to try it out. +T: Eric Youngdale diff -Nru linux-2.6.7/Documentation/abi/CREDITS linux-2.6.7-abi/Documentation/abi/CREDITS --- linux-2.6.7/Documentation/abi/CREDITS 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/Documentation/abi/CREDITS 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,79 @@ +A (non-definitive) list of people who appear to have worked on the +emulator and, in some cases, what they appear to have done. + +This list is in no particular order. + +This list should probably be better maintained :-). + +If anyone feels that they are not properly credited here, send diffs to +this file. + + +======================================================================== + +Brandon S. Allbery or + +Graham Adams + +Tor Arntsen or + Emulator as of pl13 + +Philip Balister + Emulator as of pl13 + gdb for coff + +Alfred Longyear + COFF loader + Emulator as of pl12 + Original author of libc_s. COFF version. + +Mike Jagdis + Changes for loadable module version of the emulator. + Multi-personality detection and syscall mapping. + Error code mapping. + Wyse V/386 socket interface. + /dev/socksys socket interface. + /dev/spx to Unix domain socket for local X connections. + Named pipe to Unix domain socket open kludge. + XTI/TLI STREAMS based networking interface. + X.out loader for 386 Xenix binaries. + BSD support. + Trace dummy device. + Segment (LDT) mapping for x.out binaries. + Xenix 286 emulator overlay. + Current source maintainer and primary developer. + +Joseph L. Portman III + Major emulator developer. + libc_s + +Drew Sullivan + Past emulator source maintainer. + +Eric Youngdale (prev. & ) + First cut of the emulator. + ELF loader, plus memory manager and fs/exec.c modifications + to allow multiple binary formats to be loaded. + Keeper of the tsx-11 archive. + libc_s (elf version), plus bugfixes, reorganization, etc. + SVr4 portions of emulator. + +Karl Kiniger + Interactive 4.0 binary recognition and special support. + +Remete Gabor + Miscellaneous patches. + +Scott Michel + SCO multiscreen ioctls. + +Stephan Riess + SCO tape ioctls. + +Peter Polte + Xenix fcntl() file locking facilities. + +C.A. Lademann + +Miguel de Icaza + Sparc support. diff -Nru linux-2.6.7/Documentation/abi/Error.map linux-2.6.7-abi/Documentation/abi/Error.map --- linux-2.6.7/Documentation/abi/Error.map 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/Documentation/abi/Error.map 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,143 @@ +Mapping of error codes from Linux to various personalities. Codes which Linux +may generate but which can't be mapped directly in a given personality must +be mapped to the nearest equivalent which may invoke the correct behaviour +in the application. This is especially true for things like the ERESTART* +set of error returns! + +NOTES: + +The Xenix set was built with reference to an old SCO Xenix manual rather +than by reference to a real system. It may be incomplete or wrong. If anyone +has access to the Xenix TCP/IP kit we need to add mappings for the TCP/IP +error codes. + +Other personalities may need adding. COFF binaries default + +Linux Name Linux ABI SCO Wyse Xenix 386bsd + +EPERM 1 /* Operation not permitted */ +ENOENT 2 /* No such file or directory */ +ESRCH 3 /* No such process */ +EINTR 4 /* Interrupted system call */ +EIO 5 /* I/O error */ +ENXIO 6 /* No such device or address */ +E2BIG 7 /* Arg list too long */ +ENOEXEC 8 /* Exec format error */ +EBADF 9 /* Bad file number */ +ECHILD 10 /* No child processes */ +EAGAIN 11 35 /* Try again */ +ENOMEM 12 /* Out of memory */ +EACCES 13 /* Permission denied */ +EFAULT 14 /* Bad address */ +ENOTBLK 15 /* Block device required */ +EBUSY 16 /* Device or resource busy */ +EEXIST 17 /* File exists */ +EXDEV 18 /* Cross-device link */ +ENODEV 19 /* No such device */ +ENOTDIR 20 /* Not a directory */ +EISDIR 21 /* Is a directory */ +EINVAL 22 /* Invalid argument */ +ENFILE 23 /* File table overflow */ +EMFILE 24 /* Too many open files */ +ENOTTY 25 /* Not a typewriter */ +ETXTBSY 26 /* Text file busy */ +EFBIG 27 /* File too large */ +ENOSPC 28 /* No space left on device */ +ESPIPE 29 /* Illegal seek */ +EROFS 30 /* Read-only file system */ +EMLINK 31 /* Too many links */ +EPIPE 32 /* Broken pipe */ +EDOM 33 /* Math argument out of domain of func */ +ERANGE 34 /* Math result not representable */ +EDEADLK 35 45 45 45 36 11 /* Resource deadlock would occur */ +ENAMETOOLONG 36 78 78 228 EINVAL 63 /* File name too long */ +ENOLCK 37 46 46 46 45 77 /* No record locks available */ +ENOSYS 38 89 89 EINVAL EINVAL 78 /* Function not implemented */ +ENOTEMPTY 39 93 145 231 EINVAL 66 /* Directory not empty */ +ELOOP 40 90 150 227 EINVAL 62 /* Too many symbolic links encountered */ +EWOULDBLOCK EAGAIN 90 90 200 EINVAL 35 /* Operation would block */ +ENOMSG 42 35 35 35 43 ? /* No message of desired type */ +EIDRM 43 36 36 36 44 ? /* Identifier removed */ +ECHRNG 44 37 37 37 EINVAL ? /* Channel number out of range */ +EL2NSYNC 45 38 38 38 EINVAL ? /* Level 2 not synchronized */ +EL3HLT 46 39 39 39 EINVAL ? /* Level 3 halted */ +EL3RST 47 40 40 40 EINVAL ? /* Level 3 reset */ +ELNRNG 48 41 41 41 EINVAL ? /* Link number out of range */ +EUNATCH 49 42 42 42 EINVAL ? /* Protocol driver not attached */ +ENOCSI 50 43 43 43 EINVAL ? /* No CSI structure available */ +EL2HLT 51 44 44 44 EINVAL ? /* Level 2 halted */ +EBADE 52 ? 50 50 EINVAL ? /* Invalid exchange */ +EBADR 53 ? 51 51 EINVAL ? /* Invalid request descriptor */ +EXFULL 54 ? 52 52 EINVAL ? /* Exchange full */ +ENOANO 55 ? 53 53 EINVAL ? /* No anode */ +EBADRQC 56 ? 54 54 EINVAL ? /* Invalid request code */ +EBADSLT 57 ? 55 55 EINVAL ? /* Invalid slot */ +EDEADLOCK 58 ? 56 56 36 11 /* File locking deadlock error */ +EBFONT 59 ? 57 57 EINVAL ? /* Bad font file format */ +ENOSTR 60 EINVAL ? /* Device not a stream */ +ENODATA 61 EINVAL ? /* No data available */ +ETIME 62 EINVAL ? /* Timer expired */ +ENOSR 63 EINVAL ? /* Out of streams resources */ +ENONET 64 EINVAL ? /* Machine is not on the network */ +ENOPKG 65 EINVAL ? /* Package not installed */ +EREMOTE 66 EINVAL 71 /* Object is remote */ +ENOLINK 67 EINVAL ? /* Link has been severed */ +EADV 68 EINVAL ? /* Advertise error */ +ESRMNT 69 EINVAL ? /* Srmount error */ +ECOMM 70 EINVAL ? /* Communication error on send */ +EPROTO 71 ? ? /* Protocol error */ +EMULTIHOP 72 74 74 74 ? ? /* Multihop attempted */ +EDOTDOT 73 76 76 76 ? ? /* RFS specific error */ +EBADMSG 74 77 77 77 ? ? /* Not a data message */ +EOVERFLOW 75 79 EINVAL EINVAL ? ? /* Value too large for defined data type */ +ENOTUNIQ 76 80 80 80 ? ? /* Name not unique on network */ +EBADFD 77 81 81 81 ? ? /* File descriptor in bad state */ +EREMCHG 78 82 82 82 ? ? /* Remote address changed */ +ELIBACC 79 83 83 83 ? ? /* Can not access a needed shared library */ +ELIBBAD 80 84 84 84 ? ? /* Accessing a corrupted shared library */ +ELIBSCN 81 85 85 85 ? ? /* .lib section in a.out corrupted */ +ELIBMAX 82 86 86 86 ? ? /* Attempting to link in too many shared libraries */ +ELIBEXEC 83 87 87 87 ? ? /* Cannot exec a shared library directly */ +EILSEQ 84 88 EINVAL EINVAL ? ? /* Illegal byte sequence */ +ERESTART 85 91 EINTR EINTR ? ? /* Interrupted system call should be restarted */ +ESTRPIPE 86 92 EINVAL EINVAL ? ? /* Streams pipe error */ +EUSERS 87 94 EINVAL 233 ? 68 /* Too many users */ +ENOTSOCK 88 95 93 203 ? 38 /* Socket operation on non-socket */ +EDESTADDRREQ 89 96 94 204 ? 39 /* Destination address required */ +EMSGSIZE 90 97 95 205 ? 40 /* Message too long */ +EPROTOTYPE 91 98 96 206 ? 41 /* Protocol wrong type for socket */ +ENOPROTOOPT 92 99 EINVAL 207 ? 42 /* Protocol not available */ +EPROTONOSUPPORT 93 120 97 208 ? 43 /* Protocol not supported */ +ESOCKTNOSUPPORT 94 121 98 209 ? 44 /* Socket type not supported */ +EOPNOTSUPP 95 122 99 210 ? 45 /* Operation not supported on transport endpoint */ +EPFNOSUPPORT 96 123 100 211 ? 46 /* Protocol family not supported */ +EAFNOSUPPORT 97 124 101 212 ? 47 /* Address family not supported by protocol */ +EADDRINUSE 98 125 102 213 ? 48 /* Address already in use */ +EADDRNOTAVAIL 99 126 103 214 ? 49 /* Cannot assign requested address */ +ENETDOWN 100 127 104 215 ? 50 /* Network is down */ +ENETUNREACH 101 128 105 216 ? 51 /* Network is unreachable */ +ENETRESET 102 129 106 217 ? 52 /* Network dropped connection because of reset */ +ECONNABORTED 103 130 107 218 ? 53 /* Software caused connection abort */ +ECONNRESET 104 131 108 219 ? 54 /* Connection reset by peer */ +ENOBUFS 105 132 63 220 ? 55 /* No buffer space available */ +EISCONN 106 133 110 221 ? 56 /* Transport endpoint is already connected */ +ENOTCONN 107 134 111 222 ? 57 /* Transport endpoint is not connected */ +ESHUTDOWN 108 143 112 223 ? 58 /* Cannot send after transport endpoint shutdown */ +ETOOMANYREFS 109 144 113 224 ? 59 /* Too many references: cannot splice */ +ETIMEDOUT 110 145 114 225 ? 60 /* Connection timed out */ +ECONNREFUSED 111 146 115 226 ? 61 /* Connection refused */ +EHOSTDOWN 112 147 116 229 ? 64 /* Host is down */ +EHOSTUNREACH 113 148 117 230 ? 65 /* No route to host */ +EALREADY 114 149 92 202 ? 37 /* Operation already in progress */ +EINPROGRESS 115 150 91 201 ? 36 /* Operation now in progress */ +ESTALE 116 EINVAL EINVAL 237 ? 70 /* Stale NFS file handle */ +EUCLEAN 117 ? 135 135 35 ? /* Structure needs cleaning */ +ENOTNAM 118 ? 137 137 37 ? /* Not a XENIX named type file */ +ENAVAIL 119 ? 138 138 38 ? /* No XENIX semaphores available */ +EISNAM 120 ? 139 139 39 ? /* Is a named type file */ +EREMOTEIO 121 ? 140 140 EINVAL ? /* Remote I/O error */ +EDQUOT 122 ? ENOSPC 234 ENOSPC 69 /* Quota exceeded */ + +ERESTARTSYS 512 EINTR EINTR EINTR EINTR EINTR +ERESTARTNOINTR 513 EINTR EINTR EINTR EINTR EINTR +ERESTARTNOHAND 514 EINTR EINTR EINTR EINTR EINTR /* restart if no handler.. */ diff -Nru linux-2.6.7/Documentation/abi/HINTS linux-2.6.7-abi/Documentation/abi/HINTS --- linux-2.6.7/Documentation/abi/HINTS 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/Documentation/abi/HINTS 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,245 @@ +PROBLEM: + Cannot determine user name by reference to /etc/passwd. Failure + to determine the user name causes some programs (notably programs + built with Informix 4GL) to exit. + +REASON: + The functions that parse /etc/passwd are sensitive under SCO + at least. A corrupt line is taken to be the end of the file + and further entries are ignored. Any line which has a null + home directory counts as a corrupt line for SCO. + +SOLUTION: + Ensure that all lines in /etc/passwd have home directories + specified. Simply edit /etc/passwd with an editor. + + +# ----------------------------------------------------------------------- + +PROBLEM: + Cannot connect to X server using local connection. + +REASON: + Some versions of X libraries seem to require 'localhost' to be + allowed to connect to the X server even if we aren't using a + TCP/IP connection. The X libraries used for VSI*FAX require + this, the X libraries used for WordPerfect don't. + +SOLUTION: + Explicitly allow 'localhost' to connect to the X server using + 'xhost localhost'. + + +# ----------------------------------------------------------------------- + +PROBLEM: + Installation disks claim to be Unix tar format but they appear + to be blank MS-DOS format disks! + +REASON: + Unix provides two floppy devices, the normal floppy devices + that we all know and love (and which are listed as the Xenix + compatible devices in the man page) and a second set which + skips the first track of the disk. For some reason a few vendors + seem to use this second set when preparing distribution disks. + WordPerfect seem to do this. Linux currently only supports + the normal floppy devices. + +SOLUTION: + You have to skip the first track by hand and read each disk + individually. Try 'dd if=/dev/fd0 bs=18k skip=1 | tar xfv -' + for a 3.5" high density disk. Change the 18k to 15k for a + 5.25" high density disk. + +# ----------------------------------------------------------------------- + +PROBLEM: + A script bombs out with an unexpected EOF looking for "'". This + only happens on Linux. + +REASON: + There is a bug in the script which is only a problem on Linux. + Take the following example: + + count=`ls | wc | awk '{ printf "%05d", $1 }` + + Note the missing "'" at the end of the awk statment. The /bin/sh + supplied with SCO will assume (in this case correctly) that the + "'" should have occurred immediately before the closing "`" and + the expression will succeed. The /bin/sh used with Linux (normally + bash) does not make this assumption and gives an error message. + +SOLUTION: + Either fix the script or arrange to have it run by a SYSV shell + rather than bash. + +# ----------------------------------------------------------------------- + +PROBLEM: + Test complains that a numeric argument is required before -eq, -le + etc. + +REASON: + The GNU shellutils test and the test built in to bash which are + the versions of test used under Linux do not accept a null + argument as equivalent to 0 so 'test "" -le 5' will give an error. + Under SCO a null argument is taken as equivalent to 0 so the + statement would be evaluated as 'test 0 -le 5'. + +SOLUTION: + Fix the script to check arguments for validity before using them + or provide a fixed version of test and ensure that it is used in + preference to any shell built in. + +# ----------------------------------------------------------------------- + +PROBLEM: + Some X fonts supplied with packages appear corrupt. + +REASON: + These are probably snf fonts. The XFree86 X server used with + Linux appears to fail to load some snf fonts silently and displays + garbage. Pcf fonts work ok and should be used where possible. + +SOLUTION: + If you only have the snf fonts all you can do is to try asking the + vendor for pcf versions or the bdf definitions. + + If you have the bdf definitions (WordPerfect ship them) then you + can build a pcf set using: + + # for bdffn in *.bdf + > do + > fn=`basename $bdffn .bdf` + > [ -r $fn.snf ] && mv $fn.snf $fn.snf.old + > bdftopcf -o $fn.pcf $bdffn + > done + # mkfontdir . + # xset fp rehash + +# ----------------------------------------------------------------------- + +PROBLEM: + Function keys don't work. + +REASON: + The default sequences for function keys under Linux are "sort of" + VT10x like whereas you have probably told your application that + you are running on an ansi or SCO console. + +SOLUTION: + It is probably best to run as an ansi screen - especially if + colour is used - so use the "loadkeys" program to load the + SCO.map keyboard description from the PROD.Patches directory. + This directory also contains flexible termcap and terminfo + descriptions which will allow you run permanently with a SCO + or SVR4-like console. + +# ----------------------------------------------------------------------- + +PROBLEM: + Line drawing characters come out as weird symbols. + +REASON: + The application believes you are using a console screen with a + PC character set and is using 8-bit codes rather than escape + sequences. Linux defaults to an ISO8859-1 character set though. + +SOLUTION: + Linux can be switched to PC character set mode with the escape + sequence ESC-(-U. Arrange to have this sequence sent either + before the application is started or as part of the initialisation + that the application does. You can restore the ISO character + set afterwards with ESC-(-K. + +# ----------------------------------------------------------------------- + +PROBLEM: + SYSV binaries see the wrong time zone. + +REASON: + SYSV binaries establish the time zone from the TZ environment + variable whereas Linux uses BSD style zoneinfo files generally. + +SOLUTION: + Set the TZ environment variable to reflect your time zone. Note + that the zoneinfo mechanism can also use TZ in preference to + the /usr/lib/zoneinfo/localtime file if you wish. For this to + work you must have /usr/lib/zoneinfo/posixrules linked to one + of the US timezone files. The posixrules file defines how the + zoneinfo functions interpret TZ and this information is only + found in the US data files. See the documentation for the + timezone/zoneinfo package for details. + +# ----------------------------------------------------------------------- + +PROBLEM: + BSD binaries don't see the right time zone. + +REASON: + Although BSD binaries use the same timezone handling method as + Linux they expect the zoneinfo information in different places. + +SOLUTION: + Make the links: + + # ln -s /usr/lib/zoneinfo /etc/localtime + # ln -s /usr/lib/zoneinfo /usr/share/zoneinfo + +# ----------------------------------------------------------------------- + +PROBLEM: + BSD binaries complain that they can't find /etc/termcap. + +REASON: + They may be lying. BSD sometimes uses /usr/share/misc/termcap + or ~/.termcap (if it exists). + +SOLUTION: + Either move termcap to /usr/share/misc and make /etc/termcap + a link to it or make /usr/share/misc/termcap a link to /etc/termcap. + The use of /usr/share/misc/termcap may be useful in a networked + environment. +# ----------------------------------------------------------------------- + +PROBLEM: + SVr4 binaries cannot locate shared libraries, or fail to start. + +REASON: + The shared libraries are not in the correct location, or the dynamic + loader cannot be located by the kernel. + +SOLUTION: + Put all SVr4 shared libraries in the directory /usr/i486-sysv4/lib. + Then create two symbolic links: + + ln -s /usr/i486-sysv4/lib/libc.so.1 /usr/lib/libc.so.1 + ln -s /usr/i486-sysv4/lib/ld.so.1 /usr/lib/ld.so.1 +# ----------------------------------------------------------------------- + +PROBLEM: + SVr4 binaries want to access terminfo instead of termcap + +REASON: + SVr4 traditionally uses something called terminfo instead of + termcap to specify terminal characteristics. + +SOLUTION: + The ncurses distribution (available on many fine ftp sites) + contains a terminfo database. Just install this, and you + should be all set. +# ----------------------------------------------------------------------- + +PROBLEM: + The Informix Dynamic Server installation for SCO says + invalid INFORMIXDIR or insufficient space. + +REASON: + It wants to scan /etc/mnttab to find all possible + filesystems. Since Linux uses /etc/mtab instead the + installation program is under the impression you have + no filesystems and no space(!). + +SOLUTION: + Run the perl script Tools/mkmnttab which will build an + /etc/mnttab from /etc/mtab. diff -Nru linux-2.6.7/Documentation/abi/Local-X linux-2.6.7-abi/Documentation/abi/Local-X --- linux-2.6.7/Documentation/abi/Local-X 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/Documentation/abi/Local-X 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,22 @@ +** Local X interface + +The local X interface is simplistic. It assumes only one local X server +exists and assumes that the pathname of the Unix domain socket for +local connections is always /tmp/.X11-unix/X0. + + The SCO code opens both /dev/X0R and /dev/spx, writes a single byte +to /dev/X0R, reads a message from /dev/X0R with getmsg then writes this +message to /dev/spx with putmsg and closes /dev/X0R. This establishes +the /dev/spx file descriptor as a connection to the X server listening +on /dev/X0R. + + We ignore all activity on the /dev/X0R device (hence it is a link to +/dev/null), getmsg and putmsg are stubbed so don't do anything and opens +on the /dev/spx simply replace the open inode with a socket connected +to the X server's Unix domain socket. + + At some point in the future we will implement a simple minded /dev/X* +driver that returns some form of id via the getmsg which can then be +passed to /dev/spx with putmsg and which will allow /dev/spx to connect +to the relevant X server. This will only happen if someone actually +*needs* multiple local X servers... diff -Nru linux-2.6.7/Documentation/abi/modules.txt linux-2.6.7-abi/Documentation/abi/modules.txt --- linux-2.6.7/Documentation/abi/modules.txt 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/Documentation/abi/modules.txt 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,80 @@ +A brief overview of the Linux-ABI modules +2001-July-19 +Christoph Hellwig, + +Linux-ABI consists of a number of loadable kernel modules (you can also +compile it directly into the kernel, but no one actually does). This +document is intended to give a brief overview on the aviable modules +and how they can be classified in groups. + + +=== Binary format modules + +Some of the personalities supported by Linux-ABI use different binary +formats than the ELF format that is used by Linux native binaries. +The follwoing binary format modules do exists: + + o binfmt_coff + + This modules supports the COFF binary format as used by elder + SysV-derivate operating systems. It is used by the SVR3, + SCOSVR3, ISC and Wyse personalities. + + o binfmt_xout + + This module is intended for loading X.out binaries generated for + the Xenix operating system. + +These modules have to be loaded manually before using them. + + + +=== Personality modules + +Personality modules contain the the personality implementation and are +thus the hearts of Linux-ABI. Additionally most personality modules +contain syscalls only used by that particular personality. There are +a lot of personality modules: + + o abi-ibcs + + Support for plain SVR3/SVR4 as specified in iBCS2 or iABI4. + Additionally this module contains the Xenix and ISC personalities, + but these should be moved away from here. + + o abi-sco + + This module implements the SCO Unix 3.x/ODT and OSR5 personalities. + + o abi-solaris + + The Solaris 2 emulator. + + o abi-uw7 + + SCO UnixWare 7 / Caldera OpenUnix 8 emulator. + + o abi-wyse + + Support for Wyse V/386 ant it's multiprocessor variant. + + +=== Backend modules + +As a lot of the functionality provided by the binary format modules is +common to more than one of those, most of this functionality is moved to +backend modules. There are only a few backend modules: + + o abi-machdep + + The machine depandand part of Linux-ABI (in fact currently + Linux-ABI is i386-specific, but that _will_ change). + + o abi-svr4 + + Most of the syscalls used by all or many of the SVR3/SVR4 derivates. + + o abi-socket + + 4BSD-style socket interface, currently only used by the Wyse + emulation. This will probably go away. diff -Nru linux-2.6.7/Documentation/abi/Notes.Signal linux-2.6.7-abi/Documentation/abi/Notes.Signal --- linux-2.6.7/Documentation/abi/Notes.Signal 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/Documentation/abi/Notes.Signal 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,42 @@ +Drew, Joe, and Brandon. + +This file contains my code for the signal functions. I realized that the +existing signal functions will not suffice. This module should do the +proper processing for iBCS signals. + +There are patches to the emulate module offered by Drew in his pl14n code +release. The Makefile was changed to include the module. + +In addition, I have include a signal.doc file which contains the text from +my UNIX S5 manual describing the functions used by iBCS. I based the +emulator code on this document. Please look it over and see if I have +messed up. I believe it to be correct. However, it never hurts to have +someone check the work before we can trust it. + +It follows what I believe to be the proper calling sequence for signals. I +sent a message to the IBSC2 group with the text from the McGraw Hill book +concerning signals. If you would like a copy of the message, then let me +know. + +Of couse, this could be totally wrong. That is the whole point about +sending this out to a limited distribution. + +In addition to the processing for the various function requests, you may +have noticed that the signal _numbers_ must be changed between the values +used by iBCS and Linux. + +I have had to modify the emulate.c module to export an additional +procedure (and for emulate.c to use the procedure itself.) In addition, I +change the branch table to re-direct the signal processing to the signal.c +module. + +I hope that this will help the project when it has been proven workable. +Please let me know how this turns out -- one way or the other. + +If it does work, then I'll give the final code to Drew to merge into the +master code. That is unless, Drew, you already have it. :-) + +Thanks much. + +-- +Al Longyear longyear@netcom.com longyear@sii.com diff -Nru linux-2.6.7/Documentation/abi/Personality linux-2.6.7-abi/Documentation/abi/Personality --- linux-2.6.7/Documentation/abi/Personality 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/Documentation/abi/Personality 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,88 @@ +*** Why are multiple personalities necessary? + +Personalities are used to provide the expected set of syscalls and error +code mapping for non-Linux processes. In theory the set of syscalls and +error codes should be standardised across all SYSV systems. In practice +this is the case for SVR4, however SVR3 is a much older code base and +many vendors have extended it leading to incompatibilities between the +expected interfaces. Personalities allow us to vary the interface presented +on a per-process basis thus allowing Linux to run binaries created for +different vendor's extended SVR3s simultaneously. + + +*** How are personalities implemented? + +The per-process task structure contains a field "personality". This defaults +to 0 for Linux binaries, 1 (SVR4) for ELF binaries and 2 (SVR3) for COFF +binaries. However when the COFF loader is called on to load a new binary +it looks at the first 1k of data in each .comment section and compares +the strings it finds with a built in table. If it finds a match it will +set the personality appropriately. + + When the application makes a system call the iBCS emulation layer uses +the personality code in the per-process task structure to determine which +system call mappings to use to locate the correct function. + + If the function returns an (Linux) error code the iBCS emulation layer +uses the personality code to determine which error code mappings to use +to translate the error code in to a value the application will understand. + + +*** What personalities are implemented? + +Currently the implemented personalities are SVR4, SVR3 (as a direct +subset of SVR4), SCO 3.[24] and Wyse V/386 3.2.1. Of these the Wyse +emulation is the most complete at this time. Rather than using the +more common streams based TCP/IP stack on their SVR3, Wyse used a BSD +implementation with a system call interface. Currently the Wyse emulation +is the only one capable of running non-Linux TCP/IP binaries. + + +*** When do I need to add a personality rather than use the default? + +When your applications start failing for inexplicable reasons! Seriously, +if you have an SVR3 based Unix which does not currently have its own +personality defined then you should check some things very carefully. + + Firstly compare your system's /usr/include/sys/errno.h with the data +in the Error.map file. If the values defined in your errno.h do not +match those in the ABI column then you will need to create a new +personality in order to map error codes to the correct values. + + Next compare your system's /usr/include/sys.s with the data in the +Syscall.map file. If there are system calls in your sys.s that don't +do the same thing as those in the ABI column (other than ones that +simply aren't implemented on your system) then you will need to create +a new personality in order to mapp system calls to the correct functions. + + +*** How do I add a new personality? + +The first step is to find a way for the COFF loader to recognise your +binaries as being different. To do this you need to examine the comments +embedded in a range of binaries, system executables, bought programs of +various ages and locally compiled programs, using "mcs -p" to list the +.comments sections. If you don't have "mcs" use "strings" and look for +version or copyright messages. You are looking for one or more strings +near the top which uniquely identify the system. + + Once you have your identifying strings you must add a value for the +new personality to linux/include/linux/personality.h (just use the +next highest number) and add the strings to the table in the COFF loader +linux/fs/binfmt_coff.c. + + The next step is to modify the error map. Edit the file errmap.inc and +look at the end of the file where there is an array of pointers to error +maps call err_map. There is one entry for each personality. Add a new +entry to the end for your personality. If your personality is compatible +with an exising personality you can simply reuse the same error map (see +the duplicate entries for the SVR4 map which is use for both SVR4 and +SVR3 personalities), otherwise you must figure out how to create a new +error mapping. One day it may be documented here :-). + + Next you must modify the syscall mapping. Edit the file callmap.inc +and look at the end of the file where there is an array containg one +pointer for each personality. Add a new entry to the end. If your syscalls +match one of the existing personalities you may reuse the existing map. +Otherwise you have to build a new one. Again, one day it may be documented +here... diff -Nru linux-2.6.7/Documentation/abi/README.first linux-2.6.7-abi/Documentation/abi/README.first --- linux-2.6.7/Documentation/abi/README.first 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/Documentation/abi/README.first 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,12 @@ +First notes on Linux-ABI documentation +2001-March-30 +Christoph Hellwig, + + +Please note that most files in this directory are leftovers from iBCS, which is +dead since 1998. Do not expect this files to uptodate or complete. + +I will update the files and add new onces from time to time. + + --hch + diff -Nru linux-2.6.7/Documentation/abi/Syscall.map linux-2.6.7-abi/Documentation/abi/Syscall.map --- linux-2.6.7/Documentation/abi/Syscall.map 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/Documentation/abi/Syscall.map 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,185 @@ +Call ABI SCO 3.2 SCO 3.4 Wyse V/386 3.2.1 386bsd + + 1 exit + 2 fork + 3 read + 4 write + 5 open + 6 close + 7 wait + 8 creat + 9 link + 10 unlink + 11 exec + 12 chdir + 13 time fchdir + 14 mknod + 15 chmod + 16 chown + 17 brk/break + 18 stat getfsstat + 19 seek/seek + 20 getpid + 21 mount + 22 umount + 23 setuid + 24 getuid + 25 stime geteuid + 26 ptrace + 27 alarm recvmsg + 28 fstat sendmsg + 29 pause recvfrom + 30 utime accept + 31 stty getpeername + 32 gtty getsockname + 33 access + 34 nice chflags + 35 statfs fchflags + 36 sync + 37 kill + 38 fstatfs stat + 39 setpgrp getppid + 40 cxenix lstat + 41 dup + 42 pipe + 43 times getegid + 44 prof + 45 lock/plock ktrace + 46 setgid sigaction + 47 getgid + 48 signal sigprocmask + 49 msgsys getlogin + 50 sysi86/sys3b setlogin + 51 sysacct/acct + 52 shmsys sigpending + 53 semsys sigaltstack + 54 ioctl + 55 uadmin reboot + 56 ??? revoke + 57 utssys symlink + 58 ??? readlink + 59 execv + 60 umask + 61 chroot + 62 fcntl fstat + 63 ulimit getkerninfo + 64 ??? getpagesize + 65 ??? msync + 66 ??? vfork + 67 ??? vread + 68 ??? vwrite + 69 ??? sbrk + 70 advfs sstk + 71 unadvfs mmap + 72 rmount vadvise + 73 rumount munmap + 74 rfstart mprotect + 75 ??? madvise + 76 rdebug vhangup + 77 rfstop vlimit + 78 rfsys mincore + 79 rmdir getgroups + 80 mkdir setgroups + 81 getdents getpgrp + 82 libattach setpgid + 83 libdetach setitimer + 84 sysfs wait + 85 getmsg swapon + 86 putmsg getitimer + 87 poll gethostname + 88 lstat --- --- --- sethostname + 89 symlink --- --- --- getdtablesize + 90 readlink --- symlink --- dup2 + 91 setgroups --- lstat --- --- + 92 getgroups --- readlink --- fcntl + 93 fchmod --- --- --- select + 94 fchown --- --- --- --- + 95 sigprocmask --- --- --- fsync + 96 sigsuspend --- --- --- setpriority + 97 sigaltstack --- --- --- socket + 98 sigaction --- --- --- connect + 99 sigpending --- --- --- accept +100 context --- --- --- getpriority +101 evsys --- --- --- send +102 evtrapret --- --- --- recv +103 statvfs --- --- --- sigreturn +104 fstatvfs --- --- --- bind +105 ??? setsockopt +106 nfssys --- --- --- listen +107 waitsys --- --- --- vtimes +108 sigsendsys --- --- --- sigvec +109 hrtsys --- --- --- sigblock +110 acancel --- --- --- sigsetmask +111 async --- --- --- sigsuspend +112 priocntlsys --- --- --- sigstack +113 pathconf --- --- --- recvmsg +114 mincore --- --- --- sendmsg +115 mmap --- --- --- vtrace +116 mprotect --- --- --- gettimeofday +117 munmap --- --- --- getrusage +118 fpathconf --- --- --- getsockopt +119 vfork --- --- --- resuba +120 fchdir --- --- --- readv +121 readv --- --- --- writev +122 writev --- --- --- settimeofday +123 xstat --- --- --- fchown +124 lxstat --- --- --- fchmod +125 fxstat --- --- --- recvfrom +126 xmknod --- --- --- setreuid +127 clocal setregid +128 setrlimit --- --- lstat rename +129 getrlimit --- --- readlink truncate +130 lchown --- --- symlink ftruncate +131 memcntl --- --- --- flock +132 getpmsg --- --- --- mkfifo +133 putpmsg --- --- gethostname sendto +134 rename --- --- sethostname shutdown +135 uname --- --- getdomainname socketpair +136 setegid --- --- setdomainname mkdir +137 sysconfig --- --- --- rmdir +138 adjtime --- --- setreuid utimes +139 systeminfo --- --- setregid sigreturn +140 ??? adjtime +141 seteuid --- --- --- getpeername +142 --- --- --- --- gethostid +143 --- --- --- --- sethostid +144 --- --- --- --- getrlimit +145 --- --- --- --- setrlimit +146 --- --- --- --- killpg +147 --- --- --- --- setsid +148 --- --- --- --- quotactl +149 --- --- --- --- quota +150 --- --- --- --- getsockname +151 --- --- --- --- +152 --- --- --- --- +153 --- --- --- --- +154 --- --- --- --- +155 --- --- --- --- nfssvc +156 --- --- --- --- getdirentries +157 --- --- --- --- statfs +158 --- --- --- --- fstatfs +159 --- --- --- --- +160 --- --- --- --- async_daemon +161 --- --- --- --- getfh +162 --- --- --- --- getdomainname +163 --- --- --- --- setdomainname +164 --- --- --- --- uname +165 --- --- --- --- sysarch +166 --- --- --- --- +167 --- --- --- --- +168 --- --- --- --- +169 --- --- --- --- semsys +170 --- --- --- --- msgsys +171 --- --- --- --- shmsys +172 --- --- --- --- +173 --- --- --- --- +174 --- --- --- --- +175 --- --- --- --- ntp_gettime +176 --- --- --- --- ntp_adjtime +177 --- --- --- --- vm_allocate +178 --- --- --- --- vm_deallocate +179 --- --- --- --- vm_inherit +180 --- --- --- --- vm_protect +181 --- --- --- --- setgid +182 --- --- --- --- setegid +183 --- --- --- --- seteuid diff -Nru linux-2.6.7/Documentation/abi/TODO.ibcs linux-2.6.7-abi/Documentation/abi/TODO.ibcs --- linux-2.6.7/Documentation/abi/TODO.ibcs 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/Documentation/abi/TODO.ibcs 2004-07-22 17:44:20.000000000 +0200 @@ -0,0 +1,61 @@ + + These are leftovers from iBCS, I just removed what is already + done in linux-abi or isn't relevant for us. --hch + + +^Z disconnects but the next read seems to return an error instead +of blocking? (Fixed?) + +SIOGIFFLAGS seems to get passed an empty string as the interface name +(ISC ping). What is supposed to be happening? + +If a timod putmsg fails we should set an error status on the socket and +return it on future calls for strict compatibility. Currently we recover +from things such as protocol errors rather more than we should. + +Getmsg() - when select returns we may not be the first process to wake +up and handle the event. So the recvfrom ought to be non-blocking (not +possible?). If it would block we should go back to the select (unless +the descriptor is in non-blocking mode). (DONE?) + +How should we go about returning TLOOK? Currently we are only working +synchronously so it isn't essential yet. It looks like it's all handled +in libnsl_s. + +The T_MORE flag on t_snd() and t_rcv() marks message boundaries. Strictly +these should be preserved end-to-end. Possible across sockets? +(X/Open specify that message boundaries shouldn't be relied on with TCP) + +Need I_SETSIG ioctl to enable SIGPOLL on available input etc. Note that +a control message counts as input. This should interface with poll() too. + +getmsg() returns EINTR if a signal interrupts it but the t_*() functions +don't seem to propogate this back to the application. Presumably they +loop round? + +The SCO timod doesn't seem to pay much attention to the TI_* command +in an ioctl but uses the T_* primitive in the message block. i.e. if +you have T_BIND_REQ in the message but TI_GETINFO as the ioctl command +timod will do a bind. Currently we use the TI_* by preference. This +needs to change to avoid breaking programs that worked on SCO even +though broken. It shouldn't be _essential_ though as all this is +normally hidden in libnsl_s so should be consistent. + +Connects are currently forced synchronous. It wouldn't be too much +to allow them to happen asynchronously but the async confirmation +is supposed to contain the address we connected to and that is only +available from the connection request message. Unless we save it +somewhere or look it up from the socket. Hang on, we have getpeername() +capabilities... + +There are slight semantic differences between O_NDELAY and O_NONBLOCK +which cause different behaviour on SCO at least. For instance O_NDELAY +does cause t_connect to work asynchronously but O_NONBLOCK doesn't. +Under Linux O_NDELAY and O_NONBLOCK are the same. This could cause +problems at some point I guess... + +Under SCO at least poll and select are different. Poll works on things +that select can be used on but select cannot necessarily work on things +that can be polled. Specifically you can poll a transport end point +but not select on it. Badly written programs could block when they +wouldn't normally. diff -Nru linux-2.6.7/fs/binfmt_coff.c linux-2.6.7-abi/fs/binfmt_coff.c --- linux-2.6.7/fs/binfmt_coff.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/fs/binfmt_coff.c 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,847 @@ +/* + * These are the functions used to load COFF IBCS style executables. + * Information on COFF format may be obtained in either the Intel Binary + * Compatibility Specification 2 or O'Rilley's book on COFF. The shared + * libraries are defined only the in the Intel book. + * + * This file is based upon code written by Eric Youngdale for the ELF object + * file format. + * + * Author: Al Longyear (longyear@sii.com) + */ + +#ident "%W% %G%" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#ifndef EXPORT_NO_SYMBOLS +#define EXPORT_NO_SYMBOLS +#endif + +MODULE_DESCRIPTION("Support for the SVR3 COFF binary format"); +MODULE_AUTHOR("Al Longyear, Christoph Hellwig"); +MODULE_LICENSE("GPL"); + +EXPORT_NO_SYMBOLS; + + +static int coff_load_binary(struct linux_binprm *, struct pt_regs *); +static int coff_load_shlib(struct file *); +static int coff_preload_shlibs(struct linux_binprm *, COFF_SCNHDR *, int); +static int coff_parse_comments(struct file *, COFF_SCNHDR *, long *); + + +static struct linux_binfmt coff_format = { + NULL, THIS_MODULE, coff_load_binary, coff_load_shlib, NULL, PAGE_SIZE +}; + + +typedef struct coff_section { + long scnptr; + long size; + long vaddr; +} coff_section; + +typedef struct coff_clue { + short terminal; /* non-zero to stop parsing with this entry */ + short len; /* negative number uses strstr for lookup */ + char *text; /* text to search for */ + u_long mask_and, mask_or; +} coff_clue; + + +/* + * The following table gives clues to the "personality" of the executable + * which we hope to find in the .comment sections of the binary. + * The set here may not be comprehensive even for those systems listed. + * Use 'mcs -p' to list the .comments sections of a binary to see what + * clues might be there. Or use 'strings' if you don't have mcs. + */ +static coff_clue coff_clues[] = { + /* + * Wyse Unix V/386 3.2.1[A]. + */ + {1, 36, "@(#) UNIX System V/386 Release 3.2.1", 0, PER_WYSEV386}, + + /* + * SCO Unix V 3.2, 3.2.2, 3.2.4, 3.2.4.2 etc. + */ + {1, 23, "@(#) crt1.s 1.8 89/05/30", 0, PER_SCOSVR3}, + {1, 16, "@(#)SCO UNIX 3.2", 0, PER_SCOSVR3}, + {1, 18, "\"@(#) SCO UNIX 3.2", 0, PER_SCOSVR3}, + {1, 17, "@(#) SCO UNIX 3.2", 0, PER_SCOSVR3}, + {1, 11, "@(#)SCO 3.2", 0, PER_SCOSVR3}, + + /* + * SCO Unix 3.2.4.2 OpenServer 5 gives 32 bit inodes except + * programs compiled with ods30 compatibilty. In fact OS5 + * always gives 32 bits but the library drops the top 16 in + * odt30 mode. We know what should happen and do it however. + */ + {0, 32, "@(#) crt1.s.source 20.1 94/12/04", 0, PER_SCOSVR3}, + {1, 13, "ods_30_compat", ~0, PERF_SHORT_INODE}, + + /* + * Interactive (ISC) 4.0. + */ + {1, -1, "INTERACTIVE", 0, PER_ISCR4}, + + /* + * End of table. + */ + {0, 0, 0, 0, 0} +}; + +/* + * Parse a comments section looking for clues as to the system this + * was compiled on so we can get the system call interface right. + */ +static int +coff_parse_comments(struct file *fp, COFF_SCNHDR *sect, long *personality) +{ + u_long offset, nbytes; + int hits = 0, err; + char *buffer; + + if (!(buffer = (char *)__get_free_page(GFP_KERNEL))) + return 0; + + /* + * Fetch the size of the section. There must be something in there + * or the section wouldn't exist at all. We only bother with the + * first 8192 characters though. There isn't any point getting too + * carried away! + */ + if ((nbytes = COFF_LONG(sect->s_size)) > 8192) + nbytes = 8192; + + offset = COFF_LONG(sect->s_scnptr); + while (nbytes > 0) { + u_long count, start = 0; + char *p; + + err = kernel_read(fp, offset, buffer, + nbytes > PAGE_SIZE ? PAGE_SIZE : nbytes); + + if (err <= 0) { + free_page((u_long) buffer); + return 0; + } + + p = buffer; + for (count = 0; count < err; count++) { + coff_clue *clue; + char c; + + c = *(buffer + PAGE_SIZE - 1); + *(buffer + PAGE_SIZE - 1) = '\0'; + + for (clue = coff_clues; clue->len; clue++) { + if ((clue->len < 0 && strstr(p, clue->text)) || + (clue->len > 0 && !strncmp(p, clue->text, clue->len))) { + *personality &= clue->mask_and; + *personality |= clue->mask_or; + if (clue->terminal) { + free_page((u_long)buffer); + return 1; + } + hits++; + } + } + *(buffer + PAGE_SIZE - 1) = c; + + while (*p && count < err) + p++, count++; + if (count < err) { + p++; + count++; + start = count; + } + } + + /* + * If we didn't find an end ofstring at all this page + * probably isn't useful string data. + */ + if (start == 0) + start = err; + + nbytes -= start; + offset += start; + } + + free_page((u_long)buffer); + return (hits); +} + +/* + * Small procedure to test for the proper file alignment. + * Return the error code if the section is not properly aligned. + */ +static __inline__ int +coff_isaligned(COFF_SCNHDR *sectp) +{ + long scnptr = COFF_LONG(sectp->s_scnptr); + long vaddr = COFF_LONG(sectp->s_vaddr); + + if ((vaddr - scnptr) & ~PAGE_MASK) + return -ENOEXEC; + return 0; +} + +/* + * Clear the bytes in the last page of data. + */ +static int +coff_clear_memory(u_long addr, u_long size) +{ + int err = 0; + + if ((size = (PAGE_SIZE - (addr & ~PAGE_MASK)) & ~PAGE_MASK) == 0) + goto out; + if ((err = verify_area(VERIFY_WRITE, (void *)addr, size)) < 0) + goto out; + + while (size-- != 0) { + __put_user(0, (char *)addr); + addr++; + } + +out: + return (err); +} + +static inline unsigned long +map_coff(struct file *file, coff_section *sect, unsigned long prot, + unsigned long flag, unsigned long offset) +{ + unsigned long map_addr; + + down_write(¤t->mm->mmap_sem); + map_addr = do_mmap(file, + sect->vaddr & PAGE_MASK, + sect->size + (sect->vaddr & ~PAGE_MASK), + prot, flag, offset); + up_write(¤t->mm->mmap_sem); + + return (map_addr); +} + + +static u_long * +coff_mktables(char *p, int argc, int envc) +{ + u_long *argv, *envp; + u_long *sp; + + sp = (u_long *) ((-(u_long)sizeof(char *)) & (u_long)p); + + sp -= envc + 1; + envp = sp; + sp -= argc + 1; + argv = sp; + + put_user(argc, --sp); + current->mm->arg_start = (u_long)p; + + while (argc-- > 0) { + __put_user(p, argv++); + p += strlen_user(p); + } + + __put_user(NULL, argv); + current->mm->arg_end = current->mm->env_start = (u_long)p; + + while (envc-- > 0) { + __put_user(p, envp++); + p += strlen_user(p); + } + + __put_user(NULL, envp); + current->mm->env_end = (u_long) p; + + return (sp); +} + +/* + * Helper function to process the load operation. + */ +static int +coff_load_object(struct linux_binprm *bprm, struct pt_regs *regs, int binary) +{ + COFF_FILHDR *coff_hdr = NULL; + COFF_SCNHDR *text_sect = NULL, *data_sect = NULL, + *bss_sect = NULL, *sect_bufr = NULL, + *sect_ptr = NULL; + int text_count = 0, data_count = 0, + bss_count = 0, lib_count = 0; + coff_section text, data, bss; + u_long start_addr = 0, p = bprm->p; + short flags, aout_size = 0; + int pageable = 1, sections = 0, status = 0, i; + int coff_exec_fileno; + mm_segment_t old_fs; + + + coff_hdr = (COFF_FILHDR *)bprm->buf; + + /* + * Validate the magic value for the object file. + */ + if (COFF_I386BADMAG(*coff_hdr)) + return -ENOEXEC; + + flags = COFF_SHORT(coff_hdr->f_flags); + + /* + * The object file should have 32 BIT little endian format. Do not allow + * it to have the 16 bit object file flag set as Linux is not able to run + * on the 80286/80186/8086. + */ + if ((flags & (COFF_F_AR32WR | COFF_F_AR16WR)) != COFF_F_AR32WR) + return -ENOEXEC; + + /* + * If the file is not executable then reject the execution. This means + * that there must not be external references. + */ + if ((flags & COFF_F_EXEC) == 0) + return -ENOEXEC; + + /* + * Extract the header information which we need. + */ + sections = COFF_SHORT(coff_hdr->f_nscns); /* Number of sections */ + aout_size = COFF_SHORT(coff_hdr->f_opthdr); /* Size of opt. headr */ + + /* + * There must be at least one section. + */ + if (!sections) + return -ENOEXEC; + + if (!bprm->file->f_op->mmap) + pageable = 0; + + if (!(sect_bufr = kmalloc(sections * COFF_SCNHSZ, GFP_KERNEL))) { + printk(KERN_WARNING "coff: kmalloc failed\n"); + return -ENOMEM; + } + + status = kernel_read(bprm->file, aout_size + COFF_FILHSZ, + (char *)sect_bufr, sections * COFF_SCNHSZ); + if (status < 0) { + printk(KERN_WARNING "coff: unable to read\n"); + goto out_free_buf; + } + + status = get_unused_fd(); + if (status < 0) { + printk(KERN_WARNING "coff: unable to get free fs\n"); + goto out_free_buf; + } + + get_file(bprm->file); + fd_install(coff_exec_fileno = status, bprm->file); + + /* + * Loop through the sections and find the various types + */ + sect_ptr = sect_bufr; + + for (i = 0; i < sections; i++) { + long int sect_flags = COFF_LONG(sect_ptr->s_flags); + + switch (sect_flags) { + case COFF_STYP_TEXT: + status |= coff_isaligned(sect_ptr); + text_sect = sect_ptr; + text_count++; + break; + + case COFF_STYP_DATA: + status |= coff_isaligned(sect_ptr); + data_sect = sect_ptr; + data_count++; + break; + + case COFF_STYP_BSS: + bss_sect = sect_ptr; + bss_count++; + break; + + case COFF_STYP_LIB: + lib_count++; + break; + + default: + break; + } + + sect_ptr = (COFF_SCNHDR *) & ((char *) sect_ptr)[COFF_SCNHSZ]; + } + + /* + * If any of the sections weren't properly aligned we aren't + * going to be able to demand page this executable. Note that + * at this stage the *only* excuse for having status <= 0 is if + * the alignment test failed. + */ + if (status < 0) + pageable = 0; + + /* + * Ensure that there are the required sections. There must be one + * text sections and one each of the data and bss sections for an + * executable. A library may or may not have a data / bss section. + */ + if (text_count != 1) { + status = -ENOEXEC; + goto out_free_file; + } + if (binary && (data_count != 1 || bss_count != 1)) { + status = -ENOEXEC; + goto out_free_file; + } + + /* + * If there is no additional header then assume the file starts + * at the first byte of the text section. This may not be the + * proper place, so the best solution is to include the optional + * header. A shared library __MUST__ have an optional header to + * indicate that it is a shared library. + */ + if (aout_size == 0) { + if (!binary) { + status = -ENOEXEC; + goto out_free_file; + } + start_addr = COFF_LONG(text_sect->s_vaddr); + } else if (aout_size < (short) COFF_AOUTSZ) { + status = -ENOEXEC; + goto out_free_file; + } else { + COFF_AOUTHDR *aout_hdr; + short aout_magic; + + aout_hdr = (COFF_AOUTHDR *) &((char *)coff_hdr)[COFF_FILHSZ]; + aout_magic = COFF_SHORT(aout_hdr->magic); + + /* + * Validate the magic number in the a.out header. If it is valid then + * update the starting symbol location. Do not accept these file formats + * when loading a shared library. + */ + switch (aout_magic) { + case COFF_OMAGIC: + case COFF_ZMAGIC: + case COFF_STMAGIC: + if (!binary) { + status = -ENOEXEC; + goto out_free_file; + } + start_addr = (u_int)COFF_LONG(aout_hdr->entry); + break; + /* + * Magic value for a shared library. This is valid only when + * loading a shared library. + * + * (There is no need for a start_addr. It won't be used.) + */ + case COFF_SHMAGIC: + if (!binary) + break; + /* FALLTHROUGH */ + default: + status = -ENOEXEC; + goto out_free_file; + } + } + + /* + * Generate the proper values for the text fields + * + * THIS IS THE POINT OF NO RETURN. THE NEW PROCESS WILL TRAP OUT SHOULD + * SOMETHING FAIL IN THE LOAD SEQUENCE FROM THIS POINT ONWARD. + */ + + text.scnptr = COFF_LONG(text_sect->s_scnptr); + text.size = COFF_LONG(text_sect->s_size); + text.vaddr = COFF_LONG(text_sect->s_vaddr); + + /* + * Generate the proper values for the data fields + */ + + if (data_sect != NULL) { + data.scnptr = COFF_LONG(data_sect->s_scnptr); + data.size = COFF_LONG(data_sect->s_size); + data.vaddr = COFF_LONG(data_sect->s_vaddr); + } else { + data.scnptr = 0; + data.size = 0; + data.vaddr = 0; + } + + /* + * Generate the proper values for the bss fields + */ + + if (bss_sect != NULL) { + bss.size = COFF_LONG(bss_sect->s_size); + bss.vaddr = COFF_LONG(bss_sect->s_vaddr); + } else { + bss.size = 0; + bss.vaddr = 0; + } + + /* + * Flush the executable from memory. At this point the executable is + * committed to being defined or a segmentation violation will occur. + */ + + if (binary) { + COFF_SCNHDR *sect_ptr2 = sect_bufr; + u_long personality = PER_SVR3; + int i; + + if ((status = flush_old_exec(bprm))) + goto out_free_file; + + /* + * Look for clues as to the system this binary was compiled + * on in the comments section(s). + * + * Only look at the main binary, not the shared libraries + * (or would it be better to prefer shared libraries over + * binaries? Or could they be different???) + */ + for (i = 0; i < sections; i++) { + long sect_flags = COFF_LONG(sect_ptr2->s_flags); + + if (sect_flags == COFF_STYP_INFO && + (status = coff_parse_comments(bprm->file, + sect_ptr2, &personality)) > 0) + goto found; + + sect_ptr2 = (COFF_SCNHDR *) &((char *)sect_ptr2)[COFF_SCNHSZ]; + } + + /* + * If no .comments section was found there is no way to + * figure out the personality. Odds on it is SCO though... + */ + personality = abi_defhandler_coff; + +found: + set_personality(personality); + + current->mm->start_data = 0; + current->mm->end_data = 0; + current->mm->end_code = 0; + current->mm->mmap = NULL; + current->flags &= ~PF_FORKNOEXEC; + current->mm->rss = 0; + + /* + * Construct the parameter and environment + * string table entries. + */ + if ((status = setup_arg_pages(bprm, EXSTACK_DEFAULT)) < 0) + goto sigsegv; + + p = (u_long)coff_mktables((char *)bprm->p, + bprm->argc, bprm->envc); + + current->mm->end_code = text.size + + (current->mm->start_code = text.vaddr); + current->mm->end_data = data.size + + (current->mm->start_data = data.vaddr); + current->mm->brk = bss.size + + (current->mm->start_brk = bss.vaddr); + + current->mm->start_stack = p; + compute_creds(bprm); + start_thread(regs, start_addr, p); + } + + old_fs = get_fs(); + set_fs(get_ds()); + + if (!pageable) { + /* + * Read the file from disk... + * + * XXX: untested. + */ + loff_t pos = data.scnptr; + status = do_brk(text.vaddr, text.size); + bprm->file->f_op->read(bprm->file, + (char *)data.vaddr, data.scnptr, &pos); + status = do_brk(data.vaddr, data.size); + bprm->file->f_op->read(bprm->file, + (char *)text.vaddr, text.scnptr, &pos); + status = 0; + } else { + /* map the text pages...*/ + status = map_coff(bprm->file, &text, PROT_READ | PROT_EXEC, + MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE, + text.scnptr & PAGE_MASK); + + if (status != (text.vaddr & PAGE_MASK)) { + status = -ENOEXEC; + goto out_free_file; + } + + /* map the data pages */ + if (data.size != 0) { + status = map_coff(bprm->file, &data, + PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE, + data.scnptr & PAGE_MASK); + + if (status != (data.vaddr & PAGE_MASK)) { + status = -ENOEXEC; + goto out_free_file; + } + } + + status = 0; + } + + /* + * Construct the bss data for the process. The bss ranges from the + * end of the data (which may not be on a page boundary) to the end + * of the bss section. Allocate any necessary pages for the data. + */ + if (bss.size != 0) { + down_write(¤t->mm->mmap_sem); + do_mmap(NULL, PAGE_ALIGN(bss.vaddr), + bss.size + bss.vaddr - + PAGE_ALIGN(bss.vaddr), + PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_FIXED | MAP_PRIVATE, 0); + up_write(¤t->mm->mmap_sem); + + if ((status = coff_clear_memory(bss.vaddr, bss.size)) < 0) + goto out_free_file; + } + + set_fs(old_fs); + + if (!binary) + goto out_free_file; + + /* + * Load any shared library for the executable. + */ + if (lib_count) + status = coff_preload_shlibs(bprm, sect_bufr, sections); + + set_binfmt(&coff_format); + + /* + * Generate any needed trap for this process. If an error occured then + * generate a segmentation violation. If the process is being debugged + * then generate the load trap. (Note: If this is a library load then + * do not generate the trap here. Pass the error to the caller who + * will do it for the process in the outer lay of this procedure call.) + */ + if (status < 0) { +sigsegv: + printk(KERN_WARNING "coff: trapping process with SEGV\n"); + send_sig(SIGSEGV, current, 0); /* Generate the error trap */ + } else if (current->ptrace & PT_PTRACED) + send_sig(SIGTRAP, current, 0); + + /* We are committed. It can't fail */ + status = 0; + +out_free_file: + sys_close(coff_exec_fileno); + +out_free_buf: + kfree(sect_bufr); + return (status); +} + +/* + * This procedure is called to load a library section. The various + * libraries are loaded from the list given in the section data. + */ +static int +coff_preload_shlib(struct linux_binprm *exe_bprm, COFF_SCNHDR *sect) +{ + COFF_SLIBHD *phdr; + char *buffer; + long nbytes; + int err = 0; + + /* + * Fetch the size of the section. There must be + * enough room for at least one entry. + */ + nbytes = (long)COFF_LONG(sect->s_size); + if (nbytes < (long)COFF_SLIBSZ) + return -ENOEXEC; + + if (!(buffer = kmalloc(nbytes, GFP_KERNEL))) { + printk(KERN_WARNING "coff: unable to allocate shlib buffer\n"); + return -ENOMEM; + } + + err = kernel_read(exe_bprm->file, + COFF_LONG(sect->s_scnptr), buffer, nbytes); + + if (err < 0) + goto out; + if (err != nbytes) + goto enoexec; + + /* + * Go through the list of libraries in the data area. + */ + phdr = (COFF_SLIBHD *)buffer; + while (nbytes > (long)COFF_SLIBSZ) { + int entry_size, header_size; + mm_segment_t old_fs = get_fs(); + + entry_size = COFF_LONG(phdr->sl_entsz) * sizeof(long); + header_size = COFF_LONG(phdr->sl_pathndx) * sizeof(long); + + /* + * Validate the sizes of the various items. + * I don't trust the linker!! + */ + if ((u_int)header_size >= (u_int)nbytes) + goto enoexec; + if ((u_int)entry_size <= (u_int)header_size) + goto enoexec; + if (entry_size <= 0) + goto enoexec; + + set_fs(get_ds()); + err = sys_uselib(&((char *)phdr)[header_size]); + set_fs(old_fs); + + if (err < 0) + goto out; + + /* + * Point to the next library in the section data. + */ + nbytes -= entry_size; + phdr = (COFF_SLIBHD *) & ((char *) phdr)[entry_size]; + } + +out: + kfree(buffer); + return (err); +enoexec: + err = -ENOEXEC; + goto out; +} + +/* + * Find all library sections and preload the shared libraries. + * + * This will eventually recurse to our code and load the shared + * library with our own procedures. + */ +static int +coff_preload_shlibs(struct linux_binprm *bpp, COFF_SCNHDR *sp, int sections) +{ + long flags; + int err = 0, i; + + for (i = 0; i < sections; i++) { + flags = COFF_LONG(sp->s_flags); + if (flags == COFF_STYP_LIB) { + if ((err = coff_preload_shlib(bpp, sp))) + break; + } + sp = (COFF_SCNHDR *)&((char *)sp)[COFF_SCNHSZ]; + } + + return (err); +} + +/* + * Load the image for an (coff) binary. + * + * => this procedure is called by the main load sequence, + * it will load the executable and prepare it for execution + */ +static int +coff_load_binary(struct linux_binprm *bpp, struct pt_regs *rp) +{ + return (coff_load_object(bpp, rp, 1)); +} + +/* + * Load the image for a (coff) shared library. + * + * => this is called when we need to load a library based upon a file name. + * => also called through coff_preload_shlib + */ +static int +coff_load_shlib(struct file *fp) +{ + struct linux_binprm *bpp; + struct pt_regs regs; + int err = -ENOMEM; + + if (!(bpp = kmalloc(sizeof(struct linux_binprm), GFP_KERNEL))) { + printk(KERN_WARNING "coff: kmalloc failed\n"); + goto out; + } + + memset(bpp, 0, sizeof(struct linux_binprm)); + bpp->file = fp; + + if ((err = kernel_read(fp, 0L, bpp->buf, sizeof(bpp->buf))) < 0) + printk(KERN_WARNING "coff: unable to read library header\n"); + else + err = coff_load_object(bpp, ®s, 0); + + kfree(bpp); +out: + return (err); +} + +static int __init +coff_module_init(void) +{ + return (register_binfmt(&coff_format)); +} + +static void __exit +coff_module_exit(void) +{ + unregister_binfmt(&coff_format); +} + +module_init(coff_module_init); +module_exit(coff_module_exit); diff -Nru linux-2.6.7/fs/binfmt_xout.c linux-2.6.7-abi/fs/binfmt_xout.c --- linux-2.6.7/fs/binfmt_xout.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/fs/binfmt_xout.c 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,853 @@ +/* + * Copyright (c) 1994 Mike Jagdis (jaggy@purplet.demon.co.uk) + * Copyright (c) 2001 Christoph Hellwig (hch@caldera.de) + */ + +#ident "%W% %G%" + +/* + * This file is based upon code written by Al Longyear for the COFF file + * format which is in turn based upon code written by Eric Youngdale for + * the ELF object file format. Any errors are most likely my own however. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define __KERNEL_SYSCALLS__ +#include +#include +#include + +#include +#include + + +MODULE_DESCRIPTION("Support for the Microsoft a.out (x.out) binary format"); +MODULE_AUTHOR("Mike Jagdis, Christoph Hellwig"); +MODULE_LICENSE("GPL"); + + +/* + * This is the name of the overlay library used for handling + * Xenix/286 binaries. Usually there is no need to change this. + */ +#define _PATH_X286EMUL "/usr/lib/x286emul" + +/* + * If you compile with XOUT_DEBUG defined you will get additional + * debugging messages from the x.out module. + */ +#undef XOUT_DEBUG + +/* + * If you compile with XOUT_SEGMENTS defined the loader will take care + * to set up the LDT as would "real" Xenix. This shouldn't be necessary + * for most programs but it is just possible that something out there + * makes assumptions about its environment and uses segment overrides. + * + * The default is not to bother setting up the LDT unless we need support + * for Xenix 286 binaries. + */ +#undef XOUT_SEGMENTS + +/* + * Xenix 286 requires segment handling. + */ +#if defined(CONFIG_BINFMT_XOUT_X286) +#define XOUT_SEGMENTS +#endif + +/* + * Be verbose if XOUT_DEBUG is defined. + */ +#if defined(XOUT_DEBUG) +#define dprintk(x...) printk(x) +#else +#define dprintk(x...) +#endif + + +static int xout_load_binary(struct linux_binprm *, struct pt_regs *); +static int xout_load_library(struct file *); + +static struct linux_binfmt xout_format = { + NULL, THIS_MODULE, xout_load_binary, xout_load_library, NULL, PAGE_SIZE +}; + +#if defined(XOUT_DEBUG) && defined(XOUT_SEGMENTS) + +static u_long __gdt[2]; + +/* + * This is borrowed (with minor variations since we are in kernel mode) + * from the DPMI code for DOSEMU. I don't claim to understand LDTs :-). + */ +void +print_desc(int which) +{ + u_long base_addr, limit; + u_long *lp; + int count, type, dpl, i; + + if (which) { + lp = (u_long *)((struct desc_struct*) + (current->mm->context.segments)); + count = LDT_ENTRIES; + printk(KERN_DEBUG "xout: LDT\n"); + } else { + /* joerg from david bruce */ + asm volatile ("sgdt __gdt+2"); + lp = (u_long *)__gdt[1]; + count = 8; + printk(KERN_DEBUG "xout: GDT\n"); + } + + if (!lp) + return; + + printk(KERN_DEBUG "XOUT: SLOT BASE/SEL LIM/OFF TYPE DPL ACCESSBITS\n"); + for (i=0; i < count; i++, lp++) { + /* First 32 bits of descriptor */ + base_addr = (*lp >> 16) & 0x0000FFFF; + limit = *lp & 0x0000FFFF; + lp++; + + /* First 32 bits of descriptor */ + base_addr |= (*lp & 0xFF000000) | ((*lp << 16) & 0x00FF0000); + limit |= (*lp & 0x000F0000); + type = (*lp >> 10) & 7; + dpl = (*lp >> 13) & 3; + if ((base_addr > 0) || (limit > 0 )) { + printk(KERN_DEBUG "XOUT: %03d 0x%08lx 0x%08lx 0x%02x %03d %s%s%s%s%s%s%s\n", + i, + base_addr, limit, type, dpl, + (*lp & 0x100) ? " ACCS'D" : "", + (*lp & 0x200) ? " R&W" : " R&X", + (*lp & 0x8000) ? " PRESENT" : "", + (*lp & 0x100000) ? " USER" : "", + (*lp & 0x200000) ? " X" : "", + (*lp & 0x400000) ? " 32" : "", + (*lp & 0x800000) ? " PAGES" : ""); + } + } +} +#endif + + +static u_long * +xout_create_tables(char *p, struct linux_binprm *bprm, int ibcs) +{ + int argc = bprm->argc, envc = bprm->envc; + u_long *argv,*envp; + u_long *sp; + + sp = (u_long *) ((-(u_long)sizeof(char *)) & (u_long) p); + sp -= envc+1; + envp = sp; + sp -= argc+1; + argv = sp; + if (!ibcs) { + sp--; + put_user(envp, sp); + sp--; + put_user(argv, sp); + } + sp--; + put_user(argc, sp); + current->mm->arg_start = (u_long) p; + while (argc-->0) { + put_user(p, argv); argv++; + p += strlen_user(p); + } + put_user(NULL,argv); + current->mm->arg_end = current->mm->env_start = (u_long) p; + while (envc-->0) { + put_user(p, envp); envp++; + p += strlen_user(p); + } + put_user(NULL,envp); + current->mm->env_end = (u_long) p; + return (sp); +} + +static __inline int +isnotaligned(struct xseg *seg) +{ + dprintk(KERN_DEBUG + "xout: %04x %04x %04x %02x %08lx %08lx %08lx %08lx\n", + seg->xs_type, seg->xs_attr, seg->xs_seg, seg->xs_align, + seg->xs_filpos, seg->xs_psize, seg->xs_vsize, seg->xs_rbase); + +#if defined(XOUT_DEBUG) + if ((seg->xs_filpos - seg->xs_rbase) & ~PAGE_MASK) { + printk(KERN_DEBUG + "xout: bad alignment - demand paging disabled\n"); + } +#endif + return ((seg->xs_filpos & ~PAGE_MASK) | (seg->xs_rbase & ~PAGE_MASK)); +} + +static __inline__ void +clear_memory(u_long addr, u_long size) +{ + while (size-- != 0) + put_user(0, (char *)addr++); +} + +#if defined(XOUT_SEGMENTS) +#if defined(CONFIG_X86) +/* from linux-2.4.25/include/asm-i386/ldt.h */ +struct modify_ldt_ldt_s { + unsigned int entry_number; + unsigned long base_addr; + unsigned int limit; + unsigned int seg_32bit:1; + unsigned int contents:2; + unsigned int read_exec_only:1; + unsigned int limit_in_pages:1; + unsigned int seg_not_present:1; + unsigned int useable:1; +}; +#endif +#endif + +static int +xout_amen(struct file *fp, struct xseg *sp, int pageable, u_long *addrp, + struct xexec *xexec, struct pt_regs *regs, int impure) +{ +#if defined(XOUT_SEGMENTS) + struct xext *xext = (struct xext *)(xexec + 1); + struct desc_struct def_ldt; + struct modify_ldt_ldt_s ldt_info; + mm_segment_t old_fs; + u_long mirror_addr = 0; + int l; +#endif + u_long bss_size, bss_base; + int err = 0; + +#if defined(XOUT_SEGMENTS) + old_fs = get_fs(); + +seg_again: + l = 0; + + /* + * Xenix 386 segments simply map the whole address + * space either read-exec only or read-write. + */ + ldt_info.entry_number = sp->xs_seg >> 3; + ldt_info.read_exec_only = 0 /* ((s->xs_attr & XS_APURE) ? 1 : 0) */; + ldt_info.contents = ((sp->xs_type == XS_TTEXT) ? 2 : 0); + ldt_info.seg_not_present = 0; + ldt_info.seg_32bit = ((sp->xs_attr & XS_A32BIT) ? 1 : 0); + if (!ldt_info.seg_32bit) { + ldt_info.base_addr = *addrp; + *addrp = PAGE_ALIGN(*addrp + sp->xs_vsize); + sp->xs_rbase = ldt_info.base_addr; + } else + ldt_info.base_addr = 0; +#endif + + bss_size = sp->xs_vsize - sp->xs_psize; + bss_base = sp->xs_rbase + sp->xs_psize; + + /* + * If it is a text segment update the code boundary + * markers. If it is a data segment update the data + * boundary markers. + */ + if (sp->xs_type == XS_TTEXT) { + if ((sp->xs_rbase + sp->xs_psize) > current->mm->end_code) + current->mm->end_code = (sp->xs_rbase + sp->xs_psize); + } else if (sp->xs_type == XS_TDATA) { +#if defined(XOUT_SEGMENTS) + /* + * If it is the first data segment note that + * this is the segment we start in. If this + * isn't a 386 binary add the stack to the + * top of this segment. + */ + if ((xexec->x_cpu & XC_CPU) != XC_386) { + if (regs->ebx == regs->ecx) { + regs->ecx = sp->xs_seg; + regs->edx = sp->xs_vsize; + sp->xs_vsize = 0x10000; + *addrp = PAGE_ALIGN(ldt_info.base_addr + sp->xs_vsize); + } + } else { + if (regs->xds == regs->xcs) + regs->xds = regs->xes = regs->xss = sp->xs_seg; + } +#endif + if ((sp->xs_rbase + sp->xs_psize) > current->mm->end_data) + current->mm->end_data = (sp->xs_rbase + sp->xs_psize); + } + + if ((sp->xs_rbase + sp->xs_vsize) > current->mm->brk) { + current->mm->start_brk = + current->mm->brk = PAGE_ALIGN(sp->xs_rbase + sp->xs_vsize); + } + +#if defined(XOUT_SEGMENTS) + if (ldt_info.seg_32bit) { + ldt_info.limit = (TASK_SIZE-1) >> 12; + ldt_info.limit_in_pages = 1; + } else { + ldt_info.limit = sp->xs_vsize-1; + ldt_info.limit_in_pages = 0; + } + + dprintk(KERN_DEBUG "xout: ldt %02x, type=%d, base=0x%08lx, " + "limit=0x%08x, pages=%d, 32bit=%d\n", + ldt_info.entry_number, ldt_info.contents, + ldt_info.base_addr, ldt_info.limit, + ldt_info.limit_in_pages, ldt_info.seg_32bit); + + /* + * Use the modify_ldt syscall since this allocates + * the initial space for the LDT table, tweaks the + * GDT etc. We need to read the current LDT first + * since we need to copy the lcall7 call gate. + */ + set_fs(get_ds()); + if (!current->mm->context.size) { + sys_modify_ldt(2, &def_ldt, sizeof(def_ldt)); + + dprintk(KERN_DEBUG + "x.out: def_ldt.a 0x%08lx, def_ldt.b 0x%08lx\n", + def_ldt.a, def_ldt.b); + + l = 1; + } + + err = sys_modify_ldt(1, &ldt_info, sizeof(ldt_info)); +#if 0 + if (status >= 0 && !ntext && s->xs_seg == 0x47) { + /* Uh oh, impure binary... */ + ldt_info.entry_number = 0x3f >> 3; +#if 0 + ldt_info.read_exec_only = 1; +#else + ldt_info.read_exec_only = 0; +#endif + ldt_info.contents = 2; + status = sys_modify_ldt)(1, &ldt_info, sizeof(ldt_info)); + } +#endif + set_fs(old_fs); + if (l == 1) { + struct desc_struct *ldt; + + ldt = (struct desc_struct *)current->mm->context.ldt; + ldt->a = def_ldt.a; + ldt->b = def_ldt.b; + + l = 0; + } + if (err < 0) + printk(KERN_INFO "xout: modify_ldt returned %d\n", err); +#endif + + if (err < 0) + goto out; + + if (!pageable) { + dprintk(KERN_DEBUG "xout: Null map 0x%08lx, length 0x%08lx\n", + sp->xs_rbase, sp->xs_vsize); + down_write(¤t->mm->mmap_sem); + err = do_mmap(NULL, sp->xs_rbase, sp->xs_vsize, + PROT_READ|PROT_WRITE|PROT_EXEC, + MAP_FIXED|MAP_PRIVATE, 0); + up_write(¤t->mm->mmap_sem); + goto out; + } + + dprintk(KERN_DEBUG "xout: mmap to 0x%08lx from 0x%08lx, length 0x%08lx\n", + sp->xs_rbase, sp->xs_filpos, sp->xs_psize); + if (sp->xs_attr & XS_APURE) { + down_write(¤t->mm->mmap_sem); + err = do_mmap(fp, sp->xs_rbase, sp->xs_psize, + PROT_READ|PROT_EXEC, MAP_FIXED|MAP_SHARED, + sp->xs_filpos); + up_write(¤t->mm->mmap_sem); + } else { + down_write(¤t->mm->mmap_sem); + err = do_mmap(fp, sp->xs_rbase, sp->xs_psize, + PROT_READ|PROT_WRITE|PROT_EXEC, + MAP_FIXED|MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE, + sp->xs_filpos); + up_write(¤t->mm->mmap_sem); + } + + if (err > TASK_SIZE || err < 0) + goto out; + + /* + * Map uninitialised data. + */ + if (bss_size) { + if (bss_base & PAGE_MASK) { + clear_memory(bss_base, PAGE_ALIGN(bss_base)-bss_base); + bss_size -= (PAGE_ALIGN(bss_base) - bss_base); + bss_base = PAGE_ALIGN(bss_base); + } + + dprintk(KERN_DEBUG "xout: Null map 0x%08lx, length 0x%08lx\n", + bss_base, bss_size); + + down_write(¤t->mm->mmap_sem); + err = do_mmap(NULL, bss_base, bss_size, + PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_FIXED | MAP_PRIVATE, 0); + up_write(¤t->mm->mmap_sem); + } + +out: + if (err > TASK_SIZE) + return -EINVAL; +#if defined(XOUT_SEGMENTS) + if (err >= 0 && impure && sp->xs_seg >= 0x47) { + /* + * Uh oh, impure binary. + * Mirror this data segment to the text segment + */ + *addrp = mirror_addr = sp->xs_rbase; + sp->xs_seg = xext->xe_eseg; + sp->xs_type = XS_TTEXT; + goto seg_again; + } +#endif + return (err); +} + +/* + * Helper function to process the load operation. + */ +static int +xout_load_object(struct linux_binprm * bpp, struct pt_regs *rp, int executable) +{ + struct xexec *xexec = (struct xexec *)bpp->buf; + struct xext *xext = (struct xext *)(xexec + 1); + struct xseg *seglist; + struct file *fp = NULL; + u_long addr; + int nsegs, ntext, ndata; + int pageable = 1, err = 0; + int i; + + dprintk(KERN_DEBUG "xout: binfmt_xout entry: %s\n", + bpp->file->f_dentry->d_name.name); + + if (xexec->x_magic != X_MAGIC) { + dprintk(KERN_DEBUG "xout: bad magic %04x\n", xexec->x_magic); + return -ENOEXEC; + } + + switch (xexec->x_cpu & XC_CPU) { + case XC_386: + break; +#if defined(CONFIG_BINFMT_XOUT_X286) + case XC_8086: + case XC_286: + case XC_286V: + case XC_186: + break; +#endif + default: + dprintk(KERN_DEBUG "xout: unsupported CPU type (%02x)\n", + xexec->x_cpu); + return -ENOEXEC; + } + + /* + * We can't handle byte or word swapped headers. Well, we + * *could* but they should never happen surely? + */ + if ((xexec->x_cpu & (XC_BSWAP | XC_WSWAP)) != XC_WSWAP) { + dprintk(KERN_DEBUG "xout: wrong byte or word sex (%02x)\n", + xexec->x_cpu); + return -ENOEXEC; + } + + /* Check it's an executable. */ + if (!(xexec->x_renv & XE_EXEC)) { + dprintk(KERN_DEBUG "xout: not executable\n"); + return -ENOEXEC; + } + + /* + * There should be an extended header and there should be + * some segments. At this stage we don't handle non-segmented + * binaries. I'm not sure you can get them under Xenix anyway. + */ + if (xexec->x_ext != sizeof(struct xext)) { + dprintk(KERN_DEBUG "xout: bad extended header\n"); + return -ENOEXEC; + } + + if (!(xexec->x_renv & XE_SEG) || !xext->xe_segsize) { + dprintk(KERN_DEBUG "xout: not segmented\n"); + return -ENOEXEC; + } + + if (!(seglist = kmalloc(xext->xe_segsize, GFP_KERNEL))) { + printk(KERN_WARNING "xout: allocating segment list failed\n"); + return -ENOMEM; + } + + err = kernel_read(bpp->file, xext->xe_segpos, + (char *)seglist, xext->xe_segsize); + if (err < 0) { + dprintk(KERN_DEBUG "xout: problem reading segment table\n"); + goto out; + } + + if (!bpp->file->f_op->mmap) + pageable = 0; + + nsegs = xext->xe_segsize / sizeof(struct xseg); + + ntext = ndata = 0; + for (i = 0; i < nsegs; i++) { + switch (seglist[i].xs_type) { + case XS_TTEXT: + if (isnotaligned(seglist+i)) + pageable = 0; + ntext++; + break; + case XS_TDATA: + if (isnotaligned(seglist+i)) + pageable = 0; + ndata++; + break; + } + } + + if (!ndata) + goto out; + + /* + * Generate the proper values for the text fields + * + * THIS IS THE POINT OF NO RETURN. THE NEW PROCESS WILL TRAP OUT SHOULD + * SOMETHING FAIL IN THE LOAD SEQUENCE FROM THIS POINT ONWARD. + */ + + /* + * Flush the executable from memory. At this point the executable is + * committed to being defined or a segmentation violation will occur. + */ + if (executable) { + dprintk(KERN_DEBUG "xout: flushing executable\n"); + + flush_old_exec(bpp); + + current->mm->mmap = NULL; + current->mm->rss = 0; + + if ((err = setup_arg_pages(bpp, EXSTACK_DEFAULT)) < 0) { + send_sig(SIGSEGV, current, 1); + return (err); + } + + bpp->p = (u_long)xout_create_tables((char *)bpp->p, bpp, + (xexec->x_cpu & XC_CPU) == XC_386 ? 1 : 0); + +#if defined(XOUT_SEGMENTS) + /* + * These will be set up later once we've seen the + * segments that make the program up. + */ + current->mm->start_code = 0; + current->mm->start_data = 0; + current->mm->end_code = 0; + current->mm->end_data = 0; + current->mm->start_brk = 0; + current->mm->brk = 0; + + compute_creds(bpp); + current->flags &= ~PF_FORKNOEXEC; + + /* + * The code selector is advertised in the header. + */ + if ((xexec->x_cpu & XC_CPU) != XC_386) { + rp->ebx = rp->ecx = xext->xe_eseg; + rp->eax = xexec->x_entry; + } else { + rp->xcs = rp->xds = rp->xes = rp->xss = xext->xe_eseg; + rp->eip = xexec->x_entry; + } +#else /* XOUT_SEGMENTS */ + current->mm->start_code = 0; + current->mm->end_code = xexec->x_text; + current->mm->end_data = xexec->x_text + xexec->x_data; + current->mm->start_brk = + current->mm->brk = xexec->x_text + xexec->x_data + xexec->x_bss; + + compute_creds(bpp); + current->flags &= ~PF_FORKNOEXEC; + + rp->xcs = __USER_CS; + rp->xds = rp->xes = rp->xss = __USER_DS; + rp->eip = xexec->x_entry; +#endif /* XOUT_SEGMENTS */ + + dprintk(KERN_DEBUG "xout: entry point = 0x%x:0x%08lx\n", + xext->xe_eseg, xexec->x_entry); + + rp->esp = current->mm->start_stack = bpp->p; + + set_personality(PER_XENIX); + } + + /* + * Base address for mapping 16bit segments. This should lie above + * the emulator overlay. + */ + addr = X286_MAP_ADDR; + +#if defined(CONFIG_BINFMT_XOUT_X286) + /* + * If this isn't a 386 executable we need to load the overlay + * library to emulate a [2]86 environment and save the binary + * headers for later reference by the emulator. + */ + if ((xexec->x_cpu & XC_CPU) != XC_386) { + mm_segment_t fs = get_fs(); + + set_fs(get_ds()); + err = sys_uselib(_PATH_X286EMUL); + set_fs(fs); + if (err < 0) { + printk(KERN_ERR + "xout: loading of %s failed with error %d\n", + _PATH_X286EMUL, err); + goto out; + } + + down_write(¤t->mm->mmap_sem); + err = do_mmap(NULL, + addr, sizeof(struct xexec)+sizeof(struct xext), + PROT_READ|PROT_WRITE|PROT_EXEC, + MAP_FIXED|MAP_PRIVATE, + 0); + up_write(¤t->mm->mmap_sem); + + if (err > TASK_SIZE) + goto Einval; + if (err >= 0) { + copy_to_user((char *)addr, xexec, sizeof(struct xexec)); + copy_to_user((char *)addr+sizeof(struct xexec), xext, sizeof(struct xext)); + addr = PAGE_ALIGN(addr+sizeof(struct xexec)+sizeof(struct xext)); + } + } +#endif + + /* + * Scan the segments and map them into the process space. If this + * executable is pageable (unlikely since Xenix aligns to 1k + * boundaries and we want it aligned to 4k boundaries) this is + * all we need to do. If it isn't pageable we go round again + * afterwards and load the data. We have to do this in two steps + * because if segments overlap within a 4K page we'll lose the + * first instance when we remap the page. Hope that's clear... + */ + for (i = 0; err >= 0 && i < nsegs; i++) { + struct xseg *sp = seglist+i; + + if (sp->xs_attr & XS_AMEM) { + err = xout_amen(fp, sp, pageable, &addr, + xexec, rp, (!ntext && ndata == 1)); + } + + } + + /* + * We better fix start_data because sys_brk looks there to + * calculate data size. + * Kernel 2.2 did look at end_code so this is reasonable. + */ + if (current->mm->start_data == current->mm->start_code) + current->mm->start_data = current->mm->end_code; + + dprintk(KERN_DEBUG "xout: start code 0x%08lx, end code 0x%08lx," + " start data 0x%08lx, end data 0x%08lx, brk 0x%08lx\n", + current->mm->start_code, current->mm->end_code, + current->mm->start_data, current->mm->end_data, + current->mm->brk); + +#if defined(XOUT_DEBUG) && defined(XOUT_SEGMENTS) + print_desc(1); + print_desc(0); +#endif + + if (pageable) + goto trap; + if (err < 0) + goto trap; + + for (i = 0; (err >= 0) && (i < nsegs); i++) { + struct xseg *sp = seglist + i; + u_long psize; + + if (sp->xs_type == XS_TTEXT || sp->xs_type == XS_TDATA) { + dprintk(KERN_DEBUG "xout: read to 0x%08lx from 0x%08lx," + " length 0x%08lx\n", sp->xs_rbase, + sp->xs_filpos, sp->xs_psize); + + if (sp->xs_psize < 0) + continue; + + /* + * Do we still get the size ? Yes! [joerg] + */ + psize = kernel_read(bpp->file, sp->xs_filpos, + (char *)sp->xs_rbase, sp->xs_psize); + + if (psize != sp->xs_psize) { + dprintk(KERN_DEBUG "xout: short read\n"); + err = -1; + break; + } + } + } + + /* + * Generate any needed trap for this process. If an error occured then + * generate a segmentation violation. If the process is being debugged + * then generate the load trap. (Note: If this is a library load then + * do not generate the trap here. Pass the error to the caller who + * will do it for the process in the outer lay of this procedure call.) + */ +trap: + if (executable) { + if (err < 0) { + dprintk(KERN_DEBUG "xout: loader forces seg fault " + "(err = %d)\n", err); + send_sig(SIGSEGV, current, 0); + } else if (current->ptrace & PT_PTRACED) + send_sig(SIGTRAP, current, 0); + err = 0; + } + +out: + kfree(seglist); + + dprintk(KERN_DEBUG "xout: binfmt_xout: result = %d\n", err); + + /* + * If we are using the [2]86 emulation overlay we enter this + * rather than the real program and give it the information + * it needs to start the ball rolling. + */ + if ((xexec->x_cpu & XC_CPU) != XC_386) { +#if 0 + regs->eax = regs->eip; + regs->ebx = regs->xcs; + regs->ecx = regs->xds; + regs->xcs = __USER_CS; + regs->xds = regs->xes = regs->xss = __USER_DS; +#endif + rp->eip = 0x1020; + dprintk(KERN_DEBUG "xout: x286emul 0x%02lx:0x%04lx," + " ds=0x%02lx, stack 0x%02lx:0x%04lx\n", + rp->ebx, rp->eax, rp->ecx, rp->ecx, + rp->edx); +#ifdef notdef + while (!signal_pending(current)) + schedule(); +#endif + return (err < 0 ? err : rp->eax); + } + +#ifdef notdef + while (!signal_pending(current)) + schedule(); +#endif + /* + * Xenix 386 programs expect the initial brk value to be in eax + * on start up. Hence if we succeeded we need to pass back + * the brk value rather than the status. Ultimately the + * ret_from_sys_call assembly will place this in eax before + * resuming (starting) the process. + */ + return (err < 0 ? err : current->mm->brk); +Einval: + kfree(seglist); + return -EINVAL; +} + + +/* + * This procedure is called by the main load sequence. It will load + * the executable and prepare it for execution. It provides the additional + * parameters used by the recursive xout loader and tells the loader that + * this is the main executable. How simple it is . . . . + */ +static int +xout_load_binary(struct linux_binprm *bpp, struct pt_regs *rp) +{ + return (xout_load_object(bpp, rp, 1)); +} + +/* + * Load the image for any shared library. This is called when + * we need to load a library based upon a file name. + * + * XXX: I have never seen a Xenix shared library... --hch + */ +static int +xout_load_library(struct file *fp) +{ + struct linux_binprm *bpp; + struct pt_regs regs; + int err = -ENOMEM; + + if (!(bpp = kmalloc(sizeof(struct linux_binprm), GFP_KERNEL))) { + printk(KERN_WARNING "xout: kmalloc failed\n"); + goto out; + } + + memset(bpp, 0, sizeof(struct linux_binprm)); + bpp->file = fp; + + if ((err = kernel_read(fp, 0L, bpp->buf, sizeof(bpp->buf))) < 0) + printk(KERN_WARNING "xout: unable to read library header\n"); + else + err = xout_load_object(bpp, ®s, 0); + + kfree(bpp); +out: + return (err); +} + +static int __init +binfmt_xout_init(void) +{ + return register_binfmt(&xout_format); +} + +static void __exit +binfmt_xout_exit(void) +{ + unregister_binfmt(&xout_format); +} + +module_init(binfmt_xout_init); +module_exit(binfmt_xout_exit); diff -Nru linux-2.6.7/fs/Kconfig.binfmt linux-2.6.7-abi/fs/Kconfig.binfmt --- linux-2.6.7/fs/Kconfig.binfmt 2004-06-16 07:20:03.000000000 +0200 +++ linux-2.6.7-abi/fs/Kconfig.binfmt 2004-07-22 17:44:21.000000000 +0200 @@ -119,3 +119,5 @@ You may say M here for module support and later load the module when you have use for it; the module is called binfmt_misc. If you don't know what to answer at this point, say Y. + +source "abi/Kconfig" diff -Nru linux-2.6.7/fs/Makefile linux-2.6.7-abi/fs/Makefile --- linux-2.6.7/fs/Makefile 2004-06-16 07:19:36.000000000 +0200 +++ linux-2.6.7-abi/fs/Makefile 2004-07-22 17:44:21.000000000 +0200 @@ -19,6 +19,8 @@ obj-y += $(nfsd-y) $(nfsd-m) obj-$(CONFIG_BINFMT_AOUT) += binfmt_aout.o +obj-$(CONFIG_BINFMT_XOUT) += binfmt_xout.o +obj-$(CONFIG_BINFMT_COFF) += binfmt_coff.o obj-$(CONFIG_BINFMT_EM86) += binfmt_em86.o obj-$(CONFIG_BINFMT_MISC) += binfmt_misc.o diff -Nru linux-2.6.7/fs/pipe.c linux-2.6.7-abi/fs/pipe.c --- linux-2.6.7/fs/pipe.c 2004-06-16 07:19:35.000000000 +0200 +++ linux-2.6.7-abi/fs/pipe.c 2004-07-22 17:44:21.000000000 +0200 @@ -728,3 +728,9 @@ module_init(init_pipe_fs) module_exit(exit_pipe_fs) + +/* symbol exports for LinuxABI Sytem V R4 support */ +/* for ease of use we are exporting those needed symbols permanently */ +/* #if CONFIG_ABI_SVR4 == m */ +EXPORT_SYMBOL(do_pipe); +/* #endif */ diff -Nru linux-2.6.7/fs/readdir.c linux-2.6.7-abi/fs/readdir.c --- linux-2.6.7/fs/readdir.c 2004-06-16 07:19:22.000000000 +0200 +++ linux-2.6.7-abi/fs/readdir.c 2004-07-22 17:44:21.000000000 +0200 @@ -55,13 +55,6 @@ #ifdef __ARCH_WANT_OLD_READDIR -struct old_linux_dirent { - unsigned long d_ino; - unsigned long d_offset; - unsigned short d_namlen; - char d_name[1]; -}; - struct readdir_callback { struct old_linux_dirent __user * dirent; int result; diff -Nru linux-2.6.7/include/abi/cxenix/signal.h linux-2.6.7-abi/include/abi/cxenix/signal.h --- linux-2.6.7/include/abi/cxenix/signal.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/include/abi/cxenix/signal.h 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,16 @@ +#ifndef _ABI_CXENIX_SIGNAL_H +#define _ABI_CXENIX_SIGNAL_H + +enum { + SCO_SA_NOCLDSTOP = 0x001, + SCO_SA_COMPAT = 0x080, /* 3.2.2 compatibilty. */ + SCO_SA_SIGNAL = 0x100, +}; + +struct sco_sigaction { + void (*sa_handler)(int); + unsigned long sa_mask; + int sa_flags; +}; + +#endif /* _ABI_CXENIX_SIGNAL_H */ diff -Nru linux-2.6.7/include/abi/cxenix/sysent.h linux-2.6.7-abi/include/abi/cxenix/sysent.h --- linux-2.6.7/include/abi/cxenix/sysent.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/include/abi/cxenix/sysent.h 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,47 @@ +/* + * include/abi/xnx.h -- xenix ibcs interface + * + * Copyright (C) 1993 Drew Sullivan + * Released for general use as long as this copyright remains. + */ + +#ident "%W% %G%" + +struct sco_sigaction; +struct timeb; + +typedef unsigned short excode_t; + +extern int xnx_locking(int fd, int mode, unsigned long size); +extern int xnx_creatsem(char *sem_name, int mode); +extern int xnx_opensem(char *sem_name); +extern int xnx_sigsem(int sem_num); +extern int xnx_waitsem(int sem_num); +extern int xnx_nbwaitsem(int sem_num); +extern int xnx_rdchk(int fd); +extern int xnx_ftime(struct timeb * tp); +extern int xnx_nap(long period); +extern int xnx_sdget(char *path, int flags, long size, int mode); +extern int xnx_sdfree(char* addr); +extern int xnx_sdenter(char *addr, int flags); +extern int xnx_sdleave(char *addr); +extern int xnx_sdgetv(char *addr); +extern int xnx_sdwaitv(char *addr, int vnum); +extern int xnx_proctl(int pid, int command, char *arg); +extern int xnx_execseg(excode_t oldaddr, unsigned size); +extern int xnx_unexecseg(excode_t addr); +extern int xnx_eaccess(char *path, int mode); +extern int xnx_paccess(int pid, int cmd, int offset, int count, char *ptr); +extern int xnx_sigpending(unsigned long *set); +extern int xnx_pathconf(char *path, int name); +extern int xnx_fpathconf(int fildes, int name); + +/* signal.c */ +extern int xnx_sigaction(int, const struct sco_sigaction *, + struct sco_sigaction *); + +/* utsname.c */ +extern int xnx_utsname(u_long addr); + +/* sysent.h */ +extern void cxenix(struct pt_regs *); diff -Nru linux-2.6.7/include/abi/ioctl.h linux-2.6.7-abi/include/abi/ioctl.h --- linux-2.6.7/include/abi/ioctl.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/include/abi/ioctl.h 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,43 @@ +/* + * Copyright (C) 1994 Mike Jagdis (jaggy@purplet.demon.co.uk) + * Copyright (C) 2001 Caldera Deutschland GmbH + */ +#ifndef _ABI_IOCTL_H +#define _ABI_IOCTL_H + +#ident "%W% %G%" + +/* + * Ioctl's have the command encoded in the lower word, and the size of + * any in or out parameters in the upper word. The high 3 bits of the + * upper word are used to encode the in/out status of the parameter. + * + * Note that Linux does the same but has the IOC_IN and IOC_OUT values + * round the other way and uses 0 for IOC_VOID. + */ +enum { + /* parameter length, at most 13 bits */ + BSD_IOCPARM_MASK = 0x1fff, + /* no parameters */ + BSD_IOC_VOID = 0x20000000, + /* copy out parameters */ + BSD_IOC_OUT = 0x40000000, + /* copy in parameters */ + BSD_IOC_IN = 0x80000000, + /* possibly copy in and out parameters */ + BSD_IOC_INOUT = BSD_IOC_IN|BSD_IOC_OUT, +}; + + +#define BSD__IOC(inout,group,num,len) \ + (inout | ((len & BSD_IOCPARM_MASK) << 16) | ((group) << 8) | (num)) + +#define BSD__IO(g,n) BSD__IOC(BSD_IOC_VOID, (g), (n), 0) +#define BSD__IOR(g,n,t) BSD__IOC(BSD_IOC_OUT, (g), (n), sizeof(t)) +#define BSD__IOW(g,n,t) BSD__IOC(BSD_IOC_IN, (g), (n), sizeof(t)) +#define BSD__IOWR(g,n,t) BSD__IOC(BSD_IOC_INOUT, (g), (n), sizeof(t)) + +/* Some SYSV systems exhibit "compatible" BSD ioctls without the bumf. */ +#define BSD__IOV(c,d) (((c) << 8) | (d)) + +#endif /* _ABI_IOCTL_H */ diff -Nru linux-2.6.7/include/abi/sco/ioctl.h linux-2.6.7-abi/include/abi/sco/ioctl.h --- linux-2.6.7/include/abi/sco/ioctl.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/include/abi/sco/ioctl.h 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,13 @@ +#ifndef _ABI_SCO_IOCTL_H +#define _ABI_SCO_IOCTL_H + +/* tapeio.c */ +extern int sco_tape_ioctl(int, u_int, caddr_t); + +/* termios.c */ +extern int sco_term_ioctl(int, u_int, caddr_t); + +/* From vtkd.c */ +extern int sco_vtkbd_ioctl(int, u_int, caddr_t); + +#endif /* _ABI_SCO_IOCTL_H */ diff -Nru linux-2.6.7/include/abi/sco/mman.h linux-2.6.7-abi/include/abi/sco/mman.h --- linux-2.6.7/include/abi/sco/mman.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/include/abi/sco/mman.h 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2001 Caldera Deutschland GmbH. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef _ABI_SCO_MMAN_H +#define _ABI_SCO_MMAN_H + +#ident "%W% %G%" + +/* + * SCO OpenServer memory mapped files declarations + */ + +#define SCO_MAP_FAILED ((void *)-1) + +/* protections flags for mmap() and mprotect() */ +#define SCO_PROT_NONE 0x0000 +#define SCO_PROT_READ 0x0001 +#define SCO_PROT_WRITE 0x0002 +#define SCO_PROT_EXEC 0x0004 + +/* sharing types for mmap() */ +#define SCO_MAP_SHARED 0x0001 +#define SCO_MAP_PRIVATE 0x0002 +#define SCO_MAP_FIXED 0x0010 +#define SCO_MAP_PHMEM 0x1000 +#define SCO_MAP_KVMEM 0x2000 +#define SCO_MAP_ANCESTRAL 0x4000 +#define SCO_MAP_NOEOF 0x8000 + +#define SCO_MAP_UNIMPL \ + (SCO_MAP_PHMEM|SCO_MAP_KVMEM|SCO_MAP_ANCESTRAL|SCO_MAP_NOEOF) + +/* memcntl() subfunctions */ +#define SCO_MC_SYNC 0x0001 +#define SCO_MC_LOCK 0x0002 +#define SCO_MC_UNLOCK 0x0003 +#define SCO_MC_LOCKAS 0x0005 +#define SCO_MC_UNLOCKAS 0x0006 +#define SCO_MC_MAPCPU 0x8000 +#define SCO_MC_MAPUBLK 0x8001 + +/* msync() flags */ +#define SCO_MS_SYNC 0x0000 +#define SCO_MS_ASYNC 0x0001 +#define SCO_MS_INVALIDATE 0x0002 + +/* mlockall() flags */ +#define SCO_MCL_CURRENT 0x0001 +#define SCO_MCL_FUTURE 0x0002 + +#endif /* _ABI_SCO_MMAN_H */ diff -Nru linux-2.6.7/include/abi/sco/signal.h linux-2.6.7-abi/include/abi/sco/signal.h --- linux-2.6.7/include/abi/sco/signal.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/include/abi/sco/signal.h 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,43 @@ +#ifndef _ABI_SCO_SIGNAL_H +#define _ABI_SCO_SIGNAL_H + +/* + * Signal numbers for the SCO emulator. + */ + +#ident "%W% %G%" + +#define SCO_SIGHUP 1 /* hangup */ +#define SCO_SIGINT 2 /* interrupt (rubout) */ +#define SCO_SIGQUIT 3 /* quit (ASCII FS) */ +#define SCO_SIGILL 4 /* illegal instruction (not reset when caught) */ +#define SCO_SIGTRAP 5 /* trace trap (not reset when caught) */ +#define SCO_SIGIOT 6 /* IOT instruction */ +#define SCO_SIGABRT 6 /* used by abort, replace SIGIOT in the future */ +#define SCO_SIGEMT 7 /* EMT instruction */ +#define SCO_SIGFPE 8 /* floating point exception */ +#define SCO_SIGKILL 9 /* kill (cannot be caught or ignored) */ +#define SCO_SIGBUS 10 /* bus error */ +#define SCO_SIGSEGV 11 /* segmentation violation */ +#define SCO_SIGSYS 12 /* bad argument to system call */ +#define SCO_SIGPIPE 13 /* write on a pipe with no one to read it */ +#define SCO_SIGALRM 14 /* alarm clock */ +#define SCO_SIGTERM 15 /* software termination signal from kill */ +#define SCO_SIGUSR1 16 /* user defined signal 1 */ +#define SCO_SIGUSR2 17 /* user defined signal 2 */ +#define SCO_SIGCLD 18 /* death of a child */ +#define SCO_SIGPWR 19 /* power-fail restart */ +#define SCO_SIGWINCH 20 /* window change */ +#define SCO_SIGURG 21 /* urgent socket condition */ +#define SCO_SIGPOLL 22 /* pollable event occurred */ +#define SCO_SIGSTOP 23 /* sendable stop signal not from tty */ +#define SCO_SIGTSTP 24 /* stop signal from tty */ +#define SCO_SIGCONT 25 /* continue a stopped process */ +#define SCO_SIGTTIN 26 /* to readers pgrp upon background tty read */ +#define SCO_SIGTTOU 27 /* like TTIN for output if tp->t_local&TOSTOP */ +#define SCO_SIGVTALRM 28 /* virtual timer alarm */ +#define SCO_SIGPROF 29 /* profile alarm */ +#define SCO_SIGXCPU 30 /* CPU time limit exceeded */ +#define SCO_SIGXFSZ 31 /* File size limit exceeded */ + +#endif /* _ABI_SCO_SIGNAL_H */ diff -Nru linux-2.6.7/include/abi/sco/stat.h linux-2.6.7-abi/include/abi/sco/stat.h --- linux-2.6.7/include/abi/sco/stat.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/include/abi/sco/stat.h 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,31 @@ +#ifndef _ABI_SCO_STAT_H +#define _ABI_SCO_STAT_H + +#ident "%W% %G%" + +#include + + +struct sco_xstat { + sco_dev_t st_dev; + u_int32_t __pad1[3]; + sco_ino_t st_ino; + sco_mode_t st_mode; + sco_nlink_t st_nlink; + sco_uid_t st_uid; + sco_gid_t st_gid; + sco_dev_t st_rdev; + u_int32_t __pad2[2]; + sco_off_t st_size; + u_int32_t __pad3; + sco_time_t st_atime; + sco_time_t st_mtime; + sco_time_t st_ctime; + int32_t st_blksize; + int32_t st_blocks; + char st_fstype[16]; + u_int32_t __pad4[7]; + int32_t st_sco_flags; +}; + +#endif /* _ABI_SCO_STAT_H */ diff -Nru linux-2.6.7/include/abi/sco/sysent.h linux-2.6.7-abi/include/abi/sco/sysent.h --- linux-2.6.7/include/abi/sco/sysent.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/include/abi/sco/sysent.h 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2001 Christoph Hellwig. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef _ABI_SCO_SYSENT_H +#define _ABI_SCO_SYSENT_H + +#ident "%W% %G%" + +/* + * External function declarations for the SCO OpenServer syscall table. + */ + +#include + +struct sco_statvfs; + + +/* ioctl.c */ +extern int sco_ioctl(struct pt_regs *); + +/* misc.c */ +extern int sco_lseek(int, u_long, int); +extern int sco_fcntl(int, u_int, u_long); +extern int sco_sysi86(int, void *, int); + +/* mmap.c */ +extern int sco_mmap(u_long, size_t, int, int, int, sco_off_t); + +/* ptrace.c */ +extern int sco_ptrace(int, int, u_long, u_long); + +/* secureware.c */ +extern int sw_security(int, void *, void *, void *, void *, void *); + +/* stat.c */ +extern int sco_xstat(int, char *, void *); +extern int sco_lxstat(int, char *, void *); +extern int sco_fxstat(int, int, void *); + +/* statvfs.c */ +extern int sco_statvfs(char *, struct sco_statvfs *); +extern int sco_fstatvfs(int, struct sco_statvfs *); + +#endif /* _ABI_SCO_SYSENT_H */ diff -Nru linux-2.6.7/include/abi/sco/types.h linux-2.6.7-abi/include/abi/sco/types.h --- linux-2.6.7/include/abi/sco/types.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/include/abi/sco/types.h 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2001 Caldera Deutschland GmbH. + * Copyright (c) 2001 Christoph Hellwig. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef _ABI_SCO_TYPES_H +#define _ABI_SCO_TYPES_H + +#ident "%W% %G%" + +/* + * SCO OpenServer type declarations. + */ +#include +#include +#include +#include + + +typedef int16_t sco_dev_t; +typedef u_int32_t sco_ino_t; +typedef u_int16_t sco_mode_t; +typedef int16_t sco_nlink_t; +typedef u_int16_t sco_uid_t; +typedef u_int16_t sco_gid_t; +typedef int32_t sco_off_t; +typedef int32_t sco_time_t; + + +struct sco_statvfs { + u_int32_t f_bsize; + u_int32_t f_frsize; + u_int32_t f_blocks; + u_int32_t f_bfree; + u_int32_t f_bavail; + u_int32_t f_files; + u_int32_t f_free; + u_int32_t f_favail; + u_int32_t f_sid; + char f_basetype[16]; + u_int32_t f_flag; + u_int32_t f_namemax; + char f_fstr[32]; + u_int32_t f_filler[16]; +}; + + +/* + * Stub for now, as we still have a 16 bit dev_t. + */ +static __inline sco_dev_t +linux_to_sco_dev_t(dev_t dev) +{ + return dev; +} + +/* + * If we thought we were in a short inode environment we are + * probably already too late - getdents() will have likely + * already assumed short inodes and "fixed" anything with + * a zero low word (because it must match stat() which must + * match read() on a directory). + * + * We will just have to go along with it. + */ +static __inline sco_ino_t +linux_to_sco_ino_t(ino_t ino) +{ + if (!is_cur_personality_flag(PERF_SHORT_INODE)) + return ino; + if ((u_long)ino & 0xffff) + return ino; + return 0xfffffffe; +} + +/* + * SCO user/group IDs are the same as the old linux ones. + */ +static __inline sco_uid_t +linux_to_sco_uid_t(uid_t uid) +{ + return high2lowuid(uid); +} + +static __inline sco_gid_t +linux_to_sco_gid_t(gid_t gid) +{ + return high2lowgid(gid); +} + +#endif /* _ABI_SCO_TYPES_H */ diff -Nru linux-2.6.7/include/abi/signal.h linux-2.6.7-abi/include/abi/signal.h --- linux-2.6.7/include/abi/signal.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/include/abi/signal.h 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,76 @@ +#define NSIGNALS 32 + + +/* These are the signal numbers for the SVr4 signal handling */ +#define IBCS_SIGHUP 1 +#define IBCS_SIGINT 2 +#define IBCS_SIGQUIT 3 +#define IBCS_SIGILL 4 +#define IBCS_SIGTRAP 5 +#define IBCS_SIGIOT 6 +#define IBCS_SIGABRT 6 +#define IBCS_SIGEMT 7 +#define IBCS_SIGFPE 8 +#define IBCS_SIGKILL 9 +#define IBCS_SIGBUS 10 +#define IBCS_SIGSEGV 11 +#define IBCS_SIGSYS 12 +#define IBCS_SIGPIPE 13 +#define IBCS_SIGALRM 14 +#define IBCS_SIGTERM 15 +#define IBCS_SIGUSR1 16 +#define IBCS_SIGUSR2 17 +#define IBCS_SIGCLD 18 +#define IBCS_SIGCHLD 18 +#define IBCS_SIGPWR 19 +#define IBCS_SIGWINCH 20 +#define IBCS_SIGURG 21 /* not SCO, SCO uses SIGUSR2 for SIGURG */ +#define IBCS_SIGPOLL 22 +#define IBCS_SIGIO 22 +#define IBCS_SIGSTOP 23 +#define IBCS_SIGTSTP 24 +#define IBCS_SIGCONT 25 +#define IBCS_SIGTTIN 26 +#define IBCS_SIGTTOU 27 +#define IBCS_SIGVTALRM 28 +#define IBCS_SIGPROF 29 +#define IBCS_SIGGXCPU 30 +#define IBCS_SIGGXFSZ 31 + +#define ISC_SIGSTOP 24 +#define ISC_SIGTSTP 25 +#define ISC_SIGCONT 23 + +/* These are the signal numbers used by BSD. */ +#define BSD_SIGHUP 1 +#define BSD_SIGINT 2 +#define BSD_SIGQUIT 3 +#define BSD_SIGILL 4 +#define BSD_SIGTRAP 5 +#define BSD_SIGABRT 6 +#define BSD_SIGEMT 7 +#define BSD_SIGFPE 8 +#define BSD_SIGKILL 9 +#define BSD_SIGBUS 10 +#define BSD_SIGSEGV 11 +#define BSD_SIGSYS 12 +#define BSD_SIGPIPE 13 +#define BSD_SIGALRM 14 +#define BSD_SIGTERM 15 +#define BSD_SIGURG 16 +#define BSD_SIGSTOP 17 +#define BSD_SIGTSTP 18 +#define BSD_SIGCONT 19 +#define BSD_SIGCHLD 20 +#define BSD_SIGTTIN 21 +#define BSD_SIGTTOU 22 +#define BSD_SIGIO 23 +#define BSD_SIGXCPU 24 +#define BSD_SIGXFSZ 25 +#define BSD_SIGVTALRM 26 +#define BSD_SIGPROF 27 +#define BSD_SIGWINCH 28 +#define BSD_SIGINFO 29 +#define BSD_SIGUSR1 30 +#define BSD_SIGUSR2 31 + diff -Nru linux-2.6.7/include/abi/socksys.h linux-2.6.7-abi/include/abi/socksys.h --- linux-2.6.7/include/abi/socksys.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/include/abi/socksys.h 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,272 @@ +/* + * Copyright (C) 1994 Mike Jagdis (jaggy@purplet.demon.co.uk) + */ + +#ident "%W% %G%" + +#include +/* Get struct rtentry from linux/route.h - this should be compatible. */ +#include +/* Get struct arpreq from linux/if_arp.h - this should be compatible. */ +#include +/* Get struct ifreq and struct ifconf from linux/if.h - these should + * be compatible. */ +#include + + +struct socksysreq { + int args[7]; +}; + + +struct socknewproto { + int family; /* address family (AF_INET, etc.) */ + int type; /* protocol type (SOCK_STREAM, etc.) */ + int proto; /* per family proto number */ + dev_t dev; /* major/minor to use (must be a clone) */ + int flags; /* protosw flags */ +}; + + +/* These are nothing to do with what we know as SO_*. I think they + * are the command requests which appear in socksysreq structures? + */ +#define SSYS_SO_ACCEPT 1 +#define SSYS_SO_BIND 2 +#define SSYS_SO_CONNECT 3 +#define SSYS_SO_GETPEERNAME 4 +#define SSYS_SO_GETSOCKNAME 5 +#define SSYS_SO_GETSOCKOPT 6 +#define SSYS_SO_LISTEN 7 +#define SSYS_SO_RECV 8 +#define SSYS_SO_RECVFROM 9 +#define SSYS_SO_SEND 10 +#define SSYS_SO_SENDTO 11 +#define SSYS_SO_SETSOCKOPT 12 +#define SSYS_SO_SHUTDOWN 13 +#define SSYS_SO_SOCKET 14 +#define SSYS_SO_SELECT 15 +#define SSYS_SO_GETIPDOMAIN 16 +#define SSYS_SO_SETIPDOMAIN 17 +#define SSYS_SO_ADJTIME 18 +#define SSYS_SO_SETREUID 19 +#define SSYS_SO_SETREGID 20 +#define SSYS_SO_GETTIME 21 +#define SSYS_SO_SETTIME 22 +#define SSYS_SO_GETITIMER 23 +#define SSYS_SO_SETITIMER 24 +#define SSYS_SO_RECVMSG 25 /* Here down is SCO 3.2v5 and up */ +#define SSYS_SO_SENDMSG 26 +#define SSYS_SO_SOCKPAIR 27 + + +/* We encode the ioctl numbers using the argument size as part of + * the number. This will warn us if we haven't got compatible + * structures :-). + * Naturally the SVR3/Lachman ioctl numbers are different from the + * BSD/SVR4-XTI ioctl numbers. What more would you expect? + */ + +#define SSYS_IOCPARM_MASK 0xff /* parameters must be < 256 bytes */ +#define SSYS_IOC_VOID 0x20000000 /* no parameters */ +#define SSYS_IOC_OUT 0x40000000 /* copy out parameters */ +#define SSYS_IOC_IN 0x80000000 /* copy in parameters */ +#define SSYS_IOC_INOUT (SSYS_IOC_IN|SSYS_IOC_OUT) + +#define SSYS_IOS(x,y) (SSYS_IOC_VOID|(x<<8)|y) +#define SSYS_IOSR(x,y,t) (SSYS_IOC_OUT|((sizeof(t)&SSYS_IOCPARM_MASK)<<16)|(x<<8)|y) +#define SSYS_IOSW(x,y,t) (SSYS_IOC_IN|((sizeof(t)&SSYS_IOCPARM_MASK)<<16)|(x<<8)|y) +#define SSYS_IOSWR(x,y,t) (SSYS_IOC_INOUT|((sizeof(t)&SSYS_IOCPARM_MASK)<<16)|(x<<8)|y) + +#define SSYS_SIOCSHIWAT SSYS_IOSW('S', 1, int) /* set high watermark */ +#define SSYS_SIOCGHIWAT SSYS_IOSR('S', 2, int) /* get high watermark */ +#define SSYS_SIOCSLOWAT SSYS_IOSW('S', 3, int) /* set low watermark */ +#define SSYS_SIOCGLOWAT SSYS_IOSR('S', 4, int) /* get low watermark */ +#define SSYS_SIOCATMARK SSYS_IOSR('S', 5, int) /* at oob mark? */ +#define SSYS_SIOCSPGRP SSYS_IOSW('S', 6, int) /* set process group */ +#define SSYS_SIOCGPGRP SSYS_IOSR('S', 7, int) /* get process group */ + + +#define SSYS_FIONREAD SSYS_IOSR('S', 8, int) /* BSD compatibilty */ +#define SSYS_FIONBIO SSYS_IOSW('S', 9, int) /* BSD compatibilty */ +#define SSYS_FIOASYNC SSYS_IOSW('S', 10, int) /* BSD compatibilty */ +#define SSYS_SIOCPROTO SSYS_IOSW('S', 11, struct socknewproto) /* link proto */ +#define SSYS_SIOCGETNAME SSYS_IOSR('S', 12, struct sockaddr) /* getsockname */ +#define SSYS_SIOCGETPEER SSYS_IOSR('S', 13, struct sockaddr) /* getpeername */ +#define SSYS_IF_UNITSEL SSYS_IOSW('S', 14, int) /* set unit number */ +#define SSYS_SIOCXPROTO SSYS_IOS('S', 15) /* empty proto table */ + +#define SSYS_SIOCADDRT SSYS_IOSW('R', 9, struct rtentry) /* add route */ +#define SSYS_SIOCDELRT SSYS_IOSW('R', 10, struct rtentry) /* delete route */ + +#define SSYS_SIOCSIFADDR SSYS_IOSW('I', 11, struct ifreq) /* set ifnet address */ +#define SSYS_SIOCGIFADDR SSYS_IOSWR('I', 12, struct ifreq) /* get ifnet address */ +#define SSYS_SIOCSIFDSTADDR SSYS_IOSW('I', 13, struct ifreq) /* set p-p address */ +#define SSYS_SIOCGIFDSTADDR SSYS_IOSWR('I', 14, struct ifreq) /* get p-p address */ +#define SSYS_SIOCSIFFLAGS SSYS_IOSW('I', 15, struct ifreq) /* set ifnet flags */ +#define SSYS_SIOCGIFFLAGS SSYS_IOSWR('I', 16, struct ifreq) /* get ifnet flags */ +#define SSYS_SIOCGIFCONF SSYS_IOSWR('I', 17, struct ifconf) /* get ifnet list */ + +#define SSYS_SIOCSIFMTU SSYS_IOSW('I', 21, struct ifreq) /* get if_mtu */ +#define SSYS_SIOCGIFMTU SSYS_IOSWR('I', 22, struct ifreq) /* set if_mtu */ + +#define SSYS_SIOCIFDETACH SSYS_IOSW('I', 26, struct ifreq) /* detach interface */ +#define SSYS_SIOCGENPSTATS SSYS_IOSWR('I', 27, struct ifreq) /* get ENP stats */ + +#define SSYS_SIOCX25XMT SSYS_IOSWR('I', 29, struct ifreq) /* start a slp proc in + * x25if */ +#define SSYS_SIOCX25RCV SSYS_IOSWR('I', 30, struct ifreq) /* start a slp proc in + * x25if */ +#define SSYS_SIOCX25TBL SSYS_IOSWR('I', 31, struct ifreq) /* xfer lun table to + * kernel */ + +#define SSYS_SIOCGIFBRDADDR SSYS_IOSWR('I', 32, struct ifreq) /* get broadcast addr */ +#define SSYS_SIOCSIFBRDADDR SSYS_IOSW('I', 33, struct ifreq) /* set broadcast addr */ +#define SSYS_SIOCGIFNETMASK SSYS_IOSWR('I', 34, struct ifreq) /* get net addr mask */ +#define SSYS_SIOCSIFNETMASK SSYS_IOSW('I', 35, struct ifreq) /* set net addr mask */ +#define SSYS_SIOCGIFMETRIC SSYS_IOSWR('I', 36, struct ifreq) /* get IF metric */ +#define SSYS_SIOCSIFMETRIC SSYS_IOSW('I', 37, struct ifreq) /* set IF metric */ + +#define SSYS_SIOCSARP SSYS_IOSW('I', 38, struct arpreq) /* set arp entry */ +#define SSYS_SIOCGARP SSYS_IOSWR('I', 39, struct arpreq) /* get arp entry */ +#define SSYS_SIOCDARP SSYS_IOSW('I', 40, struct arpreq) /* delete arp entry */ + +#define SSYS_SIOCSIFNAME SSYS_IOSW('I', 41, struct ifreq) /* set interface name */ +#define SSYS_SIOCGIFONEP SSYS_IOSWR('I', 42, struct ifreq) /* get one-packet params */ +#define SSYS_SIOCSIFONEP SSYS_IOSW('I', 43, struct ifreq) /* set one-packet params */ + +#define SSYS_SIOCGENADDR SSYS_IOSWR('I', 65, struct ifreq) /* Get ethernet addr */ + +#define SSYS_SIOCSOCKSYS SSYS_IOSW('I', 66, struct socksysreq) /* Pseudo socket syscall */ + + +#define SVR4_SIOCSHIWAT SSYS_IOSW('s', 0, int) /* set high watermark */ +#define SVR4_SIOCGHIWAT SSYS_IOSR('s', 1, int) /* get high watermark */ +#define SVR4_SIOCSLOWAT SSYS_IOSW('s', 2, int) /* set low watermark */ +#define SVR4_SIOCGLOWAT SSYS_IOSR('s', 3, int) /* get low watermark */ +#define SVR4_SIOCATMARK SSYS_IOSR('s', 7, int) /* at oob mark? */ +#define SVR4_SIOCSPGRP SSYS_IOSW('s', 8, int) /* set process group */ +#define SVR4_SIOCGPGRP SSYS_IOSR('s', 9, int) /* get process group */ + +#define SVR4_SIOCADDRT SSYS_IOSW('r', 10, struct rtentry) /* add route */ +#define SVR4_SIOCDELRT SSYS_IOSW('r', 11, struct rtentry) /* delete route */ + +#define SVR4_SIOCSIFADDR SSYS_IOSW('i', 12, struct ifreq) /* set ifnet address */ +#define SVR4_SIOCGIFADDR SSYS_IOSWR('i',13, struct ifreq) /* get ifnet address */ +#define SVR4_SIOCSIFDSTADDR SSYS_IOSW('i', 14, struct ifreq) /* set p-p address */ +#define SVR4_SIOCGIFDSTADDR SSYS_IOSWR('i',15, struct ifreq) /* get p-p address */ +#define SVR4_SIOCSIFFLAGS SSYS_IOSW('i', 16, struct ifreq) /* set ifnet flags */ +#define SVR4_SIOCGIFFLAGS SSYS_IOSWR('i',17, struct ifreq) /* get ifnet flags */ +#define SVR4_SIOCSIFMEM SSYS_IOSW('i', 18, struct ifreq) /* set interface mem */ +#define SVR4_SIOCGIFMEM SSYS_IOSWR('i',19, struct ifreq) /* get interface mem */ +#define SVR4_SIOCGIFCONF SSYS_IOSWR('i',20, struct ifconf) /* get ifnet list */ +#define SVR4_SIOCSIFMTU SSYS_IOSW('i', 21, struct ifreq) /* set if_mtu */ +#define SVR4_SIOCGIFMTU SSYS_IOSWR('i',22, struct ifreq) /* get if_mtu */ + + /* from 4.3BSD */ +#define SVR4_SIOCGIFBRDADDR SSYS_IOSWR('i',23, struct ifreq) /* get broadcast addr */ +#define SVR4_SIOCSIFBRDADDR SSYS_IOSW('i',24, struct ifreq) /* set broadcast addr */ +#define SVR4_SIOCGIFNETMASK SSYS_IOSWR('i',25, struct ifreq) /* get net addr mask */ +#define SVR4_SIOCSIFNETMASK SSYS_IOSW('i',26, struct ifreq) /* set net addr mask */ +#define SVR4_SIOCGIFMETRIC SSYS_IOSWR('i',27, struct ifreq) /* get IF metric */ +#define SVR4_SIOCSIFMETRIC SSYS_IOSW('i',28, struct ifreq) /* set IF metric */ + +#define SVR4_SIOCSARP SSYS_IOSW('i', 30, struct arpreq) /* set arp entry */ +#define SVR4_SIOCGARP SSYS_IOSWR('i',31, struct arpreq) /* get arp entry */ +#define SVR4_SIOCDARP SSYS_IOSW('i', 32, struct arpreq) /* delete arp entry */ +#define SVR4_SIOCUPPER SSYS_IOSW('i', 40, struct ifreq) /* attach upper layer */ +#define SVR4_SIOCLOWER SSYS_IOSW('i', 41, struct ifreq) /* attach lower layer */ +#define SVR4_SIOCSETSYNC SSYS_IOSW('i', 44, struct ifreq) /* set syncmode */ +#define SVR4_SIOCGETSYNC SSYS_IOSWR('i', 45, struct ifreq) /* get syncmode */ +#define SVR4_SIOCSSDSTATS SSYS_IOSWR('i', 46, struct ifreq) /* sync data stats */ +#define SVR4_SIOCSSESTATS SSYS_IOSWR('i', 47, struct ifreq) /* sync error stats */ + +#define SVR4_SIOCSPROMISC SSYS_IOSW('i', 48, int) /* request promisc mode + on/off */ +#define SVR4_SIOCADDMULTI SSYS_IOSW('i', 49, struct ifreq) /* set m/c address */ +#define SVR4_SIOCDELMULTI SSYS_IOSW('i', 50, struct ifreq) /* clr m/c address */ + +/* protocol i/o controls */ +#define SVR4_SIOCSNIT SSYS_IOSW('p', 0, struct nit_ioc) /* set nit modes */ +#define SVR4_SIOCGNIT SSYS_IOSWR('p', 1, struct nit_ioc) /* get nit modes */ + +/* STREAMS based socket emulation */ + +#define SVR4_SIOCPROTO SSYS_IOSW('s', 51, struct socknewproto) /* link proto */ +#define SVR4_SIOCGETNAME SSYS_IOSR('s', 52, struct sockaddr) /* getsockname */ +#define SVR4_SIOCGETPEER SSYS_IOSR('s', 53, struct sockaddr) /* getpeername */ +#define SVR4_IF_UNITSEL SSYS_IOSW('s', 54, int) /* set unit number */ +#define SVR4_SIOCXPROTO SSYS_IOS('s', 55) /* empty proto table */ + +#define SVR4_SIOCIFDETACH SSYS_IOSW('i', 56, struct ifreq) /* detach interface */ +#define SVR4_SIOCGENPSTATS SSYS_IOSWR('i', 57, struct ifreq) /* get ENP stats */ +#define SVR4_SIOCX25XMT SSYS_IOSWR('i', 59, struct ifreq) /* start a slp proc in + * x25if */ +#define SVR4_SIOCX25RCV SSYS_IOSWR('i', 60, struct ifreq) /* start a slp proc in + * x25if */ +#define SVR4_SIOCX25TBL SSYS_IOSWR('i', 61, struct ifreq) /* xfer lun table to + * kernel */ +#define SVR4_SIOCSLGETREQ SSYS_IOSWR('i', 71, struct ifreq) /* wait for switched + * SLIP request */ +#define SVR4_SIOCSLSTAT SSYS_IOSW('i', 72, struct ifreq) /* pass SLIP info to + * kernel */ +#define SVR4_SIOCSIFNAME SSYS_IOSW('i', 73, struct ifreq) /* set interface name */ +#define SVR4_SIOCGENADDR SSYS_IOSWR('i', 85, struct ifreq) /* Get ethernet addr */ +#define SVR4_SIOCSOCKSYS SSYS_IOSW('i', 86, struct socksysreq) /* Pseudo socket syscall */ + + +#if 0 +/* Strange, there also seem to be two byte SVR4 ioctls used which are + * not simply the BSD style ioctl with the high word masked out. i.e the + * class character doesn't match what I expect. + */ +#define SVRX_SIOCGIFCONF 0x8912 +#define SVRX_SIOCGIFFLAGS 0x8913 +#endif + + +/* With NFS/NIS there is also a pseudo device /dev/nfsd which understands + * some ioctls. Since these don't conflict with the socksys ioctls we + * just link nfsd to socksys and let socksys handle both sets. + */ +#define NIOCNFSD 1 +#define NIOCOLDGETFH 2 +#define NIOCASYNCD 3 +#define NIOCSETDOMNAM 4 +#define NIOCGETDOMNAM 5 +#define NIOCCLNTHAND 6 +#define NIOCEXPORTFS 7 +#define NIOCGETFH 8 +#define NIOCLSTAT 9 + +/* These ioctls take argument structures... */ +struct domnam_args { + char *name; + int namelen; +}; + +struct lstat_args { + char *fname; + void *statb; +}; + +#define NFS_FHSIZE 32 +typedef union { + struct { + unsigned short fsid; /* filesystem id (device) */ + unsigned long fno; /* file number (inode) */ + unsigned long fgen; /* file generation */ + unsigned short ex_fsid; /* exported fs id (device) */ + unsigned long ex_fno; /* exported file no (inode) */ + unsigned long ex_fgen; /* exported file gen */ + } fh; + char pad[NFS_FHSIZE]; +} fhandle_t; + +struct getfh_args { + char *fname; + fhandle_t *fhp; +}; + +extern void inherit_socksys_funcs(unsigned int fd, int state); +extern int socksys_fdinit(int fd, int rw, const char *buf, int *count); diff -Nru linux-2.6.7/include/abi/solaris/stat.h linux-2.6.7-abi/include/abi/solaris/stat.h --- linux-2.6.7/include/abi/solaris/stat.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/include/abi/solaris/stat.h 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,29 @@ +#ifndef _ABI_SOLARIS_STAT_H +#define _ABI_SOLARIS_STAT_H + +#ident "%W% %G%" + +#include + + +struct sol_stat64 { + sol_dev_t st_dev; + u_int32_t st_pad1[3]; + sol_ino_t st_ino; + sol_mode_t st_mode; + sol_nlink_t st_nlink; + sol_uid_t st_uid; + sol_gid_t st_gid; + sol_dev_t st_rdev; + u_int32_t st_pad2[2]; + sol_off_t st_size; + sol_time_t st_atime; + sol_time_t st_mtime; + sol_time_t st_ctime; + int32_t st_blksize; + int64_t st_blocks; + char st_fstype[16]; + u_int32_t st_pad4[4]; +}; + +#endif /* _ABI_SOLARIS_STAT_H */ diff -Nru linux-2.6.7/include/abi/solaris/sysent.h linux-2.6.7-abi/include/abi/solaris/sysent.h --- linux-2.6.7/include/abi/solaris/sysent.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/include/abi/solaris/sysent.h 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,54 @@ +#ifndef _ABI_SOLARIS_SYSENT_H +#define _ABI_SOLARIS_SYSENT_H + +#ident "%W% %G%" + +struct sol_stat64; +struct sol_nmsghdr; +struct sockaddr; + + +/* lfs.c */ +extern int sol_open64(const char *, int, int); +extern int sol_getdents64(int fd, char *, int); +extern int sol_mmap64(u_int, u_int, int, int, int, u_int, u_int); + +/* socket.c */ +extern int solaris_socket(int family, int type, int protocol); +extern int solaris_socketpair(int *usockvec); +extern int solaris_bind(int fd, struct sockaddr *addr, int addrlen); +extern int solaris_setsockopt(int fd, int level, int optname, + u32 optval, int optlen); +extern int solaris_getsockopt(int fd, int level, int optname, + u32 optval, u32 optlen); +extern int solaris_connect(int fd, struct sockaddr *addr, int addrlen); +extern int solaris_accept(int fd, struct sockaddr *addr, int *addrlen); +extern int solaris_listen(int fd, int backlog); +extern int solaris_shutdown(int fd, int how); +extern int solaris_recvfrom(int s, char *buf, int len, int flags, + u32 from, u32 fromlen); +extern int solaris_recv(int s, char *buf, int len, int flags); +extern int solaris_sendto(int s, char *buf, int len, int flags, + u32 to, u32 tolen); +extern int solaris_send(int s, char *buf, int len, int flags); +extern int solaris_getpeername(int fd, struct sockaddr *addr, + int *addrlen); +extern int solaris_getsockname(int fd, struct sockaddr *addr, + int *addrlen); +extern int solaris_sendmsg(int fd, struct sol_nmsghdr *user_msg, + unsigned user_flags); +extern int solaris_recvmsg(int fd, struct sol_nmsghdr *user_msg, + unsigned user_flags); + +/* solarisx86.c */ +extern int sol_llseek(struct pt_regs *regs); +extern int sol_memcntl(unsigned addr, unsigned len, int cmd, + unsigned arg, int attr, int mask); +extern int sol_acl(char *pathp, int cmd, int nentries, void *aclbufp); + +/* stat.c */ +extern int sol_stat64(char *, struct sol_stat64 *); +extern int sol_lstat64(char *, struct sol_stat64 *); +extern int sol_fstat64(u_int fd, struct sol_stat64 *); + +#endif /* _ABI_SOLARIS_SYSENT_H */ diff -Nru linux-2.6.7/include/abi/solaris/types.h linux-2.6.7-abi/include/abi/solaris/types.h --- linux-2.6.7/include/abi/solaris/types.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/include/abi/solaris/types.h 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2001 Christoph Hellwig. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef _ABI_SOLARIS_TYPES_H +#define _ABI_SOLARIS_TYPES_H + +#ident "%W% %G%" + +/* + * Solaris 2 type declarations. + */ +#include /* Solaris 2 is based on SVR4 */ + +typedef svr4_dev_t sol_dev_t; +typedef u_int64_t sol_ino_t; +typedef svr4_mode_t sol_mode_t; +typedef svr4_nlink_t sol_nlink_t; +typedef svr4_uid_t sol_uid_t; +typedef svr4_gid_t sol_gid_t; +typedef int64_t sol_off_t; +typedef svr4_time_t sol_time_t; + +typedef u_int64_t sol_fsblkcnt64_t; +typedef u_int64_t sol_fsfilcnt64_t; + + +#define linux_to_sol_dev_t(dev) \ + linux_to_svr4_dev_t(dev) + +#define linux_to_sol_ino_t(ino) \ + linux_to_svr4_ino_t(ino) + +#define linux_to_sol_uid_t(uid) \ + linux_to_svr4_uid_t(uid) + +#define linux_to_sol_gid_t(gid) \ + linux_to_svr4_gid_t(gid) + +#endif /* _ABI_SOLARIS_TYPES_H */ diff -Nru linux-2.6.7/include/abi/stream.h linux-2.6.7-abi/include/abi/stream.h --- linux-2.6.7/include/abi/stream.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/include/abi/stream.h 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,42 @@ +/* + * Copyright (C) 1994 Mike Jagdis (jaggy@purplet.demon.co.uk) + */ +#ifndef _IBCS_STREAM_H_ +#define _IBCS_STREAM_H_ + +#ident "%W% %G%" + +#define MSG_HIPRI 1 +#define RS_HIPRI MSG_HIPRI +#define MSG_ANY 2 +#define MSG_BAND 4 + +#define MORECTL 1 +#define MOREDATA 2 + +struct strbuf { + int maxlen; /* size of buffer */ + int len; /* number of bytes in buffer */ + char *buf; /* pointer to buffer */ +}; + +/* Used for the I_PEEK STREAMS ioctl. */ +struct strpeek { + struct strbuf ctl; + struct strbuf dat; + long flags; +}; + +/* Used for the I_FDINSERT STREAMS ioctl. */ +struct strfdinsert { + struct strbuf ctlbuf; + struct strbuf datbuf; + long flags; + unsigned int fildes; + int offset; +}; + +extern int stream_fdinsert(struct pt_regs *regs, int fd, + struct strfdinsert *arg); + +#endif diff -Nru linux-2.6.7/include/abi/svr4/ioctl.h linux-2.6.7-abi/include/abi/svr4/ioctl.h --- linux-2.6.7/include/abi/svr4/ioctl.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/include/abi/svr4/ioctl.h 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,40 @@ +#ifndef _ABI_SVR4_IOCTL_H +#define _ABI_SVR4_IOCTL_H + +/* + * Function prototypes used for SVR4 ioctl emulation. + */ + +#ident "%W% %G%" + +extern int __svr4_ioctl(struct pt_regs *, int, unsigned long, void *); + +/* consio.c */ +extern int svr4_console_ioctl(int, u_int, caddr_t); +extern int svr4_video_ioctl(int, u_int, caddr_t); + +/* filio.c */ +extern int svr4_fil_ioctl(int, u_int, caddr_t); + +/* sockio.c */ +extern int svr4_stream_ioctl(struct pt_regs *regs, int, u_int, caddr_t); + +/* socksys.c */ +extern int abi_ioctl_socksys(int, u_int, caddr_t); + +/* tapeio.c */ +extern int svr4_tape_ioctl(int, u_int, caddr_t); + +/* termios.c */ +extern int bsd_ioctl_termios(int, u_int, void *); +extern int svr4_term_ioctl(int, u_int, caddr_t); +extern int svr4_termiox_ioctl(int, u_int, caddr_t); + +/* timod.c */ +extern int svr4_sockmod_ioctl(int, u_int, caddr_t); +extern int do_getmsg(int, struct pt_regs *, char *, int, + int *, char *, int, int *, int *); +extern int do_putmsg(int, struct pt_regs *, char *, int, + char *, int, int); + +#endif /* _ABI_SVR4_IOCTL_H */ diff -Nru linux-2.6.7/include/abi/svr4/ipc.h linux-2.6.7-abi/include/abi/svr4/ipc.h --- linux-2.6.7/include/abi/svr4/ipc.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/include/abi/svr4/ipc.h 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,214 @@ +/* + * Copyright (c) 1994 Mike Jagdis. + * Copyright (c) 2001 Christoph Hellwig. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef _ABI_SVR4_IPC_H +#define _ABI_SVR4_IPC_H + +#ident "%W% %G%" + +/* + * General IPC + */ +enum { + SVR4_IPC_RMID = 0, + SVR4_IPC_SET = 1, + SVR4_IPC_STAT = 2, + SVR4_IPC_RMID_L = 10, + SVR4_IPC_SET_L = 11, + SVR4_IPC_STAT_L = 12, +}; + +struct ibcs2_ipc_perm { + u_int16_t uid; /* owner's user id */ + u_int16_t gid; /* owner's group id */ + u_int16_t cuid; /* creator's user id */ + u_int16_t cgid; /* creator's group id */ + u_int16_t mode; /* access modes */ + u_int16_t seq; /* slot usage sequence number */ + int32_t key; /* key */ +}; + +struct abi4_ipc_perm { + u_int32_t uid; /* owner's user id */ + u_int32_t gid; /* owner's group id */ + u_int32_t cuid; /* creator's user id */ + u_int32_t cgid; /* creator's group id */ + u_int32_t mode; /* access modes */ + u_int32_t seq; /* slot usage sequence number */ + int32_t key; /* key */ + int32_t pad[4]; /* reserved */ +}; + +/* + * Message queues + */ +enum { + SVR4_msgget = 0, + SVR4_msgctl = 1, + SVR4_msgrcv = 2, + SVR4_msgsnd = 3, +}; + +struct ibcs2_msqid_ds { + struct ibcs2_ipc_perm msg_perm; + struct msg *msg_first; + struct msg *msg_last; + u_int16_t msg_cbytes; + u_int16_t msg_qnum; + u_int16_t msg_qbytes; + u_int16_t msg_lspid; + u_int16_t msg_lrpid; + time_t msg_stime; + time_t msg_rtime; + time_t msg_ctime; +}; + +struct abi4_msg { + struct abi4_msg *msg_next; + int32_t msg_type; + u_int16_t msg_ts; + int16_t msg_spot; +}; + +struct abi4_msqid_ds { + struct abi4_ipc_perm msg_perm; + struct msg *msg_first; + struct msg *msg_last; + u_int32_t msg_cbytes; + u_int32_t msg_qnum; + u_int32_t msg_qbytes; + u_int32_t msg_lspid; + u_int32_t msg_lrpid; + u_int32_t msg_stime; + u_int32_t msg_pad1; + u_int32_t msg_rtime; + u_int32_t msg_pad2; + u_int32_t msg_ctime; + u_int32_t msg_pad3; + u_int32_t msg_pad4[4]; +}; + +/* + * Shared memory + */ +enum { + SVR4_shmat = 0, + SVR4_shmctl = 1, + SVR4_shmdt = 2, + SVR4_shmget = 3, +}; + +/* shmctl() operations */ +enum { + SVR4_SHM_LOCK = 3, + SVR4_SHM_UNLOCK = 4, +}; + +struct ibcs2_shmid_ds { + struct ibcs2_ipc_perm shm_perm; /* operation permissions */ + int32_t shm_segsz; /* size of segment in bytes */ + struct region *__pad1; /* ptr to region structure */ + char __pad2[4]; /* for swap compatibility */ + u_int16_t shm_lpid; /* pid of last shmop */ + u_int16_t shm_cpid; /* pid of creator */ + u_int16_t shm_nattch; /* used only for shminfo */ + u_int16_t __pad3; + time_t shm_atime; /* last shmat time */ + time_t shm_dtime; /* last shmdt time */ + time_t shm_ctime; /* last change time */ +}; + +struct abi4_shmid_ds { + struct abi4_ipc_perm shm_perm; /* operation permissions */ + int32_t shm_segsz; /* size of segment in bytes */ + struct region *__pad1; /* ptr to region structure */ + u_int16_t shm_lckcnt; /* number of locks */ + char __pad2[2]; /* for swap compatibility */ + u_int32_t shm_lpid; /* pid of last shmop */ + u_int32_t shm_cpid; /* pid of creator */ + u_int32_t shm_nattch;/* used only for shminfo */ + u_int32_t shm_cnattch; + u_int32_t shm_atime; /* last shmat time */ + u_int32_t shm_pad1; + u_int32_t shm_dtime; /* last shmdt time */ + u_int32_t shm_pad2; + u_int32_t shm_ctime; /* last change time */ + u_int32_t shm_pad3; + u_int32_t shm_pad4[4]; +}; + +/* + * Semaphores + */ +enum { + SVR4_semctl = 0, + SVR4_semget = 1, + SVR4_semop = 2, +}; + +/* semctl() operations */ +enum { + SVR4_SEM_GETNCNT = 3, + SVR4_SEM_GETPID = 4, + SVR4_SEM_GETVAL = 5, + SVR4_SEM_GETALL = 6, + SVR4_SEM_GETZCNT = 7, + SVR4_SEM_SETVAL = 8, + SVR4_SEM_SETALL = 9, +}; + +/* mapping of svr4 semaphore operations to Linux (if available) */ +static int svr4sem2linux[] = { + [SVR4_IPC_RMID] = IPC_RMID, + [SVR4_IPC_SET] = IPC_SET, + [SVR4_IPC_STAT] = IPC_STAT, + [SVR4_SEM_GETNCNT] = GETNCNT, + [SVR4_SEM_GETPID] = GETPID, + [SVR4_SEM_GETVAL] = GETVAL, + [SVR4_SEM_GETALL] = GETALL, + [SVR4_SEM_GETZCNT] = GETZCNT, + [SVR4_SEM_SETVAL] = SETVAL, + [SVR4_SEM_SETALL] = SETALL, + [SVR4_IPC_RMID_L] = IPC_RMID, + [SVR4_IPC_SET_L] = IPC_SET, + [SVR4_IPC_STAT_L] = IPC_STAT, +}; + +struct ibcs2_semid_ds { + struct ibcs2_ipc_perm sem_perm; + struct sem *sem_base; + u_int16_t sem_nsems; + char __pad[2]; + u_int32_t sem_otime; + u_int32_t sem_ctime; +}; + +struct abi4_semid_ds { + struct abi4_ipc_perm sem_perm; + struct sem *sem_base; + u_int16_t sem_nsems; + char __pad[2]; /* this pad is not in the abi doc! */ + u_int32_t sem_otime; + u_int32_t sem_pad1; + u_int32_t sem_ctime; + u_int32_t sem_pad2; + u_int32_t sem_pad3[4]; +}; + +#endif /* _ABI_SVR4_IPC_H */ diff -Nru linux-2.6.7/include/abi/svr4/mman.h linux-2.6.7-abi/include/abi/svr4/mman.h --- linux-2.6.7/include/abi/svr4/mman.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/include/abi/svr4/mman.h 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2001 Christoph Hellwig. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef _ABI_SVR4_MMAN_H +#define _ABI_SVR4_MMAN_H + +#ident "%W% %G%" + +/* + * SVR4 memory mapped files declarations + */ + +#define SVR4_MAP_FAILED ((void *)-1) + +/* protections flags for mmap() and mprotect() */ +#define SVR4_PROT_NONE 0x0000 +#define SVR4_PROT_READ 0x0001 +#define SVR4_PROT_WRITE 0x0002 +#define SVR4_PROT_EXEC 0x0004 + +/* sharing types for mmap() */ +#define SVR4_MAP_SHARED 0x0001 +#define SVR4_MAP_PRIVATE 0x0002 +#define SVR4_MAP_FIXED 0x0010 +#define SVR4_MAP_RENAME 0x0020 +#define SVR4_MAP_NORESERVE 0x0040 +#define SVR4_MAP_ANONYMOUS 0x0100 +#define SVR4__MAP_NEW 0x80000000 + +#define SVR4_MAP_UNIMPL (SVR4_MAP_RENAME|SVR4__MAP_NEW) + +/* memcntl() subfunctions */ +#define SVR4_MC_SYNC 0x0001 +#define SVR4_MC_LOCK 0x0002 +#define SVR4_MC_UNLOCK 0x0003 +#define SVR4_MC_ADVISE 0x0004 +#define SVR4_MC_LOCKAS 0x0005 +#define SVR4_MC_UNLOCKAS 0x0006 + +/* msync() flags */ +#define SVR4_MS_SYNC 0x0000 +#define SVR4_MS_ASYNC 0x0001 +#define SVR4_MS_INVALIDATE 0x0002 + +/* mlockall() flags */ +#define SVR4_MCL_CURRENT 0x0001 +#define SVR4_MCL_FUTURE 0x0002 + +/* madvice() advices */ +#define SVR4_MADV_NORMAL 0x0000 +#define SVR4_MADV_RANDOM 0x0001 +#define SVR4_MADV_SEQUENTIAL 0x0002 +#define SVR4_MADV_WILLNEED 0x0003 +#define SVR4_MADV_DONTNEED 0x0004 + +#endif /* _ABI_SVR4_MMAN_H */ diff -Nru linux-2.6.7/include/abi/svr4/sigaction.h linux-2.6.7-abi/include/abi/svr4/sigaction.h --- linux-2.6.7/include/abi/svr4/sigaction.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/include/abi/svr4/sigaction.h 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,24 @@ +#ifndef _ABI_SVR4_SIGACTION_H +#define _ABI_SVR4_SIGACTION_H + +#ident "%W% %G%" + +/* signal.c */ +struct task_struct; +extern void deactivate_signal(struct task_struct *, int); + +struct abi_sigaction { + int sa_flags; + __sighandler_t sa_handler; + unsigned long sa_mask; + int sa_resv[2]; /* Reserved for something or another */ +}; +#define ABI_SA_ONSTACK 1 +#define ABI_SA_RESETHAND 2 +#define ABI_SA_RESTART 4 +#define ABI_SA_SIGINFO 8 +#define ABI_SA_NODEFER 16 +#define ABI_SA_NOCLDWAIT 0x10000 +#define ABI_SA_NOCLDSTOP 0x20000 + +#endif /* _ABI_SVR4_SIGACTION_H */ diff -Nru linux-2.6.7/include/abi/svr4/siginfo.h linux-2.6.7-abi/include/abi/svr4/siginfo.h --- linux-2.6.7/include/abi/svr4/siginfo.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/include/abi/svr4/siginfo.h 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,32 @@ +#ifndef _ABI_SVR4_SIGINFO_H +#define _ABI_SVR4_SIGINFO_H + +struct svr4_siginfo { + int si_signo; + int si_code; + int si_errno; + union { + struct { /* kill(), SIGCLD */ + long _pid; + union { + struct { + long _uid; + } _kill; + struct { + long _utime; + int _status; + long _stime; + } _cld; + } _pdata; + } _proc; + struct { /* SIGSEGV, SIGBUS, SIGILL, SIGFPE */ + char * _addr; + } _fault; + struct { /* SIGPOLL, SIGXFSZ */ + int _fd; + long _band; + } _file; + } _data; +}; + +#endif /* _ABI_SVR4_SIGINFO_H */ diff -Nru linux-2.6.7/include/abi/svr4/sigset.h linux-2.6.7-abi/include/abi/svr4/sigset.h --- linux-2.6.7/include/abi/svr4/sigset.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/include/abi/svr4/sigset.h 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,9 @@ +#ifndef _ABI_SVR4_SIGSET_H +#define _ABI_SVR4_SIGSET_H + +typedef void (*svr4_sig_t)(int, void *, void *); +typedef struct svr4_sigset { + u_int setbits[4]; +} svr4_sigset_t; + +#endif /* _ABI_SVR4_SIGSET_H */ diff -Nru linux-2.6.7/include/abi/svr4/sockio.h linux-2.6.7-abi/include/abi/svr4/sockio.h --- linux-2.6.7/include/abi/svr4/sockio.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/include/abi/svr4/sockio.h 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2001 Caldera Deutschland GmbH. + * Copyright (c) 2001 Christoph Hellwig. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef _ABI_SVR4_SOCKIO_H +#define _ABI_SVR4_SOCKIO_H + +#ident "%W% %G%" + +#include /* for "struct sockaddr" et al */ +#include /* for "svr4_caddr_t" et al */ + + +#define SVR4_IFF_UP 0x0001 +#define SVR4_IFF_BROADCAST 0x0002 +#define SVR4_IFF_DEBUG 0x0004 +#define SVR4_IFF_LOOPBACK 0x0008 +#define SVR4_IFF_POINTOPOINT 0x0010 +#define SVR4_IFF_NOTRAILERS 0x0020 +#define SVR4_IFF_RUNNING 0x0040 +#define SVR4_IFF_NOARP 0x0080 +#define SVR4_IFF_PROMISC 0x0100 +#define SVR4_IFF_ALLMULTI 0x0200 +#define SVR4_IFF_INTELLIGENT 0x0400 +#define SVR4_IFF_MULTICAST 0x0800 +#define SVR4_IFF_MULTI_BCAST 0x1000 +#define SVR4_IFF_UNNUMBERED 0x2000 +#define SVR4_IFF_PRIVATE 0x8000 + + +/* + * Struct used for one-packet mode params in if ioctls + */ +struct svr4_onepacket { + u_int spsize; /* short packet size */ + u_int spthresh; /* short packet threshold */ +}; + +/* + * Interface specific tuning information that TCP can use to its + * advantage. + */ +struct svr4_ifperf { + u_int ip_recvspace; /* Receive window to use */ + u_int ip_sendspace; /* Send window to use */ + u_int ip_fullsize; /* use full-size frames */ +}; + +#if 0 +/* + * Interface request structure used for socket ioctl's. All interface + * ioctl's must have parameter definitions which begin with ifr_name. The + * remainder may be interface specific. + */ +struct svr4_ifreq { +#define SVR4_IFNAMSIZ 16 + union { + char ifrn_name[SVR4_IFNAMSIZ]; + } ifr_ifrn; + union { + struct sockaddr ifru_addr; + struct sockaddr ifru_dstaddr; + struct sockaddr ifru_broadaddr; + int ifru_int[2]; + svr4_caddr_t ifru_data; + char ifru_enaddr[6]; + struct svr4_onepacket ifru_onepacket; + struct svr4_ifperf ifru_perf; + } ifr_ifru; +#define svr4_ifr_name ifr_ifrn.ifrn_name /* if name, e.g. "en0" */ +#define svr4_ifr_addr ifr_ifru.ifru_addr /* address */ +#define svr4_ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of ptp link */ +#define svr4_ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */ +#define svr4_ifr_flags ifr_ifru.ifru_int[0] /* flags */ +#define svr4_ifr_metric ifr_ifru.ifru_int[1] /* metric */ +#define svr4_ifr_mtu ifr_ifru.ifru_int[1] /* mtu */ +#define svr4_ifr_ifindex ifr_ifru.ifru_int[1] /* ifindex */ +#define svr4_ifr_nif ifr_ifru.ifru_int[1] /* # of interfaces */ +#define svr4_ifr_naddr ifr_ifru.ifru_int[1] /* # of addresses */ +#define svr4_ifr_type ifr_ifru.ifru_int[1] /* type of interface */ +#define svr4_ifr_debug ifr_ifru.ifru_int[1] /* debug level */ +#define svr4_ifr_muxid ifr_ifru.ifru_int[1] /* multiplexor id */ +#define svr4_ifr_data ifr_ifru.ifru_data /* for use by interface */ +#define svr4_ifr_enaddr ifr_ifru.ifru_enaddr /* ethernet address */ +#define svr4_ifr_onepacket ifr_ifru.ifru_onepacket /* one-packet mode params */ +#define svr4_ifr_perf ifr_ifru.ifru_perf /* tuning parameters */ +}; +#endif + +/* socket.c */ +extern int abi_do_setsockopt(unsigned long *sp); +extern int abi_do_getsockopt(unsigned long *sp); + +/* socksys.c */ +/* + * The original Linux socket file operations. + * We use it for two thing: + * o initializing the socksys socket file operations + * o to make calls to the original poll and release routines + * from our implementations. + */ +extern struct file_operations socket_file_ops; + +#endif /* _ABI_SVR4_SOCKIO_H */ diff -Nru linux-2.6.7/include/abi/svr4/statfs.h linux-2.6.7-abi/include/abi/svr4/statfs.h --- linux-2.6.7/include/abi/svr4/statfs.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/include/abi/svr4/statfs.h 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,21 @@ +#ifndef _ABI_SVR4_STATFS_H +#define _ABI_SVR4_STATFS_H + +#ident "%W% %G%" + +#include + + +struct svr4_statfs { + int16_t f_type; + int32_t f_bsize; + int32_t f_frsize; + int32_t f_blocks; + int32_t f_bfree; + int32_t f_files; + int32_t f_ffree; + char f_fname[6]; + char f_fpack[6]; +}; + +#endif /* _ABI_SVR4_STATFS_H */ diff -Nru linux-2.6.7/include/abi/svr4/stat.h linux-2.6.7-abi/include/abi/svr4/stat.h --- linux-2.6.7/include/abi/svr4/stat.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/include/abi/svr4/stat.h 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,56 @@ +#ifndef _ABI_SVR4_STAT_H +#define _ABI_SVR4_STAT_H + +#ident "%W% %G%" + +#include + +/* + * XXX this will need additions if we support emulation of + * XXX 64bit SVR4 on 64bit Linux + */ + +struct svr4_stat { + svr4_o_dev_t st_dev; + svr4_o_ino_t st_ino; + svr4_o_mode_t st_mode; + svr4_o_nlink_t st_nlink; + svr4_o_uid_t st_uid; + svr4_o_gid_t st_gid; + svr4_o_dev_t st_rdev; + svr4_off_t st_size; + svr4_time_t st_atime; + svr4_time_t st_mtime; + svr4_time_t st_ctime; +}; + +struct svr4_xstat { + svr4_dev_t st_dev; + u_int32_t st_pad1[3]; + svr4_ino_t st_ino; + svr4_mode_t st_mode; + svr4_nlink_t st_nlink; + svr4_uid_t st_uid; + svr4_uid_t st_gid; + svr4_dev_t st_rdev; + u_int32_t st_pad2[2]; + svr4_off_t st_size; + u_int32_t st_pad3; + svr4_timestruc_t st_atim; + svr4_timestruc_t st_mtim; + svr4_timestruc_t st_ctim; + u_int32_t st_blksize; + u_int32_t st_blocks; + char st_fstype[16]; + u_int32_t st_pad4[8]; +}; + +/* + * Helpers that are used for other xstat implementations as well. + */ +struct kstat; + +extern int report_svr4_stat(struct kstat *, struct svr4_stat *); +extern int report_svr4_xstat(struct kstat *, struct svr4_xstat *); + +#endif /* _ABI_SVR4_STAT_H */ diff -Nru linux-2.6.7/include/abi/svr4/sysconf.h linux-2.6.7-abi/include/abi/svr4/sysconf.h --- linux-2.6.7/include/abi/svr4/sysconf.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/include/abi/svr4/sysconf.h 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,33 @@ +#ifndef _ABI_SVR4_SYSCONF_H +#define _ABI_SVR4_SYSCONF_H + +#ident "%W% %G%" + +/* + * Possible SVR4 sysconf parameters. + */ + +#define _CONFIG_NGROUPS 2 /* # configured supplemental groups */ +#define _CONFIG_CHILD_MAX 3 /* max # of processes per uid session */ +#define _CONFIG_OPEN_FILES 4 /* max # of open files per process */ +#define _CONFIG_POSIX_VER 5 /* POSIX version */ +#define _CONFIG_PAGESIZE 6 /* system page size */ +#define _CONFIG_CLK_TCK 7 /* ticks per second */ +#define _CONFIG_XOPEN_VER 8 /* XOPEN version */ +#define _CONFIG_NACLS_MAX 9 /* for Enhanced Security */ +#define _CONFIG_ARG_MAX 10 /* max length of exec args */ +#define _CONFIG_NPROC 11 /* # processes system is config for */ +#define _CONFIG_NENGINE 12 /* # configured processors (CPUs) */ +#define _CONFIG_NENGINE_ONLN 13 /* # online processors (CPUs) */ +#define _CONFIG_TOTAL_MEMORY 14 /* total memory */ +#define _CONFIG_USEABLE_MEMORY 15 /* user + system memory */ +#define _CONFIG_GENERAL_MEMORY 16 /* user only memory */ +#define _CONFIG_DEDICATED_MEMORY 17 /* dedicated memory */ +#define _CONFIG_NCGS_CONF 18 /* # CGs in system */ +#define _CONFIG_NCGS_ONLN 19 /* # CGs online now */ +#define _CONFIG_MAX_ENG_PER_CG 20 /* max engines per CG */ +#define _CONFIG_CACHE_LINE 21 /* memory cache line size */ +#define _CONFIG_SYSTEM_ID 22 /* system id assigned at ISL */ +#define _CONFIG_KERNEL_VM 23 /* size of kernel virtual memory */ + +#endif /* _ABI_SVR4_SYSCONF_H */ diff -Nru linux-2.6.7/include/abi/svr4/sysent.h linux-2.6.7-abi/include/abi/svr4/sysent.h --- linux-2.6.7/include/abi/svr4/sysent.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/include/abi/svr4/sysent.h 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,134 @@ +#ifndef _ABI_SVR4_SYSENT_H +#define _ABI_SVR4_SYSENT_H + +#ident "%W% %G%" + +/* + * Function prototypes used for the SVR4 emulator. + */ + +#include +#include + +struct abi_sigaction; +struct ibcs_statfs; +struct svr4_stat; +struct svr4_siginfo; +struct svr4_sigset; +struct svr4_statvfs; +struct pt_regs; +struct timeval; + + +/* MD (lcall7.c for i386) */ +extern int lcall7_syscall(struct pt_regs *); +#define abi_syscall lcall7_syscall + +/* fcntl.c */ +extern unsigned short fl_svr4_to_linux[]; +extern int svr4_fcntl(int, unsigned int, unsigned long); + +/* hrtsys.c */ +extern int svr4_hrtsys(struct pt_regs *); + +/* ioctl.c */ +extern int svr4_ioctl(struct pt_regs *); + +/* ipc.c */ +extern int svr4_semsys(struct pt_regs *); +extern int svr4_shmsys(struct pt_regs *); +extern int svr4_msgsys(struct pt_regs *); + +/* misc.c */ +extern int abi_brk(u_long); +extern int abi_exec(struct pt_regs *); +extern int abi_fork(struct pt_regs *); +extern int abi_getpid(struct pt_regs *); +extern int abi_getuid(struct pt_regs *); +extern int abi_getgid(struct pt_regs *); +extern int abi_mkdir(const char *, int); +extern int svr4_mknod(char *, svr4_o_mode_t, svr4_o_dev_t); +extern int svr4_xmknod(int, char *, svr4_mode_t, svr4_dev_t); +extern int abi_kill(int, int); +extern int abi_pipe(struct pt_regs *); +extern int abi_procids(struct pt_regs *); +extern int abi_read(int, char *, int); +extern int abi_select(int, void *, void *, void *, struct timeval *); +extern int abi_time(void); +extern int abi_wait(struct pt_regs *); + +/* mmap.c */ +extern u_long svr4_mmap(u_long, size_t, int, int, int, svr4_off_t); + +/* open.c */ +extern int svr4_open(const char *, int, int); +extern int svr4_statfs(const char *, struct svr4_statfs *, int, int); +extern int svr4_fstatfs(unsigned int, struct svr4_statfs *, int, int); +extern int svr4_getdents(int, char *, int); + +/* signal.c */ +extern int abi_sigsuspend(struct pt_regs *); +extern int abi_sigfunc(struct pt_regs *); +extern int abi_sigaction(int, const struct abi_sigaction *, + struct abi_sigaction *); +extern int abi_sigprocmask(int, u_long *, u_long *); +extern int abi_sigsuspend(struct pt_regs *); + +/* socksys.c */ +extern int socksys_syscall(u_long *); + +/* stream.c */ +extern int svr4_getmsg(struct pt_regs *); +extern int svr4_putmsg(struct pt_regs *); +extern int svr4_getpmsg(struct pt_regs *); +extern int svr4_putpmsg(struct pt_regs *); + +/* svr4.c */ +extern int svr4_access(char *, int); +extern int svr4_waitid(int, int, struct svr4_siginfo *, int); +extern int svr4_waitsys(struct pt_regs *); +extern int svr4_seteuid(int); +extern int svr4_setegid(int); +extern int svr4_fpathconf(int, int); +extern int svr4_pathconf(char *, int); +extern int svr4_sigpending(int, struct svr4_sigset *); +extern int svr4_context(struct pt_regs *); + +/* sysconf.c */ +extern int ibcs_sysconf(int); + +/* sysfs.c */ +extern int svr4_sysfs(int, int, int); + +/* sysinfo.c */ +extern int svr4_sysinfo(int, char *, long); + +/* ulimit.c */ +extern int svr4_ulimit(int, int); +extern int svr4_getrlimit(int, void *); +extern int svr4_setrlimit(int, void *); + +/* stat.c */ +extern int svr4_stat(char *, struct svr4_stat *); +extern int svr4_lstat(char *, struct svr4_stat *); +extern int svr4_fstat(u_int, struct svr4_stat *); +extern int svr4_xstat(int, char *, void *); +extern int svr4_fxstat(int, int, void *); +extern int svr4_lxstat(int, char *, void *); + +/* sysconf.c */ +extern int svr4_sysconfig(int); + +/* sysi86.c */ +extern int svr4_sysi86(int, void *, int); + +/* utsname.c */ +extern int abi_utsname(u_long); +extern int v7_utsname(u_long); + +/* statvfs.c */ +extern int svr4_statvfs(char *, struct svr4_statvfs *); +extern int svr4_fstatvfs(int, struct svr4_statvfs *); + + +#endif /* _ABI_SVR4_SYSENT_H */ diff -Nru linux-2.6.7/include/abi/svr4/termios.h linux-2.6.7-abi/include/abi/svr4/termios.h --- linux-2.6.7/include/abi/svr4/termios.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/include/abi/svr4/termios.h 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,29 @@ +#ifndef _ABI_SVR4_TERMIOS_H +#define _ABI_SVR4_TERMIOS_H + +#ident "%W% %G%" + +/* + * SVR4 termios declarations. + */ + +#define SVR_NCC 8 +struct svr_termio { + u_int16_t c_iflag; + u_int16_t c_oflag; + u_int16_t c_cflag; + u_int16_t c_lflag; + char c_line; + u_char c_cc[SVR_NCC]; +}; + +#define SVR4_NCCS (19) +struct svr4_termios { + u_long c_iflag; + u_long c_oflag; + u_long c_cflag; + u_long c_lflag; + u_char c_cc[SVR4_NCCS]; +}; + +#endif /* _ABI_SVR4_TERMIOS_H */ diff -Nru linux-2.6.7/include/abi/svr4/types.h linux-2.6.7-abi/include/abi/svr4/types.h --- linux-2.6.7/include/abi/svr4/types.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/include/abi/svr4/types.h 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2001 Caldera Deutschland GmbH. + * Copyright (c) 2001 Christoph Hellwig. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef _ABI_SVR4_TYPES_H +#define _ABI_SVR4_TYPES_H + +#ident "%W% %G%" + +/* + * SVR4 type declarations. + */ +#include +#include +#include +#include + +/* + * XXX this will need additions if we support emulation of + * XXX 64bit SVR4 on 64bit Linux + */ +typedef u_int32_t svr4_dev_t; +typedef u_int32_t svr4_ino_t; +typedef u_int32_t svr4_mode_t; +typedef u_int32_t svr4_nlink_t; +typedef int32_t svr4_uid_t; +typedef int32_t svr4_gid_t; +typedef int32_t svr4_off_t; +typedef int32_t svr4_time_t; +typedef struct timeval svr4_timestruc_t; + +typedef int16_t svr4_o_dev_t; +typedef int16_t svr4_o_pid_t; +typedef u_int16_t svr4_o_ino_t; +typedef u_int16_t svr4_o_mode_t; +typedef int16_t svr4_o_nlink_t; +typedef u_int16_t svr4_o_uid_t; +typedef u_int16_t svr4_o_gid_t; + +/* + * Convert a linux dev number into the SVR4 equivalent. + */ +static __inline svr4_dev_t +linux_to_svr4_dev_t(dev_t dev) +{ + return (dev & 0xff) | ((dev & 0xff00) << 10); +} + +/* + * SVR4 old (=SVR3) dev_t is the same as linux. + */ +static __inline svr4_o_dev_t +linux_to_svr4_o_dev_t(dev_t dev) +{ + return dev; +} + +/* + * If we thought we were in a short inode environment we are + * probably already too late - getdents() will have likely + * already assumed short inodes and "fixed" anything with + * a zero low word (because it must match stat() which must + * match read() on a directory). + * + * We will just have to go along with it. + */ +static __inline svr4_ino_t +linux_to_svr4_ino_t(ino_t ino) +{ + if (!is_cur_personality_flag(PERF_SHORT_INODE)) + return ino; + if ((u_long)ino & 0xffff) + return ino; + return 0xfffffffe; +} + +/* + * Old SVR4 ino_t _must_ be in a short inode enviroment. + */ +static __inline svr4_o_ino_t +linux_to_svr4_o_ino_t(ino_t ino) +{ + if ((u_long)ino & 0xffff) + return (svr4_o_ino_t)ino; + return 0xfffe; +} + +/* + * SVR4 UIDs/GIDs are the same as current Linux ones, + * old (SVR3) ones are the same as old Linux ones. + */ +static __inline svr4_uid_t +linux_to_svr4_uid_t(uid_t uid) +{ + return uid; +} + +static __inline svr4_o_uid_t +linux_to_svr4_o_uid_t(uid_t uid) +{ + return high2lowuid(uid); +} + +static __inline svr4_gid_t +linux_to_svr4_gid_t(gid_t gid) +{ + return gid; +} + +static __inline svr4_o_gid_t +linux_to_svr4_o_gid_t(gid_t gid) +{ + return high2lowgid(gid); +} + +#endif /* _ABI_SVR4_TYPES_H */ diff -Nru linux-2.6.7/include/abi/tli.h linux-2.6.7-abi/include/abi/tli.h --- linux-2.6.7/include/abi/tli.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/include/abi/tli.h 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,355 @@ +#ifndef __TLI_H +#define __TLI_H + + +struct t_info { + long addr; + long options; + long tsdu; + long etsdu; + long connect; + long discon; + long servtype; +}; + + +/* Error codes used by TLI transport providers. */ +#define TBADADDR 1 +#define TBADOPT 2 +#define TACCES 3 +#define TBADF 4 +#define TNOADDR 5 +#define TOUTSTATE 6 +#define TBADSEQ 7 +#define TSYSERR 8 +#define TLOOK 9 +#define TBADDATA 10 +#define TBUFOVFLW 11 +#define TFLOW 12 +#define TNODATA 13 +#define TNODIS 14 +#define TNOUDERR 15 +#define TBADFLAG 16 +#define TNOREL 17 +#define TNOTSUPPORT 18 +#define TSTATECHNG 19 + + +/* User level states (maintained internally by libnsl_s). */ +#define T_UNINIT 0 +#define T_UNBND 1 +#define T_IDLE 2 +#define T_OUTCON 3 +#define T_INCON 4 +#define T_DATAXFER 5 +#define T_OUTREL 6 +#define T_INREL 7 +#define T_FAKE 8 +#define T_HACK 12 + +/* Kernel level states of a transport end point. */ +#define TS_UNBND 0 /* unbound */ +#define TS_WACK_BREQ 1 /* waiting for T_BIND_REQ ack */ +#define TS_WACK_UREQ 2 /* waiting for T_UNBIND_REQ ack */ +#define TS_IDLE 3 /* idle */ +#define TS_WACK_OPTREQ 4 /* waiting for T_OPTMGMT_REQ ack */ +#define TS_WACK_CREQ 5 /* waiting for T_CONN_REQ ack */ +#define TS_WCON_CREQ 6 /* waiting for T_CONN_REQ confirmation */ +#define TS_WRES_CIND 7 /* waiting for T_CONN_IND */ +#define TS_WACK_CRES 8 /* waiting for T_CONN_RES ack */ +#define TS_DATA_XFER 9 /* data transfer */ +#define TS_WIND_ORDREL 10 /* releasing read but not write */ +#define TS_WREQ_ORDREL 11 /* wait to release write but not read */ +#define TS_WACK_DREQ6 12 /* waiting for T_DISCON_REQ ack */ +#define TS_WACK_DREQ7 13 /* waiting for T_DISCON_REQ ack */ +#define TS_WACK_DREQ9 14 /* waiting for T_DISCON_REQ ack */ +#define TS_WACK_DREQ10 15 /* waiting for T_DISCON_REQ ack */ +#define TS_WACK_DREQ11 16 /* waiting for T_DISCON_REQ ack */ +#define TS_NOSTATES 17 + + +/* Messages used by "timod". */ +#define T_CONN_REQ 0 +#define T_CONN_RES 1 +#define T_DISCON_REQ 2 +#define T_DATA_REQ 3 +#define T_EXDATA_REQ 4 +#define T_INFO_REQ 5 +#define T_BIND_REQ 6 +#define T_UNBIND_REQ 7 +#define T_UNITDATA_REQ 8 +#define T_OPTMGMT_REQ 9 +#define T_ORDREL_REQ 10 + +#define T_CONN_IND 11 +#define T_CONN_CON 12 +#define T_DISCON_IND 13 +#define T_DATA_IND 14 +#define T_EXDATA_IND 15 +#define T_INFO_ACK 16 +#define T_BIND_ACK 17 +#define T_ERROR_ACK 18 +#define T_OK_ACK 19 +#define T_UNITDATA_IND 20 +#define T_UDERROR_IND 21 +#define T_OPTMGMT_ACK 22 +#define T_ORDREL_IND 23 + +/* Flags used from user level library routines. */ +#define T_MORE 0x0001 +#define T_EXPEDITED 0x0002 +#define T_NEGOTIATE 0x0004 +#define T_CHECK 0x0008 +#define T_DEFAULT 0x0010 +#define T_SUCCESS 0x0020 +#define T_FAILURE 0x0040 +#define T_CURRENT 0x0080 +#define T_PARTSUCCESS 0x0100 +#define T_READONLY 0x0200 +#define T_NOTSUPPORT 0x0400 + + +struct T_conn_req { + long PRIM_type; /* T_CONN_REQ */ + long DEST_length; + long DEST_offset; + long OPT_length; + long OPT_offset; +}; + +struct T_conn_res { + long PRIM_type; /* T_CONN_RES */ + void *QUEUE_ptr; + long OPT_length; + long OPT_offset; + long SEQ_number; +}; + +struct T_discon_req { + long PRIM_type; /* T_DISCON_REQ */ + long SEQ_number; +}; + +struct T_data_req { + long PRIM_type; /* T_DATA_REQ */ + long MORE_flag; +}; + +struct T_exdata_req { + long PRIM_type; /* T_EXDATA_REQ */ + long MORE_flag; +}; + +struct T_info_req { + long PRIM_type; /* T_INFO_REQ */ +}; + +struct T_bind_req { + long PRIM_type; /* T_BIND_REQ */ + long ADDR_length; + long ADDR_offset; + unsigned long CONIND_number; +}; + +struct T_unbind_req { + long PRIM_type; /* T_UNBIND_REQ */ +}; + +struct T_unitdata_req { + long PRIM_type; /* T_UNITDATA_REQ */ + long DEST_length; + long DEST_offset; + long OPT_length; + long OPT_offset; +}; + +struct T_optmgmt_req { + long PRIM_type; /* T_OPTMGMT_REQ */ + long OPT_length; + long OPT_offset; + long MGMT_flags; +}; + +struct T_ordrel_req { + long PRIM_type; /* T_ORDREL_REQ */ +}; + + +struct T_conn_ind { + long PRIM_type; /* T_CONN_IND */ + long SRC_length; + long SRC_offset; + long OPT_length; + long OPT_offset; + long SEQ_number; +}; + +struct T_conn_con { + long PRIM_type; /* T_CONN_CON */ + long RES_length; + long RES_offset; + long OPT_length; + long OPT_offset; +}; + +struct T_discon_ind { + long PRIM_type; /* T_DISCON_IND */ + long DISCON_reason; + long SEQ_number; +}; + +struct T_data_ind { + long PRIM_type; /* T_DATA_IND */ + long MORE_flag; +}; + +struct T_exdata_ind { + long PRIM_type; /* T_EXDATA_IND */ + long MORE_flag; +}; + +/* information acknowledgment */ + +struct T_info_ack { + long PRIM_type; /* T_INFO_ACK */ + long TSDU_size; + long ETSDU_size; + long CDATA_size; + long DDATA_size; + long ADDR_size; + long OPT_size; + long TIDU_size; + long SERV_type; + long CURRENT_state; + long PROVIDER_flag; +}; + +struct T_bind_ack { + long PRIM_type; /* T_BIND_ACK */ + long ADDR_length; + long ADDR_offset; + unsigned long CONIND_number; +}; + +struct T_error_ack { + long PRIM_type; /* T_ERROR_ACK */ + long ERROR_prim; + long TLI_error; + long UNIX_error; +}; + +struct T_ok_ack { + long PRIM_type; /* T_OK_ACK */ + long CORRECT_prim; +}; + +struct T_unitdata_ind { + long PRIM_type; /* T_UNITDATA_IND */ + long SRC_length; + long SRC_offset; + long OPT_length; + long OPT_offset; +}; + +struct T_uderror_ind { + long PRIM_type; /* T_UDERROR_IND */ + long DEST_length; + long DEST_offset; + long OPT_length; + long OPT_offset; + long ERROR_type; +}; + +struct T_optmgmt_ack { + long PRIM_type; /* T_OPTMGMT_ACK */ + long OPT_length; + long OPT_offset; + long MGMT_flags; +}; + +struct T_ordrel_ind { + long PRIM_type; /* T_ORDREL_IND */ +}; + + +union T_primitives { + long type; + struct T_conn_req conn_req; + struct T_conn_res conn_res; + struct T_discon_req discon_req; + struct T_data_req data_req; + struct T_exdata_req exdata_req; + struct T_info_req info_req; + struct T_bind_req bind_req; + struct T_unbind_req unbind_req; + struct T_unitdata_req unitdata_req; + struct T_optmgmt_req optmgmt_req; + struct T_ordrel_req ordrel_req; + struct T_conn_ind conn_ind; + struct T_conn_con conn_con; + struct T_discon_ind discon_ind; + struct T_data_ind data_ind; + struct T_exdata_ind exdata_ind; + struct T_info_ack info_ack; + struct T_bind_ack bind_ack; + struct T_error_ack error_ack; + struct T_ok_ack ok_ack; + struct T_unitdata_ind unitdata_ind; + struct T_uderror_ind uderror_ind; + struct T_optmgmt_ack optmgmt_ack; + struct T_ordrel_ind ordrel_ind; +}; + + +/* The t_opthdr structure defines the layout of options in a T_OPTMGMT_* + * data buffer. This is specified in the X/Open specs but does not + * appear to exist in SCO 3.2.x, SCO OS5, Interactive SVR4 or UnixWare 1.x. + * There are programs that make options request however. + * The older TLI uses struct opthdr which is different and incompatible + * (see below). + */ +struct t_opthdr { + unsigned long len; /* *Total* length including header */ + unsigned long level; + unsigned long name; + unsigned long status; + char value[0]; /* and onwards... */ +}; + +struct opthdr { + long level; + long name; + long len; /* Length of option value */ + char value[0]; /* and onwards... */ +}; + + +struct T_primsg { + struct T_primsg *next; + unsigned char pri; + unsigned char band; + int length; + long type; +}; + +#define XTI_MAGIC 638654838 + +struct T_private { + int magic; + long state; + int offset; + struct T_primsg *pfirst, *plast; +}; + +#define Priv(file) ((struct T_private *)(file->private_data)) + +extern int timod_ioctl(struct pt_regs *, int, unsigned int, void *, int, int *); +extern int timod_putmsg(int, struct inode *, int, struct pt_regs *); +extern int timod_getmsg(int, struct inode *, int, struct pt_regs *); +extern int timod_update_socket(int, struct file *, struct pt_regs *); + +#ifndef SOCKSYS_MAJOR +#define SOCKSYS_MAJOR 30 +#endif + +#endif /* __TLI_H */ diff -Nru linux-2.6.7/include/abi/unused-termios.h linux-2.6.7-abi/include/abi/unused-termios.h --- linux-2.6.7/include/abi/unused-termios.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/include/abi/unused-termios.h 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,199 @@ +/* + * This file was entered from the book + * Intel386 Family Binary Compatability Specification 2 + * McGraw-Hill Book company + * ISBN 0-07-031219-2 + */ + +#ident "%W% %G%" + +#define NCC 8 +#define NCCS 13 + +typedef unsigned short tcflag_t; +typesef unsigned char cc_t; +typedef unsigned long speed_t; + +struct termio { + unsigned short c_iflag; + unsigned short c_oflag; + unsigned short c_cflag; + unsigned short c_lflag; + char c_line; + unsigned char c_cc[NC]; +}; + +struct termios { + tcflag_t c_iflag; + tcflag_t c_oflag; + tcflag_t c_cflag; + tcflag_t c_lflag; + char c_line; + cc_t c_cc[NCCS]; + char c_ispeed; + char c_ospeed; +}; + +#define VINTR 0 +#define VQUIT 1 +#define VERASE 2 +#define VKILL 3 +#define VEOF 4 +#define VEOL 5 +#define VEOL2 6 +#define VMIN 4 +#define VTIME 5 +#define VSWTCH 7 +#define VSUSP 10 +#define VSTART 11 +#define VSTOP 12 + +#define CNUL 0 +#define CDEL 0377 +#define CESC '\\' +#define CINTR 0177 +#define CQUIT 034 +#define CERASE '#' +#define CKILL '@' +#define CSTART 021 +#define CSTOP 023 +#define CSWTCH 032 +#define CNSWTCH 0 +#define CSUSP 032 + +#define IGNBRK 0000001 +#define BRKINT 0000002 +#define IGNPAR 0000004 +#define PARMRK 0000010 +#define INPCK 0000020 +#define ISTRIP 0000040 +#define INLCR 0000100 +#define IGNCR 0000200 +#define ICRNL 0000400 +#define IUCLC 0001000 +#define IXON 0002000 +#define IXANY 0004000 +#define IXOFF 0010000 +#define IMAXBEL 0020000 /* RESERVED */ +#define DOSMODE 0100000 + +#define OPOST 00000001 +#define OLCUC 00000002 +#define ONLCR 00000004 +#define OCRNL 00000010 +#define ONOCR 00000020 +#define ONLRET 00000040 +#define OFILL 00000100 +#define OFDEL 00000200 +#define NLDLY 00000400 +#define NL0 0 +#define NL1 00000400 +#define CRDLY 00003000 +#define CR0 0 +#define CR1 00001000 +#define CR2 00002000 +#define CR3 00003000 +#define TABDLY 00014000 +#define TAB0 0 +#define TAB1 00004000 +#define TAB2 00010000 +#define TAB3 00014000 +#define BSDLY 00200000 +#define BS0 0 +#define BS1 00200000 +#define VTDLY 00400000 +#define VT0 0 +#define VT1 00400000 +#define FFDLY 01000000 +#define FF0 0 +#define FF1 01000000 + +#define CBAUD 0000017 +#define CSIZE 0000060 +#define CS5 0 +#define CS6 0000020 +#define CS7 0000040 +#define CS8 0000060 +#define CSTOPB 0000100 +#define CREAD 0000200 +#define PARENB 0000400 +#define PARODD 0001000 +#define HUPCL 0002000 +#define CLOCAL 0004000 +#define RCV1EN 0010000 +#define XMT1EN 0020000 +#define LOBLK 0040000 +#define XCLUDE 0100000 + +#define ISIG 0000001 +#define ICANON 0000002 +#define XCASE 0000004 +#define ECHO 0000010 +#define ECHOE 0000020 +#define ECHOK 0000040 +#define ECHONL 0000100 +#define NOFLSH 0000200 +#define IEXTEN 0000400 +#defien TOSTOP 0001000 + +/* Bits 10-15 (0176000) in the c_lflag field are RESERVED */ + +/* +#define XIOC ('x'<<8) Level 2 +*/ +#define XIOC (('i'<<8)|('X'<<16)) +#define XCGETA (XIOC|1) +#define XCSETA (XIOC|2) +#define XCSETAW (XIOC|3) +#define XCSETAF (XIOC|4) + +#define TIOC ('T'<<8) + +#define TCGETA (TIOC|1) +#define TCSETA (TIOC|2) +#define TCSETAW (TIOC|3) +#define TCSETAF (TIOC|4) +#define TCSBRK (TIOC|5) +#define TCXONC (TIOC|6) +#define TCFLSH (TIOC|7) + +#define TIOCGWINSZ (TIOC|104) +#define TIOCSWINSZ (TIOC|103) + +#define TCSANOW XCSETA +#define TCSADRAIN XCSETAW +#define TCSAFLUSH XCSETAF +#define TCSADFLUSH XCSETAF + +#define TCIFLUSH 0 +#define TCOFLUSH 1 +#define TCIOFLUSH 2 + +#define TCOOFF 0 +#define TCOON 1 +#define TCIOFF 2 +#define TCION 3 + +#define B0 0 +#define B50 1 +#define B75 2 +#define B110 3 +#define B134 4 +#define B150 5 +#define B200 6 +#define B300 7 +#define B600 8 +#define B1200 9 +#define B1800 10 +#define B2400 11 +#define B4800 12 +#define B9600 13 +#define B19200 14 +#define B38400 15 + +struct winsize { + unsigned short ws_row; + unsigned short ws_col; + unsigned short ws_xpixel; + unsigned short ws_ypixel; +}; diff -Nru linux-2.6.7/include/abi/util/errno.h linux-2.6.7-abi/include/abi/util/errno.h --- linux-2.6.7/include/abi/util/errno.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/include/abi/util/errno.h 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,17 @@ +#ifndef _ABI_UTIL_ERRNO_H +#define _ABI_UTIL_ERRNO_H + +#ident "%W% %G%" + +#include +#include + +/* + * Translate the errno numbers from linux to current personality. + * This should be removed and all other sources changed to call the + * map function above directly. + */ +#define iABI_errors(errno) \ + (map_value(current_thread_info()->exec_domain->err_map, errno, 1)) + +#endif /* _ABI_UTIL_ERRNO_H */ diff -Nru linux-2.6.7/include/abi/util/map.h linux-2.6.7-abi/include/abi/util/map.h --- linux-2.6.7/include/abi/util/map.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/include/abi/util/map.h 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,113 @@ +#ifndef _ABI_MAP_H +#define _ABI_MAP_H + +#ident "%W% %G%" + +/* + * Copyright (C) 1994 Mike Jagdis (jaggy@purplet.demon.co.uk) + */ + + +struct map_segment { + int start, end; + u_char *map; +}; + + +static __inline u_short +map_flags(u_short f, u_short map[]) +{ + u_short m, r = 0; + int i; + + for (i = 0, m = 1; i < 16; i++) { + if (f & m) + r |= map[i]; + m <<= 1; + } + + return r; +} + +static __inline long +map_bitvec(u_long vec, long map[]) +{ + u_long newvec = 0, m = 1; + int i; + + for (i = 1; i <= 32; i++) { + if ((vec & m) && map[i] != -1) + newvec |= (1 << map[i]); + m <<= 1; + } + + return newvec; +} + +static __inline u_long +map_sigvec_from_kernel(sigset_t vec, u_long map[]) +{ + u_long newvec = 0; + int i; + + for (i = 1; i <= 32; i++) { + if (sigismember(&vec, i) && map[i] != -1) + newvec |= (1 << map[i]); + } + + return newvec; +} + +static __inline sigset_t +map_sigvec_to_kernel(u_long vec, u_long map[]) +{ + sigset_t newvec; + u_long m = 1; + int i; + + sigemptyset(&newvec); + for (i = 1; i <= 32; i++) { + if ((vec & m) && map[i] != -1) + sigaddset(&newvec, map[i]); + m <<= 1; + } + + return newvec; +} + +static __inline int +map_value(struct map_segment *m, int val, int def) +{ + struct map_segment *seg; + + /* + * If no mapping exists in this personality just return the + * number we were given. + */ + if (!m) + return val; + + /* + * Search the map looking for a mapping for the given number. + */ + for (seg = m; seg->start != -1; seg++) { + if (seg->start <= val && val <= seg->end) { + /* + * If the start and end are the same then this + * segment has one entry and the map is the value + * it maps to. Otherwise if we have a vector we + * pick out the relevant value, if we don't have + * a vector we give identity mapping. + */ + if (seg->start == seg->end) + return (int)seg->map; + else + return (seg->map ? seg->map[val-seg->start] : val); + } + } + + /* Number isn't mapped. Returned the requested default. */ + return def; +} + +#endif /* ABI_MAP_H */ diff -Nru linux-2.6.7/include/abi/util/revalidate.h linux-2.6.7-abi/include/abi/util/revalidate.h --- linux-2.6.7/include/abi/util/revalidate.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/include/abi/util/revalidate.h 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,31 @@ +/* + * This is straight from linux/fs/stat.c. + */ +#ifndef _ABI_UTIL_REVALIDATE_H +#define _ABI_UTIL_REVALIDATE_H + +#ident "%W% %G%" + +#include + +/* LINUXABI_TODO */ +/* + * This is required for proper NFS attribute caching (so it says there). + * Maybe the kernel should export it - but it is basically simple... + */ +static __inline int +do_revalidate(struct dentry *dentry) +{ + struct inode *inode = dentry->d_inode; + struct iattr attr; + int error; + + attr.ia_valid = 0; /* setup an empty flag for the inode attribute change */ + + down(&inode->i_sem); + error = notify_change(dentry, &attr); + up(&inode->i_sem); + return error; +} + +#endif /* _ABI_UTIL_REVALIDATE_H */ diff -Nru linux-2.6.7/include/abi/util/socket.h linux-2.6.7-abi/include/abi/util/socket.h --- linux-2.6.7/include/abi/util/socket.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/include/abi/util/socket.h 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,13 @@ +#ifndef _ABI_UTIL_SOCKET_H +#define _ABI_UTIL_SOCKET_H + +/* + * These aren't (currently) defined by Linux. Watch out for warnings + * about redefinitions... + */ +#define SO_USELOOPBACK 0xff02 +#define SO_ORDREL 0xff03 +#define SO_IMASOCKET 0xff04 +#define SO_PROTOTYPE 0xff09 + +#endif /* _ABI_UTIL_SOCKET_H */ diff -Nru linux-2.6.7/include/abi/util/stat.h linux-2.6.7-abi/include/abi/util/stat.h --- linux-2.6.7/include/abi/util/stat.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/include/abi/util/stat.h 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,36 @@ +/* + * Mostly ripped from Al Viro's stat-a-AC9-10 patch, 2001 Christoph Hellwig. + */ +#ifndef _ABI_UTIL_STAT_H +#define _ABI_UTIL_STAT_H + +#ident "%W% %G%" + +#if 0 +/* gone to ./include/linux/stat.h */ +struct kstat { + ino_t ino; + atomic_t count; + dev_t dev; + umode_t mode; + nlink_t nlink; + uid_t uid; + gid_t gid; + dev_t rdev; + loff_t size; + time_t atime; + time_t mtime; + time_t ctime; + unsigned long blksize; + unsigned long blocks; +}; +#endif + +#if 0 +/* gone to ./include/linux/fs.h */ +extern int vfs_stat(char *, struct kstat *); +extern int vfs_lstat(char *, struct kstat *); +extern int vfs_fstat(int, struct kstat *); +#endif + +#endif /* _ABI_UTIL_STAT_H */ diff -Nru linux-2.6.7/include/abi/util/sysent.h linux-2.6.7-abi/include/abi/util/sysent.h --- linux-2.6.7/include/abi/util/sysent.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/include/abi/util/sysent.h 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,83 @@ +#ifndef _ABI_SYSENT_H +#define _ABI_SYSENT_H + +#ident "%W% %G%" + + +#include + +struct pt_regs; +struct sysent; + +/* + * This is needed for subdispatchers like cxenix(). + */ +extern void lcall7_dispatch(struct pt_regs *, struct sysent *, int); + + +/* + * - If an entry is 'Ukn' we don't know how to handle it yet. + * - Spl means that we need to do special processing for this syscall. + * - Fast means that even the error return handling is done by the function. + * - Unimpl means the syscall is not implemented at all. + */ +enum { + Spl = 0x65, /* pass the regs structure down */ + Fast = 0x66, /* same as above + regs already setup at return */ + Unimpl = 0x67, /* syscall is not implemented yet */ + Ukn = Unimpl, /* source compat (XXX: kill me!) */ +}; + +/* + * Every entry in the systen tables is described by this structure. + */ +struct sysent { + void *se_syscall; /* function to call */ + short se_nargs; /* number of aguments */ + + /* + * Theses are only used for syscall tracing. + */ + char *se_name; /* name of function */ + char *se_args; /* how to print the argument list */ +}; + +/* + * Types for syscall pointers. + */ +typedef int (*syscall_t)(struct pt_regs *); +typedef int (*syscallv_t)(void); +typedef int (*syscall1_t)(int); +typedef int (*syscall2_t)(int, int); +typedef int (*syscall3_t)(int, int, int); +typedef int (*syscall4_t)(int, int, int, int); +typedef int (*syscall5_t)(int, int, int, int, int); +typedef int (*syscall6_t)(int, int, int, int, int, int); +typedef int (*syscall7_t)(int, int, int, int, int, int, int); + +/* + * Marcos to call syscall pointers. + */ +#define SYSCALL_VOID(sys) \ + ((syscallv_t)(sys))(); +#define SYSCALL_PREGS(sys, regs) \ + ((syscall_t)(sys))((regs)) +#define SYSCALL_1ARG(sys, args) \ + ((syscall1_t)(sys))((args)[0]) +#define SYSCALL_2ARG(sys, args) \ + ((syscall2_t)(sys))((args)[0], (args)[1]) +#define SYSCALL_3ARG(sys, args) \ + ((syscall3_t)(sys))((args)[0], (args)[1], (args)[2]) +#define SYSCALL_4ARG(sys, args) \ + ((syscall4_t)(sys))((args)[0], (args)[1], (args)[2], (args)[3]) +#define SYSCALL_5ARG(sys, args) \ + ((syscall5_t)(sys))((args)[0], (args)[1], (args)[2], \ + (args)[3], (args)[4]) +#define SYSCALL_6ARG(sys, args) \ + ((syscall6_t)(sys))((args)[0], (args)[1], (args)[2], \ + (args)[3], (args)[4], (args)[5]) +#define SYSCALL_7ARG(sys, args) \ + ((syscall7_t)(sys))((args)[0], (args)[1], (args)[2], \ + (args)[3], (args)[4], (args)[5], (args)[6]) + +#endif /* _ABI_SYSENT_H */ diff -Nru linux-2.6.7/include/abi/util/trace.h linux-2.6.7-abi/include/abi/util/trace.h --- linux-2.6.7/include/abi/util/trace.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/include/abi/util/trace.h 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2001 Christoph Hellwig. + * All rights resered. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#ifndef _ABI_TRACE_H_ +#define _ABI_TRACE_H_ + +#ident "%W% %G%" + +/* + * Linux-ABI tracing helpers. + */ +#include + + +/* + * Tracing flags. + */ +enum { + ABI_TRACE_API = 0x00000001, /* all call/return values */ + ABI_TRACE_IOCTL = 0x00000002, /* all ioctl calls */ + ABI_TRACE_IOCTL_F = 0x00000004, /* ioctl calls that fail */ + ABI_TRACE_SIGNAL = 0x00000008, /* all signal calls */ + ABI_TRACE_SIGNAL_F = 0x00000010, /* signal calls that fail */ + ABI_TRACE_SOCKSYS = 0x00000020, /* socksys and spx devices */ + ABI_TRACE_STREAMS = 0x00000040, /* STREAMS faking */ + ABI_TRACE_UNIMPL = 0x00000100, /* unimplemened functions */ +}; +extern u_int abi_traceflg; + + +/* + * Check if a syscall needs tracing. + */ +#define abi_traced(res) (abi_traceflg & (res)) + +/* + * Unconditinal trace. + */ +#define __abi_trace(fmt...) \ +do { \ + printk(KERN_DEBUG "[%s:%d]: ", current->comm, current->pid); \ + printk(fmt); \ +} while(0) + +/* + * Trace depending on reason. + */ +#define abi_trace(res, fmt...) \ +do { \ + if (abi_traced(res)) \ + __abi_trace(fmt); \ +} while(0) + +/* prototype for ./abi/util/plist.h */ +extern void plist(char *, char *, int *); + +#endif /* _ABI_TRACE_H_ */ diff -Nru linux-2.6.7/include/abi/uw7/acl.h linux-2.6.7-abi/include/abi/uw7/acl.h --- linux-2.6.7/include/abi/uw7/acl.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/include/abi/uw7/acl.h 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,25 @@ +#ifndef _ABI_UW7_ACL_H +#define _ABI_UW7_ACL_H + +#ident "%W% %G%" + +/* + * UnixWare 7 ACL bits (unused so far). + */ + +enum { + GETACL = 1, + SETACL = 2, + GETACLCNT = 3, +}; + +struct uw7_acl { + int a_type; + uid_t a_id; + u_int16_t a_perm; +}; + + +/* int uw7_acl(char * path, int cmd, int nentries, struct acl * aclp); */ + +#endif /* _ABI_UW7_ACL_H */ diff -Nru linux-2.6.7/include/abi/uw7/context.h linux-2.6.7-abi/include/abi/uw7/context.h --- linux-2.6.7/include/abi/uw7/context.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/include/abi/uw7/context.h 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,43 @@ +#ifndef _ABI_UW7_CONTEXT_H +#define _ABI_UW7_CONTEXT_H + +#ident "%W% %G%" + +/* + * UnixWare context bits. + */ + +/* ss_size <-> ss_flags which is why we can't use native Linux stack_t :( */ +typedef struct uw7_stack { + void *ss_sp; + int ss_size; + int ss_flags; +} uw7_stack_t; + +/* XXX more registers, please */ +typedef struct uw7_mcontext { + unsigned short gs, __gsh; + unsigned short fs, __fsh; + unsigned short es, __esh; + unsigned short ds, __dsh; +} uw7_mcontext_t; + +typedef struct uw7_sigset { + unsigned int sigbits[4]; +} uw7_sigset_t; + +typedef struct uw7_context { + unsigned long uc_flags; + struct uw7_context *uc_link; + uw7_sigset_t uc_sigmask; + uw7_stack_t uc_stack; + uw7_mcontext_t uc_mcontext; + void *uc_pdata; + char uc_unused[16]; +} uw7_context_t; + +#define UW7_GETCONTEXT 0 +#define UW7_SETCONTEXT 1 +#define UW7_GETXCONTEXT 2 + +#endif /* _ABI_UW7_CONTEXT_H */ diff -Nru linux-2.6.7/include/abi/uw7/resource.h linux-2.6.7-abi/include/abi/uw7/resource.h --- linux-2.6.7/include/abi/uw7/resource.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/include/abi/uw7/resource.h 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,36 @@ +#ifndef _ABI_UW7_RESOURCE_H +#define _ABI_UW7_RESOURCE_H + +#ident "%W% %G%" + +/* + * UnixWare 7 resource limit handling. + */ + +typedef u_int64_t uw7_rlim64_t; + +struct uw7_rlim64 { + uw7_rlim64_t rlim_cur; /* current limit */ + uw7_rlim64_t rlim_max; /* maximum value for rlim_cur */ +}; + +enum { + UW7_RLIMIT_CPU = 0, /* cpu time in milliseconds */ + UW7_RLIMIT_FSIZE = 1, /* maximum file size */ + UW7_RLIMIT_DATA = 2, /* data size */ + UW7_RLIMIT_STACK = 3, /* stack size */ + UW7_RLIMIT_CORE = 4, /* core file size */ + UW7_RLIMIT_NOFILE = 5, /* file descriptors */ + UW7_RLIMIT_VMEM = 6, /* maximum mapped memory */ +}; + +static int uw7_to_linux_rlimit[] = { + RLIMIT_CPU, + RLIMIT_DATA, + RLIMIT_STACK, + RLIMIT_CORE, + RLIMIT_NOFILE, + RLIMIT_AS +}; + +#endif /* _ABI_UW7_RESOURCE_H */ diff -Nru linux-2.6.7/include/abi/uw7/stat.h linux-2.6.7-abi/include/abi/uw7/stat.h --- linux-2.6.7/include/abi/uw7/stat.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/include/abi/uw7/stat.h 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,33 @@ +#ifndef _ABI_UW7_STAT_H +#define _ABI_UW7_STAT_H + +#ident "%W% %G%" + + +#include + +struct uw7_stat64 { + uw7_dev_t st_dev; + u_int32_t st_pad1[3]; + uw7_ino_t st_ino; + uw7_mode_t st_mode; + uw7_nlink_t st_nlink; + uw7_uid_t st_uid; + uw7_gid_t st_gid; + uw7_dev_t st_rdev; + u_int32_t st_pad2[2]; + uw7_off_t st_size; + struct timeval st_atime; + struct timeval st_mtime; + struct timeval st_ctime; + int32_t st_blksize; + int64_t st_blocks; + char st_fstype[16]; + int32_t st_aclcnt; + u_int32_t st_level; + u_int32_t st_flags; + u_int32_t st_cmwlevel; + u_int32_t st_pad4[4]; +}; + +#endif /* _ABI_UW7_STAT_H */ diff -Nru linux-2.6.7/include/abi/uw7/statvfs.h linux-2.6.7-abi/include/abi/uw7/statvfs.h --- linux-2.6.7/include/abi/uw7/statvfs.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/include/abi/uw7/statvfs.h 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,26 @@ +#ifndef _ABI_UW7_STATVFS_H +#define _ABI_UW7_STATVFS_H + +#ident "%W% %G%" + +#include + + +struct uw7_statvfs64 { + u_int32_t f_bsize; /* file system block size */ + u_int32_t f_frsize; /* file system fragment size */ + uw7_fsblkcnt64_t f_blocks; /* total # of fragments */ + uw7_fsblkcnt64_t f_bfree; /* total # of free fragments */ + uw7_fsblkcnt64_t f_bavail; /* # of free fragments avail */ + uw7_fsfilcnt64_t f_files; /* total # of inodes */ + uw7_fsfilcnt64_t f_ffree; /* total # of free inodes */ + uw7_fsfilcnt64_t f_favail; /* # of free inodes avail */ + u_int32_t f_fsid; /* file system id */ + char f_basetype[16]; /* target fs type name */ + u_int32_t f_flag; /* bit-mask of flags */ + u_int32_t f_namemax; /* maximum file name length */ + char f_fstr[32]; /* filesystem string */ + u_int32_t f_filler[16]; /* reserved */ +}; + +#endif /* _ABI_UW7_STATVFS_H */ diff -Nru linux-2.6.7/include/abi/uw7/sysent.h linux-2.6.7-abi/include/abi/uw7/sysent.h --- linux-2.6.7/include/abi/uw7/sysent.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/include/abi/uw7/sysent.h 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,58 @@ +#ifndef _ABI_UW7_SYSENT_H +#define _ABI_UW7_SYSENT_H + +#ident "%W% %G%" + +/* + * External function declarations for the SCO UnixWare 7 syscall table. + */ + +struct pt_regs; +struct uw7_rlimit64; +struct uw7_stack; +struct uw7_statvfs64; + + +/* access.c */ +extern int uw7_access(char *, int); + +/* context.c */ +extern int uw7_context(struct pt_regs *); +extern int uw7_sigaltstack(const struct uw7_stack *, struct uw7_stack *); + +/* misc.c */ +extern int uw7_sleep(int); +extern int uw7_seteuid(int); +extern int uw7_setegid(int); +extern int uw7_pread(u_int, char *, int, long); +extern int uw7_pwrite(u_int, char *, int, long); +extern int uw7_stty(int, int); +extern int uw7_gtty(int, int); + +/* ioctl.c */ +extern int uw7_ioctl(struct pt_regs *); + +/* lfs.c */ +extern int uw7_truncate64(const char *, u_long, u_long); +extern int uw7_ftruncate64(int, u_long, u_long); +extern int uw7_statvfs64(char *, struct uw7_statvfs64 *); +extern int uw7_fstatvfs64(int, struct uw7_statvfs64 *); +extern int uw7_getrlimit64(int, struct uw7_rlimit64 *); +extern int uw7_setrlimit64(int, const struct uw7_rlimit64 *); +extern int uw7_lseek64(int, u_int, u_int, int); +extern ssize_t uw7_pread64(int, char *, int, u_int, u_int); +extern ssize_t uw7_pwrite64(int, char *, int, u_int, u_int); +extern int uw7_creat64(const char *, int); + +/* mac.c */ +extern int uw7_mldmode(int); + +/* mmap.c */ +extern int uw7_mmap64(u_long, size_t, int, int, int, u_long, u_long); + +/* stat.c */ +extern int uw7_xstat(int, char *, void *); +extern int uw7_lxstat(int, char *, void *); +extern int uw7_fxstat(int, int, void *); + +#endif /* _ABI_UW7_SYSENT_H */ diff -Nru linux-2.6.7/include/abi/uw7/termbits.h linux-2.6.7-abi/include/abi/uw7/termbits.h --- linux-2.6.7/include/abi/uw7/termbits.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/include/abi/uw7/termbits.h 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,147 @@ +#ifndef _ABI_UW7_TERMBITS_H +#define _ABI_UW7_TERMBITS_H + +#define UW7_TIOC ('T'<<8) +#define UW7_TCGETA (UW7_TIOC|1) +#define UW7_TCSETA (UW7_TIOC|2) +#define UW7_TCSETAW (UW7_TIOC|3) +#define UW7_TCSETAF (UW7_TIOC|4) +#define UW7_TCSBRK (UW7_TIOC|5) +#define UW7_TCXONC (UW7_TIOC|6) +#define UW7_TCFLSH (UW7_TIOC|7) +#define UW7_TCDSET (UW7_TIOC|32) +#define UW7_RTS_TOG (UW7_TIOC|33) +#define UW7_TIOCGWINSZ (UW7_TIOC|104) +#define UW7_TIOCSWINSZ (UW7_TIOC|103) +#define UW7_TCGETS (UW7_TIOC|13) +#define UW7_TCSETS (UW7_TIOC|14) +#define UW7_TCSANOW UW7_TCSETS +#define UW7_TCSETSW (UW7_TIOC|15) +#define UW7_TCSADRAIN UW7_TCSETSW +#define UW7_TCSETSF (UW7_TIOC|16) +#define UW7_TCSAFLUSH UW7_TCSETSF + +/* + * VEOF/VEOL and VMIN/VTIME are overloaded. + * VEOF/VEOL are used in canonical mode (ICANON), + * otherwise VMIN/VTIME are used. + */ +#define UW7_VINTR 0 +#define UW7_VQUIT 1 +#define UW7_VERASE 2 +#define UW7_VKILL 3 +#define UW7_VEOF 4 +#define UW7_VEOL 5 +#define UW7_VEOL2 6 +#define UW7_VMIN 4 +#define UW7_VTIME 5 +#define UW7_VSWTCH 7 +#define UW7_VSTART 8 +#define UW7_VSTOP 9 +#define UW7_VSUSP 10 +#define UW7_VDSUSP 11 +#define UW7_VREPRINT 12 +#define UW7_VDISCARD 13 +#define UW7_VWERASE 14 +#define UW7_VLNEXT 15 + +/* + * Input modes (c_iflag), same as Linux bits, except DOSMODE (obsolete). + */ +#define UW7_IFLAG_MSK 0017777 +#define UW7_IGNBRK 0000001 +#define UW7_BRKINT 0000002 +#define UW7_IGNPAR 0000004 +#define UW7_PARMRK 0000010 +#define UW7_INPCK 0000020 +#define UW7_ISTRIP 0000040 +#define UW7_INLCR 0000100 +#define UW7_IGNCR 0000200 +#define UW7_ICRNL 0000400 +#define UW7_IUCLC 0001000 +#define UW7_IXON 0002000 +#define UW7_IXANY 0004000 +#define UW7_IXOFF 0010000 +#define UW7_IMAXBEL 0020000 +#define UW7_DOSMODE 0100000 + +/* + * Output modes (c_oflag), exactly the same as Linux bits. + */ +#define UW7_OFLAG_MSK 0177777 +#define UW7_OPOST 0000001 +#define UW7_OLCUC 0000002 +#define UW7_ONLCR 0000004 +#define UW7_OCRNL 0000010 +#define UW7_ONOCR 0000020 +#define UW7_ONLRET 0000040 +#define UW7_OFILL 0000100 +#define UW7_OFDEL 0000200 +#define UW7_NLDLY 0000400 +#define UW7_NL0 0000000 +#define UW7_NL1 0000400 +#define UW7_CRDLY 0003000 +#define UW7_CR0 0000000 +#define UW7_CR1 0001000 +#define UW7_CR2 0002000 +#define UW7_CR3 0003000 +#define UW7_TABDLY 0014000 +#define UW7_TAB0 0000000 +#define UW7_TAB1 0004000 +#define UW7_TAB2 0010000 +#define UW7_TAB3 0014000 +#define UW7_XTABS UW7_TAB3 +#define UW7_BSDLY 0020000 +#define UW7_BS0 0000000 +#define UW7_BS1 0020000 +#define UW7_VTDLY 0040000 +#define UW7_VT0 0000000 +#define UW7_VT1 0040000 +#define UW7_FFDLY 0100000 +#define UW7_FF0 0000000 +#define UW7_FF1 0100000 + +/* + * Control modes (c_cflag). + */ +#define UW7_CFLAG_MSK 0177777 +#define UW7_CBAUD 0000017 +#define UW7_CSIZE 0000060 +#define UW7_CS5 0000000 +#define UW7_CS6 0000020 +#define UW7_CS7 0000040 +#define UW7_CS8 0000060 +#define UW7_CSTOPB 0000100 +#define UW7_CREAD 0000200 +#define UW7_PARENB 0000400 +#define UW7_PARODD 0001000 +#define UW7_HUPCL 0002000 +#define UW7_CLOCAL 0004000 +#define UW7_XCLUDE 0100000 +#define UW7_CIBAUD 000003600000 +#define UW7_IBSHIFT 16 +#define UW7_PAREXT 000004000000 + +/* + * Local modes (c_lflag), same as Linux except + * UW7_FLUSHO is different and UW7_DEFECHO is obsolete (set to 0). + */ +#define UW7_LFLAG_MSK 0001777 +#define UW7_ISIG 0000001 +#define UW7_ICANON 0000002 +#define UW7_XCASE 0000004 +#define UW7_ECHO 0000010 +#define UW7_ECHOE 0000020 +#define UW7_ECHOK 0000040 +#define UW7_ECHONL 0000100 +#define UW7_NOFLSH 0000200 +#define UW7_TOSTOP 0000400 +#define UW7_ECHOCTL 0001000 +#define UW7_ECHOPRT 0002000 +#define UW7_ECHOKE 0004000 +#define UW7_DEFECHO 0010000 +#define UW7_FLUSHO 0020000 +#define UW7_PENDIN 0040000 +#define UW7_IEXTEN 0100000 + +#endif /* _ABI_UW7_TERMBITS_H */ diff -Nru linux-2.6.7/include/abi/uw7/termios.h linux-2.6.7-abi/include/abi/uw7/termios.h --- linux-2.6.7/include/abi/uw7/termios.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/include/abi/uw7/termios.h 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,13 @@ +#ifndef _ABI_UW7_TERMIOS_H +#define _ABI_UW7_TERMIOS_H + +#define UW7_NCCS (19) +struct uw7_termios { + unsigned long c_iflag; + unsigned long c_oflag; + unsigned long c_cflag; + unsigned long c_lflag; + unsigned char c_cc[UW7_NCCS]; +}; + +#endif /* _ABI_UW7_TERMIOS_H */ diff -Nru linux-2.6.7/include/abi/uw7/types.h linux-2.6.7-abi/include/abi/uw7/types.h --- linux-2.6.7/include/abi/uw7/types.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/include/abi/uw7/types.h 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2001 Christoph Hellwig. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef _ABI_UW7_TYPES_H +#define _ABI_UW7_TYPES_H + +#ident "%W% %G%" + +/* + * UnixWare 7 type declarations. + */ +#include /* UnixWare is based on SVR4 */ + +typedef svr4_dev_t uw7_dev_t; +typedef u_int64_t uw7_ino_t; +typedef svr4_mode_t uw7_mode_t; +typedef svr4_nlink_t uw7_nlink_t; +typedef svr4_uid_t uw7_uid_t; +typedef svr4_gid_t uw7_gid_t; +typedef int64_t uw7_off_t; +typedef struct timeval uw7_timestruc_t; + +typedef u_int64_t uw7_fsblkcnt64_t; +typedef u_int64_t uw7_fsfilcnt64_t; + + +#define linux_to_uw7_dev_t(dev) \ + linux_to_svr4_dev_t(dev) + +#define linux_to_uw7_ino_t(ino) \ + linux_to_svr4_ino_t(ino) + +#define linux_to_uw7_uid_t(uid) \ + linux_to_svr4_uid_t(uid) + +#define linux_to_uw7_gid_t(gid) \ + linux_to_svr4_gid_t(gid) + +#endif /* _ABI_UW7_TYPES_H */ diff -Nru linux-2.6.7/include/abi/wyse/net.h linux-2.6.7-abi/include/abi/wyse/net.h --- linux-2.6.7/include/abi/wyse/net.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/include/abi/wyse/net.h 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,59 @@ +/* + * Copyright (C) 1994 Mike Jagdis (jaggy@purplet.demon.co.uk) + */ + +#ident "%W% %G%" + +/* + * Wyse extensions for 4.3 BSD TCP/IP in V/386 3.2.1A + */ +#include + +/* Get struct rtentry from linux/route.h - this should be compatible. */ +#include +/* Get struct arpreq from linux/if_arp.h - this should be compatible. */ +#include +/* Get struct ifreq and struct ifconf from linux/if.h - these should + * be compatible. */ +#include + + +/* Wyse use BSD style ioctls. This will warn us if we haven't got compatible + * structures :-). + */ + +/* socket i/o controls */ +#define WVR3_SIOCSHIWAT BSD__IOW('s', 0, int) /* set high watermark */ +#define WVR3_SIOCGHIWAT BSD__IOR('s', 1, int) /* get high watermark */ +#define WVR3_SIOCSLOWAT BSD__IOW('s', 2, int) /* set low watermark */ +#define WVR3_SIOCGLOWAT BSD__IOR('s', 3, int) /* get low watermark */ +#define WVR3_SIOCATMARK BSD__IOR('s', 7, int) /* at oob mark? */ +#define WVR3_SIOCSPGRP BSD__IOW('s', 8, int) /* set process group */ +#define WVR3_SIOCGPGRP BSD__IOR('s', 9, int) /* get process group */ + +#define WVR3_SIOCADDRT BSD__IOW('r', 10, struct rtentry) /* add route */ +#define WVR3_SIOCDELRT BSD__IOW('r', 11, struct rtentry) /* delete route */ + +#define WVR3_SIOCSIFADDR BSD__IOW('i', 12, struct ifreq) /* set ifnet address */ +#define WVR3_SIOCGIFADDR BSD__IOWR('i',13, struct ifreq) /* get ifnet address */ +#define WVR3_SIOCSIFDSTADDR BSD__IOW('i', 14, struct ifreq) /* set p-p address */ +#define WVR3_SIOCGIFDSTADDR BSD__IOWR('i',15, struct ifreq) /* get p-p address */ +#define WVR3_SIOCSIFFLAGS BSD__IOW('i', 16, struct ifreq) /* set ifnet flags */ +#define WVR3_SIOCGIFFLAGS BSD__IOWR('i',17, struct ifreq) /* get ifnet flags */ +#define WVR3_SIOCGIFBRDADDR BSD__IOWR('i',18, struct ifreq) /* get broadcast addr */ +#define WVR3_SIOCSIFBRDADDR BSD__IOW('i',19, struct ifreq) /* set broadcast addr */ +#define WVR3_SIOCGIFCONF BSD__IOWR('i',20, struct ifconf) /* get ifnet list */ +#define WVR3_SIOCGIFNETMASK BSD__IOWR('i',21, struct ifreq) /* get net addr mask */ +#define WVR3_SIOCSIFNETMASK BSD__IOW('i',22, struct ifreq) /* set net addr mask */ +#define WVR3_SIOCGIFMETRIC BSD__IOWR('i',23, struct ifreq) /* get IF metric */ +#define WVR3_SIOCSIFMETRIC BSD__IOW('i',24, struct ifreq) /* set IF metric */ +#define WVR3_SIOCSIFHADDR BSD__IOW('i', 25, struct ifreq) /* set hardware addr */ +#define WVR3_SIOCGIFHADDR BSD__IOWR('i',26, struct ifreq) /* get hardware addr */ +#define WVR3_SIOCRIFHADDR BSD__IOW('i', 27, struct ifreq) /* reset hardware addr */ + +#define WVR3_SIOCSARP BSD__IOW('i', 30, struct arpreq) /* set arp entry */ +#define WVR3_SIOCGARP BSD__IOWR('i',31, struct arpreq) /* get arp entry */ +#define WVR3_SIOCDARP BSD__IOW('i', 32, struct arpreq) /* delete arp entry */ + +#define WVR3_SIOCADDMULTI BSD__IOW('i', 33, struct ifreq) /* set multicast addr */ +#define WVR3_SIOCDELMULTI BSD__IOW('i', 34, struct ifreq) /* set multicast addr */ diff -Nru linux-2.6.7/include/abi/wyse/sysent.h linux-2.6.7-abi/include/abi/wyse/sysent.h --- linux-2.6.7/include/abi/wyse/sysent.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/include/abi/wyse/sysent.h 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2001 Christoph Hellwig. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef _ABI_WYSE_SYSENT_H +#define _ABI_WYSE_SYSENT_H + +#ident "%W% %G%" + +/* + * External function declarations for the Wyse V/386 syscall table. + */ + +struct sockaddr; + + +/* ptrace.c */ +extern int wyse_ptrace(int, int, u_long, u_long); + +/* socket.c */ +extern int wyse_gethostname(char *, int); +extern int wyse_getdomainname(char *, int); +extern int wyse_wait3(int *); +extern int wyse_socket(int, int, int); +extern int wyse_setsockopt(int, int, int, char *, int); +extern int wyse_getsockopt(int, int, int, char *, int *); +extern int wyse_recvfrom(int, void *, size_t, unsigned, + struct sockaddr *, int *); +extern int wyse_recv(int, void *, size_t, unsigned); +extern int wyse_sendto(int, void *, size_t, unsigned, + struct sockaddr *, int); +extern int wyse_send(int, void *, size_t, unsigned); + +/* syslocal.c */ +extern int wyse_syslocal(struct pt_regs *); + +#endif /* _ABI_WYSE_SYSENT_H */ diff -Nru linux-2.6.7/include/asm-i386/abi_machdep.h linux-2.6.7-abi/include/asm-i386/abi_machdep.h --- linux-2.6.7/include/asm-i386/abi_machdep.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/include/asm-i386/abi_machdep.h 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2001 Caldera Deutschland GmbH. + * Copyright (c) 2001 Christoph Hellwig. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef _ASM_ABI_MACHDEP_H +#define _ASM_ABI_MACHDEP_H + +#include + +/** + * get_syscall_parameter - get syscall parameter + * @regs: saved register contents + * @n: nth syscall to get + * + * This function gets the nth syscall parameter if + * the syscall got a &struct pt_regs * passed instead + * of the traditional C calling convention. + */ +static __inline unsigned long +get_syscall_parameter(struct pt_regs *regs, int n) +{ + unsigned long r; + + __get_user(r, ((unsigned long *)regs->esp)+(n+1)); + return r; +} + +/** + * set_error - set error number + * @regs: saved register contents + * @errno: error number + * + * This function sets the syscall error return for lcall7 + * calling conventions to @errno. + */ +static __inline void +set_error(struct pt_regs *regs, int errno) +{ + regs->eax = errno; + regs->eflags |= 1; +} + +/** + * clear_error - clear error return flag + * @regs: saved register contents + * + * This funtion clears the flag that indicates an error + * return for lcall7-based syscalls. + */ +static __inline void +clear_error(struct pt_regs *regs) +{ + regs->eflags &= ~1; +} + +/** + * set_result - set syscall return value + * @regs: saved register contents + * + * This funtion sets the return value for syscalls + * that have the saved register set calling convention. + */ +static __inline void +set_result(struct pt_regs *regs, int r) +{ + regs->eax = r; +} + +/** + * get_result - get syscall return value + * @regs: saved register contents + * + * This funtion gets the return value for syscalls + * that have the saved register set calling convention. + */ +static __inline int +get_result(struct pt_regs *regs) +{ + return regs->eax; +} + +#endif /* _ASM_ABI_MACHDEP_H */ diff -Nru linux-2.6.7/include/asm-i386/elf.h linux-2.6.7-abi/include/asm-i386/elf.h --- linux-2.6.7/include/asm-i386/elf.h 2004-06-16 07:19:42.000000000 +0200 +++ linux-2.6.7-abi/include/asm-i386/elf.h 2004-07-22 17:44:21.000000000 +0200 @@ -117,7 +117,20 @@ #define AT_SYSINFO_EHDR 33 #ifdef __KERNEL__ -#define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX) + +#include + +#define SET_PERSONALITY(ex, ibcs2) \ +do { \ + unsigned long personality = abi_defhandler_elf; \ + if ((ex).e_flags == EF_386_UW7) \ + personality = PER_UW7; \ + else if ((ex).e_flags == EF_386_OSR5) \ + personality = PER_OSR5; \ + else if (ibcs2) \ + personality = abi_defhandler_libcso; \ + set_personality(personality); \ +} while (0) extern int dump_task_regs (struct task_struct *, elf_gregset_t *); extern int dump_task_fpu (struct task_struct *, elf_fpregset_t *); diff -Nru linux-2.6.7/include/asm-i386/elfmark.h linux-2.6.7-abi/include/asm-i386/elfmark.h --- linux-2.6.7/include/asm-i386/elfmark.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/include/asm-i386/elfmark.h 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,37 @@ +/* + * elfmark - set ELF header e_flags value to an abi-specific value. + * + * This utility is used for marking ELF binaries (including shared libraries) + * for use by the UW Linux kernel module that provides exec domain for PER_UW7 + * personality. Run only on IA32 architectures. + * + * Authors - Tigran Aivazian , + * Christoph Hellwig + * + * This software is under GPL + */ +#ifndef _ELFMARK_H +#define _ELFMARK_H + +/* + * The e_flags value for SCO UnixWare 7/UDK binaries + */ +#ifndef EF_386_UW7 +#define EF_386_UW7 0x314B4455 +#endif + +/* + * The e_flags value for SCO OpenServer 5 binaries. + */ +#ifndef EF_386_OSR5 +#define EF_386_OSR5 0x3552534f +#endif + +/* + * e_flags value with no special meaning. + */ +#ifndef EF_386_NONE +#define EF_386_NONE 0 +#endif + +#endif /* _ELFMARK_H */ diff -Nru linux-2.6.7/include/asm-i386/namei.h linux-2.6.7-abi/include/asm-i386/namei.h --- linux-2.6.7/include/asm-i386/namei.h 2004-06-16 07:19:43.000000000 +0200 +++ linux-2.6.7-abi/include/asm-i386/namei.h 2004-07-22 17:44:21.000000000 +0200 @@ -1,4 +1,4 @@ -/* $Id$ +/* $Id$ * linux/include/asm-i386/namei.h * * Included from linux/fs/namei.c @@ -7,11 +7,55 @@ #ifndef __I386_NAMEI_H #define __I386_NAMEI_H -/* This dummy routine maybe changed to something useful - * for /usr/gnemul/ emulation stuff. - * Look at asm-sparc/namei.h for details. +#include + +/* + * The base directory for our emulations. + * - sparc uses usr/gmemul here. + */ +#define I386_EMUL_BASE "emul/" + +/* + * We emulate quite a lot operting systems... */ +#define I386_SVR4_EMUL I386_EMUL_BASE "/svr4/" +#define I386_SVR3_EMUL I386_EMUL_BASE "/svr3/" +#define I386_SCOSVR3_EMUL I386_EMUL_BASE "/sco/" +#define I386_OSR5_EMUL I386_EMUL_BASE "/osr5/" +#define I386_WYSEV386_EMUL I386_EMUL_BASE "/wyse/" +#define I386_ISCR4_EMUL I386_EMUL_BASE "/isc/" +#define I386_BSD_EMUL I386_EMUL_BASE "/bsd/" +#define I386_XENIX_EMUL I386_EMUL_BASE "/xenix/" +#define I386_SOLARIS_EMUL I386_EMUL_BASE "/solaris/" +#define I386_UW7_EMUL I386_EMUL_BASE "/uw7/" -#define __emul_prefix() NULL +static inline char *__emul_prefix(void) +{ +#if defined(CONFIG_ABI) || defined (CONFIG_ABI_MODULE) + switch (get_cur_personality()) { + case PER_SVR4: + return I386_SVR4_EMUL; + case PER_SVR3: + return I386_SVR3_EMUL; + case PER_SCOSVR3: + return I386_SCOSVR3_EMUL; + case PER_OSR5: + return I386_OSR5_EMUL; + case PER_WYSEV386: + return I386_WYSEV386_EMUL; + case PER_ISCR4: + return I386_ISCR4_EMUL; + case PER_BSD: + return I386_BSD_EMUL; + case PER_XENIX: + return I386_XENIX_EMUL; + case PER_SOLARIS: + return I386_SOLARIS_EMUL; + case PER_UW7: + return I386_UW7_EMUL; + } +#endif /* CONFIG_ABI || CONFIG_ABI_MODULE */ + return NULL; +} #endif /* __I386_NAMEI_H */ diff -Nru linux-2.6.7/include/asm-i386/unistd.h linux-2.6.7-abi/include/asm-i386/unistd.h --- linux-2.6.7/include/asm-i386/unistd.h 2004-06-16 07:19:37.000000000 +0200 +++ linux-2.6.7-abi/include/asm-i386/unistd.h 2004-07-22 17:44:21.000000000 +0200 @@ -412,6 +412,7 @@ #include #include #include +#include /* for old_sigset_t */ /* * we need this inline - forking from kernel space will result @@ -451,7 +452,11 @@ const struct sigaction __user *act, struct sigaction __user *oact, size_t sigsetsize); - +extern asmlinkage int sys_ipc(uint call, int first, int second, + int third, void *ptr, long fifth); +extern asmlinkage long sys_sigaltstack(const stack_t *uss, stack_t *uoss); +extern asmlinkage int sys_sigsuspend(int history0, int history1, + old_sigset_t mask); #endif /* diff -Nru linux-2.6.7/include/asm-parisc/processor.h linux-2.6.7-abi/include/asm-parisc/processor.h --- linux-2.6.7/include/asm-parisc/processor.h 2004-06-16 07:20:26.000000000 +0200 +++ linux-2.6.7-abi/include/asm-parisc/processor.h 2004-07-22 17:44:21.000000000 +0200 @@ -262,7 +262,7 @@ */ #ifdef __LP64__ -#define USER_WIDE_MODE (personality(current->personality) == PER_LINUX) +#define USER_WIDE_MODE (is_cur_personality_id(PERID_LINUX)) #else #define USER_WIDE_MODE 0 #endif diff -Nru linux-2.6.7/include/linux/fs.h linux-2.6.7-abi/include/linux/fs.h --- linux-2.6.7/include/linux/fs.h 2004-06-16 07:19:02.000000000 +0200 +++ linux-2.6.7-abi/include/linux/fs.h 2004-07-22 17:44:21.000000000 +0200 @@ -1474,6 +1474,18 @@ extern int vfs_readdir(struct file *, filldir_t, void *); +#ifndef __ia64__ +struct old_linux_dirent { + unsigned long d_ino; + unsigned long d_offset; + unsigned short d_namlen; + char d_name[1]; +}; + +extern asmlinkage long old_readdir(unsigned int fd, + struct old_linux_dirent __user * dirent, unsigned int count); +#endif + extern int vfs_stat(char __user *, struct kstat *); extern int vfs_lstat(char __user *, struct kstat *); extern int vfs_fstat(unsigned int, struct kstat *); diff -Nru linux-2.6.7/include/linux/major.h linux-2.6.7-abi/include/linux/major.h --- linux-2.6.7/include/linux/major.h 2004-06-16 07:19:02.000000000 +0200 +++ linux-2.6.7-abi/include/linux/major.h 2004-07-22 17:44:21.000000000 +0200 @@ -55,6 +55,7 @@ #define ACSI_MAJOR 28 #define AZTECH_CDROM_MAJOR 29 #define GRAPHDEV_MAJOR 29 /* SparcLinux & Linux/68k /dev/fb */ +#define SOCKSYS_MAJOR 30 /* iBCS needs this for STREAMS-based TCP/IP */ #define CM206_CDROM_MAJOR 32 #define IDE2_MAJOR 33 #define IDE3_MAJOR 34 diff -Nru linux-2.6.7/include/linux/personality.h linux-2.6.7-abi/include/linux/personality.h --- linux-2.6.7/include/linux/personality.h 2004-06-16 07:19:23.000000000 +0200 +++ linux-2.6.7-abi/include/linux/personality.h 2004-07-22 17:44:21.000000000 +0200 @@ -8,9 +8,12 @@ struct exec_domain; struct pt_regs; +typedef unsigned long personality_t; /* type for full personality value */ +typedef unsigned char per_id_t; /* type for base per id */ + extern int register_exec_domain(struct exec_domain *); extern int unregister_exec_domain(struct exec_domain *); -extern int __set_personality(unsigned long); +extern int __set_personality(personality_t); /* @@ -24,49 +27,85 @@ /* - * Flags for bug emulation. + * Basic personality ids (per_id). + * + * The per_id is occupying byte 0. + * (It has to fit into an unsigned char! -> per_id_t) + */ +enum { + PERID_LINUX = 0x00, /* native execution mode of os platform */ + PERID_SVR4 = 0x01, + PERID_SVR3 = 0x02, + PERID_SCOSVR3 = 0x03, /* and SCO-OS-R5 */ + PERID_WYSEV386 = 0x04, + PERID_ISCR4 = 0x05, + PERID_BSD = 0x06, /* and SUN OS */ + PERID_XENIX = 0x07, + PERID_LINUX32 = 0x08, /* 32 bit mode on non-32 bit platforms */ + PERID_IRIX32 = 0x09, /* IRIX5 32-bit */ + PERID_IRIXN32 = 0x0a, /* IRIX6 new 32-bit */ + PERID_IRIX64 = 0x0b, /* IRIX6 64-bit */ + PERID_RISCOS = 0x0c, + PERID_SOLARIS = 0x0d, + PERID_UW7 = 0x0e, + PERID_OSF4 = 0x0f, /* OSF/1 v4 */ + PERID_HPUX = 0x10, + PERID_MASK = 0xff, +}; + +/* + * Flags for customizing the behaviour of a base personality id. * - * These occupy the top three bytes. + * The flags occupy bytes 1 trough 3. Byte 0 is for the base personality id. + * (Avoid defining the top bit, it will conflict with error returns.) */ enum { +#if 1 /* only for compatibilty with old code */ MMAP_PAGE_ZERO = 0x0100000, ADDR_LIMIT_32BIT = 0x0800000, SHORT_INODE = 0x1000000, WHOLE_SECONDS = 0x2000000, - STICKY_TIMEOUTS = 0x4000000, + STICKY_TIMEOUTS = 0x4000000, ADDR_LIMIT_3GB = 0x8000000, +#endif + /* ffffffpp */ + PERF_MMAP_PAGE_ZERO = 0x00100000, + PERF_ADDR_LIMIT_32BIT = 0x00800000, + PERF_SHORT_INODE = 0x01000000, + PERF_WHOLE_SECONDS = 0x02000000, + PERF_STICKY_TIMEOUTS = 0x04000000, + PERF_ADDR_LIMIT_3GB = 0x08000000, + PERF_MASK = 0xFFFFFF00, }; /* - * Personality types. - * - * These go in the low byte. Avoid using the top bit, it will - * conflict with error returns. + * Predefined personality profiles. */ enum { - PER_LINUX = 0x0000, - PER_LINUX_32BIT = 0x0000 | ADDR_LIMIT_32BIT, - PER_SVR4 = 0x0001 | STICKY_TIMEOUTS | MMAP_PAGE_ZERO, - PER_SVR3 = 0x0002 | STICKY_TIMEOUTS | SHORT_INODE, - PER_SCOSVR3 = 0x0003 | STICKY_TIMEOUTS | - WHOLE_SECONDS | SHORT_INODE, - PER_OSR5 = 0x0003 | STICKY_TIMEOUTS | WHOLE_SECONDS, - PER_WYSEV386 = 0x0004 | STICKY_TIMEOUTS | SHORT_INODE, - PER_ISCR4 = 0x0005 | STICKY_TIMEOUTS, - PER_BSD = 0x0006, - PER_SUNOS = 0x0006 | STICKY_TIMEOUTS, - PER_XENIX = 0x0007 | STICKY_TIMEOUTS | SHORT_INODE, - PER_LINUX32 = 0x0008, - PER_LINUX32_3GB = 0x0008 | ADDR_LIMIT_3GB, - PER_IRIX32 = 0x0009 | STICKY_TIMEOUTS,/* IRIX5 32-bit */ - PER_IRIXN32 = 0x000a | STICKY_TIMEOUTS,/* IRIX6 new 32-bit */ - PER_IRIX64 = 0x000b | STICKY_TIMEOUTS,/* IRIX6 64-bit */ - PER_RISCOS = 0x000c, - PER_SOLARIS = 0x000d | STICKY_TIMEOUTS, - PER_UW7 = 0x000e | STICKY_TIMEOUTS | MMAP_PAGE_ZERO, - PER_OSF4 = 0x000f, /* OSF/1 v4 */ - PER_HPUX = 0x0010, - PER_MASK = 0x00ff, + PER_LINUX = PERID_LINUX, + PER_LINUX_32BIT = PERID_LINUX | PERF_ADDR_LIMIT_32BIT, + PER_SVR4 = PERID_SVR4 | PERF_STICKY_TIMEOUTS | PERF_MMAP_PAGE_ZERO, + PER_SVR3 = PERID_SVR3 | PERF_STICKY_TIMEOUTS | PERF_SHORT_INODE, + PER_SCOSVR3 = PERID_SCOSVR3 | PERF_STICKY_TIMEOUTS | + PERF_WHOLE_SECONDS | PERF_SHORT_INODE, + PER_OSR5 = PERID_SCOSVR3 | PERF_STICKY_TIMEOUTS | PERF_WHOLE_SECONDS, + PER_WYSEV386 = PERID_WYSEV386 | PERF_STICKY_TIMEOUTS | PERF_SHORT_INODE, + PER_ISCR4 = PERID_ISCR4 | PERF_STICKY_TIMEOUTS, + PER_BSD = PERID_BSD, + PER_SUNOS = PERID_BSD | PERF_STICKY_TIMEOUTS, + PER_XENIX = PERID_XENIX | PERF_STICKY_TIMEOUTS | PERF_SHORT_INODE, + PER_LINUX32 = PERID_LINUX32, + PER_LINUX32_3GB = PERID_LINUX32 | PERF_ADDR_LIMIT_3GB, + PER_IRIX32 = PERID_IRIX32 | PERF_STICKY_TIMEOUTS,/* IRIX5 32-bit */ + PER_IRIXN32 = PERID_IRIXN32 | PERF_STICKY_TIMEOUTS,/* IRIX6 new 32-bit */ + PER_IRIX64 = PERID_IRIX64 | PERF_STICKY_TIMEOUTS,/* IRIX6 64-bit */ + PER_RISCOS = PERID_RISCOS, + PER_SOLARIS = PERID_SOLARIS | PERF_STICKY_TIMEOUTS, + PER_UW7 = PERID_UW7 | PERF_STICKY_TIMEOUTS | PERF_MMAP_PAGE_ZERO, + PER_OSF4 = PERID_OSF4,/* OSF/1 v4 */ + PER_HPUX = PERID_HPUX, + PER_MASK = PERID_MASK | PERF_MASK, + PER_QUERY = 0xffffffff, /* indicates query when passed to sys_personality */ }; @@ -81,8 +120,8 @@ struct exec_domain { const char *name; /* name of the execdomain */ handler_t handler; /* handler for syscalls */ - unsigned char pers_low; /* lowest personality */ - unsigned char pers_high; /* highest personality */ + per_id_t pers_low; /* lowest personality id for this execdomain */ + per_id_t pers_high; /* highest personality id for this execdomain */ unsigned long *signal_map; /* signal mapping */ unsigned long *signal_invmap; /* reverse signal mapping */ struct map_segment *err_map; /* error mapping */ @@ -94,19 +133,72 @@ }; /* - * Return the base personality without flags. + * Return the base personality id of the given personality. */ -#define personality(pers) (pers & PER_MASK) +#define get_personality_id(personality) ((personality) & PERID_MASK) +/* compatibility with old naming */ +#define personality(personality) get_personality_id(personality) + +/* + * Return the flags of the given personality. + */ +#define get_personality_flags(personality) ((personality) & PERF_MASK) /* * Personality of the currently running process. */ -#define get_personality (current->personality) +#define get_cur_personality() (current->personality) + +/* + * Return the base personality id of current process. + */ +#define get_cur_personality_id() get_personality_id(get_cur_personality()) + +/* + * Return the flags of the personality of current process. + */ +#define get_cur_personality_flags() get_personality_flags(get_cur_personality()) + +/* + * Check if the personality of the current process matches with the given value. + */ +#define is_cur_personality(personality) \ + (get_cur_personality() == (personality)) + +/* + * Check if the pers id of the current userland process matches the given. + * No masking does apply to the given id! + */ +#define is_cur_personality_id(per_id) \ + (get_cur_personality_id() == (per_id)) + +/* + * Check if the personality id of the current userland process + * matches the personality id of the given personality code value. + */ +#define is_cur_same_personality_id_as(personality) \ + (get_cur_personality_id() == get_personality_id(personality)) + +/* + * Check if the current userland process has set one or more of the given flags. + * This macro works only with single flags! + */ +#define is_cur_personality_flag(per_flag) \ + (get_cur_personality_flags() & (per_flag)) + +/* + * Check if the current userland process has all of the given flags set. + * This macro works only with single flags! + */ +#define is_cur_personality_all_flags(per_flags) \ + (get_cur_personality_flags() & (per_flags) == (per_flags)) /* - * Change personality of the currently running process. + * Set a new personality for the current userland process (if not already set). */ -#define set_personality(pers) \ - ((current->personality == pers) ? 0 : __set_personality(pers)) +#define set_cur_personality(personality) \ + (is_cur_personality(personality) ? 0 : __set_personality(personality)) +/* compatibility with old naming */ +#define set_personality(personality) set_cur_personality(personality) #endif /* _LINUX_PERSONALITY_H */ diff -Nru linux-2.6.7/include/linux/xout.h linux-2.6.7-abi/include/linux/xout.h --- linux-2.6.7/include/linux/xout.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/include/linux/xout.h 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,192 @@ +/* + * Copyright (c) 1994 Mike Jagdis (jaggy@purplet.demon.co.uk) + */ +#ifndef _ABI_XOUT_H_ +#define _ABI_XOUT_H_ + +#ident "%W% %G%" + +/* + * This file is based on available documentation for the Xenix x.out + * format. Much is missing here. There is just enough to allow us to + * support 386 small model and not a lot more. + */ + +/* + * X.out header + */ +struct xexec { + u_short x_magic; /* magic number */ + u_short x_ext; /* size of header extension */ + + /* + * For segmented binaries the following sizes are the sums + * of the segment sizes. + */ + long x_text; /* size of text segments */ + long x_data; /* size of initialized data */ + long x_bss; /* size of uninitialized data */ + long x_syms; /* size of symbol table */ + long x_reloc; /* relocation table length */ + + long x_entry; /* entry point */ + char x_cpu; /* cpu type and byte/word order */ + char x_relsym; /* undefined */ + u_short x_renv; /* run-time environment */ +}; + +/* + * X.out header extension + */ +struct xext { + /* + * These are unused. + * */ + long xe_trsize; /* ??? */ + long xe_drsize; /* ??? */ + long xe_tbase; /* ??? */ + long xe_dbase; /* ??? */ + + long xe_stksize; /* stack size (if XE_FS set) */ + + /* + * The following are present if XE_SEG is set. + */ + long xe_segpos; /* offset to segment table */ + long xe_segsize; /* segment table size */ + long xe_mdtpos; /* offset to machdep table */ + long xe_mdtsize; /* machine dependent table size */ + char xe_mdttype; /* machine dependent table type */ + char xe_pagesize; /* file pagesize, in 512 units */ + char xe_ostype; /* operating system type */ + char xe_osvers; /* operating system version */ + u_short xe_eseg; /* entry segment, machdep */ + u_short xe_sres; /* reserved */ +}; + +/* + * X.out segment description. + */ +struct xseg { + u_short xs_type; /* segment type */ + u_short xs_attr; /* segment attributes */ + u_short xs_seg; /* segment number */ + char xs_align; /* log base 2 of alignment */ + char xs_cres; /* unused */ + u_long xs_filpos; /* file position */ + u_long xs_psize; /* physical size (in file) */ + u_long xs_vsize; /* virtual size (in core) */ + u_long xs_rbase; /* relocation base addr/offset */ + u_short xs_noff; /* segment name table offset */ + u_short xs_sres; /* unused */ + long xs_lres; /* unused */ +}; + + +/* + * Magic number for an x.out header. + */ +#define X_MAGIC 0x0206 /* indicates x.out header */ + +/* + * Codes for x_cpu. + */ +#define XC_BSWAP 0x80 /* bytes swapped */ +#define XC_WSWAP 0x40 /* words swapped */ +#define XC_8086 0x04 /* I8086 */ +#define XC_286 0x09 /* iAPX 80286 */ +#define XC_286V 0x29 /* iAPX 80286, use xe_osver for version */ +#define XC_386 0x0a /* iAPX 80386 */ +#define XC_186 0x0b /* iAPX 80186 */ +#define XC_CPU 0x3f /* cpu mask */ + +/* + * Flags for the run-time environment. + */ +#define XE_V2 0x4000 /* version 2.x */ +#define XE_V3 0x8000 /* version 3.x */ +#define XE_OSV 0xc000 /* if XE_SEG use xe_osvers ... */ +#define XE_V5 XE_OSV /* else assume v5.x */ +#define XE_VERS 0xc000 /* version mask */ + +#define XE_5_3 0x2000 /* binary needs 5.3 functionality */ +#define XE_LOCK 0x1000 /* Use Advisory locking */ +#define XE_SEG 0x0800 /* segment table present */ +#define XE_ABS 0x0400 /* absolute memory image (standalone) */ +#define XE_ITER 0x0200 /* iterated text/data present */ +#define XE_HDATA 0x0100 /* huge model data (never used) */ +#define XE_VMOD XE_HDATA /* virtual module */ +#define XE_FPH 0x0080 /* floating point hardware required */ +#define XE_LTEXT 0x0040 /* large model text */ +#define XE_LDATA 0x0020 /* large model data */ +#define XE_OVER 0x0010 /* text overlay */ +#define XE_FS 0x0008 /* fixed stack */ +#define XE_PURE 0x0004 /* pure text */ +#define XE_SEP 0x0002 /* separate I & D */ +#define XE_EXEC 0x0001 /* executable */ + + +/* + * Segment types. + */ +#define XS_TNULL 0 /* unused segment */ +#define XS_TTEXT 1 /* text segment */ +#define XS_TDATA 2 /* data segment */ +#define XS_TSYMS 3 /* symbol table segment */ +#define XS_TREL 4 /* relocation segment */ +#define XS_TSESTR 5 /* segment table's string table segment */ +#define XS_TGRPS 6 /* group definitions segment */ + +#define XS_TIDATA 64 /* iterated data */ +#define XS_TTSS 65 /* tss */ +#define XS_TLFIX 66 /* lodfix */ +#define XS_TDNAME 67 /* descriptor names */ +#define XS_TDTEXT 68 /* debug text segment */ +#define XS_TIDBG XS_TDTEXT +#define XS_TDFIX 69 /* debug relocation */ +#define XS_TOVTAB 70 /* overlay table */ +#define XS_T71 71 +#define XS_TSYSTR 72 /* symbol string table */ + +/* + * Segment attributes. + */ +#define XS_AMEM 0x8000 /* is a memory image */ + +/* + * For text and data segment types + */ +#define XS_AITER 0x0001 /* contains iteration records */ +#define XS_AHUGE 0x0002 /* contains huge element */ +#define XS_ABSS 0x0004 /* contains implicit BSS */ +#define XS_APURE 0x0008 /* read only, shareable */ +#define XS_AEDOWN 0x0010 /* expands downward (stack) */ +#define XS_APRIV 0x0020 /* may not be combined */ +#define XS_A32BIT 0x0040 /* is 32 bit */ + +/* + * File position macros, valid only if !XE_SEG. + */ +#define XEXTPOS(xp) ((long) sizeof(struct xexec)) +#define XTEXTPOS(xp) (XEXTPOS(xp) + (long) (xp)->x_ext) +#define XDATAPOS(xp) (XTEXTPOS(xp) + (xp)->x_text) +#define XBSSPOS(xp) (XDATAPOS(xp) + (xp)->x_data) +#define XSYMPOS(xp) (XDATAPOS(xp) + (xp)->x_data) +#define XRELPOS(xp) (XSYMPOS(xp) + (xp)->x_syms) +#define XENDPOS(xp) (XRELPOS(xp) + (xp)->x_reloc) + +#define XRTEXTPOS(xp, ep) (XRELPOS(xp)) +#define XRDATAPOS(xp, ep) (XRELPOS(xp) + (ep)->xe_trsize) + + +/* + * Specials for the Linux Xenix 286 emulator. + * + * The base address that 286 segments are loaded above. This should be + * above memory used by the emulator overlay. Actual segment data + * starts slightly higher than this since we map the xexec and xext + * structures of the executable to this address. + */ +#define X286_MAP_ADDR 0x4000000 + +#endif /* _ABI_XOUT_H_ */ diff -Nru linux-2.6.7/include/net/sock.h linux-2.6.7-abi/include/net/sock.h --- linux-2.6.7/include/net/sock.h 2004-06-16 07:19:43.000000000 +0200 +++ linux-2.6.7-abi/include/net/sock.h 2004-07-22 17:44:21.000000000 +0200 @@ -381,6 +381,7 @@ SOCK_DESTROY, SOCK_BROADCAST, SOCK_TIMESTAMP, + SOCK_BSDISM, }; static inline void sock_set_flag(struct sock *sk, enum sock_flags flag) diff -Nru linux-2.6.7/kernel/exec_domain.c linux-2.6.7-abi/kernel/exec_domain.c --- linux-2.6.7/kernel/exec_domain.c 2004-06-16 07:19:36.000000000 +0200 +++ linux-2.6.7-abi/kernel/exec_domain.c 2004-07-22 17:44:21.000000000 +0200 @@ -18,10 +18,14 @@ #include -static void default_handler(int, struct pt_regs *); +#if !defined(CONFIG_ABI_LATE_PROBING) +static void lcall_default_handler(int, struct pt_regs *); +#else +static void lcall_autodetect_handler(int, struct pt_regs *); +#endif -static struct exec_domain *exec_domains = &default_exec_domain; -static rwlock_t exec_domains_lock = RW_LOCK_UNLOCKED; +static struct exec_domain *exec_domains = &default_exec_domain; /* linked list of registered exed domains */ +static rwlock_t exec_domains_lock = RW_LOCK_UNLOCKED; /* access lock for linked list */ static u_long ident_map[32] = { @@ -31,77 +35,125 @@ 24, 25, 26, 27, 28, 29, 30, 31 }; +#define PERID_DEFAULT PERID_LINUX /* Linux personality id. */ + struct exec_domain default_exec_domain = { .name = "Linux", /* name */ - .handler = default_handler, /* lcall7 causes a seg fault. */ - .pers_low = 0, /* PER_LINUX personality. */ - .pers_high = 0, /* PER_LINUX personality. */ +#if !defined(CONFIG_ABI_LATE_PROBING) + .handler = lcall_default_handler,/* any unknown lcall raises a segmentation fault */ +#else + .handler = lcall_autodetect_handler,/* lcall 0x07 & 0x27 causes autoconfig or a seg fault. */ +#endif + .pers_low = PERID_DEFAULT, /* low personality id */ + .pers_high = PERID_DEFAULT, /* high personality id */ .signal_map = ident_map, /* Identity map signals. */ .signal_invmap = ident_map, /* - both ways. */ }; +#if !defined(CONFIG_ABI_LATE_PROBING) static void -default_handler(int segment, struct pt_regs *regp) +lcall_default_handler(int segment, struct pt_regs *regp) { - u_long pers = 0; + /* raise a segfault for the current process */ + send_sig(SIGSEGV, current, 1); +} +#else +static void +lcall_autodetect_handler(int segment, struct pt_regs *regp) +{ + personality_t personality = PER_LINUX; /* * This may have been a static linked SVr4 binary, so we would * have the personality set incorrectly. Or it might have been * a Solaris/x86 binary. We can tell which because the former * uses lcall7, while the latter used lcall 0x27. - * Try to find or load the appropriate personality, and fall back - * to just forcing a SEGV. + * Try to find or load the appropriate personality on first invocation. + * If loading failed and handler is still default then raise a SEGV. * * XXX: this is IA32-specific and should be moved to the MD-tree. */ switch (segment) { #ifdef __i386__ case 0x07: - pers = abi_defhandler_lcall7; + personality = abi_defhandler_lcall7; break; case 0x27: - pers = PER_SOLARIS; + personality = PER_SOLARIS; break; #endif } - set_personality(pers); + set_personality(personality); - if (current_thread_info()->exec_domain->handler != default_handler) - current_thread_info()->exec_domain->handler(segment, regp); - else + if (current_thread_info()->exec_domain->handler == lcall_autodetect_handler) + { + /* we are still at the same handler - recursing impossible! */ + /* raise a segfault for the current process */ send_sig(SIGSEGV, current, 1); + } + else + { + /* identifying the needed handler at exec time succeeded. */ + /* recursively call these installed handler (one level deep) */ + current_thread_info()->exec_domain->handler(segment, regp); + } } +#endif static struct exec_domain * lookup_exec_domain(u_long personality) { struct exec_domain * ep; - u_long pers = personality(personality); - + per_id_t per_id = get_personality_id(personality); + + /* browse for id in list of exec domains */ read_lock(&exec_domains_lock); for (ep = exec_domains; ep; ep = ep->next) { - if (pers >= ep->pers_low && pers <= ep->pers_high) + if (per_id >= ep->pers_low && per_id <= ep->pers_high) if (try_module_get(ep->module)) + { + read_unlock(&exec_domains_lock); goto out; + } } + read_unlock(&exec_domains_lock); #ifdef CONFIG_KMOD - read_unlock(&exec_domains_lock); - request_module("personality-%ld", pers); - read_lock(&exec_domains_lock); + /* request loading of all data bound to personality id */ + request_module("personality-%i", per_id); + /* browse for id in list of exec domains - once again */ + read_lock(&exec_domains_lock); for (ep = exec_domains; ep; ep = ep->next) { - if (pers >= ep->pers_low && pers <= ep->pers_high) + if (per_id >= ep->pers_low && per_id <= ep->pers_high) if (try_module_get(ep->module)) + { + read_unlock(&exec_domains_lock); goto out; + } } + read_unlock(&exec_domains_lock); #endif + /* matching exec domain is still not availabel. */ +#if !defined(CONFIG_ABI_LATE_PROBING) + ep = NULL; /* error */ +#else +#if 0 + printk(KERN_WARNING \ + "%s: personality-%i not found, using %i instead.\n", + __FILE__, per_id, PER_DEFAULT); +#endif + + /* we will start with default exec domain. */ + /* this will allow simple programs (mov/ret) to fully execute. */ + /* complex programs will run until the very first syscall. */ + /* then the syscall handler will attempt switch the identity again. */ ep = &default_exec_domain; +#endif + out: - read_unlock(&exec_domains_lock); return (ep); } @@ -159,25 +211,36 @@ struct exec_domain *ep, *oep; ep = lookup_exec_domain(personality); + if(!ep) + return -ENOEXEC; + + /* if the needed exec domain is already set for this process + then we save the works for registering with the new fs + and releasing the old fs and exec_domain, + we just have to update the personality to this process */ if (ep == current_thread_info()->exec_domain) { current->personality = personality; return 0; } + /* when the new fs is already bound to the current process */ if (atomic_read(¤t->fs->count) != 1) { struct fs_struct *fsp, *ofsp; + /* register as client for the new fs by copying it */ fsp = copy_fs_struct(current->fs); if (fsp == NULL) { module_put(ep->module); return -ENOMEM; } + /* replace the old with the new fs */ task_lock(current); ofsp = current->fs; current->fs = fsp; task_unlock(current); + /* quit as a client to the old fs */ put_fs_struct(ofsp); } @@ -186,17 +249,20 @@ * current->fs. */ + /* replace the old with the new exec_domain */ current->personality = personality; oep = current_thread_info()->exec_domain; current_thread_info()->exec_domain = ep; set_fs_altroot(); + /* quit as client for the old exec_domain */ module_put(oep->module); + return 0; } int -get_exec_domain_list(char *page) +get_exec_domain_list(char *page) /* handler for /proc/execdomains */ { struct exec_domain *ep; int len = 0; @@ -215,11 +281,12 @@ { u_long old = current->personality; - if (personality != 0xffffffff) { - set_personality(personality); - if (current->personality != personality) - return -EINVAL; - } + if (personality == PER_QUERY) + return (long)old; + + set_personality(personality); + if (get_cur_personality() != personality) + return -EINVAL; return (long)old; } diff -Nru linux-2.6.7/kernel/fork.c linux-2.6.7-abi/kernel/fork.c --- linux-2.6.7/kernel/fork.c 2004-06-16 07:18:57.000000000 +0200 +++ linux-2.6.7-abi/kernel/fork.c 2004-07-22 17:44:21.000000000 +0200 @@ -1289,3 +1289,9 @@ sizeof(struct mm_struct), 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL); } + +/* symbol exports for LinuxABI Sytem V R4 support */ +/* for ease of use we are exporting those needed symbols permanently */ +/* #if CONFIG_ABI_SVR4 == m */ +EXPORT_SYMBOL(do_fork); +/* #endif */ diff -Nru linux-2.6.7/kernel/Makefile linux-2.6.7-abi/kernel/Makefile --- linux-2.6.7/kernel/Makefile 2004-06-16 07:19:01.000000000 +0200 +++ linux-2.6.7-abi/kernel/Makefile 2004-07-22 17:44:21.000000000 +0200 @@ -7,7 +7,7 @@ sysctl.o capability.o ptrace.o timer.o user.o \ signal.o sys.o kmod.o workqueue.o pid.o \ rcupdate.o intermodule.o extable.o params.o posix-timers.o \ - kthread.o + kthread.o syscall_ksyms.o obj-$(CONFIG_FUTEX) += futex.o obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o diff -Nru linux-2.6.7/kernel/syscall_ksyms.c linux-2.6.7-abi/kernel/syscall_ksyms.c --- linux-2.6.7/kernel/syscall_ksyms.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7-abi/kernel/syscall_ksyms.c 2004-07-22 17:44:21.000000000 +0200 @@ -0,0 +1,182 @@ +/* + * Exports all Linux syscalls. + * Christoph Hellwig (hch@caldera.de), 2001 + */ + +#include +#include +#include +#define __KERNEL_SYSCALLS__ +#include +#include +#include +#include +#include +#include + +EXPORT_SYMBOL(sys_uselib); +EXPORT_SYMBOL(sys_sync); +EXPORT_SYMBOL(sys_fsync); +EXPORT_SYMBOL(sys_fdatasync); +EXPORT_SYMBOL(sys_dup); +EXPORT_SYMBOL(sys_dup2); +EXPORT_SYMBOL(sys_fcntl); +#if (BITS_PER_LONG == 32) +EXPORT_SYMBOL(sys_fcntl64); +#endif +EXPORT_SYMBOL(sys_ioctl); +EXPORT_SYMBOL(sys_link); +EXPORT_SYMBOL(sys_mkdir); +EXPORT_SYMBOL(sys_mknod); +EXPORT_SYMBOL(sys_rename); +EXPORT_SYMBOL(sys_rmdir); +EXPORT_SYMBOL(sys_symlink); +EXPORT_SYMBOL(sys_unlink); +EXPORT_SYMBOL(sys_umount); +EXPORT_SYMBOL(sys_oldumount); +EXPORT_SYMBOL(sys_mount); +EXPORT_SYMBOL(sys_pivot_root); +EXPORT_SYMBOL(sys_access); +EXPORT_SYMBOL(sys_chdir); +EXPORT_SYMBOL(sys_fchdir); +EXPORT_SYMBOL(sys_chroot); +EXPORT_SYMBOL(sys_chmod); +EXPORT_SYMBOL(sys_fchmod); +EXPORT_SYMBOL(sys_chown); +EXPORT_SYMBOL(sys_lchown); +EXPORT_SYMBOL(sys_fchown); +EXPORT_SYMBOL(sys_close); +#if !defined(__alpha__) +EXPORT_SYMBOL(sys_creat); +#endif +EXPORT_SYMBOL(sys_open); +EXPORT_SYMBOL(sys_statfs); +EXPORT_SYMBOL(sys_fstatfs); +EXPORT_SYMBOL(sys_ftruncate); +EXPORT_SYMBOL(sys_ftruncate64); +EXPORT_SYMBOL(sys_truncate); +EXPORT_SYMBOL(sys_truncate64); +#if !defined(__alpha__) && !defined(__ia64__) +EXPORT_SYMBOL(sys_utime); +#endif +EXPORT_SYMBOL(sys_utimes); +EXPORT_SYMBOL(sys_vhangup); +#if !defined(__alpha__) +EXPORT_SYMBOL(sys_lseek); +#endif +EXPORT_SYMBOL(sys_llseek); +EXPORT_SYMBOL(sys_read); +EXPORT_SYMBOL(sys_readv); +EXPORT_SYMBOL(sys_pread64); +EXPORT_SYMBOL(sys_pwrite64); +EXPORT_SYMBOL(sys_write); +EXPORT_SYMBOL(sys_writev); +EXPORT_SYMBOL(old_readdir); +EXPORT_SYMBOL(sys_poll); +EXPORT_SYMBOL(sys_select); +EXPORT_SYMBOL(sys_readlink); +EXPORT_SYMBOL(sys_sysfs); +EXPORT_SYMBOL(sys_acct); +EXPORT_SYMBOL(sys_exit); +EXPORT_SYMBOL(sys_getitimer); +EXPORT_SYMBOL(sys_setitimer); +EXPORT_SYMBOL(sys_gettimeofday); +EXPORT_SYMBOL(sys_settimeofday); +EXPORT_SYMBOL(sys_stime); +EXPORT_SYMBOL(sys_time); +#if !defined(__alpha__) +EXPORT_SYMBOL(sys_nice); +#endif +EXPORT_SYMBOL(sys_sched_setscheduler); +EXPORT_SYMBOL(sys_sched_setparam); +EXPORT_SYMBOL(sys_sched_getscheduler); +EXPORT_SYMBOL(sys_sched_getparam); +EXPORT_SYMBOL(sys_sched_get_priority_max); +EXPORT_SYMBOL(sys_sched_get_priority_min); +EXPORT_SYMBOL(sys_sched_rr_get_interval); +EXPORT_SYMBOL(sys_kill); +EXPORT_SYMBOL(sys_rt_sigaction); +EXPORT_SYMBOL(sys_rt_sigpending); +EXPORT_SYMBOL(sys_rt_sigprocmask); +EXPORT_SYMBOL(sys_rt_sigtimedwait); +EXPORT_SYMBOL(sys_sigaltstack); +EXPORT_SYMBOL(sys_sigpending); +EXPORT_SYMBOL(sys_sigprocmask); +EXPORT_SYMBOL(sys_sigsuspend); +EXPORT_SYMBOL(sys_gethostname); +EXPORT_SYMBOL(sys_sethostname); +EXPORT_SYMBOL(sys_setdomainname); +EXPORT_SYMBOL(sys_getrlimit); +EXPORT_SYMBOL(sys_setsid); +EXPORT_SYMBOL(sys_getsid); +EXPORT_SYMBOL(sys_getpgid); +EXPORT_SYMBOL(sys_setpgid); +EXPORT_SYMBOL(sys_getgroups); +EXPORT_SYMBOL(sys_setgroups); +EXPORT_SYMBOL(sys_setpriority); +EXPORT_SYMBOL(sys_getpriority); +EXPORT_SYMBOL(sys_reboot); +EXPORT_SYMBOL(sys_setgid); +EXPORT_SYMBOL(sys_setuid); +EXPORT_SYMBOL(sys_times); +EXPORT_SYMBOL(sys_umask); +EXPORT_SYMBOL(sys_prctl); +EXPORT_SYMBOL(sys_setreuid); +EXPORT_SYMBOL(sys_setregid); +#if !defined(__alpha__) && !defined(__ia64__) +EXPORT_SYMBOL(sys_alarm); +#endif +#if !defined(__alpha__) +EXPORT_SYMBOL(sys_getpid); +EXPORT_SYMBOL(sys_getppid); +EXPORT_SYMBOL(sys_getuid); +EXPORT_SYMBOL(sys_geteuid); +EXPORT_SYMBOL(sys_getgid); +EXPORT_SYMBOL(sys_getegid); +#endif +EXPORT_SYMBOL(sys_gettid); +EXPORT_SYMBOL(sys_nanosleep); +#if defined(CONFIG_UID16) +EXPORT_SYMBOL(sys_setreuid16); +EXPORT_SYMBOL(sys_setregid16); +EXPORT_SYMBOL(sys_getgroups16); +EXPORT_SYMBOL(sys_setgroups16); +#endif +EXPORT_SYMBOL(sys_wait4); +EXPORT_SYMBOL(sys_waitpid); +EXPORT_SYMBOL(sys_sendfile); +EXPORT_SYMBOL(sys_brk); +EXPORT_SYMBOL(sys_msync); +EXPORT_SYMBOL(sys_madvise); +EXPORT_SYMBOL(sys_mincore); +EXPORT_SYMBOL(sys_munmap); +EXPORT_SYMBOL(sys_mprotect); +EXPORT_SYMBOL(sys_socket); +EXPORT_SYMBOL(sys_socketpair); +EXPORT_SYMBOL(sys_bind); +EXPORT_SYMBOL(sys_listen); +EXPORT_SYMBOL(sys_accept); +EXPORT_SYMBOL(sys_connect); +EXPORT_SYMBOL(sys_getsockname); +EXPORT_SYMBOL(sys_getpeername); +EXPORT_SYMBOL(sys_sendto); +EXPORT_SYMBOL(sys_send); +EXPORT_SYMBOL(sys_recvfrom); +EXPORT_SYMBOL(sys_setsockopt); +EXPORT_SYMBOL(sys_getsockopt); +EXPORT_SYMBOL(sys_shutdown); +EXPORT_SYMBOL(sys_sendmsg); +EXPORT_SYMBOL(sys_recvmsg); +EXPORT_SYMBOL(sys_socketcall); + +EXPORT_SYMBOL(sys_msgget); +EXPORT_SYMBOL(sys_msgsnd); +EXPORT_SYMBOL(sys_msgrcv); +EXPORT_SYMBOL(sys_msgctl); +EXPORT_SYMBOL(sys_semget); +EXPORT_SYMBOL(sys_semop); +EXPORT_SYMBOL(sys_semctl); +EXPORT_SYMBOL(sys_shmget); +EXPORT_SYMBOL(do_shmat); +EXPORT_SYMBOL(sys_shmdt); +EXPORT_SYMBOL(sys_shmctl); diff -Nru linux-2.6.7/Makefile linux-2.6.7-abi/Makefile --- linux-2.6.7/Makefile 2004-06-16 07:19:37.000000000 +0200 +++ linux-2.6.7-abi/Makefile 2004-07-22 17:44:51.000000000 +0200 @@ -422,6 +422,7 @@ net-y := net/ libs-y := lib/ core-y := usr/ +abi-y := abi/ endif # KBUILD_EXTMOD ifeq ($(dot-config),1) @@ -488,12 +489,14 @@ vmlinux-dirs := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \ $(core-y) $(core-m) $(drivers-y) $(drivers-m) \ - $(net-y) $(net-m) $(libs-y) $(libs-m))) + $(net-y) $(net-m) $(libs-y) $(libs-m) \ + $(abi-y) $(abi-m))) vmlinux-alldirs := $(sort $(vmlinux-dirs) $(patsubst %/,%,$(filter %/, \ $(init-n) $(init-) \ $(core-n) $(core-) $(drivers-n) $(drivers-) \ - $(net-n) $(net-) $(libs-n) $(libs-)))) + $(net-n) $(net-) $(libs-n) $(libs-) \ + $(abi-n) $(abi-)))) init-y := $(patsubst %/, %/built-in.o, $(init-y)) core-y := $(patsubst %/, %/built-in.o, $(core-y)) @@ -502,6 +505,7 @@ libs-y1 := $(patsubst %/, %/lib.a, $(libs-y)) libs-y2 := $(patsubst %/, %/built-in.o, $(libs-y)) libs-y := $(libs-y1) $(libs-y2) +abi-y := $(patsubst %/, %/built-in.o, $(abi-y)) # Build vmlinux # --------------------------------------------------------------------------- @@ -513,7 +517,7 @@ # we cannot yet know if we will need to relink vmlinux. # So we descend into init/ inside the rule for vmlinux again. head-y += $(HEAD) -vmlinux-objs := $(head-y) $(init-y) $(core-y) $(libs-y) $(drivers-y) $(net-y) +vmlinux-objs := $(head-y) $(init-y) $(core-y) $(libs-y) $(drivers-y) $(net-y) $(abi-y) quiet_cmd_vmlinux__ = LD $@ define cmd_vmlinux__ @@ -523,6 +527,7 @@ $(libs-y) \ $(drivers-y) \ $(net-y) \ + $(abi-y) \ --end-group \ $(filter .tmp_kallsyms%,$^) \ -o $@ diff -Nru linux-2.6.7/net/socket.c linux-2.6.7-abi/net/socket.c --- linux-2.6.7/net/socket.c 2004-06-16 07:19:13.000000000 +0200 +++ linux-2.6.7-abi/net/socket.c 2004-07-22 17:44:21.000000000 +0200 @@ -120,7 +120,7 @@ * in the operation structures but are done directly via the socketcall() multiplexor. */ -static struct file_operations socket_file_ops = { +struct file_operations socket_file_ops = { .owner = THIS_MODULE, .llseek = no_llseek, .aio_read = sock_aio_read, @@ -2024,7 +2024,7 @@ } #endif /* CONFIG_PROC_FS */ -/* ABI emulation layers need these two */ +/* LinuxABI emulation layer modules do need these exports */ EXPORT_SYMBOL(move_addr_to_kernel); EXPORT_SYMBOL(move_addr_to_user); EXPORT_SYMBOL(sock_alloc); @@ -2040,3 +2040,8 @@ EXPORT_SYMBOL(sock_unregister); EXPORT_SYMBOL(sock_wake_async); EXPORT_SYMBOL(sockfd_lookup); +/* symbol exports for LinuxABI Sytem V R4 support */ +/* for ease of use we are exporting those needed symbols permanently */ +/* #if CONFIG_ABI_SVR4 == m */ +EXPORT_SYMBOL(socket_file_ops); +/* #endif */