]> git.pld-linux.org Git - packages/kernel.git/blame - linux-abi-2.6.8.1.patch
- [2.4.2x, 2.6.x] don't recursively crash in die() on CHRP/PReP machines
[packages/kernel.git] / linux-abi-2.6.8.1.patch
CommitLineData
42e5f5c1 1diff -Nru linux-2.6.7/abi/cxenix/Makefile linux-2.6.7-abi/abi/cxenix/Makefile
2--- linux-2.6.7/abi/cxenix/Makefile 1970-01-01 01:00:00.000000000 +0100
3+++ linux-2.6.7-abi/abi/cxenix/Makefile 2004-07-22 17:44:20.000000000 +0200
4@@ -0,0 +1,7 @@
5+
6+abi-cxenix-objs := sysent.o misc.o stubs.o signal.o pathconf.o utsname.o
7+
8+obj-$(CONFIG_ABI_SCO) += abi-cxenix.o
9+
10+abi-cxenix.o: $(abi-cxenix-objs)
11+ $(LD) -r -o $@ $(abi-cxenix-objs)
12diff -Nru linux-2.6.7/abi/cxenix/misc.c linux-2.6.7-abi/abi/cxenix/misc.c
13--- linux-2.6.7/abi/cxenix/misc.c 1970-01-01 01:00:00.000000000 +0100
14+++ linux-2.6.7-abi/abi/cxenix/misc.c 2004-07-22 17:44:20.000000000 +0200
15@@ -0,0 +1,296 @@
16+/*
17+ * misc.c - misc cxenix() subcalls
18+ *
19+ * Copyright (c) 1993,1994 Drew Sullivan
20+ * Copyright (c) 1994-1996 Mike Jagdis
21+ */
22+
23+#ident "%W% %G%"
24+
25+#include <linux/types.h>
26+#include <linux/module.h>
27+#include <linux/errno.h>
28+#include <linux/kernel.h>
29+#include <linux/unistd.h>
30+#include <linux/ptrace.h>
31+#include <linux/fcntl.h>
32+#include <linux/time.h>
33+#include <linux/signal.h>
34+#include <linux/syscalls.h>
35+#include <linux/termios.h>
36+#include <asm/uaccess.h>
37+
38+#include <abi/util/trace.h>
39+#include <abi/util/sysent.h>
40+#include <abi/svr4/sigaction.h>
41+
42+
43+struct timeb {
44+ time_t time;
45+ u_short millitm;
46+ short timezone;
47+ short dstflag;
48+};
49+
50+enum {
51+ XF_UNLCK = 0,
52+ XF_WRLCK = 1,
53+ XF_RDLCK = 3,
54+};
55+
56+struct ibcs_flock {
57+ short l_type;
58+ short l_whence;
59+ off_t l_start;
60+ off_t l_len;
61+ short l_sysid;
62+ short l_pid;
63+};
64+
65+
66+/*
67+ * locking() requires mandatory locking. Processes that attempt to
68+ * read or write a region locked with locking() are required to block.
69+ * You need to build a kernel with mandatory locking support and set
70+ * the permissions on the required file to setgid, no group execute.
71+ */
72+int
73+xnx_locking(int fd, int mode, unsigned long size)
74+{
75+ struct flock fl;
76+ mm_segment_t old_fs;
77+ int error;
78+
79+ if ((mode < 0 || mode > 7) && mode != 20) {
80+#if defined(CONFIG_ABI_TRACE)
81+ abi_trace(ABI_TRACE_API,
82+ "unsupported locking() mode=0x%x\n", mode);
83+#endif
84+ return -EINVAL;
85+ }
86+
87+ /*
88+ * Modes 5, 6 & 7 are very like the fcntl mechanism but
89+ * we can't just punt to that because the type values are
90+ * different.
91+ */
92+ if (mode > 4 && mode < 8) {
93+ struct ibcs_flock *ifl = (struct ibcs_flock *)size;
94+ short t;
95+
96+ error = verify_area(VERIFY_READ, ifl, sizeof(*ifl));
97+ if (error)
98+ return error;
99+
100+ get_user(t, &ifl->l_type);
101+ switch (t) {
102+ case XF_UNLCK: t = F_UNLCK; break;
103+ case XF_WRLCK: t = F_WRLCK; break;
104+ case XF_RDLCK: t = F_RDLCK; break;
105+ default: return -EINVAL;
106+ }
107+ put_user(t, &ifl->l_type);
108+
109+ error = sys_fcntl(fd, mode, (u_long)ifl);
110+
111+ get_user(t, &ifl->l_type);
112+ switch (t) {
113+ case F_UNLCK: t = XF_UNLCK; break;
114+ case F_WRLCK: t = XF_WRLCK; break;
115+ case F_RDLCK: t = XF_RDLCK; break;
116+ }
117+ put_user(t, &ifl->l_type);
118+
119+ get_user(t, &ifl->l_sysid);
120+ put_user(t, &ifl->l_pid);
121+ put_user(0, &ifl->l_sysid);
122+ return error;
123+ }
124+
125+ fl.l_type = (mode == 0 ? F_UNLCK
126+ : ((mode <= 2 || mode == 20) ? F_WRLCK
127+ : F_RDLCK));
128+ fl.l_whence = 1;
129+ fl.l_start = 0;
130+ fl.l_len = size;
131+
132+ old_fs = get_fs();
133+ set_fs (get_ds());
134+ error = sys_fcntl(fd, (mode == 5) ? F_GETLK
135+ : (!(mode % 2) ? F_SETLK : F_SETLKW), (u_long)&fl);
136+ set_fs(old_fs);
137+ return error;
138+}
139+
140+
141+/* Check if input is available */
142+int
143+xnx_rdchk(int fd)
144+{
145+ int error, nbytes;
146+ mm_segment_t old_fs;
147+
148+ old_fs = get_fs();
149+ set_fs (get_ds());
150+ error = sys_ioctl(fd, FIONREAD, (long)&nbytes);
151+ set_fs(old_fs);
152+
153+ if (error < 0) return error;
154+ return nbytes ? 1 : 0;
155+}
156+
157+/*
158+ * Linux has a stub sys_ftime. Perhaps this should be there? On the other
159+ * hand it's an old call that probably shouldn't be used by most modern
160+ * applications so perhaps it's better here where it needn't bloat the
161+ * base kernel.
162+ */
163+int
164+xnx_ftime(struct timeb *tp)
165+{
166+ struct timeval tv;
167+ struct timezone tz;
168+ int error;
169+ mm_segment_t old_fs;
170+
171+ error = verify_area(VERIFY_WRITE, tp, sizeof(struct timeb));
172+ if (error)
173+ return error;
174+
175+ old_fs = get_fs();
176+ set_fs (get_ds());
177+ error = sys_gettimeofday(&tv, &tz);
178+ set_fs(old_fs);
179+ if (error)
180+ return error;
181+
182+ put_user(tv.tv_sec, &tp->time);
183+ put_user((unsigned short)(tv.tv_usec/1000), &tp->millitm);
184+ put_user((short)tz.tz_minuteswest, &tp->timezone);
185+ put_user((short)tz.tz_dsttime, &tp->dstflag);
186+
187+ return 0;
188+}
189+
190+#define USE_NEW_NAP_CODE
191+
192+#ifndef USE_NEW_NAP_CODE
193+static __inline __sighandler_t
194+sigaction(int sig, __sighandler_t handler)
195+{
196+ struct k_sigaction *k = &current->sighand->action[sig-1];
197+ __sighandler_t old_handler;
198+
199+ spin_lock(&current->sighand->siglock);
200+ old_handler = k->sa.sa_handler;
201+ k->sa.sa_handler = handler;
202+ spin_unlock(&current->sighand->siglock);
203+
204+ return old_handler;
205+}
206+#endif
207+
208+/* go to sleep for period milliseconds */
209+/* - returns either an EINTR error or returns the elapsed time */
210+/* Note:
211+ for SCO OpenServer 5.0.6 the original nap was fixed so that it
212+ no longer waits a minimum of 2 tick (20ms)
213+ but fewer time with a 10 ms granularity */
214+long
215+xnx_nap(long period)
216+{
217+#ifdef USE_NEW_NAP_CODE
218+ // Hz means the number of jiffies per second.
219+ // the below code needs HZ to be 1 <= HZ <= 1000
220+ // in order to work correctly in any case.
221+#if HZ > 1000
222+#error this code only works with HZ <= 1000
223+#endif
224+ struct timeval tv1, tv2;
225+ struct timezone tz;
226+ mm_segment_t oldfs;
227+ long period_s; // seconds part
228+ long period_ms_hz; // milli seconds part, scaled to a base of HZ
229+ long period_j; // jiffies
230+
231+ if (!period)
232+ return 0; // zereo request, zero reply
233+
234+ oldfs = get_fs();
235+ set_fs(get_ds());
236+ sys_gettimeofday(&tv1, &tz);
237+
238+ period_s = period / 1000;
239+ period_ms_hz = (period - period_s * 1000) * HZ;
240+ period_j = period_s * HZ + period_ms_hz / 1000;
241+ // take care of rounding errors, round up
242+ if (period > period_j * (1000 / HZ)) period_j++;
243+
244+ set_current_state(TASK_INTERRUPTIBLE);
245+ schedule_timeout (period_j);
246+
247+ sys_gettimeofday(&tv2, &tz);
248+ set_fs(oldfs);
249+
250+ if (signal_pending(current))
251+ return -EINTR; // interrupted
252+ return (tv2.tv_sec - tv1.tv_sec) * 1000
253+ + (tv2.tv_usec - tv1.tv_usec + 500) / 1000;
254+#else
255+ __sighandler_t old_handler;
256+ struct itimerval it;
257+ struct timeval tv1, tv2;
258+ struct timezone tz;
259+ mm_segment_t oldfs;
260+
261+ if (!period)
262+ return 0;
263+
264+ it.it_interval.tv_sec = 0;
265+ it.it_interval.tv_usec = 0;
266+ it.it_value.tv_sec = 0;
267+ it.it_value.tv_usec = period * 1000;
268+
269+ oldfs = get_fs();
270+ set_fs(get_ds());
271+
272+ sys_gettimeofday(&tv1, &tz);
273+ old_handler = sigaction(SIGALRM, SIG_DFL); // SIG_DFL -> terminate
274+ sys_setitimer(ITIMER_REAL, &it, NULL);
275+ sys_pause();
276+ sigaction(SIGALRM, old_handler);
277+ sys_gettimeofday(&tv2, &tz);
278+ set_fs(oldfs);
279+
280+ deactivate_signal(current, SIGALRM);
281+
282+ if (signal_pending(current))
283+ return -EINTR;
284+ return ((tv2.tv_sec - tv1.tv_sec) * 1000000
285+ + (tv2.tv_usec - tv1.tv_usec)) / 1000;
286+#endif
287+}
288+
289+/*
290+ * eaccess() checks access to the given path using the effective
291+ * uid/gid rather than the real uid/gid.
292+ */
293+int
294+xnx_eaccess(char *path, int mode)
295+{
296+ uid_t ouid;
297+ gid_t ogid;
298+ int err;
299+
300+ ouid = current->uid;
301+ ogid = current->gid;
302+ current->uid = current->euid;
303+ current->gid = current->egid;
304+
305+ err = sys_access(path, mode);
306+
307+ current->uid = ouid;
308+ current->gid = ogid;
309+
310+ return err;
311+}
312diff -Nru linux-2.6.7/abi/cxenix/pathconf.c linux-2.6.7-abi/abi/cxenix/pathconf.c
313--- linux-2.6.7/abi/cxenix/pathconf.c 1970-01-01 01:00:00.000000000 +0100
314+++ linux-2.6.7-abi/abi/cxenix/pathconf.c 2004-07-22 17:44:20.000000000 +0200
315@@ -0,0 +1,140 @@
316+/*
317+ * pathconf.c - support for xenix pathconf
318+ *
319+ * Copyright (c) 1993,1994 Drew Sullivan
320+ * Copyright (c) 1994-1996 Mike Jagdis
321+ */
322+
323+#ident "%W% %G%"
324+
325+#include <linux/errno.h>
326+#include <linux/fs.h>
327+#include <linux/slab.h>
328+#include <linux/sched.h>
329+#include <linux/unistd.h>
330+#include <linux/syscalls.h>
331+#include <linux/statfs.h>
332+#include <asm/uaccess.h>
333+
334+
335+enum {
336+ _PC_LINK_MAX = 0,
337+ _PC_MAX_CANON = 1,
338+ _PC_MAX_INPUT = 2,
339+ _PC_NAME_MAX = 3,
340+ _PC_PATH_MAX = 4,
341+ _PC_PIPE_BUF = 5,
342+ _PC_CHOWN_RESTRICTED = 6,
343+ _PC_NO_TRUNC = 7,
344+ _PC_VDISABLE = 8,
345+};
346+
347+static int
348+xnx_name_max(char *path)
349+{
350+ struct statfs stf;
351+ mm_segment_t fs;
352+ char *p;
353+ int error;
354+
355+ p = getname(path);
356+ if (IS_ERR(p))
357+ return PTR_ERR(p);
358+
359+ fs = get_fs();
360+ set_fs(get_ds());
361+ error = sys_statfs(p, &stf);
362+ set_fs(fs);
363+
364+ putname(p);
365+ if (error)
366+ return (error);
367+ return (stf.f_namelen);
368+}
369+
370+int
371+xnx_pathconf(char *path, int name)
372+{
373+ switch (name) {
374+ case _PC_LINK_MAX:
375+ /*
376+ * Although Linux headers define values on a per
377+ * filesystem basis there is no way to access
378+ * these without hard coding fs information here
379+ * so for now we use a bogus value.
380+ */
381+ return LINK_MAX;
382+ case _PC_MAX_CANON:
383+ return MAX_CANON;
384+ case _PC_MAX_INPUT:
385+ return MAX_INPUT;
386+ case _PC_PATH_MAX:
387+ return PATH_MAX;
388+ case _PC_PIPE_BUF:
389+ return PIPE_BUF;
390+ case _PC_CHOWN_RESTRICTED:
391+ /*
392+ * We should really think about this and tell
393+ * the truth.
394+ */
395+ return 0;
396+ case _PC_NO_TRUNC:
397+ /* Not sure... It could be fs dependent? */
398+ return 1;
399+ case _PC_VDISABLE:
400+ return 1;
401+ case _PC_NAME_MAX:
402+ return xnx_name_max(path);
403+ }
404+ return -EINVAL;
405+}
406+
407+int
408+xnx_fpathconf(int fildes, int name)
409+{
410+ switch (name) {
411+ case _PC_LINK_MAX:
412+ /*
413+ * Although Linux headers define values on a per
414+ * filesystem basis there is no way to access
415+ * these without hard coding fs information here
416+ * so for now we use a bogus value.
417+ */
418+ return LINK_MAX;
419+ case _PC_MAX_CANON:
420+ return MAX_CANON;
421+ case _PC_MAX_INPUT:
422+ return MAX_INPUT;
423+ case _PC_PATH_MAX:
424+ return PATH_MAX;
425+ case _PC_PIPE_BUF:
426+ return PIPE_BUF;
427+ case _PC_CHOWN_RESTRICTED:
428+ /*
429+ * We should really think about this and tell
430+ * the truth.
431+ */
432+ return 0;
433+ case _PC_NO_TRUNC:
434+ /* Not sure... It could be fs dependent? */
435+ return 1;
436+ case _PC_VDISABLE:
437+ return 1;
438+ case _PC_NAME_MAX:
439+ {
440+ struct statfs buf;
441+ int error;
442+ mm_segment_t old_fs;
443+
444+ old_fs = get_fs();
445+ set_fs (get_ds());
446+ error = sys_fstatfs(fildes, &buf);
447+ set_fs(old_fs);
448+ if (!error)
449+ return buf.f_namelen;
450+ return error;
451+ }
452+ }
453+
454+ return -EINVAL;
455+}
456diff -Nru linux-2.6.7/abi/cxenix/signal.c linux-2.6.7-abi/abi/cxenix/signal.c
457--- linux-2.6.7/abi/cxenix/signal.c 1970-01-01 01:00:00.000000000 +0100
458+++ linux-2.6.7-abi/abi/cxenix/signal.c 2004-07-22 17:44:20.000000000 +0200
459@@ -0,0 +1,89 @@
460+#ident "%W% %G%"
461+
462+#include <linux/module.h>
463+#include <linux/kernel.h>
464+#include <linux/personality.h>
465+#include <linux/sched.h>
466+#define __KERNEL_SYSCALLS__
467+#include <linux/unistd.h>
468+#include <asm/uaccess.h>
469+
470+#include <abi/cxenix/signal.h>
471+#include <abi/signal.h>
472+
473+#include <abi/util/map.h>
474+#include <abi/util/sysent.h>
475+
476+
477+int
478+xnx_sigaction(int sco_signum, const struct sco_sigaction *action,
479+ struct sco_sigaction *oldaction)
480+{
481+ struct sco_sigaction new_sa, old_sa;
482+ struct sigaction nsa, osa;
483+ mm_segment_t fs;
484+ int error, signo;
485+
486+ if (sco_signum >= NSIGNALS)
487+ return -EINVAL;
488+ signo = current_thread_info()->exec_domain->signal_map[sco_signum];
489+
490+ if (oldaction) {
491+ error = verify_area(VERIFY_WRITE, oldaction,
492+ sizeof(struct sco_sigaction));
493+ if (error)
494+ return (error);
495+ }
496+
497+ if (action) {
498+ error = copy_from_user(&new_sa, action,
499+ sizeof(struct sco_sigaction));
500+ if (error)
501+ return -EFAULT;
502+ nsa.sa_restorer = NULL;
503+ nsa.sa_handler = new_sa.sa_handler;
504+ nsa.sa_mask = map_sigvec_to_kernel(new_sa.sa_mask,
505+ current_thread_info()->exec_domain->signal_map);
506+ nsa.sa_flags = SA_NOMASK;
507+ if (new_sa.sa_flags & SCO_SA_NOCLDSTOP)
508+ nsa.sa_flags |= SA_NOCLDSTOP;
509+ }
510+
511+ fs = get_fs();
512+ set_fs(get_ds());
513+ error = sys_rt_sigaction(signo, action ? &nsa : NULL,
514+ oldaction ? &osa : NULL, sizeof(sigset_t));
515+ set_fs(fs);
516+
517+ if (error || !oldaction)
518+ return (error);
519+
520+ old_sa.sa_handler = osa.sa_handler;
521+ old_sa.sa_mask = map_sigvec_from_kernel(osa.sa_mask,
522+ current_thread_info()->exec_domain->signal_invmap);
523+ old_sa.sa_flags = 0;
524+ if (osa.sa_flags & SA_NOCLDSTOP)
525+ old_sa.sa_flags |= SCO_SA_NOCLDSTOP;
526+
527+ if (copy_to_user(oldaction, &old_sa, sizeof(struct sco_sigaction)))
528+ return -EFAULT;
529+ return 0;
530+}
531+
532+int
533+xnx_sigpending(u_long *setp)
534+{
535+ sigset_t lxpending;
536+ u_long pending;
537+
538+ spin_lock_irq(&current->sighand->siglock);
539+ sigandsets(&lxpending, &current->blocked, &current->pending.signal);
540+ spin_unlock_irq(&current->sighand->siglock);
541+
542+ pending = map_sigvec_from_kernel(lxpending,
543+ current_thread_info()->exec_domain->signal_invmap);
544+
545+ if (copy_to_user(setp, &pending, sizeof(u_long)))
546+ return -EFAULT;
547+ return 0;
548+}
549diff -Nru linux-2.6.7/abi/cxenix/stubs.c linux-2.6.7-abi/abi/cxenix/stubs.c
550--- linux-2.6.7/abi/cxenix/stubs.c 1970-01-01 01:00:00.000000000 +0100
551+++ linux-2.6.7-abi/abi/cxenix/stubs.c 2004-07-22 17:44:20.000000000 +0200
552@@ -0,0 +1,123 @@
553+/*
554+ * stubs.c - stubs for unimplemented cxenix subcalls
555+ *
556+ * Copyright (c) 1993,1994 Drew Sullivan.
557+ * Copyright (c) 1994-1996 Mike Jagdis.
558+ */
559+
560+#ident "%W% %G%"
561+
562+#include <linux/errno.h>
563+#include <linux/types.h>
564+#include <linux/ptrace.h>
565+
566+#include <abi/cxenix/sysent.h>
567+
568+
569+int
570+xnx_creatsem(char *sem_name, int mode)
571+{
572+ return -EPERM;
573+}
574+
575+int
576+xnx_opensem(char *sem_name)
577+{
578+ return -EPERM;
579+}
580+
581+int
582+xnx_sigsem(int sem_num)
583+{
584+ return -EPERM;
585+}
586+
587+int
588+xnx_waitsem(int sem_num)
589+{
590+ return -EPERM;
591+}
592+
593+int
594+xnx_nbwaitsem(int sem_num)
595+{
596+ return -EPERM;
597+}
598+
599+
600+int
601+xnx_sdget(char *path, int flags, long size, int mode)
602+{
603+ return -EPERM;
604+}
605+
606+int
607+xnx_sdfree(char* addr)
608+{
609+ return -EPERM;
610+}
611+
612+int
613+xnx_sdenter(char *addr, int flags)
614+{
615+ return -EPERM;
616+}
617+
618+int
619+xnx_sdleave(char *addr)
620+{
621+ return -EPERM;
622+}
623+
624+int
625+xnx_sdgetv(char *addr)
626+{
627+ return -EPERM;
628+}
629+
630+int
631+xnx_sdwaitv(char *addr, int vnum)
632+{
633+ return -EPERM;
634+}
635+
636+
637+/*
638+ * This allows processes to be allowed to exceed available swap. The man
639+ * page isn't too clear - it seems to suggest Xenix supports physical
640+ * memory > swap but this doesn't make sense to me? It almost certainly
641+ * isn't useful for Linux to actually do anything with this - just lie.
642+ */
643+enum {
644+ XNX_PRHUGEX = 1,
645+ XNX_PRNORMEX = 2,
646+};
647+
648+int
649+xnx_proctl(int pid, int command, char *arg)
650+{
651+ return 0;
652+}
653+
654+int
655+xnx_execseg(excode_t oldaddr, unsigned size)
656+{
657+ return -EPERM;
658+}
659+
660+
661+int
662+xnx_unexecseg(excode_t addr)
663+{
664+ return -EPERM;
665+}
666+
667+/*
668+ * This allows running adb without executing any programs, but disassembly
669+ * will work fine with that lie.
670+ */
671+int
672+xnx_paccess(int pid, int cmd, int offset, int count, char *ptr)
673+{
674+ return 0;
675+}
676diff -Nru linux-2.6.7/abi/cxenix/sysent.c linux-2.6.7-abi/abi/cxenix/sysent.c
677--- linux-2.6.7/abi/cxenix/sysent.c 1970-01-01 01:00:00.000000000 +0100
678+++ linux-2.6.7-abi/abi/cxenix/sysent.c 2004-07-22 17:44:20.000000000 +0200
679@@ -0,0 +1,96 @@
680+#ident "%W% %G%"
681+
682+#include <linux/module.h>
683+#include <linux/kernel.h>
684+#include <linux/personality.h>
685+#include <linux/sched.h>
686+#include <linux/ptrace.h>
687+#include <linux/syscalls.h>
688+#include <asm/uaccess.h>
689+
690+#include <abi/svr4/sysent.h>
691+#include <abi/cxenix/sysent.h>
692+
693+#include <abi/util/errno.h>
694+#include <abi/util/sysent.h>
695+
696+
697+MODULE_DESCRIPTION("Xenix/OpenServer cxenix call support");
698+MODULE_AUTHOR("Christoph Hellwig, partially taken from iBCS");
699+MODULE_LICENSE("GPL");
700+
701+
702+static struct sysent cxenix_table[] = {
703+/* 0 */ { 0, Ukn, "syscall", "" },
704+/* 1 */ { xnx_locking, 3, "locking", "ddd" },
705+/* 2 */ { xnx_creatsem, 2, "creatsem", "sd" },
706+/* 3 */ { xnx_opensem, 1, "opensem", "s" },
707+/* 4 */ { xnx_sigsem, 1, "sigsem", "d" },
708+/* 5 */ { xnx_waitsem, 1, "waitsem", "d" },
709+/* 6 */ { xnx_nbwaitsem, 1, "nbwaitsem", "d" },
710+/* 7 */ { xnx_rdchk, 1, "rdchk", "d" },
711+/* 8 */ { 0, Ukn, "stkgro", "" },
712+/* 9 */ { 0, Ukn, "?", "" },
713+/* 10 */ { sys_ftruncate, 2, "chsize", "dd" },
714+/* 11 */ { xnx_ftime, 1, "ftime", "x" },
715+/* 12 */ { xnx_nap, 1, "nap", "d" },
716+/* 13 */ { xnx_sdget, 4, "sdget", "sddd" },
717+/* 14 */ { xnx_sdfree, 1, "sdfree", "x" },
718+/* 15 */ { xnx_sdenter, 2, "sdenter", "xd" },
719+/* 16 */ { xnx_sdleave, 1, "sdleave", "x" },
720+/* 17 */ { xnx_sdgetv, 1, "sdgetv", "x" },
721+/* 18 */ { xnx_sdwaitv, 2, "sdwaitv", "xd" },
722+/* 19 */ { 0, Ukn, "brkctl", "" },
723+/* 20 */ { 0, Ukn, "?", "" },
724+/* 21 */ { 0, 2, "sco-getcwd?", "dx" },
725+/* 22 */ { 0, Ukn, "?", "" },
726+/* 23 */ { 0, Ukn, "?", "" },
727+/* 24 */ { 0, Ukn, "?", "" },
728+/* 25 */ { 0, Ukn, "?", "" },
729+/* 26 */ { 0, Ukn, "?", "" },
730+/* 27 */ { 0, Ukn, "?", "" },
731+/* 28 */ { 0, Ukn, "?", "" },
732+/* 29 */ { 0, Ukn, "?", "" },
733+/* 30 */ { 0, Ukn, "?", "" },
734+/* 31 */ { 0, Ukn, "?", "" },
735+/* 32 */ { xnx_proctl, 3, "proctl", "ddx" },
736+/* 33 */ { xnx_execseg, 2, "execseg", "xd" },
737+/* 34 */ { xnx_unexecseg, 1, "unexecseg", "x" },
738+/* 35 */ { 0, Ukn, "?", "" },
739+/* 36 */ { sys_select, 5, "select", "dxxxx" },
740+/* 37 */ { xnx_eaccess, 2, "eaccess", "so" },
741+/* 38 */ { xnx_paccess, 5, "paccess", "dddds" },
742+/* 39 */ { xnx_sigaction, 3, "sigaction", "dxx" },
743+/* 40 */ { abi_sigprocmask, 3, "sigprocmask", "dxx" },
744+/* 41 */ { xnx_sigpending, 1, "sigpending", "x" },
745+/* 42 */ { abi_sigsuspend, Spl, "sigsuspend", "x" },
746+/* 43 */ { sys_getgroups16, 2, "getgroups", "dx" },
747+/* 44 */ { sys_setgroups16, 2, "setgroups", "dx" },
748+/* 45 */ { ibcs_sysconf, 1, "sysconf", "d" },
749+/* 46 */ { xnx_pathconf, 2, "pathconf", "sd" },
750+/* 47 */ { xnx_fpathconf, 2, "fpathconf", "dd" },
751+/* 48 */ { sys_rename, 2, "rename", "ss" },
752+/* 49 */ { 0, Ukn, "?", "" },
753+/* 50 */ { xnx_utsname, 1, "utsname", "x" },
754+/* 51 */ { 0, Ukn, "?", "" },
755+/* 52 */ { 0, Ukn, "?", "" },
756+/* 53 */ { 0, Ukn, "?", "" },
757+/* 54 */ { 0, Ukn, "?", "" },
758+/* 55 */ { sys_getitimer, 2, "getitimer", "dx" },
759+/* 56 */ { sys_setitimer, 3, "setitimer", "dxx" }
760+};
761+
762+
763+void cxenix(struct pt_regs *regs)
764+{
765+ int sysno = regs->eax >> 8;
766+
767+ if (sysno >= ARRAY_SIZE(cxenix_table))
768+ set_error(regs, iABI_errors(-EINVAL));
769+ else
770+ lcall7_dispatch(regs, &cxenix_table[sysno], 1);
771+}
772+
773+#if defined(CONFIG_ABI_SYSCALL_MODULES)
774+EXPORT_SYMBOL(cxenix);
775+#endif
776diff -Nru linux-2.6.7/abi/cxenix/utsname.c linux-2.6.7-abi/abi/cxenix/utsname.c
777--- linux-2.6.7/abi/cxenix/utsname.c 1970-01-01 01:00:00.000000000 +0100
778+++ linux-2.6.7-abi/abi/cxenix/utsname.c 2004-07-22 17:44:20.000000000 +0200
779@@ -0,0 +1,89 @@
780+/*
781+ * utsname.c - support for the utsname subcall of cxenix
782+ *
783+ * Copyright (C) 1994 Mike Jagdis (jaggy@purplet.demon.co.uk)
784+ */
785+
786+#ident "%W% %G%"
787+
788+#include <linux/mm.h>
789+#include <linux/sched.h>
790+#include <linux/personality.h>
791+#include <linux/utsname.h>
792+#include <linux/eisa.h>
793+#include <asm/uaccess.h>
794+
795+
796+static char sco_serial[10] = "public";
797+
798+struct xnx_utsname {
799+ char sysname[9];
800+ char nodename[9];
801+ char release[16];
802+ char kernelid[20];
803+ char machine[9];
804+ char bustype[9];
805+ char sysserial[10];
806+ u_short sysorigin;
807+ u_short sysoem;
808+ char numusers[9];
809+ u_short numcpu;
810+};
811+
812+#define set_utsfield(to, from, dotchop) \
813+ { \
814+ char *p; \
815+ int i, len = (sizeof(to) > sizeof(from) ? sizeof(from) : sizeof(to)); \
816+ __copy_to_user(to, from, len); \
817+ if (dotchop) \
818+ for (p=from,i=0; *p && *p != '.' && --len; p++,i++); \
819+ else \
820+ i = len - 1; \
821+ __put_user('\0', to+i); \
822+ }
823+
824+
825+int
826+xnx_utsname(u_long addr)
827+{
828+ struct xnx_utsname *utp = (struct xnx_utsname *)addr;
829+ int error;
830+
831+ /*
832+ * This shouldn't be invoked by anything that isn't running
833+ * in the SCO personality. I can envisage a program that uses
834+ * this to test if utp is running on SCO or not. It probably
835+ * won't happen but let's make sure utp doesn't anyway...
836+ */
837+ if (!is_cur_personality(PER_SCOSVR3))
838+ return -ENOSYS;
839+
840+ down_read(&uts_sem);
841+ error = verify_area(VERIFY_WRITE, utp, sizeof (struct xnx_utsname));
842+ if (!error) {
843+ if (abi_fake_utsname) {
844+ set_utsfield(utp->sysname, "SCO_SV", 0);
845+ set_utsfield(utp->nodename, system_utsname.nodename, 1);
846+ set_utsfield(utp->release, "3.2v5.0.0\0", 0);
847+ } else {
848+ set_utsfield(utp->sysname, system_utsname.nodename, 1);
849+ set_utsfield(utp->nodename, system_utsname.nodename, 1);
850+ set_utsfield(utp->release, system_utsname.release, 0);
851+ }
852+ set_utsfield(utp->kernelid, system_utsname.version, 0);
853+ set_utsfield(utp->machine, system_utsname.machine, 0);
854+ if (EISA_bus) {
855+ set_utsfield(utp->bustype, "EISA", 0);
856+ } else {
857+ set_utsfield(utp->bustype, "ISA", 0);
858+ }
859+ set_utsfield(utp->sysserial, sco_serial, 0);
860+ __put_user(0xffff, &utp->sysorigin);
861+ __put_user(0xffff, &utp->sysoem);
862+ set_utsfield(utp->numusers, "unlim", 0);
863+ __put_user(1, &utp->numcpu);
864+ }
865+ up_read(&uts_sem);
866+
867+ return (error);
868+}
869diff -Nru linux-2.6.7/abi/ibcs/Makefile linux-2.6.7-abi/abi/ibcs/Makefile
870--- linux-2.6.7/abi/ibcs/Makefile 1970-01-01 01:00:00.000000000 +0100
871+++ linux-2.6.7-abi/abi/ibcs/Makefile 2004-07-22 17:44:20.000000000 +0200
872@@ -0,0 +1,7 @@
873+
874+abi-ibcs-objs := sysent.o
875+
876+obj-$(CONFIG_ABI_IBCS) += abi-ibcs.o
877+
878+abi-ibcs.o: $(abi-ibcs-objs)
879+ $(LD) -r -o $@ $(abi-ibcs-objs)
880diff -Nru linux-2.6.7/abi/ibcs/sysent.c linux-2.6.7-abi/abi/ibcs/sysent.c
881--- linux-2.6.7/abi/ibcs/sysent.c 1970-01-01 01:00:00.000000000 +0100
882+++ linux-2.6.7-abi/abi/ibcs/sysent.c 2004-07-22 17:44:20.000000000 +0200
883@@ -0,0 +1,412 @@
884+/*
885+ * Copyright (c) 2001 Christoph Hellwig.
886+ * All rights reserved.
887+ *
888+ * This program is free software; you can redistribute it and/or modify
889+ * it under the terms of the GNU General Public License as published by
890+ * the Free Software Foundation; either version 2 of the License, or
891+ * (at your option) any later version.
892+ *
893+ * This program is distributed in the hope that it will be useful,
894+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
895+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
896+ * GNU General Public License for more details.
897+ *
898+ * You should have received a copy of the GNU General Public License
899+ * along with this program; if not, write to the Free Software
900+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
901+ */
902+
903+#ident "%W% %G%"
904+
905+/*
906+ * SVR4 personality switch.
907+ */
908+#include <linux/config.h>
909+#include <linux/kernel.h>
910+#include <linux/module.h>
911+#include <linux/init.h>
912+#include <linux/personality.h>
913+#include <linux/syscalls.h>
914+#include <linux/socket.h>
915+#include <linux/highuid.h>
916+#include <linux/net.h>
917+#include <asm/uaccess.h>
918+
919+#include <abi/svr4/sysent.h>
920+#include <abi/signal.h>
921+
922+#include <abi/util/errno.h>
923+#include <abi/util/sysent.h>
924+#include <abi/util/socket.h>
925+
926+MODULE_DESCRIPTION("iBCS2/iABI4 personality");
927+MODULE_AUTHOR("Christoph Hellwig, partially taken from iBCS");
928+MODULE_LICENSE("GPL");
929+
930+
931+/*
932+ * We could remove some of the long identity mapped runs but at the
933+ * expense of extra comparisons for each mapping at run time...
934+ */
935+static u_char ibcs_err_table[] = {
936+/* 0 - 9 */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
937+/* 10 - 19 */ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
938+/* 20 - 29 */ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
939+/* 30 - 39 */ 30, 31, 32, 33, 34, 45, 78, 46, 89, 93,
940+/* 40 - 49 */ 90, 90, 35, 36, 37, 38, 39, 40, 41, 42,
941+/* 50 - 59 */ 43, 44, 50, 51, 52, 53, 54, 55, 56, 57,
942+/* 60 - 69 */ 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
943+/* 70 - 79 */ 70, 71, 74, 76, 77, 79, 80, 81, 82, 83,
944+/* 80 - 89 */ 84, 85, 86, 87, 88, 91, 92, 94, 95, 96,
945+/* 90 - 99 */ 97, 98, 99, 120, 121, 122, 123, 124, 125, 126,
946+/* 100 - 109 */ 127, 128, 129, 130, 131, 132, 133, 134, 143, 144,
947+/* 110 - 119 */ 145, 146, 147, 148, 149, 150, 22, 135, 137, 138,
948+/* 120 - 122 */ 139, 140, 28
949+};
950+
951+/*
952+ * Map Linux RESTART* values (512,513,514) to EINTR
953+ */
954+static u_char lnx_err_table[] = {
955+/* 512 - 514 */ EINTR, EINTR, EINTR
956+};
957+
958+struct map_segment ibcs_err_map[] = {
959+ { 0, 0+sizeof(ibcs_err_table)-1, ibcs_err_table },
960+ { 512, 512+sizeof(lnx_err_table)-1, lnx_err_table },
961+ { -1 }
962+};
963+
964+static long linux_to_ibcs_signals[NSIGNALS+1] = {
965+/* 0 - 3 */ 0, IBCS_SIGHUP, IBCS_SIGINT, IBCS_SIGQUIT,
966+/* 4 - 7 */ IBCS_SIGILL, IBCS_SIGTRAP, IBCS_SIGABRT, -1,
967+/* 8 - 11 */ IBCS_SIGFPE, IBCS_SIGKILL, IBCS_SIGUSR1, IBCS_SIGSEGV,
968+/* 12 - 15 */ IBCS_SIGUSR2, IBCS_SIGPIPE, IBCS_SIGALRM, IBCS_SIGTERM,
969+/* 16 - 19 */ IBCS_SIGSEGV, IBCS_SIGCHLD, IBCS_SIGCONT, IBCS_SIGSTOP,
970+/* 20 - 23 */ IBCS_SIGTSTP, IBCS_SIGTTIN, IBCS_SIGTTOU, IBCS_SIGURG,
971+/* 24 - 27 */ IBCS_SIGGXCPU, IBCS_SIGGXFSZ, IBCS_SIGVTALRM, IBCS_SIGPROF,
972+/* 28 - 31 */ IBCS_SIGWINCH, IBCS_SIGIO, IBCS_SIGPWR, -1,
973+/* 32 */ -1
974+};
975+
976+static long ibcs_to_linux_signals[NSIGNALS+1] = {
977+/* 0 - 3 */ 0, SIGHUP, SIGINT, SIGQUIT,
978+/* 4 - 7 */ SIGILL, SIGTRAP, SIGIOT, SIGUNUSED,
979+/* 8 - 11 */ SIGFPE, SIGKILL, SIGUNUSED, SIGSEGV,
980+/* 12 - 15 */ SIGUNUSED, SIGPIPE, SIGALRM, SIGTERM,
981+/* 16 - 19 */ SIGUSR1, SIGUSR2, SIGCHLD, SIGPWR,
982+/* 20 - 23 */ SIGWINCH, SIGURG, SIGPOLL, SIGSTOP,
983+/* 24 - 27 */ SIGTSTP, SIGCONT, SIGTTIN, SIGTTOU,
984+/* 28 - 31 */ SIGVTALRM, SIGPROF, SIGXCPU, SIGXFSZ,
985+/* 32 */ -1
986+};
987+
988+static char ibcs_socktype[] = {
989+ SOCK_STREAM,
990+ SOCK_DGRAM,
991+ 0,
992+ SOCK_RAW,
993+ SOCK_RDM,
994+ SOCK_SEQPACKET
995+};
996+
997+static struct map_segment ibcs_socktype_map[] = {
998+ { 1, 6, ibcs_socktype },
999+ { -1 }
1000+};
1001+
1002+static struct map_segment ibcs_sockopt_map[] = {
1003+ { 0x0001, 0x0001, (char *)SO_DEBUG },
1004+ { 0x0002, 0x0002, (char *)__SO_ACCEPTCON },
1005+ { 0x0004, 0x0004, (char *)SO_REUSEADDR },
1006+ { 0x0008, 0x0008, (char *)SO_KEEPALIVE },
1007+ { 0x0010, 0x0010, (char *)SO_DONTROUTE },
1008+ { 0x0020, 0x0020, (char *)SO_BROADCAST },
1009+ { 0x0040, 0x0040, (char *)SO_USELOOPBACK },
1010+ { 0x0080, 0x0080, (char *)SO_LINGER },
1011+ { 0x0100, 0x0100, (char *)SO_OOBINLINE },
1012+ { 0x0200, 0x0200, (char *)SO_ORDREL },
1013+ { 0x0400, 0x0400, (char *)SO_IMASOCKET },
1014+ { 0x1001, 0x1001, (char *)SO_SNDBUF },
1015+ { 0x1002, 0x1002, (char *)SO_RCVBUF },
1016+ { 0x1003, 0x1003, (char *)SO_SNDLOWAT },
1017+ { 0x1004, 0x1004, (char *)SO_RCVLOWAT },
1018+ { 0x1005, 0x1005, (char *)SO_SNDTIMEO },
1019+ { 0x1006, 0x1006, (char *)SO_RCVTIMEO },
1020+ { 0x1007, 0x1007, (char *)SO_ERROR },
1021+ { 0x1008, 0x1008, (char *)SO_TYPE },
1022+ { 0x1009, 0x1009, (char *)SO_PROTOTYPE },
1023+ { -1 }
1024+};
1025+
1026+static struct map_segment ibcs_af_map[] = {
1027+ { 0, 2, NULL },
1028+ { -1 }
1029+};
1030+
1031+
1032+static struct sysent ibcs_syscall_table[] = {
1033+ { abi_syscall, Fast, "syscall", "" }, /* 0 */
1034+ { sys_exit, 1, "exit", "d" }, /* 1 */
1035+ { abi_fork, Spl, "fork", "" }, /* 2 */
1036+ { abi_read, 3, "read", "dpd" }, /* 3 */
1037+ { sys_write, 3, "write", "dpd" }, /* 4 */
1038+ { svr4_open, 3, "open", "soo" }, /* 5 */
1039+ { sys_close, 1, "close", "d" }, /* 6 */
1040+ { abi_wait, Spl, "wait", "xxx" }, /* 7 */
1041+ { sys_creat, 2, "creat", "so" }, /* 8 */
1042+ { sys_link, 2, "link", "ss" }, /* 9 */
1043+ { sys_unlink, 1, "unlink", "s" }, /* 10 */
1044+ { abi_exec, Spl, "exec", "sxx" }, /* 11 */
1045+ { sys_chdir, 1, "chdir", "s" }, /* 12 */
1046+ { abi_time, 0, "time", "" }, /* 13 */
1047+ { svr4_mknod, 3, "mknod", "soo" }, /* 14 */
1048+ { sys_chmod, 2, "chmod", "so" }, /* 15 */
1049+ { sys_chown, 3, "chown", "sdd" }, /* 16 */
1050+ { abi_brk, 1, "brk/break", "x" }, /* 17 */
1051+ { svr4_stat, 2, "stat", "sp" }, /* 18 */
1052+ { sys_lseek, 3, "seek/lseek", "ddd" }, /* 19 */
1053+ { abi_getpid, Spl, "getpid", "" }, /* 20 */
1054+ { 0, Ukn, "mount", "" }, /* 21 */
1055+ { sys_umount, 1, "umount", "s" }, /* 22 */
1056+ { sys_setuid, 1, "setuid", "d" }, /* 23 */
1057+ { abi_getuid, Spl, "getuid", "" }, /* 24 */
1058+ { sys_stime, 1, "stime", "d" }, /* 25 */
1059+ { 0, Ukn, "ptrace", "" }, /* 26 */
1060+ { sys_alarm, 1, "alarm", "d" }, /* 27 */
1061+ { svr4_fstat, 2, "fstat", "dp" }, /* 28 */
1062+ { sys_pause, 0, "pause", "" }, /* 29 */
1063+ { sys_utime, 2, "utime", "xx" }, /* 30 */
1064+ { 0, Ukn, "stty", "" }, /* 31 */
1065+ { 0, Ukn, "gtty", "" }, /* 32 */
1066+ { sys_access, 2, "access", "so" }, /* 33 */
1067+ { sys_nice, 1, "nice", "d" }, /* 34 */
1068+ { svr4_statfs, 4, "statfs", "spdd" }, /* 35 */
1069+ { sys_sync, 0, "sync", "" }, /* 36 */
1070+ { abi_kill, 2, "kill", "dd" }, /* 37 */
1071+ { svr4_fstatfs, 4, "fstatfs", "dpdd" }, /* 38 */
1072+ { abi_procids, Spl, "procids", "d" }, /* 39 */
1073+ { 0, Ukn, "cxenix", "" }, /* 40 */
1074+ { sys_dup, 1, "dup", "d" }, /* 41 */
1075+ { abi_pipe, Spl, "pipe", "" }, /* 42 */
1076+ { sys_times, 1, "times", "p" }, /* 43 */
1077+ { 0, Ukn, "prof", "" }, /* 44 */
1078+ { 0, Ukn, "lock/plock", "" }, /* 45 */
1079+ { sys_setgid, 1, "setgid", "d" }, /* 46 */
1080+ { abi_getgid, Spl, "getgid", "" }, /* 47 */
1081+ { abi_sigfunc, Fast, "sigfunc", "xxx" }, /* 48 */
1082+ { svr4_msgsys, Spl, "msgsys", "dxddd" }, /* 49 */
1083+ { svr4_sysi86, 3, "sysi86", "d" }, /* 50 */
1084+ { sys_acct, 1, "acct/sysacct", "x" }, /* 51 */
1085+ { svr4_shmsys, Fast, "shmsys", "ddxo" }, /* 52 */
1086+ { svr4_semsys, Spl, "semsys", "dddx" }, /* 53 */
1087+ { svr4_ioctl, Spl, "ioctl", "dxx" }, /* 54 */
1088+ { 0, 3, "uadmin", "xxx" }, /* 55 */
1089+ { 0, Ukn, "?", "" }, /* 56 */
1090+ { v7_utsname, 1, "utsys", "x" }, /* 57 */
1091+ { sys_fsync, 1, "fsync", "d" }, /* 58 */
1092+ { abi_exec, Spl, "execv", "spp" }, /* 59 */
1093+ { sys_umask, 1, "umask", "o" }, /* 60 */
1094+ { sys_chroot, 1, "chroot", "s" }, /* 61 */
1095+ { svr4_fcntl, 3, "fcntl", "dxx" }, /* 62 */
1096+ { svr4_ulimit, 2, "ulimit", "xx" }, /* 63 */
1097+ { 0, Ukn, "?", "" }, /* 64 */
1098+ { 0, Ukn, "?", "" }, /* 65 */
1099+ { 0, Ukn, "?", "" }, /* 66 */
1100+ { 0, Ukn, "?", "" }, /* 67 */
1101+ { 0, Ukn, "?", "" }, /* 68 */
1102+ { 0, Ukn, "?", "" }, /* 69 */
1103+ { 0, Ukn, "advfs", "" }, /* 70 */
1104+ { 0, Ukn, "unadvfs", "" }, /* 71 */
1105+ { 0, Ukn, "rmount", "" }, /* 72 */
1106+ { 0, Ukn, "rumount", "" }, /* 73 */
1107+ { 0, Ukn, "rfstart", "" }, /* 74 */
1108+ { 0, Ukn, "?", "" }, /* 75 */
1109+ { 0, Ukn, "rdebug", "" }, /* 76 */
1110+ { 0, Ukn, "rfstop", "" }, /* 77 */
1111+ { 0, Ukn, "rfsys", "" }, /* 78 */
1112+ { sys_rmdir, 1, "rmdir", "s" }, /* 79 */
1113+ { abi_mkdir, 2, "mkdir", "so" }, /* 80 */
1114+ { svr4_getdents, 3, "getdents", "dxd" }, /* 81 */
1115+ { 0, Ukn, "libattach", "" }, /* 82 */
1116+ { 0, Ukn, "libdetach", "" }, /* 83 */
1117+ { svr4_sysfs, 3, "sysfs", "dxx" }, /* 84 */
1118+ { svr4_getmsg, Spl, "getmsg", "dxxx" }, /* 85 */
1119+ { svr4_putmsg, Spl, "putmsg", "dxxd" }, /* 86 */
1120+ { sys_poll, 3, "poll", "xdd" }, /* 87 */
1121+ { svr4_lstat, 2, "lstat", "sp" }, /* 88 */
1122+ { sys_symlink, 2, "symlink", "ss" }, /* 89 */
1123+ { sys_readlink, 3, "readlink", "spd" }, /* 90 */
1124+ { sys_setgroups, 2, "setgroups", "dp" }, /* 91 */
1125+ { sys_getgroups, 2, "getgroups", "dp" }, /* 92 */
1126+ { sys_fchmod, 2, "fchmod", "do" }, /* 93 */
1127+ { sys_fchown, 3, "fchown", "ddd" }, /* 94 */
1128+ { abi_sigprocmask, 3, "sigprocmask", "dxx" }, /* 95 */
1129+ { abi_sigsuspend, Spl, "sigsuspend", "x" }, /* 96 */
1130+ { 0, 2, "sigaltstack", "xx" }, /* 97 */
1131+ { abi_sigaction, 3, "sigaction", "dxx" }, /* 98 */
1132+ { svr4_sigpending, 2, "sigpending", "dp" }, /* 99 */
1133+ { svr4_context, Spl, "context", "" }, /* 100 */
1134+ { 0, Ukn, "evsys", "" }, /* 101 */
1135+ { 0, Ukn, "evtrapret", "" }, /* 102 */
1136+ { svr4_statvfs, 2, "statvfs", "sp" }, /* 103 */
1137+ { svr4_fstatvfs, 2, "fstatvfs", "dp" }, /* 104 */
1138+ { 0, Ukn, "sysisc", "" }, /* 105 */
1139+ { 0, Ukn, "nfssys", "" }, /* 106 */
1140+ { 0, 4, "waitid", "ddxd" }, /* 107 */
1141+ { 0, 3, "sigsendsys", "ddd" }, /* 108 */
1142+ { svr4_hrtsys, Spl, "hrtsys", "xxx" }, /* 109 */
1143+ { 0, 3, "acancel", "dxd" }, /* 110 */
1144+ { 0, Ukn, "async", "" }, /* 111 */
1145+ { 0, Ukn, "priocntlsys", "" }, /* 112 */
1146+ { svr4_pathconf, 2, "pathconf", "sd" }, /* 113 */
1147+ { 0, 3, "mincore", "xdx" }, /* 114 */
1148+ { svr4_mmap, 6, "mmap", "xxxxdx"},/* 115 */
1149+ { sys_mprotect, 3, "mprotect", "xdx" },/* 116 */
1150+ { sys_munmap, 2, "munmap", "xd" },/* 117 */
1151+ { svr4_fpathconf, 2, "fpathconf", "dd" }, /* 118 */
1152+ { abi_fork, Spl, "vfork", "" }, /* 119 */
1153+ { sys_fchdir, 1, "fchdir", "d" }, /* 120 */
1154+ { sys_readv, 3, "readv", "dxd" }, /* 121 */
1155+ { sys_writev, 3, "writev", "dxd" }, /* 122 */
1156+ { svr4_xstat, 3, "xstat", "dsx" }, /* 123 */
1157+ { svr4_lxstat, 3, "lxstat", "dsx" }, /* 124 */
1158+ { svr4_fxstat, 3, "fxstat", "ddx" }, /* 125 */
1159+ { svr4_xmknod, 4, "xmknod", "dsox" }, /* 126 */
1160+ { 0, Ukn, "syslocal", "d" }, /* 127 */
1161+ { svr4_getrlimit, 2, "setrlimit", "dx" }, /* 128 */
1162+ { svr4_setrlimit, 2, "getrlimit", "dx" }, /* 129 */
1163+ { 0, 3, "lchown", "sdd" }, /* 130 */
1164+ { 0, Ukn, "memcntl", "" }, /* 131 */
1165+#if defined(CONFIG_ABI_XTI)
1166+ { svr4_getpmsg, 5, "getpmsg", "dxxxx" }, /* 132 */
1167+ { svr4_putpmsg, 5, "putpmsg", "dxxdd" }, /* 133 */
1168+#else
1169+ { 0, 5, "getpmsg", "dxxxx" }, /* 132 */
1170+ { 0, 5, "putpmsg", "dxxdd" }, /* 133 */
1171+#endif
1172+ { sys_rename, 2, "rename", "ss" }, /* 134 */
1173+ { abi_utsname, 1, "uname", "x" }, /* 135 */
1174+ { svr4_setegid, 1, "setegid", "d" }, /* 136 */
1175+ { svr4_sysconfig, 1, "sysconfig", "d" }, /* 137 */
1176+ { 0, Ukn, "adjtime", "" }, /* 138 */
1177+ { svr4_sysinfo, 3, "systeminfo", "dsd" }, /* 139 */
1178+ { socksys_syscall, 1, "socksys", "x" }, /* 140 */
1179+ { svr4_seteuid, 1, "seteuid", "d" }, /* 141 */
1180+ { 0, Ukn, "?", "" }, /* 142 */
1181+ { 0, Ukn, "?", "" }, /* 143 */
1182+ { 0, 2, "secsys", "dx" }, /* 144 */
1183+ { 0, 4, "filepriv", "sdxd" }, /* 145 */
1184+ { 0, 3, "procpriv", "dxd" }, /* 146 */
1185+ { 0, 3, "devstat", "sdx" }, /* 147 */
1186+ { 0, 5, "aclipc", "ddddx" }, /* 148 */
1187+ { 0, 3, "fdevstat", "ddx" }, /* 149 */
1188+ { 0, 3, "flvlfile", "ddx" }, /* 150 */
1189+ { 0, 3, "lvlfile", "sdx" }, /* 151 */
1190+ { 0, Ukn, "?", "" }, /* 152 */
1191+ { 0, 2, "lvlequal", "xx" }, /* 153 */
1192+ { 0, 2, "lvlproc", "dx" }, /* 154 */
1193+ { 0, Ukn, "?", "" }, /* 155 */
1194+ { 0, 4, "lvlipc", "dddx" }, /* 156 */
1195+ { 0, 4, "acl", "sddx" }, /* 157 */
1196+ { 0, Ukn, "auditevt", "" }, /* 158 */
1197+ { 0, Ukn, "auditctl", "" }, /* 159 */
1198+ { 0, Ukn, "auditdmp", "" }, /* 160 */
1199+ { 0, Ukn, "auditlog", "" }, /* 161 */
1200+ { 0, Ukn, "auditbuf", "" }, /* 162 */
1201+ { 0, 2, "lvldom", "xx" }, /* 163 */
1202+ { 0, Ukn, "lvlvfs", "" }, /* 164 */
1203+ { 0, 2, "mkmld", "so" }, /* 165 */
1204+ { 0, Ukn, "mlddone", "" }, /* 166 */
1205+ { 0, 2, "secadvise", "xx" }, /* 167 */
1206+ { 0, Ukn, "online", "" }, /* 168 */
1207+ { sys_setitimer, 3, "setitimer", "dxx" }, /* 169 */
1208+ { sys_getitimer, 2, "getitimer", "dx" }, /* 170 */
1209+ { sys_gettimeofday, 2, "gettimeofday", "xx" }, /* 171 */
1210+ { sys_settimeofday, 2, "settimeofday", "xx" }, /* 172 */
1211+ { 0, Ukn, "lwpcreate", "" }, /* 173 */
1212+ { 0, Ukn, "lwpexit", "" }, /* 174 */
1213+ { 0, Ukn, "lwpwait", "" }, /* 175 */
1214+ { 0, Ukn, "lwpself", "" }, /* 176 */
1215+ { 0, Ukn, "lwpinfo", "" }, /* 177 */
1216+ { 0, Ukn, "lwpprivate", "" }, /* 178 */
1217+ { 0, Ukn, "processorbind","" }, /* 179 */
1218+ { 0, Ukn, "processorexbind","" }, /* 180 */
1219+ { 0, Ukn, "", "" }, /* 181 */
1220+ { 0, Ukn, "sync_mailbox", "" }, /* 182 */
1221+ { 0, Ukn, "prepblock", "" }, /* 183 */
1222+ { 0, Ukn, "block", "" }, /* 184 */
1223+ { 0, Ukn, "rdblock", "" }, /* 185 */
1224+ { 0, Ukn, "unblock", "" }, /* 186 */
1225+ { 0, Ukn, "cancelblock", "" }, /* 187 */
1226+ { 0, Ukn, "?", "" }, /* 188 */
1227+ { 0, Ukn, "pread", "" }, /* 189 */
1228+ { 0, Ukn, "pwrite", "" }, /* 190 */
1229+ { sys_truncate, 2, "truncate", "sd" }, /* 191 */
1230+ { sys_ftruncate, 2, "ftruncate", "dd" }, /* 192 */
1231+ { 0, Ukn, "lwpkill", "" }, /* 193 */
1232+ { 0, Ukn, "sigwait", "" }, /* 194 */
1233+ { 0, Ukn, "fork1", "" }, /* 195 */
1234+ { 0, Ukn, "forkall", "" }, /* 196 */
1235+ { 0, Ukn, "modload", "" }, /* 197 */
1236+ { 0, Ukn, "moduload", "" }, /* 198 */
1237+ { 0, Ukn, "modpath", "" }, /* 199 */
1238+ { 0, Ukn, "modstat", "" }, /* 200 */
1239+ { 0, Ukn, "modadm", "" }, /* 201 */
1240+ { 0, Ukn, "getksym", "" }, /* 202 */
1241+ { 0, Ukn, "lwpsuspend", "" }, /* 203 */
1242+ { 0, Ukn, "lwpcontinue", "" }, /* 204 */
1243+ { 0, Ukn, "?", "" }, /* 205 */
1244+ { 0, Ukn, "?", "" }, /* 206 */
1245+ { 0, Ukn, "?", "" }, /* 207 */
1246+ { 0, Ukn, "?", "" },
1247+ { 0, Ukn, "?", "" },
1248+ { 0, Ukn, "?", "" },
1249+ { 0, Ukn, "?", "" },
1250+ { 0, Ukn, "?", "" },
1251+ { 0, Ukn, "?", "" },
1252+ { 0, Ukn, "?", "" },
1253+ { 0, Ukn, "?", "" }
1254+};
1255+
1256+static void
1257+ibcs_lcall7(int segment, struct pt_regs *regs)
1258+{
1259+ int sysno = regs->eax & 0xff;
1260+
1261+ if (sysno >= ARRAY_SIZE(ibcs_syscall_table))
1262+ set_error(regs, iABI_errors(-EINVAL));
1263+ else
1264+ lcall7_dispatch(regs, &ibcs_syscall_table[regs->eax & 0xff], 1);
1265+}
1266+
1267+static struct exec_domain ibcs_exec_domain = {
1268+ name: "iBCS2/iABI4",
1269+ handler: ibcs_lcall7,
1270+ pers_low: 1 /* PER_SVR4 */,
1271+ pers_high: 2 /* PER_SVR3 */,
1272+ signal_map: ibcs_to_linux_signals,
1273+ signal_invmap: linux_to_ibcs_signals,
1274+ err_map: ibcs_err_map,
1275+ socktype_map: ibcs_socktype_map,
1276+ sockopt_map: ibcs_sockopt_map,
1277+ af_map: ibcs_af_map,
1278+ module: THIS_MODULE
1279+};
1280+
1281+static int __init
1282+ibcs_init(void)
1283+{
1284+ return register_exec_domain(&ibcs_exec_domain);
1285+}
1286+
1287+
1288+static void __exit
1289+ibcs_exit(void)
1290+{
1291+ unregister_exec_domain(&ibcs_exec_domain);
1292+}
1293+
1294+module_init(ibcs_init);
1295+module_exit(ibcs_exit);
1296diff -Nru linux-2.6.7/abi/isc/Makefile linux-2.6.7-abi/abi/isc/Makefile
1297--- linux-2.6.7/abi/isc/Makefile 1970-01-01 01:00:00.000000000 +0100
1298+++ linux-2.6.7-abi/abi/isc/Makefile 2004-07-22 17:44:20.000000000 +0200
1299@@ -0,0 +1,7 @@
1300+
1301+abi-isc-objs := sysent.o
1302+
1303+obj-$(CONFIG_ABI_ISC) += abi-isc.o
1304+
1305+abi-isc.o: $(abi-isc-objs)
1306+ $(LD) -r -o $@ $(abi-isc-objs)
1307diff -Nru linux-2.6.7/abi/isc/sysent.c linux-2.6.7-abi/abi/isc/sysent.c
1308--- linux-2.6.7/abi/isc/sysent.c 1970-01-01 01:00:00.000000000 +0100
1309+++ linux-2.6.7-abi/abi/isc/sysent.c 2004-07-22 17:44:20.000000000 +0200
1310@@ -0,0 +1,460 @@
1311+/*
1312+ * Copyright (c) 2001 Christoph Hellwig.
1313+ * All rights reserved.
1314+ *
1315+ * This program is free software; you can redistribute it and/or modify
1316+ * it under the terms of the GNU General Public License as published by
1317+ * the Free Software Foundation; either version 2 of the License, or
1318+ * (at your option) any later version.
1319+ *
1320+ * This program is distributed in the hope that it will be useful,
1321+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1322+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1323+ * GNU General Public License for more details.
1324+ *
1325+ * You should have received a copy of the GNU General Public License
1326+ * along with this program; if not, write to the Free Software
1327+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1328+ */
1329+
1330+#ident "%W% %G%"
1331+
1332+/*
1333+ * ISC personality switch.
1334+ */
1335+#include <linux/config.h>
1336+#include <linux/kernel.h>
1337+#include <linux/module.h>
1338+#include <linux/init.h>
1339+#include <linux/personality.h>
1340+#include <linux/syscalls.h>
1341+#include <linux/socket.h>
1342+#include <linux/net.h>
1343+#include <asm/uaccess.h>
1344+
1345+#include <abi/svr4/sysent.h>
1346+#include <abi/signal.h>
1347+
1348+#include <abi/util/errno.h>
1349+#include <abi/util/sysent.h>
1350+#include <abi/util/socket.h>
1351+
1352+MODULE_DESCRIPTION("ISC personality");
1353+MODULE_AUTHOR("Christoph Hellwig, partially taken from iBCS");
1354+MODULE_LICENSE("GPL");
1355+
1356+
1357+/* forward */
1358+static int isc_setostype(int);
1359+
1360+/*
1361+ * We could remove some of the long identity mapped runs but at the
1362+ * expense of extra comparisons for each mapping at run time...
1363+ */
1364+static u_char isc_err_table[] = {
1365+/* 0 - 9 */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
1366+/* 10 - 19 */ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
1367+/* 20 - 29 */ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
1368+/* 30 - 39 */ 30, 31, 32, 33, 34, 45, 78, 46, 89, 93,
1369+/* 40 - 49 */ 90, 90, 35, 36, 37, 38, 39, 40, 41, 42,
1370+/* 50 - 59 */ 43, 44, 50, 51, 52, 53, 54, 55, 56, 57,
1371+/* 60 - 69 */ 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
1372+/* 70 - 79 */ 70, 71, 74, 76, 77, 79, 80, 81, 82, 83,
1373+/* 80 - 89 */ 84, 85, 86, 87, 88, 91, 92, 94, 95, 96,
1374+/* 90 - 99 */ 97, 98, 99, 120, 121, 122, 123, 124, 125, 126,
1375+/* 100 - 109 */ 127, 128, 129, 130, 131, 132, 133, 134, 143, 144,
1376+/* 110 - 119 */ 145, 146, 147, 148, 149, 150, 22, 135, 137, 138,
1377+/* 120 - 122 */ 139, 140, 28
1378+};
1379+
1380+/*
1381+ * Map Linux RESTART* values (512,513,514) to EINTR
1382+ */
1383+static u_char lnx_err_table[] = {
1384+/* 512 - 514 */ EINTR, EINTR, EINTR
1385+};
1386+
1387+struct map_segment isc_err_map[] = {
1388+ { 0, 0+sizeof(isc_err_table)-1, isc_err_table },
1389+ { 512, 512+sizeof(lnx_err_table)-1, lnx_err_table },
1390+ { -1 }
1391+};
1392+
1393+/*
1394+ * ISC's error mapping is a little different.
1395+ */
1396+static long linux_to_isc_signals[NSIGNALS+1] = {
1397+/* 0 - 3 */ 0, IBCS_SIGHUP, IBCS_SIGINT, IBCS_SIGQUIT,
1398+/* 4 - 7 */ IBCS_SIGILL, IBCS_SIGTRAP, IBCS_SIGABRT, -1,
1399+/* 8 - 11 */ IBCS_SIGFPE, IBCS_SIGKILL, IBCS_SIGUSR1, IBCS_SIGSEGV,
1400+/* 12 - 15 */ IBCS_SIGUSR2, IBCS_SIGPIPE, IBCS_SIGALRM, IBCS_SIGTERM,
1401+/* 16 - 19 */ IBCS_SIGSEGV, IBCS_SIGCHLD, ISC_SIGCONT, ISC_SIGSTOP,
1402+/* 20 - 23 */ ISC_SIGTSTP, IBCS_SIGTTIN, IBCS_SIGTTOU, IBCS_SIGUSR1,
1403+/* 24 - 27 */ IBCS_SIGGXCPU, IBCS_SIGGXFSZ, IBCS_SIGVTALRM, IBCS_SIGPROF,
1404+/* 28 - 31 */ IBCS_SIGWINCH, IBCS_SIGIO, IBCS_SIGPWR, -1,
1405+/* 32 */ -1
1406+};
1407+
1408+static long isc_to_linux_signals[NSIGNALS+1] = {
1409+/* 0 - 3 */ 0, SIGHUP, SIGINT, SIGQUIT,
1410+/* 4 - 7 */ SIGILL, SIGTRAP, SIGIOT, SIGUNUSED,
1411+/* 8 - 11 */ SIGFPE, SIGKILL, SIGUNUSED, SIGSEGV,
1412+/* 12 - 15 */ SIGUNUSED, SIGPIPE, SIGALRM, SIGTERM,
1413+/* 16 - 19 */ SIGUSR1, SIGUSR2, SIGCHLD, SIGPWR,
1414+/* 20 - 23 */ SIGWINCH, -1, SIGPOLL, SIGCONT,
1415+/* 24 - 27 */ SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU,
1416+/* 28 - 31 */ SIGVTALRM, SIGPROF, SIGXCPU, SIGXFSZ,
1417+/* 32 */ -1
1418+};
1419+
1420+static char isc_socktype[] = {
1421+ SOCK_STREAM,
1422+ SOCK_DGRAM,
1423+ 0,
1424+ SOCK_RAW,
1425+ SOCK_RDM,
1426+ SOCK_SEQPACKET
1427+};
1428+
1429+static struct map_segment isc_socktype_map[] = {
1430+ { 1, 6, isc_socktype },
1431+ { -1 }
1432+};
1433+
1434+static struct map_segment isc_sockopt_map[] = {
1435+ { 0x0001, 0x0001, (char *)SO_DEBUG },
1436+ { 0x0002, 0x0002, (char *)__SO_ACCEPTCON },
1437+ { 0x0004, 0x0004, (char *)SO_REUSEADDR },
1438+ { 0x0008, 0x0008, (char *)SO_KEEPALIVE },
1439+ { 0x0010, 0x0010, (char *)SO_DONTROUTE },
1440+ { 0x0020, 0x0020, (char *)SO_BROADCAST },
1441+ { 0x0040, 0x0040, (char *)SO_USELOOPBACK },
1442+ { 0x0080, 0x0080, (char *)SO_LINGER },
1443+ { 0x0100, 0x0100, (char *)SO_OOBINLINE },
1444+ { 0x0200, 0x0200, (char *)SO_ORDREL },
1445+ { 0x0400, 0x0400, (char *)SO_IMASOCKET },
1446+ { 0x1001, 0x1001, (char *)SO_SNDBUF },
1447+ { 0x1002, 0x1002, (char *)SO_RCVBUF },
1448+ { 0x1003, 0x1003, (char *)SO_SNDLOWAT },
1449+ { 0x1004, 0x1004, (char *)SO_RCVLOWAT },
1450+ { 0x1005, 0x1005, (char *)SO_SNDTIMEO },
1451+ { 0x1006, 0x1006, (char *)SO_RCVTIMEO },
1452+ { 0x1007, 0x1007, (char *)SO_ERROR },
1453+ { 0x1008, 0x1008, (char *)SO_TYPE },
1454+ { 0x1009, 0x1009, (char *)SO_PROTOTYPE },
1455+ { -1 }
1456+};
1457+
1458+static struct map_segment isc_af_map[] = {
1459+ { 0, 2, NULL },
1460+ { -1 }
1461+};
1462+
1463+
1464+static struct sysent sysisc_table[] = {
1465+/* 0 */ { 0, Ukn, "sysisc0", "" },
1466+/* 1 */ { isc_setostype, 1, "setostype", "d" },
1467+/* 2 */ { sys_rename, 2, "rename", "ss" },
1468+/* 3 */ { abi_sigaction, 3, "sigaction", "dxx" },
1469+/* 4 */ { abi_sigprocmask, 3, "sicprocmask", "dxx" },
1470+/* 5 */ { 0, 1, "sigpending", "x" },
1471+/* 6 */ { sys_getgroups16, 2, "getgroups", "dp" },
1472+/* 7 */ { sys_setgroups16, 2, "setgroups", "dp" },
1473+/* 8 */ { 0, Ukn, "pathconf", "" },
1474+/* 9 */ { 0, Ukn, "fpathconf", "" },
1475+/* 10 */ { ibcs_sysconf, 1, "sysconf", "d" },
1476+/* 11 */ { sys_waitpid, 3, "waitpid", "dxx" },
1477+/* 12 */ { sys_setsid, 0, "setsid", "" },
1478+/* 13 */ { sys_setpgid, 2, "setpgid", "dd" },
1479+/* 14 */ { 0, Ukn, "adduser", "" },
1480+/* 15 */ { 0, Ukn, "setuser", "" },
1481+/* 16 */ { 0, Ukn, "sysisc16", "" },
1482+/* 17 */ { abi_sigsuspend, Spl, "sigsuspend", "x" },
1483+/* 18 */ { sys_symlink, 2, "symlink", "ss" },
1484+/* 19 */ { sys_readlink, 3, "readlink", "spd" },
1485+/* 20 */ { 0, Ukn, "getmajor", "" }
1486+};
1487+
1488+static void
1489+isc_sysisc(struct pt_regs *regs)
1490+{
1491+ int sysno;
1492+
1493+ __get_user(sysno, ((unsigned long *)regs->esp)+1);
1494+
1495+ if (sysno >= ARRAY_SIZE(sysisc_table))
1496+ set_error(regs, iABI_errors(-EINVAL));
1497+ else
1498+ lcall7_dispatch(regs, &sysisc_table[sysno], 2);
1499+}
1500+
1501+static int
1502+isc_setostype(int arg1)
1503+{
1504+ return 0;
1505+}
1506+
1507+static struct sysent isc_syscall_table[] = {
1508+ { abi_syscall, Fast, "syscall", "" }, /* 0 */
1509+ { sys_exit, 1, "exit", "d" }, /* 1 */
1510+ { abi_fork, Spl, "fork", "" }, /* 2 */
1511+ { abi_read, 3, "read", "dpd" }, /* 3 */
1512+ { sys_write, 3, "write", "dpd" }, /* 4 */
1513+ { svr4_open, 3, "open", "soo" }, /* 5 */
1514+ { sys_close, 1, "close", "d" }, /* 6 */
1515+ { abi_wait, Spl, "wait", "xxx" }, /* 7 */
1516+ { sys_creat, 2, "creat", "so" }, /* 8 */
1517+ { sys_link, 2, "link", "ss" }, /* 9 */
1518+ { sys_unlink, 1, "unlink", "s" }, /* 10 */
1519+ { abi_exec, Spl, "exec", "sxx" }, /* 11 */
1520+ { sys_chdir, 1, "chdir", "s" }, /* 12 */
1521+ { abi_time, 0, "time", "" }, /* 13 */
1522+ { svr4_mknod, 3, "mknod", "soo" }, /* 14 */
1523+ { sys_chmod, 2, "chmod", "so" }, /* 15 */
1524+ { sys_chown, 3, "chown", "sdd" }, /* 16 */
1525+ { abi_brk, 1, "brk/break", "x" }, /* 17 */
1526+ { svr4_stat, 2, "stat", "sp" }, /* 18 */
1527+ { sys_lseek, 3, "seek/lseek", "ddd" }, /* 19 */
1528+ { abi_getpid, Spl, "getpid", "" }, /* 20 */
1529+ { 0, Ukn, "mount", "" }, /* 21 */
1530+ { sys_umount, 1, "umount", "s" }, /* 22 */
1531+ { sys_setuid, 1, "setuid", "d" }, /* 23 */
1532+ { abi_getuid, Spl, "getuid", "" }, /* 24 */
1533+ { sys_stime, 1, "stime", "d" }, /* 25 */
1534+ { 0, Ukn, "ptrace", "" }, /* 26 */
1535+ { sys_alarm, 1, "alarm", "d" }, /* 27 */
1536+ { svr4_fstat, 2, "fstat", "dp" }, /* 28 */
1537+ { sys_pause, 0, "pause", "" }, /* 29 */
1538+ { sys_utime, 2, "utime", "xx" }, /* 30 */
1539+ { 0, Ukn, "stty", "" }, /* 31 */
1540+ { 0, Ukn, "gtty", "" }, /* 32 */
1541+ { sys_access, 2, "access", "so" }, /* 33 */
1542+ { sys_nice, 1, "nice", "d" }, /* 34 */
1543+ { svr4_statfs, 4, "statfs", "spdd" }, /* 35 */
1544+ { sys_sync, 0, "sync", "" }, /* 36 */
1545+ { abi_kill, 2, "kill", "dd" }, /* 37 */
1546+ { svr4_fstatfs, 4, "fstatfs", "dpdd" }, /* 38 */
1547+ { abi_procids, Spl, "procids", "d" }, /* 39 */
1548+ { 0, Ukn, "cxenix", "" }, /* 40 */
1549+ { sys_dup, 1, "dup", "d" }, /* 41 */
1550+ { abi_pipe, Spl, "pipe", "" }, /* 42 */
1551+ { sys_times, 1, "times", "p" }, /* 43 */
1552+ { 0, Ukn, "prof", "" }, /* 44 */
1553+ { 0, Ukn, "lock/plock", "" }, /* 45 */
1554+ { sys_setgid, 1, "setgid", "d" }, /* 46 */
1555+ { abi_getgid, Spl, "getgid", "" }, /* 47 */
1556+ { abi_sigfunc, Fast, "sigfunc", "xxx" }, /* 48 */
1557+ { svr4_msgsys, Spl, "msgsys", "dxddd" }, /* 49 */
1558+ { svr4_sysi86, 3, "sysi86", "d" }, /* 50 */
1559+ { sys_acct, 1, "acct/sysacct", "x" }, /* 51 */
1560+ { svr4_shmsys, Fast, "shmsys", "ddxo" }, /* 52 */
1561+ { svr4_semsys, Spl, "semsys", "dddx" }, /* 53 */
1562+ { svr4_ioctl, Spl, "ioctl", "dxx" }, /* 54 */
1563+ { 0, 3, "uadmin", "xxx" }, /* 55 */
1564+ { 0, Ukn, "?", "" }, /* 56 */
1565+ { v7_utsname, 1, "utsys", "x" }, /* 57 */
1566+ { sys_fsync, 1, "fsync", "d" }, /* 58 */
1567+ { abi_exec, Spl, "execv", "spp" }, /* 59 */
1568+ { sys_umask, 1, "umask", "o" }, /* 60 */
1569+ { sys_chroot, 1, "chroot", "s" }, /* 61 */
1570+ { svr4_fcntl, 3, "fcntl", "dxx" }, /* 62 */
1571+ { svr4_ulimit, 2, "ulimit", "xx" }, /* 63 */
1572+ { 0, Ukn, "?", "" }, /* 64 */
1573+ { 0, Ukn, "?", "" }, /* 65 */
1574+ { 0, Ukn, "?", "" }, /* 66 */
1575+ { 0, Ukn, "?", "" }, /* 67 */
1576+ { 0, Ukn, "?", "" }, /* 68 */
1577+ { 0, Ukn, "?", "" }, /* 69 */
1578+ { 0, Ukn, "advfs", "" }, /* 70 */
1579+ { 0, Ukn, "unadvfs", "" }, /* 71 */
1580+ { 0, Ukn, "rmount", "" }, /* 72 */
1581+ { 0, Ukn, "rumount", "" }, /* 73 */
1582+ { 0, Ukn, "rfstart", "" }, /* 74 */
1583+ { 0, Ukn, "?", "" }, /* 75 */
1584+ { 0, Ukn, "rdebug", "" }, /* 76 */
1585+ { 0, Ukn, "rfstop", "" }, /* 77 */
1586+ { 0, Ukn, "rfsys", "" }, /* 78 */
1587+ { sys_rmdir, 1, "rmdir", "s" }, /* 79 */
1588+ { abi_mkdir, 2, "mkdir", "so" }, /* 80 */
1589+ { svr4_getdents, 3, "getdents", "dxd" }, /* 81 */
1590+ { 0, Ukn, "libattach", "" }, /* 82 */
1591+ { 0, Ukn, "libdetach", "" }, /* 83 */
1592+ { svr4_sysfs, 3, "sysfs", "dxx" }, /* 84 */
1593+ { svr4_getmsg, Spl, "getmsg", "dxxx" }, /* 85 */
1594+ { svr4_putmsg, Spl, "putmsg", "dxxd" }, /* 86 */
1595+ { sys_poll, 3, "poll", "xdd" }, /* 87 */
1596+ { svr4_lstat, 2, "lstat", "sp" }, /* 88 */
1597+ { sys_symlink, 2, "symlink", "ss" }, /* 89 */
1598+ { sys_readlink, 3, "readlink", "spd" }, /* 90 */
1599+ { sys_setgroups, 2, "setgroups", "dp" }, /* 91 */
1600+ { sys_getgroups, 2, "getgroups", "dp" }, /* 92 */
1601+ { sys_fchmod, 2, "fchmod", "do" }, /* 93 */
1602+ { sys_fchown, 3, "fchown", "ddd" }, /* 94 */
1603+ { abi_sigprocmask, 3, "sigprocmask", "dxx" }, /* 95 */
1604+ { abi_sigsuspend, Spl, "sigsuspend", "x" }, /* 96 */
1605+ { 0, 2, "sigaltstack", "xx" }, /* 97 */
1606+ { abi_sigaction, 3, "sigaction", "dxx" }, /* 98 */
1607+ { svr4_sigpending, 2, "sigpending", "dp" }, /* 99 */
1608+ { svr4_context, Spl, "context", "" }, /* 100 */
1609+ { 0, Ukn, "evsys", "" }, /* 101 */
1610+ { 0, Ukn, "evtrapret", "" }, /* 102 */
1611+ { svr4_statvfs, 2, "statvfs", "sp" }, /* 103 */
1612+ { svr4_fstatvfs, 2, "fstatvfs", "dp" }, /* 104 */
1613+ { isc_sysisc, Fast, "sysisc", "" }, /* 105 */
1614+ { 0, Ukn, "nfssys", "" }, /* 106 */
1615+ { 0, 4, "waitid", "ddxd" }, /* 107 */
1616+ { 0, 3, "sigsendsys", "ddd" }, /* 108 */
1617+ { svr4_hrtsys, Spl, "hrtsys", "xxx" }, /* 109 */
1618+ { 0, 3, "acancel", "dxd" }, /* 110 */
1619+ { 0, Ukn, "async", "" }, /* 111 */
1620+ { 0, Ukn, "priocntlsys", "" }, /* 112 */
1621+ { svr4_pathconf, 2, "pathconf", "sd" }, /* 113 */
1622+ { 0, 3, "mincore", "xdx" }, /* 114 */
1623+ { svr4_mmap, 6, "mmap", "xxxxdx"},/* 115 */
1624+ { sys_mprotect, 3, "mprotect", "xdx" },/* 116 */
1625+ { sys_munmap, 2, "munmap", "xd" },/* 117 */
1626+ { svr4_fpathconf, 2, "fpathconf", "dd" }, /* 118 */
1627+ { abi_fork, Spl, "vfork", "" }, /* 119 */
1628+ { sys_fchdir, 1, "fchdir", "d" }, /* 120 */
1629+ { sys_readv, 3, "readv", "dxd" }, /* 121 */
1630+ { sys_writev, 3, "writev", "dxd" }, /* 122 */
1631+ { svr4_xstat, 3, "xstat", "dsx" }, /* 123 */
1632+ { svr4_lxstat, 3, "lxstat", "dsx" }, /* 124 */
1633+ { svr4_fxstat, 3, "fxstat", "ddx" }, /* 125 */
1634+ { svr4_xmknod, 4, "xmknod", "dsox" }, /* 126 */
1635+ { 0, Ukn, "syslocal", "d" }, /* 127 */
1636+ { svr4_getrlimit, 2, "setrlimit", "dx" }, /* 128 */
1637+ { svr4_setrlimit, 2, "getrlimit", "dx" }, /* 129 */
1638+ { 0, 3, "lchown", "sdd" }, /* 130 */
1639+ { 0, Ukn, "memcntl", "" }, /* 131 */
1640+#if defined(CONFIG_ABI_XTI)
1641+ { svr4_getpmsg, 5, "getpmsg", "dxxxx" }, /* 132 */
1642+ { svr4_putpmsg, 5, "putpmsg", "dxxdd" }, /* 133 */
1643+#else
1644+ { 0, 5, "getpmsg", "dxxxx" }, /* 132 */
1645+ { 0, 5, "putpmsg", "dxxdd" }, /* 133 */
1646+#endif
1647+ { sys_rename, 2, "rename", "ss" }, /* 134 */
1648+ { abi_utsname, 1, "uname", "x" }, /* 135 */
1649+ { svr4_setegid, 1, "setegid", "d" }, /* 136 */
1650+ { svr4_sysconfig, 1, "sysconfig", "d" }, /* 137 */
1651+ { 0, Ukn, "adjtime", "" }, /* 138 */
1652+ { svr4_sysinfo, 3, "systeminfo", "dsd" }, /* 139 */
1653+ { socksys_syscall, 1, "socksys", "x" }, /* 140 */
1654+ { svr4_seteuid, 1, "seteuid", "d" }, /* 141 */
1655+ { 0, Ukn, "?", "" }, /* 142 */
1656+ { 0, Ukn, "?", "" }, /* 143 */
1657+ { 0, 2, "secsys", "dx" }, /* 144 */
1658+ { 0, 4, "filepriv", "sdxd" }, /* 145 */
1659+ { 0, 3, "procpriv", "dxd" }, /* 146 */
1660+ { 0, 3, "devstat", "sdx" }, /* 147 */
1661+ { 0, 5, "aclipc", "ddddx" }, /* 148 */
1662+ { 0, 3, "fdevstat", "ddx" }, /* 149 */
1663+ { 0, 3, "flvlfile", "ddx" }, /* 150 */
1664+ { 0, 3, "lvlfile", "sdx" }, /* 151 */
1665+ { 0, Ukn, "?", "" }, /* 152 */
1666+ { 0, 2, "lvlequal", "xx" }, /* 153 */
1667+ { 0, 2, "lvlproc", "dx" }, /* 154 */
1668+ { 0, Ukn, "?", "" }, /* 155 */
1669+ { 0, 4, "lvlipc", "dddx" }, /* 156 */
1670+ { 0, 4, "acl", "sddx" }, /* 157 */
1671+ { 0, Ukn, "auditevt", "" }, /* 158 */
1672+ { 0, Ukn, "auditctl", "" }, /* 159 */
1673+ { 0, Ukn, "auditdmp", "" }, /* 160 */
1674+ { 0, Ukn, "auditlog", "" }, /* 161 */
1675+ { 0, Ukn, "auditbuf", "" }, /* 162 */
1676+ { 0, 2, "lvldom", "xx" }, /* 163 */
1677+ { 0, Ukn, "lvlvfs", "" }, /* 164 */
1678+ { 0, 2, "mkmld", "so" }, /* 165 */
1679+ { 0, Ukn, "mlddone", "" }, /* 166 */
1680+ { 0, 2, "secadvise", "xx" }, /* 167 */
1681+ { 0, Ukn, "online", "" }, /* 168 */
1682+ { sys_setitimer, 3, "setitimer", "dxx" }, /* 169 */
1683+ { sys_getitimer, 2, "getitimer", "dx" }, /* 170 */
1684+ { sys_gettimeofday, 2, "gettimeofday", "xx" }, /* 171 */
1685+ { sys_settimeofday, 2, "settimeofday", "xx" }, /* 172 */
1686+ { 0, Ukn, "lwpcreate", "" }, /* 173 */
1687+ { 0, Ukn, "lwpexit", "" }, /* 174 */
1688+ { 0, Ukn, "lwpwait", "" }, /* 175 */
1689+ { 0, Ukn, "lwpself", "" }, /* 176 */
1690+ { 0, Ukn, "lwpinfo", "" }, /* 177 */
1691+ { 0, Ukn, "lwpprivate", "" }, /* 178 */
1692+ { 0, Ukn, "processorbind","" }, /* 179 */
1693+ { 0, Ukn, "processorexbind","" }, /* 180 */
1694+ { 0, Ukn, "", "" }, /* 181 */
1695+ { 0, Ukn, "sync_mailbox", "" }, /* 182 */
1696+ { 0, Ukn, "prepblock", "" }, /* 183 */
1697+ { 0, Ukn, "block", "" }, /* 184 */
1698+ { 0, Ukn, "rdblock", "" }, /* 185 */
1699+ { 0, Ukn, "unblock", "" }, /* 186 */
1700+ { 0, Ukn, "cancelblock", "" }, /* 187 */
1701+ { 0, Ukn, "?", "" }, /* 188 */
1702+ { 0, Ukn, "pread", "" }, /* 189 */
1703+ { 0, Ukn, "pwrite", "" }, /* 190 */
1704+ { sys_truncate, 2, "truncate", "sd" }, /* 191 */
1705+ { sys_ftruncate, 2, "ftruncate", "dd" }, /* 192 */
1706+ { 0, Ukn, "lwpkill", "" }, /* 193 */
1707+ { 0, Ukn, "sigwait", "" }, /* 194 */
1708+ { 0, Ukn, "fork1", "" }, /* 195 */
1709+ { 0, Ukn, "forkall", "" }, /* 196 */
1710+ { 0, Ukn, "modload", "" }, /* 197 */
1711+ { 0, Ukn, "moduload", "" }, /* 198 */
1712+ { 0, Ukn, "modpath", "" }, /* 199 */
1713+ { 0, Ukn, "modstat", "" }, /* 200 */
1714+ { 0, Ukn, "modadm", "" }, /* 201 */
1715+ { 0, Ukn, "getksym", "" }, /* 202 */
1716+ { 0, Ukn, "lwpsuspend", "" }, /* 203 */
1717+ { 0, Ukn, "lwpcontinue", "" }, /* 204 */
1718+ { 0, Ukn, "?", "" }, /* 205 */
1719+ { 0, Ukn, "?", "" }, /* 206 */
1720+ { 0, Ukn, "?", "" }, /* 207 */
1721+ { 0, Ukn, "?", "" },
1722+ { 0, Ukn, "?", "" },
1723+ { 0, Ukn, "?", "" },
1724+ { 0, Ukn, "?", "" },
1725+ { 0, Ukn, "?", "" },
1726+ { 0, Ukn, "?", "" },
1727+ { 0, Ukn, "?", "" },
1728+ { 0, Ukn, "?", "" }
1729+};
1730+
1731+static void
1732+isc_lcall7(int segment, struct pt_regs *regs)
1733+{
1734+ int sysno = regs->eax & 0xff;
1735+
1736+ if (sysno >= ARRAY_SIZE(isc_syscall_table))
1737+ set_error(regs, iABI_errors(-EINVAL));
1738+ else
1739+ lcall7_dispatch(regs, &isc_syscall_table[sysno], 1);
1740+}
1741+
1742+static struct exec_domain isc_exec_domain = {
1743+ name: "ISC",
1744+ handler: isc_lcall7,
1745+ pers_low: 5 /* PER_ISCR4 */,
1746+ pers_high: 5 /* PER_ISCR4 */,
1747+ signal_map: isc_to_linux_signals,
1748+ signal_invmap: linux_to_isc_signals,
1749+ err_map: isc_err_map,
1750+ socktype_map: isc_socktype_map,
1751+ sockopt_map: isc_sockopt_map,
1752+ af_map: isc_af_map,
1753+ module: THIS_MODULE
1754+};
1755+
1756+static int __init
1757+isc_init(void)
1758+{
1759+ return register_exec_domain(&isc_exec_domain);
1760+}
1761+
1762+
1763+static void __exit
1764+isc_exit(void)
1765+{
1766+ unregister_exec_domain(&isc_exec_domain);
1767+}
1768+
1769+module_init(isc_init);
1770+module_exit(isc_exit);
1771diff -Nru linux-2.6.7/abi/Kconfig linux-2.6.7-abi/abi/Kconfig
1772--- linux-2.6.7/abi/Kconfig 1970-01-01 01:00:00.000000000 +0100
1773+++ linux-2.6.7-abi/abi/Kconfig 2004-07-22 17:44:20.000000000 +0200
1774@@ -0,0 +1,166 @@
1775+#
1776+# Linux-ABI configuration
1777+#
1778+
1779+# this file gets source'ed into the kernel file formats menu entry
1780+# via ./fs/Kconfig.binfmt
1781+
1782+config ABI
1783+ bool "Extended Linux-ABI support (alien binarys and syscalls)"
1784+ depends on X86=y
1785+ default n
1786+ help
1787+ Support for a few alien syscall interfaces. This allows you to run
1788+ a binary that got build for other Unix compatible platforms.
1789+
1790+
1791+config ABI_SVR4
1792+ tristate "SVR3/SVR4 family syscall support for x86 binarys"
1793+ depends on X86=y
1794+ depends on ABI
1795+ default n
1796+
1797+
1798+comment "SVR3/SVR4 based syscall support for x86: (please check one or more)"
1799+ depends on ABI_SVR4
1800+
1801+config ABI_IBCS
1802+ tristate "iBCS2/iABI4 syscall support"
1803+ depends on ABI_SVR4
1804+
1805+config ABI_ISC
1806+ tristate "ISC syscall support"
1807+ depends on ABI_SVR4
1808+
1809+config ABI_SCO
1810+ tristate "SCO OpenServer 5/SCO Unix 3.x/Xenix syscall support"
1811+ depends on ABI_SVR4
1812+
1813+config ABI_SOLARIS
1814+ tristate "Solaris 2.x syscall support"
1815+ depends on ABI_SVR4
1816+
1817+config ABI_UW7
1818+ tristate "UnixWare 7.x syscall support"
1819+ depends on ABI_SVR4
1820+
1821+config ABI_WYSE
1822+ tristate "Wyse V/386 syscall support"
1823+ depends on ABI_SVR4
1824+
1825+
1826+comment "SVR3/SVR4 related binary format support for x86:"
1827+ depends on ABI_SVR4
1828+
1829+config BINFMT_COFF
1830+ tristate "COFF binary support (SVR3)"
1831+ depends on ABI_SVR4
1832+
1833+config BINFMT_XOUT
1834+ tristate "x.out binary support (Xenix)"
1835+ depends on ABI_SVR4
1836+
1837+config BINFMT_XOUT_X286
1838+ bool "x.out segmented binary support (Xenix/80286)"
1839+ depends on BINFMT_XOUT
1840+
1841+
1842+config ABI_LATE_PROBING
1843+ bool
1844+ prompt "Late probing of personality trough syscall handler"
1845+ depends on ABI
1846+ default y
1847+ help
1848+ There is a minor general uncertainty on identification of binary
1849+ formats. It might happen that statically linked SVr4 binary could
1850+ be falsely assigned to a Linux personality. Solaris/x86 binarys
1851+ are another sample for a falsely assigned Linux personality.
1852+ If this option is set the lcall handler for Linux will switch
1853+ to SVr4 personality as soon as lcall 0x07 is used, or it will
1854+ switch to Solaris personality when lcall 0x27 is used.
1855+ Since this on-the-fly personality switching is a one way path
1856+ a malicious program might make use of exactly that ability.
1857+ For system consistency reasons personality detection should go
1858+ that way. The better solution is to improve the personality
1859+ detection code at load time in contrast to runtime detection.
1860+ At present load time probing is not perfect, so better say yes.
1861+
1862+config ABI_TRACE
1863+ bool
1864+ prompt "Include prints for syscall tracking via ABI_TRACE ioctl"
1865+ depends on ABI
1866+ default y
1867+ help
1868+ This option allows to control the inclusion of code that prints
1869+ kernel messages for tracking special syscalls events like errors.
1870+ Typically this messages further have to be enabled via the
1871+ ABI_TRACE ioctl. This option will not remove the ioctl interface
1872+ but will only remove the backend coding which produces the prints.
1873+ You can disable thise option if you want to reduce the kernel size
1874+ or have other concerns, e.g. code size or possible message floods.
1875+
1876+# --- internal options, values will get derived from prior settings ---
1877+
1878+# the abi-util (./abi/util) codebase
1879+# does currently only contain code for the ABI_TRACE coding
1880+# and has to be present as soon as the SVR4 code is present.
1881+config ABI_UTIL
1882+ tristate
1883+ depends on ABI_TRACE
1884+ default y if ABI_SVR4=y
1885+ default m if ABI_SVR4=m
1886+ default n
1887+
1888+config ABI_SPX
1889+ bool
1890+ depends on ABI!=n
1891+ default y
1892+
1893+config ABI_XTI
1894+ bool
1895+ depends on ABI!=n
1896+ default y
1897+
1898+config ABI_TLI_OPTMGMT
1899+ bool
1900+ depends on ABI!=n
1901+ default y
1902+
1903+config ABI_XTI_OPTMGMT
1904+ bool
1905+ depends on ABI!=n
1906+ default n
1907+
1908+# there are syscall interfaces which do get statically linked
1909+config ABI_SYSCALL_STATICS
1910+ bool
1911+ default y if ABI_UW7=y || ABI_SOLARIS=y || ABI_IBCS=y || ABI_ISC=y || ABI_SCO=y || ABI_WYSE=y
1912+ default n
1913+
1914+# there are syscall interfaces which do get build as module
1915+config ABI_SYSCALL_MODULES
1916+ bool
1917+ default y if ABI_UW7=m || ABI_SOLARIS=m || ABI_IBCS=m || ABI_ISC=m || ABI_SCO=m || ABI_WYSE=m
1918+ default n
1919+
1920+# the LCALL7 code for SVR4 family support must _not_ be a module
1921+# when there is at least a single, statically bound syscall driver.
1922+# if there are only modules, then the LCALL code can be a module as well.
1923+# if there is no module at all then we dont need the LCALL7 code.
1924+config ABI_LCALL7
1925+ tristate
1926+ default y if ABI_SYSCALL_STATICS=y
1927+ default m if ABI_SYSCALL_MODULES=y
1928+ default n
1929+
1930+# notes:
1931+# * only a static SVR4 core coding will allow static syscall drivers,
1932+# * setting a syscall driver to modules will be the only way to allow
1933+# this single module to plug into SVR4 core coding.
1934+# * there is no generic "register my entrypoints" request for modules
1935+# in the curent codebase. (this might be a TODO)
1936+# * the exported LCALL7 syms will only be usefull to syscall driver modules.
1937+# * LCALL7 is only usefull if there are syscall drivers (static or module).
1938+# * an "empty" SVR4 might be usefull for debugging and non-x86 targets.
1939+
1940+### EOF ###
1941diff -Nru linux-2.6.7/abi/Makefile linux-2.6.7-abi/abi/Makefile
1942--- linux-2.6.7/abi/Makefile 1970-01-01 01:00:00.000000000 +0100
1943+++ linux-2.6.7-abi/abi/Makefile 2004-07-22 17:44:20.000000000 +0200
1944@@ -0,0 +1,8 @@
1945+obj-$(CONFIG_ABI) += util/
1946+obj-$(CONFIG_ABI_SVR4) += svr4/
1947+obj-$(CONFIG_ABI_SCO) += sco/ cxenix/
1948+obj-$(CONFIG_ABI_WYSE) += wyse/
1949+obj-$(CONFIG_ABI_UW7) += uw7/
1950+obj-$(CONFIG_ABI_SOLARIS) += solaris/
1951+obj-$(CONFIG_ABI_IBCS) += ibcs/
1952+obj-$(CONFIG_ABI_ISC) += isc/
1953diff -Nru linux-2.6.7/abi/sco/ioctl.c linux-2.6.7-abi/abi/sco/ioctl.c
1954--- linux-2.6.7/abi/sco/ioctl.c 1970-01-01 01:00:00.000000000 +0100
1955+++ linux-2.6.7-abi/abi/sco/ioctl.c 2004-07-22 17:44:20.000000000 +0200
1956@@ -0,0 +1,184 @@
1957+/*
1958+ * ioctl.c - SCO Unix ioctl(2) switch
1959+ *
1960+ * Copyright (C) 1991, 1992 Linus Torvalds
1961+ *
1962+ * Written by Drew Sullivan.
1963+ * Rewritten by Mike Jagdis.
1964+ */
1965+
1966+#ident "%W% %G%"
1967+
1968+#include <linux/config.h>
1969+#include <linux/errno.h>
1970+#include <linux/kernel.h>
1971+#include <linux/ptrace.h>
1972+#include <asm/uaccess.h>
1973+
1974+#include <asm/abi_machdep.h>
1975+#include <abi/sco/ioctl.h>
1976+#include <abi/svr4/ioctl.h>
1977+
1978+
1979+/*
1980+ * do_ioctl() is a meta mapper, that is
1981+ * it looks up the class of the ioctl and then
1982+ * dispatchs to lower level routines to handle the
1983+ * mapping of the actual ioctls
1984+ */
1985+static int
1986+do_ioctl(struct pt_regs *regs, int fd, unsigned long ioctl_num, void *arg)
1987+{
1988+ unsigned int class = ioctl_num >> 8;
1989+ char class_str[4];
1990+
1991+ switch (class) {
1992+
1993+ /*
1994+ * SCO ioctls on the pseudo NFS device probably.
1995+ */
1996+ case 0:
1997+ return abi_ioctl_socksys(fd, ioctl_num, arg);
1998+
1999+ /*
2000+ * SCO console keyboard stuff?
2001+ */
2002+ case 'A':
2003+ return -EINVAL;
2004+
2005+ case 'm':
2006+ return sco_tape_ioctl(fd, ioctl_num, arg);
2007+
2008+ case 't':
2009+ return bsd_ioctl_termios(fd, ioctl_num, arg);
2010+
2011+ case 'f':
2012+ return svr4_fil_ioctl(fd, ioctl_num, arg);
2013+
2014+ /*
2015+ * Xenix ioctl compatibility.
2016+ */
2017+ case 'T':
2018+ return svr4_term_ioctl(fd, ioctl_num & 0xFF, arg);
2019+
2020+ case ('i' << 16) | ('X' << 8): /* iBCS2 POSIX */
2021+ case 'x': /* Pre-iBCS2 POSIX */
2022+ return sco_term_ioctl(fd, ioctl_num & 0xFF, arg);
2023+
2024+ case 'C':
2025+ case 'c':
2026+ return svr4_console_ioctl(fd, ioctl_num, arg);
2027+
2028+ case ('i' << 16) | ('C' << 8): /* iBCS2 POSIX */
2029+ return svr4_video_ioctl(fd, ioctl_num & 0xFF, arg);
2030+
2031+ /*
2032+ * These aren't implemented and are never likely to be as they
2033+ * are specific to drivers for obscure hardware. (For those
2034+ * that don't know they're the JERQ ioctls. Says it all
2035+ * really!)
2036+ */
2037+ case 'j':
2038+ return -EINVAL;
2039+
2040+ /*
2041+ * The 'S' set could also be display mode switch
2042+ * ioctls in a SCO 3.2.x x<4 environment. It should
2043+ * depend on the descriptor they are applied to.
2044+ * According to ISC the Xenix STREAMS ioctls had the
2045+ * high bit set on the command to differentiate them
2046+ * from mode switch ioctls. Yuk, yuk, yuk...
2047+ */
2048+ case 'S':
2049+ return svr4_stream_ioctl(regs, fd, ioctl_num & 0x7F, arg);
2050+
2051+ /*
2052+ * These are STREAMS socket module ioctls.
2053+ */
2054+ case 'I':
2055+#if defined(CONFIG_ABI_XTI)
2056+ return svr4_sockmod_ioctl(fd, ioctl_num & 0xFF, arg);
2057+#else
2058+ return -EINVAL;
2059+#endif
2060+
2061+ /*
2062+ * These are SCO <vtkd.h> ioctls - see vtkd.h
2063+ */
2064+ case 'v':
2065+ case 'K':
2066+ return sco_vtkbd_ioctl(fd, ioctl_num, arg);
2067+
2068+ /*
2069+ * SCO channel mapping. I can't find any documentation
2070+ * for this. These are the LD?MAP ioctls defined in
2071+ * sys/termio.h and sys/emap.h. They are used by mapchan.
2072+ */
2073+ case 'D':
2074+ return -EINVAL;
2075+ }
2076+
2077+ /*
2078+ * If we haven't handled it yet it must be a BSD style ioctl
2079+ * with a (possible) argument description in the high word of
2080+ * the opcode.
2081+ */
2082+ switch (class & 0xff) {
2083+
2084+ /*
2085+ * From SVR4 as specified in sys/iocomm.h.
2086+ */
2087+ case 'f':
2088+ return svr4_fil_ioctl(fd, ioctl_num, arg);
2089+
2090+ /*
2091+ * BSD or V7 terminal ioctls.
2092+ */
2093+ case 't':
2094+ return bsd_ioctl_termios(fd, ioctl_num, arg);
2095+
2096+ /*
2097+ * SVR3 streams based socket TCP/IP ioctls.
2098+ *
2099+ * These are handed over to the standard ioctl
2100+ * handler since /dev/socksys is an emulated device
2101+ * and front ends any sockets created through it.
2102+ * Note that 'S' ioctls without the BSDish argument
2103+ * type in the high bytes are STREAMS ioctls and 'I'
2104+ * ioctls without the BSDish type in the high bytes
2105+ * are the STREAMS socket module ioctls. (see above).
2106+ */
2107+ case 'S':
2108+ case 'R':
2109+ case 'I':
2110+ return abi_ioctl_socksys(fd, ioctl_num, arg);
2111+ }
2112+
2113+ /*
2114+ * If nothing has handled it yet someone may have to do some
2115+ * more work...
2116+ */
2117+ class_str[0] = class & 0xFF0000 ? (char)((class >> 16) & 0xFF) : '.';
2118+ class_str[1] = class & 0x00FF00 ? (char)((class >> 8) & 0xFF) : '.';
2119+ class_str[2] = class & 0x0000FF ? (char)((class ) & 0xFF) : '.';
2120+ class_str[3] = 0;
2121+
2122+ printk(KERN_DEBUG "sco: ioctl(%d, %lx[%s], 0x%p) unsupported\n",
2123+ fd, ioctl_num, class_str, arg);
2124+
2125+ return -EINVAL;
2126+}
2127+
2128+int
2129+sco_ioctl(struct pt_regs *regs)
2130+{
2131+ u_int num;
2132+ int fd;
2133+ caddr_t data;
2134+
2135+ fd = (int)get_syscall_parameter(regs, 0);
2136+ num = (u_int)get_syscall_parameter(regs, 1);
2137+ data = (caddr_t)get_syscall_parameter(regs, 2);
2138+
2139+ return do_ioctl(regs, fd, num, data);
2140+}
2141diff -Nru linux-2.6.7/abi/sco/Makefile linux-2.6.7-abi/abi/sco/Makefile
2142--- linux-2.6.7/abi/sco/Makefile 1970-01-01 01:00:00.000000000 +0100
2143+++ linux-2.6.7-abi/abi/sco/Makefile 2004-07-22 17:44:20.000000000 +0200
2144@@ -0,0 +1,12 @@
2145+
2146+abi-sco-objs := sysent.o misc.o mmap.o ptrace.o secureware.o \
2147+ stat.o statvfs.o
2148+
2149+# various ioctl emulation stuff
2150+abi-sco-objs += ioctl.o termios.o tapeio.o vtkbd.o
2151+
2152+
2153+obj-$(CONFIG_ABI_SCO) += abi-sco.o
2154+
2155+abi-sco.o: $(abi-sco-objs)
2156+ $(LD) -r -o $@ $(abi-sco-objs)
2157diff -Nru linux-2.6.7/abi/sco/misc.c linux-2.6.7-abi/abi/sco/misc.c
2158--- linux-2.6.7/abi/sco/misc.c 1970-01-01 01:00:00.000000000 +0100
2159+++ linux-2.6.7-abi/abi/sco/misc.c 2004-07-22 17:44:20.000000000 +0200
2160@@ -0,0 +1,98 @@
2161+/*
2162+ * Copyright (c) 2001 Christoph Hellwig.
2163+ * All rights reserved.
2164+ *
2165+ * This program is free software; you can redistribute it and/or modify
2166+ * it under the terms of the GNU General Public License as published by
2167+ * the Free Software Foundation; either version 2 of the License, or
2168+ * (at your option) any later version.
2169+ *
2170+ * This program is distributed in the hope that it will be useful,
2171+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2172+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2173+ * GNU General Public License for more details.
2174+ *
2175+ * You should have received a copy of the GNU General Public License
2176+ * along with this program; if not, write to the Free Software
2177+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2178+ */
2179+
2180+#ident "%W% %G%"
2181+
2182+/*
2183+ * Misc SCO syscalls.
2184+ */
2185+#include <linux/errno.h>
2186+#include <linux/sched.h>
2187+#include <linux/file.h>
2188+#include <linux/types.h>
2189+#include <linux/spinlock.h>
2190+#include <linux/stat.h>
2191+#include <linux/syscalls.h>
2192+#include <linux/fs.h>
2193+#include <asm/uaccess.h>
2194+
2195+#include <abi/svr4/sysent.h>
2196+
2197+
2198+int
2199+sco_lseek(int fd, u_long offset, int whence)
2200+{
2201+ int error;
2202+
2203+ error = sys_lseek(fd, offset, whence);
2204+ if (error == -ESPIPE) {
2205+ struct file *fp = fget(fd);
2206+ struct inode *ip;
2207+
2208+ if (fp == NULL)
2209+ goto out;
2210+ ip = fp->f_dentry->d_inode;
2211+ if (ip && (S_ISCHR(ip->i_mode) || S_ISBLK(ip->i_mode)))
2212+ error = 0;
2213+ fput(fp);
2214+ }
2215+out:
2216+ return (error);
2217+}
2218+
2219+int
2220+sco_fcntl(int fd, u_int cmd, u_long arg)
2221+{
2222+ /*
2223+ * This could be SCO's get highest fd open if the fd we
2224+ * are called on is -1 otherwise it could be F_CHKFL.
2225+ */
2226+ if (fd == -1 && cmd == 8) {
2227+ struct files_struct *files = current->files;
2228+ int rval;
2229+
2230+ /* compare to ./fs/open.c: get_unused_fd */
2231+ spin_lock(&files->file_lock);
2232+ rval = find_first_zero_bit(files->open_fds->fds_bits, files->max_fdset);
2233+ spin_unlock(&files->file_lock);
2234+
2235+ return rval;
2236+ }
2237+
2238+ return svr4_fcntl(fd, cmd, arg);
2239+}
2240+
2241+int
2242+sco_sysi86(int cmd, void *arg1, int arg2)
2243+{
2244+ switch (cmd) {
2245+ case 114 /*SI86GETFEATURES*/ :
2246+ /*
2247+ * No, I don't know what these feature flags actually
2248+ * _mean_. This vector just matches SCO OS 5.0.0.
2249+ */
2250+#define OSR5_FEATURES "\001\001\001\001\001\001\001\001\002\001\001\001"
2251+ arg2 = max(arg2, 12);
2252+ if (copy_to_user(arg1, OSR5_FEATURES, arg2))
2253+ return -EFAULT;
2254+ return arg2;
2255+ default:
2256+ return svr4_sysi86(cmd, arg1, arg2);
2257+ }
2258+}
2259diff -Nru linux-2.6.7/abi/sco/mmap.c linux-2.6.7-abi/abi/sco/mmap.c
2260--- linux-2.6.7/abi/sco/mmap.c 1970-01-01 01:00:00.000000000 +0100
2261+++ linux-2.6.7-abi/abi/sco/mmap.c 2004-07-22 17:44:20.000000000 +0200
2262@@ -0,0 +1,65 @@
2263+/*
2264+ * Copyright (c) 2001 Caldera Deutschland GmbH.
2265+ * All rights reserved.
2266+ *
2267+ * This program is free software; you can redistribute it and/or modify
2268+ * it under the terms of the GNU General Public License as published by
2269+ * the Free Software Foundation; either version 2 of the License, or
2270+ * (at your option) any later version.
2271+ *
2272+ * This program is distributed in the hope that it will be useful,
2273+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2274+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2275+ * GNU General Public License for more details.
2276+ *
2277+ * You should have received a copy of the GNU General Public License
2278+ * along with this program; if not, write to the Free Software
2279+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2280+ */
2281+
2282+#ident "%W% %G%"
2283+
2284+/*
2285+ * Support for mmap on SCO OpenServer 5.
2286+ */
2287+#include <linux/mm.h>
2288+#include <linux/errno.h>
2289+#include <linux/file.h>
2290+#include <linux/mman.h>
2291+#include <asm/uaccess.h>
2292+
2293+#include <abi/sco/mman.h>
2294+#include <abi/sco/types.h>
2295+
2296+#include <abi/util/trace.h>
2297+
2298+
2299+int
2300+sco_mmap(u_long addr, size_t len, int prot, int flags, int fd, sco_off_t off)
2301+{
2302+ struct file *file;
2303+ u_long mapaddr;
2304+
2305+ if (flags & SCO_MAP_UNIMPL) {
2306+#if defined(CONFIG_ABI_TRACE)
2307+ abi_trace(ABI_TRACE_UNIMPL,
2308+ "unsupported mmap flags: 0x%x\n", flags & SCO_MAP_UNIMPL);
2309+#endif
2310+ flags &= ~SCO_MAP_UNIMPL;
2311+ }
2312+
2313+ file = fget(fd);
2314+ if (!file)
2315+ return -EBADF;
2316+
2317+ flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
2318+ down_write(&current->mm->mmap_sem);
2319+ mapaddr = do_mmap(file, addr, len, prot, flags | MAP_FIXED, off);
2320+ up_write(&current->mm->mmap_sem);
2321+
2322+ fput(file);
2323+
2324+ if (mapaddr == addr)
2325+ return 0;
2326+ return mapaddr;
2327+}
2328diff -Nru linux-2.6.7/abi/sco/ptrace.c linux-2.6.7-abi/abi/sco/ptrace.c
2329--- linux-2.6.7/abi/sco/ptrace.c 1970-01-01 01:00:00.000000000 +0100
2330+++ linux-2.6.7-abi/abi/sco/ptrace.c 2004-07-22 17:44:20.000000000 +0200
2331@@ -0,0 +1,112 @@
2332+/*
2333+ * ptrace.c - SCO OpenServer ptrace(2) support.
2334+ *
2335+ * Copyright (c) 1995 Mike Jagdis (jaggy@purplet.demon.co.uk)
2336+ */
2337+
2338+#ident "%W% %G%"
2339+
2340+/*
2341+ * This file is nearly identical to abi/wyse/ptrace.c, please keep it in sync.
2342+ */
2343+#include <linux/module.h>
2344+#include <linux/errno.h>
2345+#include <linux/sched.h>
2346+#include <linux/kernel.h>
2347+#include <linux/mm.h>
2348+#include <linux/personality.h>
2349+#include <linux/user.h>
2350+#define __KERNEL_SYSCALLS__
2351+#include <linux/unistd.h>
2352+#include <linux/ptrace.h>
2353+
2354+#include <asm/uaccess.h>
2355+
2356+#include <abi/signal.h>
2357+#include <abi/util/trace.h>
2358+
2359+
2360+#define NREGS 19
2361+#define U(X) ((unsigned long)&((struct user *)0)->X)
2362+
2363+static unsigned long sco_to_linux_reg[NREGS] = {
2364+ U(regs.gs), U(regs.fs), U(regs.es), U(regs.ds),
2365+ U(regs.edi), U(regs.esi),
2366+ U(regs.ebp),
2367+ U(regs.esp /* ESP */),
2368+ U(regs.ebx), U(regs.edx), U(regs.ecx), U(regs.eax),
2369+ U(signal /* Trap */),
2370+ U(reserved /* ERR */),
2371+ U(regs.eip), U(regs.cs), U(regs.eflags),
2372+ U(regs.esp), U(regs.ss)
2373+};
2374+
2375+#if defined(CONFIG_ABI_TRACE)
2376+static const char *regnam[] = {
2377+ "EBX", "ECX", "EDX", "ESI", "EDI", "EBP", "EAX",
2378+ "DS", "ES", "FS", "GS", "ORIG_EAX", "EIP", "CS",
2379+ "EFL", "UESP", "SS"
2380+};
2381+#endif
2382+
2383+int
2384+sco_ptrace(int req, int pid, u_long addr, u_long data)
2385+{
2386+ u_long res;
2387+
2388+ /*
2389+ * Slight variations between iBCS and Linux codes.
2390+ */
2391+ if (req == PTRACE_ATTACH)
2392+ req = 10;
2393+ else if (req == PTRACE_DETACH)
2394+ req = 11;
2395+
2396+ if (req == 3 || req == 6) {
2397+ /* get offset of u_ar0 */
2398+ if (addr == 0x1200)
2399+ return 0x4000;
2400+
2401+ /* remap access to the registers. */
2402+ if ((addr & 0xff00) == 0x4000) { /* Registers */
2403+ addr = (addr & 0xff) >> 2;
2404+ if (addr > NREGS)
2405+ return -EIO;
2406+ addr = sco_to_linux_reg[addr];
2407+ if (addr == -1)
2408+ return -EIO;
2409+ }
2410+ }
2411+
2412+ if (req == 7 && data > 0) {
2413+ if (data > NSIGNALS)
2414+ return -EIO;
2415+ data = current_thread_info()->exec_domain->signal_map[data];
2416+ }
2417+
2418+ if (req == 1 || req == 2 || req == 3) {
2419+ mm_segment_t old_fs = get_fs();
2420+ int error;
2421+
2422+ set_fs(get_ds());
2423+ error = sys_ptrace(req, pid, addr, (long)&res);
2424+ set_fs(old_fs);
2425+
2426+ if (error)
2427+ return (error);
2428+ }
2429+
2430+#if defined(CONFIG_ABI_TRACE)
2431+ if (req == 3 || req == 6) {
2432+ abi_trace(ABI_TRACE_API, "%ld [%s] = 0x%08lx\n",
2433+ addr >> 2, (addr >> 2) < ARRAY_SIZE(regnam) ?
2434+ regnam[addr >> 2] : "???",
2435+ req == 3 ? res : data);
2436+ }
2437+#endif
2438+
2439+ if (req == 1 || req == 2 || req == 3)
2440+ return (res);
2441+
2442+ return sys_ptrace(req, pid, addr, data);
2443+}
2444diff -Nru linux-2.6.7/abi/sco/secureware.c linux-2.6.7-abi/abi/sco/secureware.c
2445--- linux-2.6.7/abi/sco/secureware.c 1970-01-01 01:00:00.000000000 +0100
2446+++ linux-2.6.7-abi/abi/sco/secureware.c 2004-07-22 17:44:20.000000000 +0200
2447@@ -0,0 +1,63 @@
2448+/*
2449+ * Copyright (c) 1994 Mike Jagdis.
2450+ * All rights reserved.
2451+ *
2452+ * This program is free software; you can redistribute it and/or modify
2453+ * it under the terms of the GNU General Public License as published by
2454+ * the Free Software Foundation; either version 2 of the License, or
2455+ * (at your option) any later version.
2456+ *
2457+ * This program is distributed in the hope that it will be useful,
2458+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2459+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2460+ * GNU General Public License for more details.
2461+ *
2462+ * You should have received a copy of the GNU General Public License
2463+ * along with this program; if not, write to the Free Software
2464+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2465+ */
2466+
2467+#ident "%W% %G%"
2468+
2469+#include <linux/errno.h>
2470+#include <linux/kernel.h>
2471+#include <linux/sched.h>
2472+
2473+/*
2474+ * SecureWare, Inc. provided the C2 security subsystem used on SCO Unix.
2475+ * This is not that package. This does not even attempt to emulate
2476+ * that package. This emulates just enough of the "obvious" bits to
2477+ * allow some programs to get a bit further. It is not useful to
2478+ * try to implement C2 security in an emulator. Nor is it particularly
2479+ * useful to run SCO's secure admin programs on Linux anyway...
2480+ */
2481+enum {
2482+ SW_GETLUID = 0x01,
2483+ SW_SETLUID = 0x02,
2484+};
2485+
2486+int
2487+sw_security(int cmd, void *p1, void *p2, void *p3, void *p4, void *p5)
2488+{
2489+ switch (cmd) {
2490+ case SW_GETLUID:
2491+ /*
2492+ * We want the login user id. We don't have it
2493+ * specifically so we'll just use the real uid
2494+ * instead - it should be good enough.
2495+ */
2496+ return (current->uid);
2497+ case SW_SETLUID:
2498+ /*
2499+ * Strictly we should only be able to call setluid()
2500+ * once but we can't enforce that. We have the choice
2501+ * between having it always succeed or always fail.
2502+ * Since setluid() should only ever be invoked by
2503+ * things like login processes we always fail it.
2504+ */
2505+ return -EPERM;
2506+ }
2507+
2508+ printk(KERN_ERR "%s: unsupported security call cmd=%d\n", __FILE__, cmd);
2509+ return -EINVAL;
2510+}
2511diff -Nru linux-2.6.7/abi/sco/stat.c linux-2.6.7-abi/abi/sco/stat.c
2512--- linux-2.6.7/abi/sco/stat.c 1970-01-01 01:00:00.000000000 +0100
2513+++ linux-2.6.7-abi/abi/sco/stat.c 2004-07-22 17:44:20.000000000 +0200
2514@@ -0,0 +1,145 @@
2515+/*
2516+ * Copyright (c) 2001 Caldera Deutschland GmbH.
2517+ * All rights reserved.
2518+ *
2519+ * This program is free software; you can redistribute it and/or modify
2520+ * it under the terms of the GNU General Public License as published by
2521+ * the Free Software Foundation; either version 2 of the License, or
2522+ * (at your option) any later version.
2523+ *
2524+ * This program is distributed in the hope that it will be useful,
2525+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2526+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2527+ * GNU General Public License for more details.
2528+ *
2529+ * You should have received a copy of the GNU General Public License
2530+ * aint32_t with this program; if not, write to the Free Software
2531+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2532+ */
2533+
2534+#ident "%W% %G%"
2535+
2536+/*
2537+ * SCO OpenServer xstat/fxstat/lxstat support.
2538+ */
2539+#include <linux/kernel.h>
2540+#include <linux/fs.h>
2541+#include <linux/sched.h>
2542+#include <linux/file.h>
2543+#include <linux/string.h>
2544+#include <asm/uaccess.h>
2545+
2546+#include <abi/sco/types.h>
2547+#include <abi/sco/stat.h>
2548+#include <abi/svr4/stat.h>
2549+
2550+#include <abi/util/trace.h>
2551+#include <abi/util/stat.h>
2552+
2553+
2554+enum {SVR4_stat = 1, SCO_xstat = 51};
2555+
2556+static int
2557+report_sco_xstat(struct kstat *stp, struct sco_xstat *bufp)
2558+{
2559+ struct sco_xstat buf;
2560+
2561+ memset(&buf, 0, sizeof(struct sco_xstat));
2562+
2563+ buf.st_dev = linux_to_sco_dev_t(stp->dev);
2564+ buf.st_ino = linux_to_sco_ino_t(stp->ino);
2565+ buf.st_mode = stp->mode;
2566+ buf.st_nlink = stp->nlink;
2567+ buf.st_uid = linux_to_sco_uid_t(stp->uid);
2568+ buf.st_gid = linux_to_sco_gid_t(stp->gid);
2569+ buf.st_rdev = linux_to_sco_dev_t(stp->rdev);
2570+
2571+ if (stp->size > MAX_NON_LFS)
2572+ return -EOVERFLOW; /* XXX: what to return for SCO?? */
2573+
2574+ buf.st_size = stp->size;
2575+
2576+ buf.st_atime = stp->atime.tv_sec;
2577+ buf.st_mtime = stp->mtime.tv_sec;
2578+ buf.st_ctime = stp->ctime.tv_sec;
2579+
2580+ buf.st_blksize = stp->blksize;
2581+ buf.st_blocks = stp->blocks;
2582+
2583+ strcpy(buf.st_fstype, "ext2");
2584+
2585+ buf.st_sco_flags = 0; /* 1 if remote */
2586+
2587+ if (copy_to_user(bufp, &buf, sizeof(struct sco_xstat)))
2588+ return -EFAULT;
2589+ return 0;
2590+}
2591+
2592+int
2593+sco_xstat(int vers, char *filename, void *bufp)
2594+{
2595+ struct kstat st;
2596+ int error;
2597+
2598+ error = vfs_stat(filename, &st);
2599+ if (error)
2600+ return error;
2601+
2602+ switch (vers) {
2603+ case SVR4_stat:
2604+ return report_svr4_stat(&st, bufp);
2605+ case SCO_xstat:
2606+ return report_sco_xstat(&st, bufp);
2607+ }
2608+
2609+#if defined(CONFIG_ABI_TRACE)
2610+ abi_trace(ABI_TRACE_API, "xstat version %d not supported\n", vers);
2611+#endif
2612+ return -EINVAL;
2613+}
2614+
2615+int
2616+sco_lxstat(int vers, char *filename, void *bufp)
2617+{
2618+ struct kstat st;
2619+ int error;
2620+
2621+ error = vfs_lstat(filename, &st);
2622+ if (error)
2623+ return error;
2624+
2625+ switch (vers) {
2626+ case SVR4_stat:
2627+ return report_svr4_stat(&st, bufp);
2628+ case SCO_xstat:
2629+ return report_sco_xstat(&st, bufp);
2630+ }
2631+
2632+#if defined(CONFIG_ABI_TRACE)
2633+ abi_trace(ABI_TRACE_API, "lxstat version %d not supported\n", vers);
2634+#endif
2635+ return -EINVAL;
2636+}
2637+
2638+int
2639+sco_fxstat(int vers, int fd, void *bufp)
2640+{
2641+ struct kstat st;
2642+ int error;
2643+
2644+ error = vfs_fstat(fd, &st);
2645+ if (error)
2646+ return error;
2647+
2648+ switch (vers) {
2649+ case SVR4_stat:
2650+ return report_svr4_stat(&st, bufp);
2651+ case SCO_xstat:
2652+ return report_sco_xstat(&st, bufp);
2653+ }
2654+
2655+#if defined(CONFIG_ABI_TRACE)
2656+ abi_trace(ABI_TRACE_API, "fxstat version %d not supported\n", vers);
2657+#endif
2658+ return -EINVAL;
2659+}
2660diff -Nru linux-2.6.7/abi/sco/statvfs.c linux-2.6.7-abi/abi/sco/statvfs.c
2661--- linux-2.6.7/abi/sco/statvfs.c 1970-01-01 01:00:00.000000000 +0100
2662+++ linux-2.6.7-abi/abi/sco/statvfs.c 2004-07-22 17:44:20.000000000 +0200
2663@@ -0,0 +1,115 @@
2664+/*
2665+ * Copyright (c) 2001 Caldera Deutschland GmbH.
2666+ * Copyright (c) 2001 Christoph Hellwig.
2667+ * All rights reserved.
2668+ *
2669+ * This program is free software; you can redistribute it and/or modify
2670+ * it under the terms of the GNU General Public License as published by
2671+ * the Free Software Foundation; either version 2 of the License, or
2672+ * (at your option) any later version.
2673+ *
2674+ * This program is distributed in the hope that it will be useful,
2675+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2676+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2677+ * GNU General Public License for more details.
2678+ *
2679+ * You should have received a copy of the GNU General Public License
2680+ * along with this program; if not, write to the Free Software
2681+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2682+ */
2683+
2684+#ident "%W% %G%"
2685+
2686+/*
2687+ * SCO OpenServer statvfs/fstatvfs support.
2688+ */
2689+#include <linux/kernel.h>
2690+#include <linux/fs.h>
2691+#include <linux/sched.h>
2692+#include <linux/file.h>
2693+#include <linux/string.h>
2694+#include <linux/vfs.h>
2695+#include <linux/mount.h>
2696+#include <linux/namei.h>
2697+#include <asm/uaccess.h>
2698+
2699+#include <abi/sco/types.h>
2700+
2701+
2702+static int
2703+report_statvfs(struct vfsmount *mnt, struct inode *ip, struct sco_statvfs *bufp)
2704+{
2705+ struct sco_statvfs buf;
2706+ struct kstatfs s;
2707+ int error;
2708+
2709+ error = vfs_statfs(mnt->mnt_sb, &s);
2710+ if (error)
2711+ return error;
2712+
2713+ memset(&buf, 0, sizeof(struct sco_statvfs));
2714+
2715+ buf.f_bsize = s.f_bsize;
2716+ buf.f_frsize = s.f_bsize;
2717+ buf.f_blocks = s.f_blocks;
2718+ buf.f_bfree = s.f_bfree;
2719+ buf.f_bavail = s.f_bavail;
2720+ buf.f_files = s.f_files;
2721+ buf.f_free = s.f_ffree;
2722+ buf.f_favail = s.f_ffree; /* SCO addition in the middle! */
2723+ buf.f_sid = ip->i_sb->s_dev;
2724+
2725+ /*
2726+ * Get the name of the filesystem.
2727+ *
2728+ * Sadly, some code "in the wild" actually checks the name
2729+ * against a hard coded list to see if it is a "real" fs or not.
2730+ *
2731+ * I believe Informix Dynamic Server for SCO is one such.
2732+ */
2733+ if (strncmp(ip->i_sb->s_type->name, "ext2", 4) == 0)
2734+ strcpy(buf.f_basetype, "HTFS");
2735+ else
2736+ strcpy(buf.f_basetype, ip->i_sb->s_type->name);
2737+
2738+ /* Check for a few flags statvfs wants but statfs doesn't have. */
2739+ if (IS_RDONLY(ip))
2740+ buf.f_flag |= 1;
2741+ if (mnt->mnt_flags & MNT_NOSUID)
2742+ buf.f_flag |= 2;
2743+
2744+ buf.f_namemax = s.f_namelen;
2745+
2746+ if (copy_to_user(bufp, &buf, sizeof(struct sco_statvfs)))
2747+ return -EFAULT;
2748+ return 0;
2749+}
2750+
2751+int
2752+sco_statvfs(char *filename, struct sco_statvfs *bufp)
2753+{
2754+ struct nameidata nd;
2755+ int error;
2756+
2757+ error = user_path_walk(filename, &nd);
2758+ if (!error) {
2759+ error = report_statvfs(nd.mnt, nd.dentry->d_inode, bufp);
2760+ path_release(&nd);
2761+ }
2762+ return error;
2763+}
2764+
2765+int
2766+sco_fstatvfs(int fd, struct sco_statvfs *bufp)
2767+{
2768+ struct file *fp;
2769+ int error = -EBADF;
2770+
2771+ fp = fget(fd);
2772+ if (fp) {
2773+ error = report_statvfs(fp->f_vfsmnt,
2774+ fp->f_dentry->d_inode, bufp);
2775+ fput(fp);
2776+ }
2777+ return error;
2778+}
2779diff -Nru linux-2.6.7/abi/sco/sysent.c linux-2.6.7-abi/abi/sco/sysent.c
2780--- linux-2.6.7/abi/sco/sysent.c 1970-01-01 01:00:00.000000000 +0100
2781+++ linux-2.6.7-abi/abi/sco/sysent.c 2004-07-22 17:44:20.000000000 +0200
2782@@ -0,0 +1,457 @@
2783+/*
2784+ * Copyright (c) 2001 Christoph Hellwig.
2785+ * All rights reserved.
2786+ *
2787+ * This program is free software; you can redistribute it and/or modify
2788+ * it under the terms of the GNU General Public License as published by
2789+ * the Free Software Foundation; either version 2 of the License, or
2790+ * (at your option) any later version.
2791+ *
2792+ * This program is distributed in the hope that it will be useful,
2793+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2794+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2795+ * GNU General Public License for more details.
2796+ *
2797+ * You should have received a copy of the GNU General Public License
2798+ * along with this program; if not, write to the Free Software
2799+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2800+ */
2801+
2802+#ident "%W% %G%"
2803+
2804+/*
2805+ * SCO Unix 3.x personality switch
2806+ */
2807+#include <linux/kernel.h>
2808+#include <linux/module.h>
2809+#include <linux/init.h>
2810+#include <linux/personality.h>
2811+#include <linux/types.h>
2812+#include <linux/syscalls.h>
2813+#include <linux/socket.h>
2814+#include <linux/net.h>
2815+#include <asm/uaccess.h>
2816+
2817+#include <abi/sco/signal.h>
2818+#include <abi/sco/sysent.h>
2819+#include <abi/svr4/sysent.h>
2820+#include <abi/cxenix/sysent.h>
2821+
2822+#include <abi/signal.h>
2823+
2824+#include <abi/util/errno.h>
2825+#include <abi/util/map.h>
2826+#include <abi/util/sysent.h>
2827+#include <abi/util/socket.h>
2828+
2829+
2830+MODULE_DESCRIPTION("OpenServer/Xenix personality");
2831+MODULE_AUTHOR("Christoph Hellwig, partially taken from iBCS");
2832+MODULE_LICENSE("GPL");
2833+
2834+
2835+static u_char sco_err_table[] = {
2836+/* 0 - 9 */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
2837+/* 10 - 19 */ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
2838+/* 20 - 29 */ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
2839+/* 30 - 39 */ 30, 31, 32, 33, 34, 45, 78, 46, 89, 145,
2840+/* 40 - 49 */ 150, 90, 35, 36, 37, 38, 39, 40, 41, 42,
2841+/* 50 - 59 */ 43, 44, 50, 51, 52, 53, 54, 55, 56, 57,
2842+/* 60 - 69 */ 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
2843+/* 70 - 79 */ 70, 71, 74, 76, 77, 79, 80, 81, 82, 83,
2844+/* 80 - 89 */ 84, 85, 86, 87, 88, 152, 153, 22, 93, 94,
2845+/* 90 - 99 */ 95, 96, 118, 97, 98, 99, 100, 101, 102, 103,
2846+/* 100 - 109 */ 104, 105, 106, 107, 108, 63, 110, 111, 112, 113,
2847+/* 110 - 119 */ 114, 115, 116, 117, 92, 91, 151, 135, 137, 138,
2848+/* 120 - 122 */ 139, 140, 28
2849+};
2850+
2851+/*
2852+ * Map Linux RESTART* values (512,513,514) to EINTR
2853+ */
2854+static u_char lnx_err_table[] = {
2855+/* 512 - 514 */ EINTR, EINTR, EINTR
2856+};
2857+
2858+static struct map_segment sco_err_map[] = {
2859+ { 0, 0+sizeof(sco_err_table)-1, sco_err_table },
2860+ { 512, 512+sizeof(lnx_err_table)-1, lnx_err_table },
2861+ { -1 }
2862+};
2863+
2864+/* XXX: move to signal.h */
2865+#define SCO__SIGSTKFLT SCO_SIGTERM /* Stack fault */
2866+
2867+static long linux_to_sco_signals[NSIGNALS + 1] = {
2868+/* 0 - 3 */ 0, SCO_SIGHUP, SCO_SIGINT, SCO_SIGQUIT,
2869+/* 4 - 7 */ SCO_SIGILL, SCO_SIGTRAP, SCO_SIGABRT, SCO_SIGBUS,
2870+/* 8 - 11 */ SCO_SIGFPE, SCO_SIGKILL, SCO_SIGUSR1, SCO_SIGSEGV,
2871+/* 12 - 15 */ SCO_SIGUSR2, SCO_SIGPIPE, SCO_SIGALRM, SCO_SIGTERM,
2872+/* 16 - 19 */ SCO__SIGSTKFLT, SCO_SIGCLD, SCO_SIGCONT, SCO_SIGSTOP,
2873+/* 20 - 23 */ SCO_SIGTSTP, SCO_SIGTTIN, SCO_SIGTTOU, SCO_SIGURG,
2874+/* 24 - 27 */ SCO_SIGXCPU, SCO_SIGXFSZ, SCO_SIGVTALRM, SCO_SIGPROF,
2875+/* 28 - 31 */ SCO_SIGWINCH, SCO_SIGPOLL, SCO_SIGPWR, SCO_SIGSYS,
2876+/* 32 */ -1
2877+};
2878+
2879+static long linux_to_xenix_signals[NSIGNALS+1] = {
2880+/* 0 - 3 */ 0, IBCS_SIGHUP, IBCS_SIGINT, IBCS_SIGQUIT,
2881+/* 4 - 7 */ IBCS_SIGILL, IBCS_SIGTRAP, IBCS_SIGABRT, -1,
2882+/* 8 - 11 */ IBCS_SIGFPE, IBCS_SIGKILL, IBCS_SIGUSR1, IBCS_SIGSEGV,
2883+/* 12 - 15 */ IBCS_SIGUSR2, IBCS_SIGPIPE, IBCS_SIGALRM, IBCS_SIGTERM,
2884+/* 16 - 19 */ IBCS_SIGSEGV, IBCS_SIGCHLD, IBCS_SIGCONT, IBCS_SIGSTOP,
2885+/* 20 - 23 */ IBCS_SIGTSTP, IBCS_SIGTTIN, IBCS_SIGTTOU, IBCS_SIGUSR1,
2886+/* 24 - 27 */ IBCS_SIGGXCPU, IBCS_SIGGXFSZ, IBCS_SIGVTALRM, IBCS_SIGPROF,
2887+/* 28 - 31 */ IBCS_SIGWINCH, 20 /*SIGIO*/, IBCS_SIGPWR, -1,
2888+/* 32 */ -1
2889+};
2890+
2891+static long sco_to_linux_signals[NSIGNALS+1] = {
2892+/* 0 - 3 */ 0, SIGHUP, SIGINT, SIGQUIT,
2893+/* 4 - 7 */ SIGILL, SIGTRAP, SIGIOT, SIGABRT,
2894+/* 8 - 11 */ SIGFPE, SIGKILL, SIGBUS, SIGSEGV,
2895+/* 12 - 15 */ SIGSYS, SIGPIPE, SIGALRM, SIGTERM,
2896+/* 16 - 19 */ SIGUSR1, SIGUSR2, SIGCHLD, SIGPWR,
2897+/* 20 - 23 */ SIGWINCH, SIGURG, SIGPOLL, SIGSTOP,
2898+/* 24 - 27 */ SIGTSTP, SIGCONT, SIGTTIN, SIGTTOU,
2899+/* 28 - 31 */ SIGVTALRM, SIGPROF, SIGXCPU, SIGXFSZ,
2900+/* 32 */ -1
2901+};
2902+
2903+static long xenix_to_linux_signals[NSIGNALS+1] = {
2904+/* 0 - 3 */ 0, SIGHUP, SIGINT, SIGQUIT,
2905+/* 4 - 7 */ SIGILL, SIGTRAP, SIGIOT, SIGUNUSED,
2906+/* 8 - 11 */ SIGFPE, SIGKILL, SIGUNUSED, SIGSEGV,
2907+/* 12 - 15 */ SIGUNUSED, SIGPIPE, SIGALRM, SIGTERM,
2908+/* 16 - 19 */ SIGUSR1, SIGUSR2, SIGCHLD, SIGPWR,
2909+/* 20 - 23 */ SIGPOLL, -1, -1, -1,
2910+/* 24 - 27 */ -1, -1, -1, -1,
2911+/* 28 - 31 */ -1, -1, -1, -1,
2912+/* 32 */ -1
2913+};
2914+
2915+static char sco_socktype[] = {
2916+ SOCK_STREAM,
2917+ SOCK_DGRAM,
2918+ 0,
2919+ SOCK_RAW,
2920+ SOCK_RDM,
2921+ SOCK_SEQPACKET
2922+};
2923+
2924+static struct map_segment sco_socktype_map[] = {
2925+ { 1, 6, sco_socktype },
2926+ { -1 }
2927+};
2928+
2929+static struct map_segment sco_sockopt_map[] = {
2930+ { 0x0001, 0x0001, (char *)SO_DEBUG },
2931+ { 0x0002, 0x0002, (char *)__SO_ACCEPTCON },
2932+ { 0x0004, 0x0004, (char *)SO_REUSEADDR },
2933+ { 0x0008, 0x0008, (char *)SO_KEEPALIVE },
2934+ { 0x0010, 0x0010, (char *)SO_DONTROUTE },
2935+ { 0x0020, 0x0020, (char *)SO_BROADCAST },
2936+ { 0x0040, 0x0040, (char *)SO_USELOOPBACK },
2937+ { 0x0080, 0x0080, (char *)SO_LINGER },
2938+ { 0x0100, 0x0100, (char *)SO_OOBINLINE },
2939+ { 0x0200, 0x0200, (char *)SO_ORDREL },
2940+ { 0x0400, 0x0400, (char *)SO_IMASOCKET },
2941+ { 0x1001, 0x1001, (char *)SO_SNDBUF },
2942+ { 0x1002, 0x1002, (char *)SO_RCVBUF },
2943+ { 0x1003, 0x1003, (char *)SO_SNDLOWAT },
2944+ { 0x1004, 0x1004, (char *)SO_RCVLOWAT },
2945+ { 0x1005, 0x1005, (char *)SO_SNDTIMEO },
2946+ { 0x1006, 0x1006, (char *)SO_RCVTIMEO },
2947+ { 0x1007, 0x1007, (char *)SO_ERROR },
2948+ { 0x1008, 0x1008, (char *)SO_TYPE },
2949+ { 0x1009, 0x1009, (char *)SO_PROTOTYPE },
2950+ { -1 }
2951+};
2952+
2953+/*
2954+ * The first three entries (AF_UNSPEC, AF_UNIX and AF_INET)
2955+ * are identity mapped. All others aren't available under
2956+ * Linux, nor are Linux's AF_AX25 and AF_IPX available from
2957+ * SCO as far as I know.
2958+ */
2959+static struct map_segment sco_af_map[] = {
2960+ { 0, 2, NULL },
2961+ { -1 }
2962+};
2963+
2964+
2965+static struct sysent sco_syscall_table[] = {
2966+/* 0 */ { abi_syscall, Fast, "syscall", "" },
2967+/* 1 */ { sys_exit, 1, "exit", "d" },
2968+/* 2 */ { abi_fork, Spl, "fork", "" },
2969+/* 3 */ { abi_read, 3, "read", "dpd" },
2970+/* 4 */ { sys_write, 3, "write", "dpd" },
2971+/* 5 */ { svr4_open, 3, "open", "soo" },
2972+/* 6 */ { sys_close, 1, "close", "d" },
2973+/* 7 */ { abi_wait, Spl, "wait", "xxx" },
2974+/* 8 */ { sys_creat, 2, "creat", "so" },
2975+/* 9 */ { sys_link, 2, "link", "ss" },
2976+/* 10 */ { sys_unlink, 1, "unlink", "s" },
2977+/* 11 */ { abi_exec, Spl, "exec", "sxx" },
2978+/* 12 */ { sys_chdir, 1, "chdir", "s" },
2979+/* 13 */ { abi_time, 0, "time", "" },
2980+/* 14 */ { svr4_mknod, 3, "mknod", "soo" },
2981+/* 15 */ { sys_chmod, 2, "chmod", "so" },
2982+/* 16 */ { sys_chown, 3, "chown", "sdd" },
2983+/* 17 */ { abi_brk, 1, "brk/break", "x" },
2984+/* 18 */ { svr4_stat, 2, "stat", "sp" },
2985+/* 19 */ { sco_lseek, 3, "seek/lseek", "ddd" },
2986+/* 20 */ { abi_getpid, Spl, "getpid", "" },
2987+/* 21 */ { 0, Ukn, "mount", "" },
2988+/* 22 */ { sys_umount, 1, "umount", "s" },
2989+/* 23 */ { sys_setuid, 1, "setuid", "d" },
2990+/* 24 */ { abi_getuid, Spl, "getuid", "" },
2991+/* 25 */ { sys_stime, 1, "stime", "d" },
2992+/* 26 */ { sco_ptrace, 4, "ptrace", "xdxx" },
2993+/* 27 */ { sys_alarm, 1, "alarm", "d" },
2994+/* 28 */ { svr4_fstat, 2, "fstat", "dp" },
2995+/* 29 */ { sys_pause, 0, "pause", "" },
2996+/* 30 */ { sys_utime, 2, "utime", "xx" },
2997+/* 31 */ { 0, Ukn, "stty", "" },
2998+/* 32 */ { 0, Ukn, "gtty", "" },
2999+/* 33 */ { sys_access, 2, "access", "so" },
3000+/* 34 */ { sys_nice, 1, "nice", "d" },
3001+/* 35 */ { svr4_statfs, 4, "statfs", "spdd" },
3002+/* 36 */ { sys_sync, 0, "sync", "" },
3003+/* 37 */ { abi_kill, 2, "kill", "dd" },
3004+/* 38 */ { svr4_fstatfs, 4, "fstatfs", "dpdd" },
3005+/* 39 */ { abi_procids, Spl, "procids", "d" },
3006+/* 40 */ { cxenix, Fast, "cxenix", "" },
3007+/* 41 */ { sys_dup, 1, "dup", "d" },
3008+/* 42 */ { abi_pipe, Spl, "pipe", "" },
3009+/* 43 */ { sys_times, 1, "times", "p" },
3010+/* 44 */ { 0 , Ukn, "prof", "" },
3011+/* 45 */ { 0, Ukn, "lock/plock", "" },
3012+/* 46 */ { sys_setgid, 1, "setgid", "d" },
3013+/* 47 */ { abi_getgid, Spl, "getgid", "" },
3014+/* 48 */ { abi_sigfunc, Fast, "sigfunc", "xxx" },
3015+/* 49 */ { svr4_msgsys, Spl, "msgsys", "dxddd" },
3016+/* 50 */ { sco_sysi86, 3, "sysi86/sys3b", "d" },
3017+/* 51 */ { sys_acct, 1, "acct/sysacct", "x" },
3018+/* 52 */ { svr4_shmsys, Fast, "shmsys", "ddxo" },
3019+/* 53 */ { svr4_semsys, Spl, "semsys", "dddx" },
3020+/* 54 */ { sco_ioctl, Spl, "ioctl", "dxx" },
3021+/* 55 */ { 0, 3, "uadmin", "xxx" },
3022+/* 56 */ { 0, Ukn, "?", "" },
3023+/* 57 */ { v7_utsname, 1, "utsys", "x" },
3024+/* 58 */ { sys_fsync, 1, "fsync", "d" },
3025+/* 59 */ { abi_exec, Spl, "execv", "spp" },
3026+/* 60 */ { sys_umask, 1, "umask", "o" },
3027+/* 61 */ { sys_chroot, 1, "chroot", "s" },
3028+/* 62 */ { sco_fcntl, 3, "fcntl", "dxx" },
3029+/* 63 */ { svr4_ulimit, 2, "ulimit", "xx" },
3030+/* 64 */ { 0, Ukn, "?", "" },
3031+/* 65 */ { 0, Ukn, "?", "" },
3032+/* 66 */ { 0, Ukn, "?", "" },
3033+/* 67 */ { 0, Ukn, "?", "" },
3034+/* 68 */ { 0, Ukn, "?", "" },
3035+/* 69 */ { 0, Ukn, "?", "" },
3036+/* 70 */ { 0, Ukn, "advfs", "" },
3037+/* 71 */ { 0, Ukn, "unadvfs", "" },
3038+/* 72 */ { 0, Ukn, "rmount", "" },
3039+/* 73 */ { 0, Ukn, "rumount", "" },
3040+/* 74 */ { 0, Ukn, "rfstart", "" },
3041+/* 75 */ { 0, Ukn, "?", "" },
3042+/* 76 */ { 0, Ukn, "rdebug", "" },
3043+/* 77 */ { 0, Ukn, "rfstop", "" },
3044+/* 78 */ { 0, Ukn, "rfsys", "" },
3045+/* 79 */ { sys_rmdir, 1, "rmdir", "s" },
3046+/* 80 */ { abi_mkdir, 2, "mkdir", "so" },
3047+/* 81 */ { svr4_getdents, 3, "getdents", "dxd" },
3048+/* 82 */ { 0, Ukn, "libattach", "" },
3049+/* 83 */ { 0, Ukn, "libdetach", "" },
3050+/* 84 */ { svr4_sysfs, 3, "sysfs", "dxx" },
3051+/* 85 */ { svr4_getmsg, Spl, "getmsg", "dxxx" },
3052+/* 86 */ { svr4_putmsg, Spl, "putmsg", "dxxd" },
3053+/* 87 */ { sys_poll, 3, "poll", "xdd" },
3054+/* 88 */ { 0, Ukn, "nosys88", "" },
3055+/* 89 */ { sw_security, 6, "security", "dxxxxx"},
3056+/* 90 */ { sys_symlink, 2, "symlink", "ss" },
3057+/* 91 */ { svr4_lstat, 2, "lstat", "sp" },
3058+/* 92 */ { sys_readlink, 3, "readlink", "spd" },
3059+
3060+ /*
3061+ * Ok, this is where the good-old SCO calls end.
3062+ * Everything from here onwards is OSR5-specific.
3063+ *
3064+ * In fact OSR5 documents only the following calls:
3065+ *
3066+ * o readv (121)
3067+ * o writev (122)
3068+ * o xstat (123)
3069+ * o lxstat (124)
3070+ * o fxstat (125)
3071+ * o clocal (127)
3072+ * o gettimeofday (171)
3073+ * o settimeofday (172)
3074+ *
3075+ * Everything else is guesswork (from AVR4/iABI4), even though
3076+ * the OSR5 ELF libs use at least some of those... (e.g. mmap).
3077+ */
3078+
3079+/* 93 */ { 0, Ukn, "?", "" },
3080+/* 94 */ { 0, Ukn, "?", "" },
3081+/* 95 */ { abi_sigprocmask, 3, "sigprocmask", "dxx" },
3082+/* 96 */ { abi_sigsuspend, Spl, "sigsuspend", "x" },
3083+/* 97 */ { 0, 2, "sigaltstack", "xx" },
3084+/* 98 */ { abi_sigaction, 3, "sigaction", "dxx" },
3085+/* 99 */ { svr4_sigpending, 2, "sigpending", "dp" },
3086+/* 100 */ { svr4_context, Spl, "context", "" },
3087+/* 101 */ { 0, Ukn, "evsys", "" },
3088+/* 102 */ { 0, Ukn, "evtrapret", "" },
3089+/* 103 */ { sco_statvfs, 2, "statvfs", "sp" },
3090+/* 104 */ { sco_fstatvfs, 2, "fstatvfs", "dp" },
3091+/* 105 */ { 0, Ukn, "unimp (sysisc)","" },
3092+/* 106 */ { 0, Ukn, "nfssys", "" },
3093+/* 107 */ { 0, 4, "waitid", "ddxd" },
3094+/* 108 */ { 0, 3, "sigsendsys", "ddd" },
3095+/* 109 */ { svr4_hrtsys, Spl, "hrtsys", "xxx" },
3096+/* 110 */ { 0, 3, "acancel", "dxd" },
3097+/* 111 */ { 0, Ukn, "async", "" },
3098+/* 112 */ { 0, Ukn, "priocntlsys", "" },
3099+/* 113 */ { svr4_pathconf, 2, "pathconf", "sd" },
3100+/* 114 */ { sys_mincore, 3, "mincore", "xdx" },
3101+/* 115 */ { sco_mmap, 6, "mmap", "xxxxdx"},
3102+/* 116 */ { sys_mprotect, 3, "mprotect", "xdx" },
3103+/* 117 */ { sys_munmap, 2, "munmap", "xd" },
3104+/* 118 */ { svr4_fpathconf, 2, "fpathconf", "dd" },
3105+/* 119 */ { abi_fork, Spl, "vfork", "" },
3106+/* 120 */ { sys_fchdir, 1, "fchdir", "d" },
3107+/* 121 */ { sys_readv, 3, "readv", "dxd" },
3108+/* 122 */ { sys_writev, 3, "writev", "dxd" },
3109+/* 123 */ { sco_xstat, 3, "xstat", "dsx" },
3110+/* 124 */ { sco_lxstat, 3, "lxstat", "dsx" },
3111+/* 125 */ { sco_fxstat, 3, "fxstat", "ddx" },
3112+/* 126 */ { svr4_xmknod, 4, "xmknod", "dsox" },
3113+/* 127 */ { 0, Ukn, "syslocal", "d" },
3114+/* 128 */ { svr4_getrlimit, 2, "setrlimit", "dx" },
3115+/* 129 */ { svr4_setrlimit, 2, "getrlimit", "dx" },
3116+/* 130 */ { 0, Ukn, "?", "" },
3117+/* 131 */ { 0, Ukn, "?", "" },
3118+/* 132 */ { 0, Ukn, "?", "" },
3119+/* 133 */ { 0, Ukn, "?", "" },
3120+/* 134 */ { 0, Ukn, "?", "" },
3121+/* 135 */ { 0, Ukn, "?", "" },
3122+/* 136 */ { 0, Ukn, "?", "" },
3123+/* 137 */ { 0, Ukn, "?", "" },
3124+/* 138 */ { 0, Ukn, "?", "" },
3125+/* 139 */ { 0, Ukn, "?", "" },
3126+/* 140 */ { socksys_syscall, 1, "socksys", "x" },
3127+/* 141 */ { 0, Ukn, "?", "" },
3128+/* 142 */ { 0, Ukn, "?", "" },
3129+/* 143 */ { 0, Ukn, "?", "" },
3130+
3131+ /*
3132+ * The next three are used when an OSR5 app is launched by
3133+ * a UnixWare libc.
3134+ *
3135+ * These aren't supported by the UW7 personality either, but
3136+ * adding the names here makes the traces look saner.
3137+ */
3138+
3139+/* 144 */ { 0, 2, "uw7-secsys", "dx" },
3140+/* 145 */ { 0, 4, "uw7-filepriv", "sdxd" },
3141+/* 146 */ { 0, 3, "uw7-procpriv", "dxd" },
3142+
3143+/* 147 */ { 0, Ukn, "?", "" },
3144+/* 148 */ { 0, Ukn, "?", "" },
3145+/* 149 */ { 0, Ukn, "?", "" },
3146+/* 150 */ { 0, Ukn, "?", "" },
3147+/* 151 */ { 0, Ukn, "?", "" },
3148+/* 152 */ { 0, Ukn, "?", "" },
3149+/* 153 */ { 0, Ukn, "?", "" },
3150+/* 154 */ { 0, Ukn, "?", "" },
3151+/* 155 */ { 0, Ukn, "?", "" },
3152+/* 156 */ { 0, Ukn, "?", "" },
3153+/* 157 */ { 0, Ukn, "?", "" },
3154+/* 158 */ { 0, Ukn, "?", "" },
3155+/* 159 */ { 0, Ukn, "?", "" },
3156+/* 160 */ { 0, Ukn, "?", "" },
3157+/* 161 */ { 0, Ukn, "?", "" },
3158+/* 162 */ { 0, Ukn, "?", "" },
3159+/* 163 */ { 0, Ukn, "?", "" },
3160+/* 164 */ { 0, Ukn, "?", "" },
3161+/* 165 */ { 0, Ukn, "?", "" },
3162+/* 166 */ { 0, Ukn, "?", "" },
3163+/* 167 */ { 0, Ukn, "?", "" },
3164+/* 168 */ { 0, Ukn, "?", "" },
3165+/* 169 */ { 0, Ukn, "?", "" },
3166+/* 170 */ { 0, Ukn, "?", "" },
3167+/* 171 */ { sys_gettimeofday, 2, "gettimeofday", "xx" },
3168+/* 172 */ { sys_settimeofday, 2, "settimeofday", "xx" },
3169+};
3170+
3171+static void
3172+sco_lcall7(int segment, struct pt_regs *regs)
3173+{
3174+ int sysno = regs->eax & 0xff;
3175+
3176+ if (sysno >= ARRAY_SIZE(sco_syscall_table))
3177+ set_error(regs, iABI_errors(-EINVAL));
3178+ else
3179+ lcall7_dispatch(regs, &sco_syscall_table[sysno], 1);
3180+}
3181+
3182+
3183+static struct exec_domain sco_exec_domain = {
3184+ name: "OpenServer",
3185+ handler: sco_lcall7,
3186+ pers_low: 3 /* PER_SCOSVR3, PER_OSR5 */,
3187+ pers_high: 3 /* PER_SCOSVR3, PER_OSR5 */,
3188+ signal_map: sco_to_linux_signals,
3189+ signal_invmap: linux_to_sco_signals,
3190+ err_map: sco_err_map,
3191+ socktype_map: sco_socktype_map,
3192+ sockopt_map: sco_sockopt_map,
3193+ af_map: sco_af_map,
3194+ module: THIS_MODULE
3195+};
3196+
3197+static struct exec_domain xenix_exec_domain = {
3198+ name: "Xenix",
3199+ handler: sco_lcall7,
3200+ pers_low: 7 /* PER_XENIX */,
3201+ pers_high: 7 /* PER_XENIX */,
3202+ signal_map: xenix_to_linux_signals,
3203+ signal_invmap: linux_to_xenix_signals,
3204+ err_map: sco_err_map,
3205+ socktype_map: sco_socktype_map,
3206+ sockopt_map: sco_sockopt_map,
3207+ af_map: sco_af_map,
3208+ module: THIS_MODULE
3209+};
3210+
3211+
3212+static int __init
3213+sco_module_init(void)
3214+{
3215+ int err;
3216+
3217+ err = register_exec_domain(&sco_exec_domain);
3218+ if (err) {
3219+ return err;
3220+ }
3221+
3222+ err = register_exec_domain(&xenix_exec_domain);
3223+ if (err) {
3224+ unregister_exec_domain(&sco_exec_domain);
3225+ return err;
3226+ }
3227+
3228+ return err;
3229+}
3230+
3231+static void __exit
3232+sco_module_exit(void)
3233+{
3234+ unregister_exec_domain(&xenix_exec_domain);
3235+ unregister_exec_domain(&sco_exec_domain);
3236+}
3237+
3238+module_init(sco_module_init);
3239+module_exit(sco_module_exit);
3240diff -Nru linux-2.6.7/abi/sco/tapeio.c linux-2.6.7-abi/abi/sco/tapeio.c
3241--- linux-2.6.7/abi/sco/tapeio.c 1970-01-01 01:00:00.000000000 +0100
3242+++ linux-2.6.7-abi/abi/sco/tapeio.c 2004-07-22 17:44:20.000000000 +0200
3243@@ -0,0 +1,112 @@
3244+#ident "%W% %G%"
3245+
3246+#include <linux/kernel.h>
3247+#include <linux/mtio.h>
3248+#include <linux/unistd.h>
3249+#include <linux/syscalls.h>
3250+
3251+#include <asm/uaccess.h>
3252+
3253+
3254+int
3255+sco_tape_ioctl(int fd, u_int cmd, caddr_t data)
3256+{
3257+ struct mtop mtop;
3258+ mm_segment_t fs;
3259+ int error;
3260+
3261+ mtop.mt_count = 1;
3262+
3263+ switch (cmd & 0xff) {
3264+ case 1: /* MT_RESET */
3265+ mtop.mt_op = MTRESET;
3266+ break;
3267+
3268+ case 2: /* MT_RETEN */
3269+ mtop.mt_op = MTRETEN;
3270+ break;
3271+
3272+ case 3: /* MT_REWIND */
3273+ mtop.mt_op = MTREW;
3274+ break;
3275+
3276+ case 4: /* MT_ERASE */
3277+ case 23: /* HP_ERASE */
3278+ mtop.mt_op = MTERASE;
3279+ break;
3280+
3281+ case 6: /* MT_RFM */
3282+ mtop.mt_op = MTFSF;
3283+ break;
3284+
3285+ case 7: /* MT_WFM */
3286+ mtop.mt_op = MTWEOF;
3287+ break;
3288+
3289+ case 8: /* MT_LOAD */
3290+ mtop.mt_op = MTLOAD;
3291+ break;
3292+
3293+ case 9: /* MT_UNLOAD */
3294+ mtop.mt_op = MTOFFL;
3295+ break;
3296+
3297+ case 19: /* MT_RSM */
3298+ mtop.mt_op = MTFSS;
3299+ break;
3300+
3301+ case 20: /* MT_WSM */
3302+ mtop.mt_op = MTWSM;
3303+ break;
3304+
3305+ case 21: /* MT_EOD */
3306+ mtop.mt_op = MTEOM;
3307+ break;
3308+
3309+ case 24: /* MT_SETBLK */
3310+ mtop.mt_op = MTSETBLK;
3311+ mtop.mt_count = (int)data;
3312+ break;
3313+
3314+ case 25: /* MT_LOCK */
3315+ mtop.mt_op = MTLOCK;
3316+ break;
3317+
3318+ case 26: /* MT_UNLOCK */
3319+ mtop.mt_op = MTUNLOCK;
3320+ break;
3321+
3322+
3323+#if 0
3324+/*
3325+ The following function codes are just copied from the SCO
3326+ include file.
3327+*/
3328+
3329+ case 0: /* MT_STATUS */
3330+ case 5: /* MT_AMOUNT */
3331+ case 10: /* MT_DSTATUS */
3332+ case 11: /* MT_FORMAT */
3333+ case 12: /* MT_GETHDR */
3334+ case 13: /* MT_PUTHDR */
3335+ case 14: /* MT_GETNEWBB */
3336+ case 15: /* MT_PUTNEWBB */
3337+ case 16: /* MT_GETVTBL */
3338+ case 17: /* MT_PUTVTBL */
3339+ case 18: /* MT_SERVO */
3340+ case 22: /* MT_FORMPART */
3341+ case 38: /* MT_SETANSI */
3342+ case 64: /* MT_REPORT */
3343+#endif
3344+ default:
3345+ printk (KERN_ERR "abi: SCO tape ioctl func=%d arg=%x unsupported\n",
3346+ cmd & 0xff, (int)data);
3347+ return -EINVAL;
3348+ }
3349+
3350+ fs = get_fs();
3351+ set_fs(get_ds());
3352+ error = sys_ioctl(fd, MTIOCTOP, (long)&mtop);
3353+ set_fs(fs);
3354+ return (error);
3355+}
3356diff -Nru linux-2.6.7/abi/sco/termios.c linux-2.6.7-abi/abi/sco/termios.c
3357--- linux-2.6.7/abi/sco/termios.c 1970-01-01 01:00:00.000000000 +0100
3358+++ linux-2.6.7-abi/abi/sco/termios.c 2004-07-22 17:44:20.000000000 +0200
3359@@ -0,0 +1,186 @@
3360+/*
3361+ * Copyright (C) 1991, 1992 Linus Torvalds
3362+ *
3363+ * Written by Drew Sullivan.
3364+ * Rewritten by Mike Jagdis.
3365+ */
3366+
3367+#ident "%W% %G%"
3368+
3369+#include <linux/errno.h>
3370+#include <linux/kernel.h>
3371+#include <linux/termios.h>
3372+#include <linux/unistd.h>
3373+#include <linux/syscalls.h>
3374+#include <asm/uaccess.h>
3375+
3376+#include <abi/svr4/ioctl.h>
3377+#include <abi/svr4/termios.h>
3378+
3379+
3380+#define SCO_NCCS (SVR_NCC+5)
3381+
3382+struct sco_termios {
3383+ u_int16_t c_iflag;
3384+ u_int16_t c_oflag;
3385+ u_int16_t c_cflag;
3386+ u_int16_t c_lflag;
3387+ char c_line;
3388+ u_char c_cc[SCO_NCCS];
3389+ char c_ispeed;
3390+ char c_ospeed;
3391+};
3392+
3393+static int
3394+sco_to_linux_termios(int fd, int op, struct sco_termios *it)
3395+{
3396+ struct termios t;
3397+ mm_segment_t old_fs;
3398+ u_short lflag, r;
3399+ char sco_cc[SCO_NCCS];
3400+ int error;
3401+
3402+ error = verify_area(VERIFY_READ, it, sizeof(struct sco_termios));
3403+ if (error)
3404+ return (error);
3405+
3406+ old_fs = get_fs();
3407+ set_fs(get_ds());
3408+ error = sys_ioctl(fd, TCGETS, (long)&t);
3409+ set_fs(old_fs);
3410+
3411+ if (error)
3412+ return (error);
3413+
3414+ __get_user(t.c_iflag, &it->c_iflag);
3415+ t.c_iflag &= ~0100000; /* DOSMODE */
3416+
3417+ __get_user(t.c_oflag, &it->c_oflag);
3418+
3419+ __get_user(t.c_cflag, &it->c_cflag);
3420+ if (t.c_cflag & 0100000) /* CRTSFL - SCO only? */
3421+ t.c_cflag |= CRTSCTS;
3422+ t.c_cflag &= ~0170000; /* LOBLK|CTSFLOW|RTSFLOW|CRTSFL */
3423+
3424+ lflag = t.c_lflag;
3425+ t.c_lflag &= ~0100777;
3426+ __get_user(r, &it->c_lflag);
3427+ t.c_lflag |= r;
3428+
3429+ if ((t.c_lflag & 0100000))
3430+ sys_ioctl(fd, TIOCEXCL, 0);
3431+ else
3432+ sys_ioctl(fd, TIOCNXCL, 0);
3433+
3434+ t.c_lflag &= ~0100000;
3435+ t.c_lflag |= (t.c_lflag & 0000400) << 7; /* Move IEXTEN */
3436+ t.c_lflag &= ~0000400;
3437+ t.c_lflag |= (t.c_lflag & 0001000) >> 1; /* Move TOSTOP */
3438+ t.c_lflag &= ~0001000;
3439+ t.c_lflag |= (lflag & 0001000); /* Restore ECHOCTL */
3440+
3441+ __get_user(t.c_line, &it->c_line); /* XXX Map this? */
3442+
3443+ copy_from_user(sco_cc, &it->c_cc, SCO_NCCS);
3444+ t.c_cc[0] = sco_cc[0];
3445+ t.c_cc[1] = sco_cc[1];
3446+ t.c_cc[2] = sco_cc[2];
3447+ t.c_cc[3] = sco_cc[3];
3448+ t.c_cc[7] = sco_cc[7];
3449+ t.c_cc[8] = sco_cc[11];
3450+ t.c_cc[9] = sco_cc[12];
3451+ t.c_cc[10] = sco_cc[10];
3452+ t.c_cc[16] = sco_cc[6];
3453+ if (t.c_lflag & ICANON) {
3454+ t.c_cc[4] = sco_cc[4];
3455+ t.c_cc[11] = sco_cc[5];
3456+ } else {
3457+ t.c_cc[4] = sco_cc[8];
3458+ t.c_cc[5] = sco_cc[5];
3459+ t.c_cc[6] = sco_cc[4];
3460+ t.c_cc[11] = sco_cc[9];
3461+ }
3462+
3463+ set_fs(get_ds());
3464+ error = sys_ioctl(fd, op, (long)&t);
3465+ set_fs(old_fs);
3466+
3467+ return (error);
3468+}
3469+
3470+static int
3471+linux_to_sco_termios(int fd, int op, struct sco_termios *it)
3472+{
3473+ struct termios t;
3474+ char sco_cc[SCO_NCCS];
3475+ mm_segment_t old_fs;
3476+ int error;
3477+
3478+ error = verify_area(VERIFY_WRITE, it, sizeof(struct sco_termios));
3479+ if (error)
3480+ return (error);
3481+
3482+ old_fs = get_fs();
3483+ set_fs(get_ds());
3484+ error = sys_ioctl(fd, op, (long)&t);
3485+ set_fs(old_fs);
3486+ if (error)
3487+ return (error);
3488+
3489+ put_user(t.c_iflag & 0017777, &it->c_iflag);
3490+
3491+ put_user(t.c_oflag & 0177777, &it->c_oflag);
3492+
3493+ if (t.c_cflag & CRTSCTS)
3494+ t.c_cflag |= 0100000; /* CRTSFL - SCO only? */
3495+ put_user(t.c_cflag & 0177777, &it->c_cflag);
3496+
3497+ t.c_lflag &= ~0001000;
3498+ t.c_lflag |= (t.c_lflag & 0000400) << 1;
3499+ t.c_lflag &= ~0000400;
3500+ t.c_lflag |= (t.c_lflag & 0100000) >> 7;
3501+ t.c_lflag &= ~0100000;
3502+ put_user(t.c_lflag & 0001777, &it->c_lflag);
3503+
3504+ put_user(t.c_line, &it->c_line); /* XXX Map this? */
3505+
3506+ sco_cc[0] = t.c_cc[0];
3507+ sco_cc[1] = t.c_cc[1];
3508+ sco_cc[2] = t.c_cc[2];
3509+ sco_cc[3] = t.c_cc[3];
3510+ sco_cc[6] = t.c_cc[16];
3511+ sco_cc[7] = t.c_cc[7];
3512+ sco_cc[8] = t.c_cc[4];
3513+ sco_cc[9] = t.c_cc[11];
3514+ sco_cc[10] = t.c_cc[10];
3515+ sco_cc[11] = t.c_cc[8];
3516+ sco_cc[12] = t.c_cc[9];
3517+ if (t.c_lflag & ICANON) {
3518+ sco_cc[4] = t.c_cc[4];
3519+ sco_cc[5] = t.c_cc[11];
3520+ } else {
3521+ sco_cc[4] = t.c_cc[6];
3522+ sco_cc[5] = t.c_cc[5];
3523+ }
3524+
3525+ copy_to_user(&it->c_cc, sco_cc, SCO_NCCS);
3526+
3527+ return (error);
3528+}
3529+
3530+int
3531+sco_term_ioctl(int fd, unsigned int func, void *arg)
3532+{
3533+ switch(func) {
3534+ case 1: /* XCGETA */
3535+ return linux_to_sco_termios(fd, TCGETS, arg);
3536+ case 2: /* XCSETA */
3537+ return sco_to_linux_termios(fd, TCSETS, arg);
3538+ case 3: /* XCSETAW */
3539+ return sco_to_linux_termios(fd, TCSETSW, arg);
3540+ case 4: /* XCSETAF */
3541+ return sco_to_linux_termios(fd, TCSETSF, arg);
3542+ }
3543+ printk(KERN_ERR "iBCS: SCO termios ioctl %d unsupported\n", func);
3544+ return -EINVAL;
3545+}
3546diff -Nru linux-2.6.7/abi/sco/vtkbd.c linux-2.6.7-abi/abi/sco/vtkbd.c
3547--- linux-2.6.7/abi/sco/vtkbd.c 1970-01-01 01:00:00.000000000 +0100
3548+++ linux-2.6.7-abi/abi/sco/vtkbd.c 2004-07-22 17:44:20.000000000 +0200
3549@@ -0,0 +1,88 @@
3550+/*
3551+ * This provides internal emulation support for the SCO <sys/vtkd.h> on
3552+ * the multiscreen console. More or less, this involves translating the
3553+ * input ioctl()'s into a similar Linux ioctl()'s.
3554+ *
3555+ * Not emulated SCO multiscreen functions:
3556+ * None.
3557+ *
3558+ * Not emulated SCO keyboard functions:
3559+ * KIOCDOSMODE set DOSMODE
3560+ * KIOCNONDOSMODE unset DOSMODE
3561+ * KDDISPINFO get display start and size
3562+ * KDGKBSTATE get state of keyboard shift keys
3563+ *
3564+ * Written by Scott Michel, scottm@intime.com
3565+ * (c) 1994 Scott Michel as part of the Linux iBCS-2 emulator project.
3566+ */
3567+
3568+#ident "%W% %G%"
3569+
3570+#include <linux/errno.h>
3571+#include <linux/kernel.h>
3572+#include <linux/vt.h>
3573+#include <linux/kd.h>
3574+#include <linux/syscalls.h>
3575+#include <asm/uaccess.h>
3576+
3577+
3578+static struct {
3579+ int in; /* only lower 8 bits */
3580+ int out; /* Linux version */
3581+} trantab[] = {
3582+#ifdef KDDISPTYPE
3583+ { 1, KDDISPTYPE },
3584+#endif
3585+ { 2, KDMAPDISP },
3586+ { 3, KDUNMAPDISP },
3587+ { 6, KDGKBMODE },
3588+ { 7, KDSKBMODE },
3589+ { 8, KDMKTONE },
3590+ { 9, KDGETMODE },
3591+ { 10, KDSETMODE },
3592+ { 11, KDADDIO },
3593+ { 12, KDDELIO },
3594+ { 60, KDENABIO },
3595+ { 61, KDDISABIO },
3596+#ifdef KIOCINFO
3597+ { 62, KIOCINFO },
3598+#endif
3599+ { 63, KIOCSOUND },
3600+ { 64, KDGKBTYPE },
3601+ { 65, KDGETLED },
3602+ { 66, KDSETLED },
3603+};
3604+
3605+
3606+int
3607+sco_vtkbd_ioctl(int fd, u_int cmd, caddr_t data)
3608+{
3609+ u_int gen = (cmd >> 8) & 0xff;
3610+ u_int spec = cmd & 0xff;
3611+ int newf, i;
3612+
3613+ switch (gen) {
3614+ case 'V':
3615+ /*
3616+ * Could make this translation process table based, but, why
3617+ * waste the valuable kernel space ?
3618+ */
3619+
3620+ newf = (spec == 1 ? VT_OPENQRY :
3621+ (spec == 2 ? VT_SETMODE :
3622+ (spec == 3 ? VT_GETMODE :
3623+ (spec == 4 ? VT_RELDISP :
3624+ (spec == 5 ? VT_ACTIVATE : -1)))));
3625+ if (newf != -1)
3626+ return sys_ioctl(fd, newf, (long)data);
3627+ break;
3628+ case 'K':
3629+ for (i = 0; i < ARRAY_SIZE(trantab); i++) {
3630+ if (spec == trantab[i].in)
3631+ return sys_ioctl(fd, trantab[i].out, (long)data);
3632+ }
3633+ /* FALLTHROUGH */
3634+ }
3635+ printk(KERN_ERR "%s: vtkd ioctl 0x%02x unsupported\n", __FILE__, cmd);
3636+ return -EINVAL;
3637+}
3638diff -Nru linux-2.6.7/abi/solaris/lfs.c linux-2.6.7-abi/abi/solaris/lfs.c
3639--- linux-2.6.7/abi/solaris/lfs.c 1970-01-01 01:00:00.000000000 +0100
3640+++ linux-2.6.7-abi/abi/solaris/lfs.c 2004-07-22 17:44:20.000000000 +0200
3641@@ -0,0 +1,235 @@
3642+/*
3643+ * Solaris Large File Summit support
3644+ */
3645+
3646+#ident "%W% %G%"
3647+
3648+#include <linux/errno.h>
3649+#include <linux/stat.h>
3650+#include <linux/fs.h>
3651+#include <linux/sched.h>
3652+#include <linux/kernel.h>
3653+#include <linux/mm.h>
3654+#include <linux/file.h>
3655+#include <linux/slab.h>
3656+#include <linux/mman.h>
3657+#include <linux/net.h>
3658+#include <linux/socket.h>
3659+#include <linux/un.h>
3660+#include <linux/dirent.h>
3661+#include <linux/syscalls.h>
3662+#include <asm/uaccess.h>
3663+
3664+#include <abi/util/map.h>
3665+#include <abi/svr4/sysent.h>
3666+
3667+
3668+int
3669+sol_open64(const char *fname, int flag, int mode)
3670+{
3671+ u_long args[3];
3672+ int error, fd;
3673+ struct file *file;
3674+ mm_segment_t old_fs;
3675+ char *p;
3676+ struct sockaddr_un addr;
3677+
3678+ fd = sys_open(fname, map_flags(flag, fl_svr4_to_linux) | O_LARGEFILE, mode);
3679+ if (fd < 0)
3680+ return fd;
3681+
3682+ /* Sometimes a program may open a pathname which it expects
3683+ * to be a named pipe (or STREAMS named pipe) when the
3684+ * Linux domain equivalent is a Unix domain socket. (e.g.
3685+ * UnixWare uses a STREAMS named pipe /dev/X/Nserver.0 for
3686+ * X :0 but Linux uses a Unix domain socket /tmp/.X11-unix/X0)
3687+ * It isn't enough just to make the symlink because you cannot
3688+ * open() a socket and read/write it. If we spot the error we can
3689+ * switch to socket(), connect() and things will likely work
3690+ * as expected however.
3691+ */
3692+ file = fget(fd);
3693+ if (!file)
3694+ return fd; /* Huh?!? */
3695+ if (!S_ISSOCK(file->f_dentry->d_inode->i_mode)) {
3696+ fput(file);
3697+ return fd;
3698+ }
3699+ fput(file);
3700+
3701+ sys_close(fd);
3702+ args[0] = AF_UNIX;
3703+ args[1] = SOCK_STREAM;
3704+ args[2] = 0;
3705+ old_fs = get_fs();
3706+ set_fs(get_ds());
3707+ fd = sys_socketcall(SYS_SOCKET, args);
3708+ set_fs(old_fs);
3709+ if (fd < 0)
3710+ return fd;
3711+
3712+ p = getname(fname);
3713+ if (IS_ERR(p)) {
3714+ sys_close(fd);
3715+ return PTR_ERR(p);
3716+ }
3717+ if (strlen(p) >= UNIX_PATH_MAX) {
3718+ putname(p);
3719+ sys_close(fd);
3720+ return -E2BIG;
3721+ }
3722+ addr.sun_family = AF_UNIX;
3723+ strcpy(addr.sun_path, p);
3724+ putname(p);
3725+
3726+ args[0] = fd;
3727+ args[1] = (int)&addr;
3728+ args[2] = sizeof(struct sockaddr_un);
3729+ set_fs(get_ds());
3730+ error = sys_socketcall(SYS_CONNECT, args);
3731+ set_fs(old_fs);
3732+ if (error) {
3733+ sys_close(fd);
3734+ return error;
3735+ }
3736+
3737+ return fd;
3738+}
3739+
3740+
3741+struct sol_dirent64 {
3742+ unsigned long long d_ino;
3743+ unsigned long long d_off;
3744+ unsigned short d_reclen;
3745+ char d_name[1];
3746+};
3747+
3748+
3749+/* If/when the readdir function is changed to read multiple entries
3750+ * at once this should be updated to take advantage of the fact.
3751+ *
3752+ * N.B. For Linux the reclen in a dirent is the number of characters
3753+ * in the filename, for SCO (at least) reclen is the total size of
3754+ * the particular dirent rounded up to the next multiple of 4. The SCO
3755+ * behaviour is faithfully emulated here.
3756+ *
3757+ * XXXX
3758+ * We don't truncate long filenames at all when copying. If we meet a
3759+ * long filename and the buffer supplied by the application simply isn't
3760+ * big enough to hold it we'll return without filling the buffer (i.e
3761+ * return 0). The application will see this as a (premature) end of
3762+ * directory. Is there a work around for this at all???
3763+ */
3764+int
3765+sol_getdents64(int fd, char *buf, int nbytes)
3766+{
3767+ int error, here, posn, reclen;
3768+ struct file *file;
3769+ struct old_linux_dirent *d;
3770+ mm_segment_t old_fs;
3771+
3772+ error = verify_area(VERIFY_WRITE, buf, nbytes);
3773+ if (error)
3774+ return error;
3775+
3776+ /* Check the file handle here. This is so we can access the current
3777+ * position in the file structure safely without a tedious call
3778+ * to sys_lseek that does nothing useful.
3779+ */
3780+ file = fget(fd);
3781+ if (!file)
3782+ return -EBADF;
3783+
3784+ d = (struct old_linux_dirent *)__get_free_page(GFP_KERNEL);
3785+ if (!d) {
3786+ fput(file);
3787+ return -ENOMEM;
3788+ }
3789+
3790+ error = posn = reclen = 0;
3791+ while (posn + reclen < nbytes) {
3792+ int string_size;
3793+ struct sol_dirent64 tmpbuf;
3794+ /* Save the current position and get another dirent */
3795+ here = file->f_pos;
3796+ old_fs = get_fs();
3797+ set_fs (get_ds());
3798+ error = old_readdir(fd, d, 1);
3799+ set_fs(old_fs);
3800+ if (error <= 0)
3801+ break;
3802+
3803+ /* If it'll fit in the buffer save it.
3804+ * Otherwise back up so it is read next time around.
3805+ * Oh, if we're at the beginning of the buffer there's
3806+ * no chance that this entry will ever fit so don't
3807+ * copy it and don't back off - we'll just pretend it
3808+ * isn't here...
3809+ */
3810+ string_size = d->d_namlen + 1; /* chars in d_name + trailing zero */
3811+ reclen = (sizeof(long long) /* d_ino */
3812+ + sizeof(long long) /* d_offset */
3813+ + sizeof(unsigned short) /* d_namlen */
3814+ + string_size
3815+ + 3) & (~3); /* align to a 4 byte boundary */
3816+ if (posn + reclen <= nbytes) {
3817+ tmpbuf.d_off = file->f_pos;
3818+ tmpbuf.d_ino = d->d_ino;
3819+ tmpbuf.d_off = file->f_pos;
3820+ tmpbuf.d_reclen = reclen;
3821+ copy_to_user(buf+posn, &tmpbuf,
3822+ sizeof(struct sol_dirent64) -1);
3823+ copy_to_user(buf+posn+sizeof(struct sol_dirent64)-2,
3824+ &d->d_name, string_size);
3825+ posn += reclen;
3826+ } else if (posn) {
3827+ sys_lseek(fd, here, 0);
3828+ } /* else posn == 0 */
3829+ }
3830+
3831+ /* Loose the intermediate buffer. */
3832+ free_page((unsigned long)d);
3833+
3834+ fput(file);
3835+
3836+ /* If we've put something in the buffer return the byte count
3837+ * otherwise return the error status.
3838+ */
3839+ return ((posn > 0) ? posn : error);
3840+}
3841+
3842+
3843+int
3844+sol_mmap64(u_int addr, u_int len, int prot, int flags,
3845+ int fd, u_int off_hi, u_int off)
3846+{
3847+ loff_t off64 = (off | ((loff_t)off_hi << 32));
3848+ u_long pgoff = (off64 >> PAGE_SHIFT);
3849+ struct file *file = NULL;
3850+ int error;
3851+
3852+ if ((off64 + PAGE_ALIGN(len)) < off64)
3853+ return -EINVAL;
3854+
3855+ if (!(off64 & ~PAGE_MASK))
3856+ return -EINVAL;
3857+
3858+ flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
3859+ if (!(flags & MAP_ANONYMOUS)) {
3860+ if (!(file = fget(fd)))
3861+ return -EBADF;
3862+ }
3863+
3864+ if (!(flags & 0x80000000) && addr)
3865+ flags |= MAP_FIXED;
3866+ else
3867+ flags &= 0x7fffffff;
3868+
3869+ down_write(&current->mm->mmap_sem);
3870+ error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
3871+ up_write(&current->mm->mmap_sem);
3872+
3873+ if (file)
3874+ fput(file);
3875+ return (error);
3876+}
3877diff -Nru linux-2.6.7/abi/solaris/Makefile linux-2.6.7-abi/abi/solaris/Makefile
3878--- linux-2.6.7/abi/solaris/Makefile 1970-01-01 01:00:00.000000000 +0100
3879+++ linux-2.6.7-abi/abi/solaris/Makefile 2004-07-22 17:44:20.000000000 +0200
3880@@ -0,0 +1,7 @@
3881+
3882+abi-solaris-objs:= lfs.o solarisx86.o socket.o stat.o sysent.o
3883+
3884+obj-$(CONFIG_ABI_SOLARIS) += abi-solaris.o
3885+
3886+abi-solaris.o: $(abi-solaris-objs)
3887+ $(LD) -r -o $@ $(abi-solaris-objs)
3888diff -Nru linux-2.6.7/abi/solaris/socket.c linux-2.6.7-abi/abi/solaris/socket.c
3889--- linux-2.6.7/abi/solaris/socket.c 1970-01-01 01:00:00.000000000 +0100
3890+++ linux-2.6.7-abi/abi/solaris/socket.c 2004-07-22 17:44:20.000000000 +0200
3891@@ -0,0 +1,496 @@
3892+/*
3893+ * socket.c: Socket syscall emulation for Solaris 2.6+
3894+ *
3895+ * Copyright (C) 1998 Jakub Jelinek (jj@ultra.linux.cz)
3896+ *
3897+ * 1999-08-19 Fixed socketpair code
3898+ * Jason Rappleye (rappleye@ccr.buffalo.edu)
3899+ */
3900+
3901+#ident "%W% %G%"
3902+
3903+#include <linux/types.h>
3904+#include <linux/sched.h>
3905+#include <linux/smp_lock.h>
3906+#include <linux/mm.h>
3907+#include <linux/slab.h>
3908+#include <linux/net.h>
3909+#include <linux/socket.h>
3910+#include <linux/file.h>
3911+#include <linux/syscalls.h>
3912+
3913+#include <asm/uaccess.h>
3914+#include <asm/string.h>
3915+
3916+#define SOCK_SOL_STREAM 2
3917+#define SOCK_SOL_DGRAM 1
3918+#define SOCK_SOL_RAW 4
3919+#define SOCK_SOL_RDM 5
3920+#define SOCK_SOL_SEQPACKET 6
3921+
3922+#define SOL_SO_SNDLOWAT 0x1003
3923+#define SOL_SO_RCVLOWAT 0x1004
3924+#define SOL_SO_SNDTIMEO 0x1005
3925+#define SOL_SO_RCVTIMEO 0x1006
3926+#define SOL_SO_STATE 0x2000
3927+
3928+#define SOL_SS_NDELAY 0x040
3929+#define SOL_SS_NONBLOCK 0x080
3930+#define SOL_SS_ASYNC 0x100
3931+
3932+#define SO_STATE 0x000e
3933+
3934+
3935+/*
3936+ * 64 bit vs 32bit issues.
3937+ */
3938+#if BITS_PER_LONG == 32
3939+# define sys32_getsockopt sys_getsockopt
3940+# define A(ptr) ((void *)(ptr))
3941+# define __kernel_size_t32 __kernel_size_t
3942+#endif
3943+
3944+
3945+int sunos_setsockopt(int fd, int level, int optname, u32 optval,
3946+ int optlen)
3947+{
3948+ int tr_opt = optname;
3949+ int ret;
3950+
3951+ if (level == SOL_IP) {
3952+ /* Multicast socketopts (ttl, membership) */
3953+ if (tr_opt >=2 && tr_opt <= 6)
3954+ tr_opt += 30;
3955+ }
3956+ ret = sys_setsockopt(fd, level, tr_opt, (char *)A(optval), optlen);
3957+ return ret;
3958+}
3959+
3960+int sunos_getsockopt(int fd, int level, int optname,
3961+ u32 optval, u32 optlen)
3962+{
3963+ int tr_opt = optname;
3964+ int ret;
3965+
3966+ if (level == SOL_IP) {
3967+ /* Multicast socketopts (ttl, membership) */
3968+ if (tr_opt >=2 && tr_opt <= 6)
3969+ tr_opt += 30;
3970+ }
3971+ ret = sys32_getsockopt(fd, level, tr_opt, (char *)optval, (int *)optlen);
3972+ return ret;
3973+}
3974+
3975+static int socket_check(int family, int type)
3976+{
3977+ if (family != PF_UNIX && family != PF_INET)
3978+ return -ESOCKTNOSUPPORT;
3979+ switch (type) {
3980+ case SOCK_SOL_STREAM:
3981+ type = SOCK_STREAM;
3982+ break;
3983+ case SOCK_SOL_DGRAM:
3984+ type = SOCK_DGRAM;
3985+ break;
3986+ case SOCK_SOL_RAW:
3987+ type = SOCK_RAW;
3988+ break;
3989+ case SOCK_SOL_RDM:
3990+ type = SOCK_RDM;
3991+ break;
3992+ case SOCK_SOL_SEQPACKET:
3993+ type = SOCK_SEQPACKET;
3994+ break;
3995+ default:
3996+ return -EINVAL;
3997+ }
3998+ return type;
3999+}
4000+
4001+static int solaris_to_linux_sockopt(int optname)
4002+{
4003+ switch (optname) {
4004+ case SOL_SO_SNDLOWAT:
4005+ optname = SO_SNDLOWAT;
4006+ break;
4007+ case SOL_SO_RCVLOWAT:
4008+ optname = SO_RCVLOWAT;
4009+ break;
4010+ case SOL_SO_SNDTIMEO:
4011+ optname = SO_SNDTIMEO;
4012+ break;
4013+ case SOL_SO_RCVTIMEO:
4014+ optname = SO_RCVTIMEO;
4015+ break;
4016+ case SOL_SO_STATE:
4017+ optname = SO_STATE;
4018+ break;
4019+ };
4020+
4021+ return optname;
4022+}
4023+
4024+int solaris_socket(int family, int type, int protocol)
4025+{
4026+ type = socket_check (family, type);
4027+ if (type < 0)
4028+ return type;
4029+ return sys_socket(family, type, protocol);
4030+}
4031+
4032+int solaris_socketpair(int *usockvec)
4033+{
4034+ /* solaris socketpair really only takes one arg at the syscall
4035+ * level, int * usockvec. The libs apparently take care of
4036+ * making sure that family==AF_UNIX and type==SOCK_STREAM. The
4037+ * pointer we really want ends up residing in the first (and
4038+ * supposedly only) argument.
4039+ */
4040+
4041+ return sys_socketpair(AF_UNIX, SOCK_STREAM, 0, (int *)usockvec);
4042+}
4043+
4044+int solaris_bind(int fd, struct sockaddr *addr, int addrlen)
4045+{
4046+ return sys_bind(fd, addr, addrlen);
4047+}
4048+
4049+int solaris_setsockopt(int fd, int level, int optname, u32 optval, int optlen)
4050+{
4051+ optname = solaris_to_linux_sockopt(optname);
4052+ if (optname < 0)
4053+ return optname;
4054+ if (optname == SO_STATE)
4055+ return 0;
4056+
4057+ return sunos_setsockopt(fd, level, optname, optval, optlen);
4058+}
4059+
4060+int solaris_getsockopt(int fd, int level, int optname, u32 optval, u32 optlen)
4061+{
4062+ optname = solaris_to_linux_sockopt(optname);
4063+ if (optname < 0)
4064+ return optname;
4065+
4066+ if (optname == SO_STATE)
4067+ optname = SOL_SO_STATE;
4068+
4069+ return sunos_getsockopt(fd, level, optname, optval, optlen);
4070+}
4071+
4072+int solaris_connect(int fd, struct sockaddr *addr, int addrlen)
4073+{
4074+ return sys_connect(fd, addr, addrlen);
4075+}
4076+
4077+int solaris_accept(int fd, struct sockaddr *addr, int *addrlen)
4078+{
4079+ return sys_accept(fd, addr, addrlen);
4080+}
4081+
4082+int solaris_listen(int fd, int backlog)
4083+{
4084+ return sys_listen(fd, backlog);
4085+}
4086+
4087+int solaris_shutdown(int fd, int how)
4088+{
4089+ return sys_shutdown(fd, how);
4090+}
4091+
4092+#define MSG_SOL_OOB 0x1
4093+#define MSG_SOL_PEEK 0x2
4094+#define MSG_SOL_DONTROUTE 0x4
4095+#define MSG_SOL_EOR 0x8
4096+#define MSG_SOL_CTRUNC 0x10
4097+#define MSG_SOL_TRUNC 0x20
4098+#define MSG_SOL_WAITALL 0x40
4099+#define MSG_SOL_DONTWAIT 0x80
4100+
4101+static int solaris_to_linux_msgflags(int flags)
4102+{
4103+ int fl = flags & (MSG_OOB|MSG_PEEK|MSG_DONTROUTE);
4104+
4105+ if (flags & MSG_SOL_EOR) fl |= MSG_EOR;
4106+ if (flags & MSG_SOL_CTRUNC) fl |= MSG_CTRUNC;
4107+ if (flags & MSG_SOL_TRUNC) fl |= MSG_TRUNC;
4108+ if (flags & MSG_SOL_WAITALL) fl |= MSG_WAITALL;
4109+ if (flags & MSG_SOL_DONTWAIT) fl |= MSG_DONTWAIT;
4110+ return fl;
4111+}
4112+
4113+static int linux_to_solaris_msgflags(int flags)
4114+{
4115+ int fl = flags & (MSG_OOB|MSG_PEEK|MSG_DONTROUTE);
4116+
4117+ if (flags & MSG_EOR) fl |= MSG_SOL_EOR;
4118+ if (flags & MSG_CTRUNC) fl |= MSG_SOL_CTRUNC;
4119+ if (flags & MSG_TRUNC) fl |= MSG_SOL_TRUNC;
4120+ if (flags & MSG_WAITALL) fl |= MSG_SOL_WAITALL;
4121+ if (flags & MSG_DONTWAIT) fl |= MSG_SOL_DONTWAIT;
4122+ return fl;
4123+}
4124+
4125+int solaris_recvfrom(int s, char *buf, int len, int flags, u32 from, u32 fromlen)
4126+{
4127+ return sys_recvfrom(s, buf, len, solaris_to_linux_msgflags(flags), (struct sockaddr *)A(from), (int *)A(fromlen));
4128+}
4129+
4130+int solaris_recv(int s, char *buf, int len, int flags)
4131+{
4132+ return sys_recvfrom(s, buf, len, solaris_to_linux_msgflags(flags), NULL, NULL);
4133+}
4134+
4135+int solaris_sendto(int s, char *buf, int len, int flags, u32 to, u32 tolen)
4136+{
4137+ return sys_sendto(s, buf, len, solaris_to_linux_msgflags(flags), (struct sockaddr *)A(to), (int)A(tolen));
4138+}
4139+
4140+int solaris_send(int s, char *buf, int len, int flags)
4141+{
4142+ return sys_sendto(s, buf, len, solaris_to_linux_msgflags(flags), NULL, 0);
4143+}
4144+
4145+int solaris_getpeername(int fd, struct sockaddr *addr, int *addrlen)
4146+{
4147+ return sys_getpeername(fd, addr, addrlen);
4148+}
4149+
4150+int solaris_getsockname(int fd, struct sockaddr *addr, int *addrlen)
4151+{
4152+ return sys_getsockname(fd, addr, addrlen);
4153+}
4154+
4155+/* XXX This really belongs in some header file... -DaveM */
4156+#define MAX_SOCK_ADDR 128 /* 108 for Unix domain -
4157+ 16 for IP, 16 for IPX,
4158+ 24 for IPv6,
4159+ about 80 for AX.25 */
4160+
4161+struct sol_nmsghdr {
4162+ u32 msg_name;
4163+ int msg_namelen;
4164+ u32 msg_iov;
4165+ u32 msg_iovlen;
4166+ u32 msg_control;
4167+ u32 msg_controllen;
4168+ u32 msg_flags;
4169+};
4170+
4171+struct sol_cmsghdr {
4172+ u32 cmsg_len;
4173+ int cmsg_level;
4174+ int cmsg_type;
4175+ unsigned char cmsg_data[0];
4176+};
4177+
4178+struct iovec32 {
4179+ u32 iov_base;
4180+ u32 iov_len;
4181+};
4182+
4183+static inline int iov_from_user32_to_kern(struct iovec *kiov,
4184+ struct iovec32 *uiov32,
4185+ int niov)
4186+{
4187+ int tot_len = 0;
4188+
4189+ while(niov > 0) {
4190+ u32 len, buf;
4191+
4192+ if(get_user(len, &uiov32->iov_len) ||
4193+ get_user(buf, &uiov32->iov_base)) {
4194+ tot_len = -EFAULT;
4195+ break;
4196+ }
4197+ tot_len += len;
4198+ kiov->iov_base = (void *)A(buf);
4199+ kiov->iov_len = (__kernel_size_t) len;
4200+ uiov32++;
4201+ kiov++;
4202+ niov--;
4203+ }
4204+ return tot_len;
4205+}
4206+
4207+static inline int msghdr_from_user32_to_kern(struct msghdr *kmsg,
4208+ struct sol_nmsghdr *umsg)
4209+{
4210+ u32 tmp1, tmp2, tmp3;
4211+ int err;
4212+
4213+ err = get_user(tmp1, &umsg->msg_name);
4214+ err |= __get_user(tmp2, &umsg->msg_iov);
4215+ err |= __get_user(tmp3, &umsg->msg_control);
4216+ if (err)
4217+ return -EFAULT;
4218+
4219+ kmsg->msg_name = (void *)A(tmp1);
4220+ kmsg->msg_iov = (struct iovec *)A(tmp2);
4221+ kmsg->msg_control = (void *)A(tmp3);
4222+
4223+ err = get_user(kmsg->msg_namelen, &umsg->msg_namelen);
4224+ err |= get_user(kmsg->msg_controllen, &umsg->msg_controllen);
4225+ err |= get_user(kmsg->msg_flags, &umsg->msg_flags);
4226+
4227+ kmsg->msg_flags = solaris_to_linux_msgflags(kmsg->msg_flags);
4228+
4229+ return err;
4230+}
4231+
4232+/* I've named the args so it is easy to tell whose space the pointers are in. */
4233+static int verify_iovec32(struct msghdr *kern_msg, struct iovec *kern_iov,
4234+ char *kern_address, int mode)
4235+{
4236+ int tot_len;
4237+
4238+ if(kern_msg->msg_namelen) {
4239+ if(mode==VERIFY_READ) {
4240+ int err = move_addr_to_kernel(kern_msg->msg_name,
4241+ kern_msg->msg_namelen,
4242+ kern_address);
4243+ if(err < 0)
4244+ return err;
4245+ }
4246+ kern_msg->msg_name = kern_address;
4247+ } else
4248+ kern_msg->msg_name = NULL;
4249+
4250+ if(kern_msg->msg_iovlen > UIO_FASTIOV) {
4251+ kern_iov = kmalloc(kern_msg->msg_iovlen * sizeof(struct iovec),
4252+ GFP_KERNEL);
4253+ if(!kern_iov)
4254+ return -ENOMEM;
4255+ }
4256+
4257+ tot_len = iov_from_user32_to_kern(kern_iov,
4258+ (struct iovec32 *)kern_msg->msg_iov,
4259+ kern_msg->msg_iovlen);
4260+ if(tot_len >= 0)
4261+ kern_msg->msg_iov = kern_iov;
4262+ else if(kern_msg->msg_iovlen > UIO_FASTIOV)
4263+ kfree(kern_iov);
4264+
4265+ return tot_len;
4266+}
4267+
4268+int solaris_sendmsg(int fd, struct sol_nmsghdr *user_msg, unsigned user_flags)
4269+{
4270+ struct socket *sock;
4271+ char address[MAX_SOCK_ADDR];
4272+ struct iovec iov[UIO_FASTIOV];
4273+ unsigned char ctl[sizeof(struct cmsghdr) + 20];
4274+ unsigned char *ctl_buf = ctl;
4275+ struct msghdr kern_msg;
4276+ int err, total_len;
4277+
4278+ if(msghdr_from_user32_to_kern(&kern_msg, user_msg))
4279+ return -EFAULT;
4280+ if(kern_msg.msg_iovlen > UIO_MAXIOV)
4281+ return -EINVAL;
4282+ err = verify_iovec32(&kern_msg, iov, address, VERIFY_READ);
4283+ if (err < 0)
4284+ goto out;
4285+ total_len = err;
4286+
4287+ if(kern_msg.msg_controllen) {
4288+ struct sol_cmsghdr *ucmsg = (struct sol_cmsghdr *)kern_msg.msg_control;
4289+ unsigned long *kcmsg;
4290+ __kernel_size_t32 cmlen;
4291+
4292+ if(kern_msg.msg_controllen > sizeof(ctl) &&
4293+ kern_msg.msg_controllen <= 256) {
4294+ err = -ENOBUFS;
4295+ ctl_buf = kmalloc(kern_msg.msg_controllen, GFP_KERNEL);
4296+ if(!ctl_buf)
4297+ goto out_freeiov;
4298+ }
4299+ __get_user(cmlen, &ucmsg->cmsg_len);
4300+ kcmsg = (unsigned long *) ctl_buf;
4301+ *kcmsg++ = (unsigned long)cmlen;
4302+ err = -EFAULT;
4303+ if(copy_from_user(kcmsg, &ucmsg->cmsg_level,
4304+ kern_msg.msg_controllen - sizeof(__kernel_size_t32)))
4305+ goto out_freectl;
4306+ kern_msg.msg_control = ctl_buf;
4307+ }
4308+ kern_msg.msg_flags = solaris_to_linux_msgflags(user_flags);
4309+
4310+ lock_kernel();
4311+ sock = sockfd_lookup(fd, &err);
4312+ if (sock != NULL) {
4313+ if (sock->file->f_flags & O_NONBLOCK)
4314+ kern_msg.msg_flags |= MSG_DONTWAIT;
4315+ err = sock_sendmsg(sock, &kern_msg, total_len);
4316+ sockfd_put(sock);
4317+ }
4318+ unlock_kernel();
4319+
4320+out_freectl:
4321+ /* N.B. Use kfree here, as kern_msg.msg_controllen might change? */
4322+ if(ctl_buf != ctl)
4323+ kfree(ctl_buf);
4324+out_freeiov:
4325+ if(kern_msg.msg_iov != iov)
4326+ kfree(kern_msg.msg_iov);
4327+out:
4328+ return err;
4329+}
4330+
4331+int solaris_recvmsg(int fd, struct sol_nmsghdr *user_msg, unsigned user_flags)
4332+{
4333+ struct iovec iovstack[UIO_FASTIOV];
4334+ struct msghdr kern_msg;
4335+ char addr[MAX_SOCK_ADDR];
4336+ struct socket *sock;
4337+ struct iovec *iov = iovstack;
4338+ struct sockaddr *uaddr;
4339+ int *uaddr_len;
4340+ unsigned long cmsg_ptr;
4341+ int err, total_len, len = 0;
4342+
4343+ if(msghdr_from_user32_to_kern(&kern_msg, user_msg))
4344+ return -EFAULT;
4345+ if(kern_msg.msg_iovlen > UIO_MAXIOV)
4346+ return -EINVAL;
4347+
4348+ uaddr = kern_msg.msg_name;
4349+ uaddr_len = &user_msg->msg_namelen;
4350+ err = verify_iovec32(&kern_msg, iov, addr, VERIFY_WRITE);
4351+ if (err < 0)
4352+ goto out;
4353+ total_len = err;
4354+
4355+ cmsg_ptr = (unsigned long) kern_msg.msg_control;
4356+ kern_msg.msg_flags = 0;
4357+
4358+ lock_kernel();
4359+ sock = sockfd_lookup(fd, &err);
4360+ if (sock != NULL) {
4361+ if (sock->file->f_flags & O_NONBLOCK)
4362+ user_flags |= MSG_DONTWAIT;
4363+ err = sock_recvmsg(sock, &kern_msg, total_len, user_flags);
4364+ if(err >= 0)
4365+ len = err;
4366+ sockfd_put(sock);
4367+ }
4368+ unlock_kernel();
4369+
4370+ if(uaddr != NULL && err >= 0)
4371+ err = move_addr_to_user(addr, kern_msg.msg_namelen, uaddr, uaddr_len);
4372+ if(err >= 0) {
4373+ err = __put_user(linux_to_solaris_msgflags(kern_msg.msg_flags), &user_msg->msg_flags);
4374+ if(!err) {
4375+ /* XXX Convert cmsg back into userspace 32-bit format... */
4376+ err = __put_user((unsigned long)kern_msg.msg_control - cmsg_ptr,
4377+ &user_msg->msg_controllen);
4378+ }
4379+ }
4380+
4381+ if(kern_msg.msg_iov != iov)
4382+ kfree(kern_msg.msg_iov);
4383+out:
4384+ if(err < 0)
4385+ return err;
4386+ return len;
4387+}
4388diff -Nru linux-2.6.7/abi/solaris/solarisx86.c linux-2.6.7-abi/abi/solaris/solarisx86.c
4389--- linux-2.6.7/abi/solaris/solarisx86.c 1970-01-01 01:00:00.000000000 +0100
4390+++ linux-2.6.7-abi/abi/solaris/solarisx86.c 2004-07-22 17:44:20.000000000 +0200
4391@@ -0,0 +1,84 @@
4392+
4393+#include <linux/types.h>
4394+#include <linux/kernel.h>
4395+#include <linux/sched.h>
4396+#include <linux/socket.h>
4397+#include <linux/file.h>
4398+#include <linux/mm.h>
4399+#include <linux/syscalls.h>
4400+#include <asm/uaccess.h>
4401+
4402+#include <abi/svr4/sigset.h>
4403+
4404+
4405+int sol_llseek(struct pt_regs * regs)
4406+{
4407+ unsigned int fd;
4408+ unsigned long offset_high, offset_low;
4409+ unsigned origin;
4410+ long long res;
4411+ unsigned int rvalue;
4412+ mm_segment_t old_fs;
4413+ struct inode *inode;
4414+ struct file *file;
4415+ get_user(fd, ((unsigned int *)regs->esp)+1);
4416+ get_user(offset_low, ((unsigned long *)regs->esp)+2);
4417+ get_user(offset_high, ((unsigned long *)regs->esp)+3);
4418+ get_user(origin, ((unsigned int *)regs->esp)+4);
4419+
4420+ old_fs = get_fs();
4421+ set_fs(get_ds());
4422+ rvalue = sys_llseek(fd,offset_high,offset_low,&res,origin);
4423+ set_fs(old_fs);
4424+
4425+ if ( rvalue < -ENOIOCTLCMD) {
4426+ regs->edx = (res >> 32);
4427+ rvalue = (res & 0xffffffff);
4428+ }
4429+ else if (rvalue == -ESPIPE) {
4430+ /* Solaris allows you to seek on a pipe */
4431+ file = fget(fd);
4432+ if (file) {
4433+ inode = file->f_dentry->d_inode;
4434+ if (inode && (S_ISCHR(inode->i_mode)
4435+ || S_ISBLK(inode->i_mode))) {
4436+ rvalue = 0;
4437+ regs->edx = 0;
4438+ }
4439+ fput(file);
4440+ }
4441+ }
4442+
4443+ return rvalue;
4444+}
4445+
4446+int sol_memcntl(unsigned addr, unsigned len, int cmd, unsigned arg,
4447+ int attr, int mask)
4448+{
4449+ // printk("ibcs_memcntl being ignored\n");
4450+ return 0;
4451+}
4452+
4453+
4454+enum {
4455+ GETACL = 1,
4456+ SETACL = 2,
4457+ GETACLCNT = 3
4458+};
4459+
4460+int sol_acl(char *pathp, int cmd, int nentries, void *aclbufp)
4461+{
4462+ switch (cmd) {
4463+ case GETACLCNT:
4464+ return 0;
4465+
4466+ case GETACL:
4467+ return -EIO;
4468+
4469+ case SETACL:
4470+ return -EPERM;
4471+
4472+ default:
4473+ return -EINVAL;
4474+ }
4475+}
4476diff -Nru linux-2.6.7/abi/solaris/stat.c linux-2.6.7-abi/abi/solaris/stat.c
4477--- linux-2.6.7/abi/solaris/stat.c 1970-01-01 01:00:00.000000000 +0100
4478+++ linux-2.6.7-abi/abi/solaris/stat.c 2004-07-22 17:44:20.000000000 +0200
4479@@ -0,0 +1,104 @@
4480+/*
4481+ * Copyright (c) 2001 Christoph Hellwig.
4482+ * All rights reserved.
4483+ *
4484+ * This program is free software; you can redistribute it and/or modify
4485+ * it under the terms of the GNU General Public License as published by
4486+ * the Free Software Foundation; either version 2 of the License, or
4487+ * (at your option) any later version.
4488+ *
4489+ * This program is distributed in the hope that it will be useful,
4490+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4491+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4492+ * GNU General Public License for more details.
4493+ *
4494+ * You should have received a copy of the GNU General Public License
4495+ * aint32_t with this program; if not, write to the Free Software
4496+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
4497+ */
4498+
4499+#ident "%W% %G%"
4500+
4501+/*
4502+ * Solaris 2 stat64 & friends support.
4503+ */
4504+#include <linux/kernel.h>
4505+#include <linux/fs.h>
4506+#include <linux/sched.h>
4507+#include <linux/file.h>
4508+#include <linux/string.h>
4509+#include <asm/uaccess.h>
4510+
4511+#include <abi/solaris/types.h>
4512+#include <abi/solaris/stat.h>
4513+
4514+#include <abi/util/trace.h>
4515+#include <abi/util/stat.h>
4516+
4517+
4518+int
4519+report_sol_stat64(struct kstat *stp, struct sol_stat64 *bufp)
4520+{
4521+ struct sol_stat64 buf;
4522+
4523+ memset(&buf, 0, sizeof(struct sol_stat64));
4524+
4525+
4526+ buf.st_dev = linux_to_sol_dev_t(stp->dev);
4527+ buf.st_ino = linux_to_sol_ino_t(stp->ino);
4528+ buf.st_mode = stp->mode;
4529+ buf.st_nlink = stp->nlink;
4530+ buf.st_uid = linux_to_sol_uid_t(stp->uid);
4531+ buf.st_gid = linux_to_sol_gid_t(stp->gid);
4532+ buf.st_rdev = linux_to_sol_dev_t(stp->rdev);
4533+ buf.st_size = stp->size;
4534+
4535+ buf.st_atime = stp->atime.tv_sec;
4536+ buf.st_mtime = stp->mtime.tv_sec;
4537+ buf.st_ctime = stp->ctime.tv_sec;
4538+
4539+ buf.st_blksize = stp->blksize;
4540+ buf.st_blocks = stp->blocks;
4541+
4542+ strcpy(buf.st_fstype, "ext2");
4543+
4544+ if (copy_to_user(bufp, &buf, sizeof(struct sol_stat64)))
4545+ return -EFAULT;
4546+ return 0;
4547+}
4548+
4549+int
4550+sol_stat64(char *filename, struct sol_stat64 *bufp)
4551+{
4552+ struct kstat st;
4553+ int error;
4554+
4555+ error = vfs_stat(filename, &st);
4556+ if (!error)
4557+ error = report_sol_stat64(&st, bufp);
4558+ return error;
4559+}
4560+
4561+int
4562+sol_lstat64(char *filename, struct sol_stat64 *bufp)
4563+{
4564+ struct kstat st;
4565+ int error;
4566+
4567+ error = vfs_lstat(filename, &st);
4568+ if (!error)
4569+ error = report_sol_stat64(&st, bufp);
4570+ return error;
4571+}
4572+
4573+int
4574+sol_fstat64(int fd, struct sol_stat64 *bufp)
4575+{
4576+ struct kstat st;
4577+ int error;
4578+
4579+ error = vfs_fstat(fd, &st);
4580+ if (!error)
4581+ error = report_sol_stat64(&st, bufp);
4582+ return error;
4583+}
4584diff -Nru linux-2.6.7/abi/solaris/sysent.c linux-2.6.7-abi/abi/solaris/sysent.c
4585--- linux-2.6.7/abi/solaris/sysent.c 1970-01-01 01:00:00.000000000 +0100
4586+++ linux-2.6.7-abi/abi/solaris/sysent.c 2004-07-22 17:44:20.000000000 +0200
4587@@ -0,0 +1,461 @@
4588+/*
4589+ * Copyright (c) 2001 Christoph Hellwig.
4590+ * All rights reserved.
4591+ *
4592+ * This program is free software; you can redistribute it and/or modify
4593+ * it under the terms of the GNU General Public License as published by
4594+ * the Free Software Foundation; either version 2 of the License, or
4595+ * (at your option) any later version.
4596+ *
4597+ * This program is distributed in the hope that it will be useful,
4598+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4599+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4600+ * GNU General Public License for more details.
4601+ *
4602+ * You should have received a copy of the GNU General Public License
4603+ * along with this program; if not, write to the Free Software
4604+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
4605+ */
4606+
4607+#ident "%W% %G%"
4608+
4609+/*
4610+ * Solaris sysent and error tables.
4611+ */
4612+#include <linux/config.h>
4613+#include <linux/kernel.h>
4614+#include <linux/module.h>
4615+#include <linux/init.h>
4616+#include <linux/personality.h>
4617+#include <linux/syscalls.h>
4618+#include <linux/socket.h>
4619+#include <linux/net.h>
4620+#include <asm/uaccess.h>
4621+
4622+#include <abi/signal.h>
4623+
4624+#include <abi/svr4/sysent.h>
4625+#include <abi/solaris/sysent.h>
4626+#include <abi/util/socket.h>
4627+
4628+#include <abi/util/errno.h>
4629+#include <abi/util/sysent.h>
4630+
4631+/* kernel module specifications */
4632+#ifndef EXPORT_NO_SYMBOLS
4633+#define EXPORT_NO_SYMBOLS
4634+#endif
4635+
4636+MODULE_DESCRIPTION("Solaris personality");
4637+MODULE_AUTHOR("Christoph Hellwig, partially taken from iBCS");
4638+MODULE_LICENSE("GPL");
4639+
4640+EXPORT_NO_SYMBOLS;
4641+
4642+
4643+/* XXX kill this one */
4644+#define ITR(trace, name, args) ,name,args
4645+
4646+
4647+/*
4648+ * We could remove some of the long identity mapped runs but at the
4649+ * expense of extra comparisons for each mapping at run time...
4650+ */
4651+static u_char solaris_err_table[] = {
4652+/* 0 - 9 */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
4653+/* 10 - 19 */ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
4654+/* 20 - 29 */ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
4655+/* 30 - 39 */ 30, 31, 32, 33, 34, 45, 78, 46, 89, 93,
4656+/* 40 - 49 */ 90, 90, 35, 36, 37, 38, 39, 40, 41, 42,
4657+/* 50 - 59 */ 43, 44, 50, 51, 52, 53, 54, 55, 56, 57,
4658+/* 60 - 69 */ 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
4659+/* 70 - 79 */ 70, 71, 74, 76, 77, 79, 80, 81, 82, 83,
4660+/* 80 - 89 */ 84, 85, 86, 87, 88, 91, 92, 94, 95, 96,
4661+/* 90 - 99 */ 97, 98, 99, 120, 121, 122, 123, 124, 125, 126,
4662+/* 100 - 109 */ 127, 128, 129, 130, 131, 132, 133, 134, 143, 144,
4663+/* 110 - 119 */ 145, 146, 147, 148, 149, 150, 22, 135, 137, 138,
4664+/* 120 - 122 */ 139, 140, 28
4665+};
4666+
4667+/*
4668+ * Map Linux RESTART* values (512,513,514) to EINTR
4669+ */
4670+static u_char lnx_err_table[] = {
4671+/* 512 - 514 */ EINTR, EINTR, EINTR
4672+};
4673+
4674+struct map_segment solaris_err_map[] = {
4675+ { 0, 0+sizeof(solaris_err_table)-1, solaris_err_table },
4676+ { 512, 512+sizeof(lnx_err_table)-1, lnx_err_table },
4677+ { -1 }
4678+};
4679+
4680+static long linux_to_solaris_signals[NSIGNALS+1] = {
4681+/* 0 - 3 */ 0, IBCS_SIGHUP, IBCS_SIGINT, IBCS_SIGQUIT,
4682+/* 4 - 7 */ IBCS_SIGILL, IBCS_SIGTRAP, IBCS_SIGABRT, -1,
4683+/* 8 - 11 */ IBCS_SIGFPE, IBCS_SIGKILL, IBCS_SIGUSR1, IBCS_SIGSEGV,
4684+/* 12 - 15 */ IBCS_SIGUSR2, IBCS_SIGPIPE, IBCS_SIGALRM, IBCS_SIGTERM,
4685+/* 16 - 19 */ IBCS_SIGSEGV, IBCS_SIGCHLD, IBCS_SIGCONT, IBCS_SIGSTOP,
4686+/* 20 - 23 */ IBCS_SIGTSTP, IBCS_SIGTTIN, IBCS_SIGTTOU, IBCS_SIGURG,
4687+/* 24 - 27 */ IBCS_SIGGXCPU, IBCS_SIGGXFSZ, IBCS_SIGVTALRM, IBCS_SIGPROF,
4688+/* 28 - 31 */ IBCS_SIGWINCH, IBCS_SIGIO, IBCS_SIGPWR, -1,
4689+/* 32 */ -1
4690+};
4691+
4692+static long solaris_to_linux_signals[NSIGNALS+1] = {
4693+/* 0 - 3 */ 0, SIGHUP, SIGINT, SIGQUIT,
4694+/* 4 - 7 */ SIGILL, SIGTRAP, SIGIOT, SIGUNUSED,
4695+/* 8 - 11 */ SIGFPE, SIGKILL, SIGUNUSED, SIGSEGV,
4696+/* 12 - 15 */ SIGUNUSED, SIGPIPE, SIGALRM, SIGTERM,
4697+/* 16 - 19 */ SIGUSR1, SIGUSR2, SIGCHLD, SIGPWR,
4698+/* 20 - 23 */ SIGWINCH, SIGURG, SIGPOLL, SIGSTOP,
4699+/* 24 - 27 */ SIGTSTP, SIGCONT, SIGTTIN, SIGTTOU,
4700+/* 28 - 31 */ SIGVTALRM, SIGPROF, SIGXCPU, SIGXFSZ,
4701+/* 32 */ -1
4702+};
4703+
4704+static char solaris_socktype[] = {
4705+ SOCK_STREAM,
4706+ SOCK_DGRAM,
4707+ 0,
4708+ SOCK_RAW,
4709+ SOCK_RDM,
4710+ SOCK_SEQPACKET
4711+};
4712+
4713+static struct map_segment solaris_socktype_map[] = {
4714+ { 1, 6, solaris_socktype },
4715+ { -1 }
4716+};
4717+
4718+static struct map_segment solaris_sockopt_map[] = {
4719+ { 0x0001, 0x0001, (char *)SO_DEBUG },
4720+ { 0x0002, 0x0002, (char *)__SO_ACCEPTCON },
4721+ { 0x0004, 0x0004, (char *)SO_REUSEADDR },
4722+ { 0x0008, 0x0008, (char *)SO_KEEPALIVE },
4723+ { 0x0010, 0x0010, (char *)SO_DONTROUTE },
4724+ { 0x0020, 0x0020, (char *)SO_BROADCAST },
4725+ { 0x0040, 0x0040, (char *)SO_USELOOPBACK },
4726+ { 0x0080, 0x0080, (char *)SO_LINGER },
4727+ { 0x0100, 0x0100, (char *)SO_OOBINLINE },
4728+ { 0x0200, 0x0200, (char *)SO_ORDREL },
4729+ { 0x0400, 0x0400, (char *)SO_IMASOCKET },
4730+ { 0x1001, 0x1001, (char *)SO_SNDBUF },
4731+ { 0x1002, 0x1002, (char *)SO_RCVBUF },
4732+ { 0x1003, 0x1003, (char *)SO_SNDLOWAT },
4733+ { 0x1004, 0x1004, (char *)SO_RCVLOWAT },
4734+ { 0x1005, 0x1005, (char *)SO_SNDTIMEO },
4735+ { 0x1006, 0x1006, (char *)SO_RCVTIMEO },
4736+ { 0x1007, 0x1007, (char *)SO_ERROR },
4737+ { 0x1008, 0x1008, (char *)SO_TYPE },
4738+ { 0x1009, 0x1009, (char *)SO_PROTOTYPE },
4739+ { -1 }
4740+};
4741+
4742+static struct map_segment solaris_af_map[] = {
4743+ { 0, 2, NULL },
4744+ { -1 }
4745+};
4746+
4747+
4748+static struct sysent solaris_syscall_table[] = {
4749+ { abi_syscall, Fast ITR(0, "syscall", "") }, /* 0 */
4750+ { sys_exit, 1 ITR(0, "exit", "d") }, /* 1 */
4751+ { abi_fork, Spl ITR(0, "fork", "") }, /* 2 */
4752+ { abi_read, 3 ITR(0, "read", "dpd") }, /* 3 */
4753+ { sys_write, 3 ITR(0, "write", "dpd") }, /* 4 */
4754+ { svr4_open, 3 ITR(0, "open", "soo") }, /* 5 */
4755+ { sys_close, 1 ITR(0, "close", "d") }, /* 6 */
4756+ { abi_wait, Spl ITR(0, "wait", "xxx") }, /* 7 */
4757+ { sys_creat, 2 ITR(0, "creat", "so") }, /* 8 */
4758+ { sys_link, 2 ITR(0, "link", "ss") }, /* 9 */
4759+ { sys_unlink, 1 ITR(0, "unlink", "s") }, /* 10 */
4760+ { abi_exec, Spl ITR(0, "exec", "sxx") }, /* 11 */
4761+ { sys_chdir, 1 ITR(0, "chdir", "s") }, /* 12 */
4762+ { abi_time, 0 ITR(0, "time", "") }, /* 13 */
4763+ { svr4_mknod, 3 ITR(0, "mknod", "soo") }, /* 14 */
4764+ { sys_chmod, 2 ITR(0, "chmod", "so") }, /* 15 */
4765+ { sys_chown, 3 ITR(0, "chown", "sdd") }, /* 16 */
4766+ { abi_brk, 1 ITR(0, "brk/break", "x") }, /* 17 */
4767+ { svr4_stat, 2 ITR(0, "stat", "sp") }, /* 18 */
4768+ { sys_lseek, 3 ITR(0, "seek/lseek", "ddd") }, /* 19 */
4769+ { abi_getpid, Spl ITR(0, "getpid", "") }, /* 20 */
4770+ { 0, Ukn ITR(1, "mount", "") }, /* 21 */
4771+ { sys_umount, 1 ITR(0, "umount", "s") }, /* 22 */
4772+ { sys_setuid, 1 ITR(0, "setuid", "d") }, /* 23 */
4773+ { abi_getuid, Spl ITR(0, "getuid", "") }, /* 24 */
4774+ { sys_stime, 1 ITR(0, "stime", "d") }, /* 25 */
4775+ { 0, Ukn ITR(0, "ptrace", "") }, /* 26 */
4776+ { sys_alarm, 1 ITR(0, "alarm", "d") }, /* 27 */
4777+ { svr4_fstat, 2 ITR(0, "fstat", "dp") }, /* 28 */
4778+ { sys_pause, 0 ITR(0, "pause", "") }, /* 29 */
4779+ { sys_utime, 2 ITR(0, "utime", "xx") }, /* 30 */
4780+ { 0, Ukn ITR(0, "stty", "") }, /* 31 */
4781+ { 0, Ukn ITR(1, "gtty", "") }, /* 32 */
4782+ { sys_access, 2 ITR(0, "access", "so") }, /* 33 */
4783+ { sys_nice, 1 ITR(0, "nice", "d") }, /* 34 */
4784+ { svr4_statfs, 4 ITR(0, "statfs", "spdd") }, /* 35 */
4785+ { sys_sync, 0 ITR(0, "sync", "") }, /* 36 */
4786+ { abi_kill, 2 ITR(0, "kill", "dd") }, /* 37 */
4787+ { svr4_fstatfs, 4 ITR(0, "fstatfs", "dpdd") }, /* 38 */
4788+ { abi_procids, Spl ITR(0, "procids", "d") }, /* 39 */
4789+ { 0, Ukn ITR(0, "cxenix", "") }, /* 40 */
4790+ { sys_dup, 1 ITR(0, "dup", "d") }, /* 41 */
4791+ { abi_pipe, Spl ITR(0, "pipe", "") }, /* 42 */
4792+ { sys_times, 1 ITR(0, "times", "p") }, /* 43 */
4793+ { 0, 0 ITR(0, "prof", "") }, /* 44 */
4794+ { 0, Ukn ITR(1, "lock/plock", "") }, /* 45 */
4795+ { sys_setgid, 1 ITR(0, "setgid", "d") }, /* 46 */
4796+ { abi_getgid, Spl ITR(0, "getgid", "") }, /* 47 */
4797+ { abi_sigfunc, Fast ITR(0, "sigfunc", "xxx") }, /* 48 */
4798+ { svr4_msgsys, Spl ITR(0, "msgsys", "dxddd")}, /* 49 */
4799+ { svr4_sysi86, 3 ITR(0, "sysi86/sys3b", "d") }, /* 50 */
4800+ { sys_acct, 1 ITR(0, "acct/sysacct", "x") }, /* 51 */
4801+ { svr4_shmsys, Fast ITR(0, "shmsys", "ddxo")}, /* 52 */
4802+ { svr4_semsys, Spl ITR(0, "semsys", "dddx")}, /* 53 */
4803+ { svr4_ioctl, Spl ITR(0, "ioctl", "dxx") }, /* 54 */
4804+ { 0, 3 ITR(0, "uadmin", "xxx") }, /* 55 */
4805+ { 0, Ukn ITR(1, "?", "") }, /* 56 */
4806+ { v7_utsname, 1 ITR(0, "utsys", "x") }, /* 57 */
4807+ { sys_fsync, 1 ITR(0, "fsync", "d") }, /* 58 */
4808+ { abi_exec, Spl ITR(0, "execv", "spp") }, /* 59 */
4809+ { sys_umask, 1 ITR(0, "umask", "o") }, /* 60 */
4810+ { sys_chroot, 1 ITR(0, "chroot", "s") }, /* 61 */
4811+ { svr4_fcntl, 3 ITR(0, "fcntl", "dxx") }, /* 62 */
4812+ { svr4_ulimit, 2 ITR(0, "ulimit", "xx") }, /* 63 */
4813+ { 0, Ukn ITR(1, "?", "") }, /* 64 */
4814+ { 0, Ukn ITR(1, "?", "") }, /* 65 */
4815+ { 0, Ukn ITR(1, "?", "") }, /* 66 */
4816+ { 0, Ukn ITR(1, "?", "") }, /* 67 */
4817+ { 0, Ukn ITR(1, "?", "") }, /* 68 */
4818+ { 0, Ukn ITR(1, "?", "") }, /* 69 */
4819+ { 0, Ukn ITR(1, "advfs", "") }, /* 70 */
4820+ { 0, Ukn ITR(1, "unadvfs", "") }, /* 71 */
4821+ { 0, Ukn ITR(1, "rmount", "") }, /* 72 */
4822+ { 0, Ukn ITR(1, "rumount", "") }, /* 73 */
4823+ { 0, Ukn ITR(1, "rfstart", "") }, /* 74 */
4824+ { 0, Ukn ITR(1, "?", "") }, /* 75 */
4825+ { 0, Ukn ITR(1, "rdebug", "") }, /* 76 */
4826+ { 0, Ukn ITR(1, "rfstop", "") }, /* 77 */
4827+ { 0, Ukn ITR(1, "rfsys", "") }, /* 78 */
4828+ { sys_rmdir, 1 ITR(0, "rmdir", "s") }, /* 79 */
4829+ { abi_mkdir, 2 ITR(0, "mkdir", "so") }, /* 80 */
4830+ { svr4_getdents, 3 ITR(0, "getdents", "dxd") }, /* 81 */
4831+ { 0, Ukn ITR(1, "libattach", "") }, /* 82 */
4832+ { 0, Ukn ITR(1, "libdetach", "") }, /* 83 */
4833+ { svr4_sysfs, 3 ITR(0, "sysfs", "dxx") }, /* 84 */
4834+ { svr4_getmsg, Spl ITR(0, "getmsg", "dxxx") }, /* 85 */
4835+ { svr4_putmsg, Spl ITR(0, "putmsg", "dxxd") }, /* 86 */
4836+ { sys_poll, 3 ITR(0, "poll", "xdd") }, /* 87 */
4837+ { svr4_lstat, 2 ITR(0, "lstat", "sp") }, /* 88 */
4838+ { sys_symlink, 2 ITR(0, "symlink", "ss") }, /* 89 */
4839+ { sys_readlink, 3 ITR(0, "readlink", "spd") }, /* 90 */
4840+ { sys_setgroups, 2 ITR(0, "setgroups", "dp") }, /* 91 */
4841+ { sys_getgroups, 2 ITR(0, "getgroups", "dp") }, /* 92 */
4842+ { sys_fchmod, 2 ITR(0, "fchmod", "do") }, /* 93 */
4843+ { sys_fchown, 3 ITR(0, "fchown", "ddd") }, /* 94 */
4844+ { abi_sigprocmask, 3 ITR(0, "sigprocmask", "dxx") }, /* 95 */
4845+ { abi_sigsuspend, Spl ITR(0, "sigsuspend", "x") }, /* 96 */
4846+ { 0, 2 ITR(1, "sigaltstack", "xx") }, /* 97 */
4847+ { abi_sigaction, 3 ITR(0, "sigaction", "dxx") }, /* 98 */
4848+ { svr4_sigpending, 2 ITR(1, "sigpending", "dp") }, /* 99 */
4849+ { svr4_context, Spl ITR(0, "context", "") }, /* 100 */
4850+ { 0, Ukn ITR(1, "evsys", "") }, /* 101 */
4851+ { 0, Ukn ITR(1, "evtrapret", "") }, /* 102 */
4852+ { svr4_statvfs, 2 ITR(0, "statvfs", "sp") }, /* 103 */
4853+ { svr4_fstatvfs, 2 ITR(0, "fstatvfs", "dp") }, /* 104 */
4854+ { 0, Ukn ITR(0, "sysisc", "") }, /* 105 */
4855+ { 0, Ukn ITR(1, "nfssys", "") }, /* 106 */
4856+ { 0, 4 ITR(0, "waitid", "ddxd") }, /* 107 */
4857+ { 0, 3 ITR(1, "sigsendsys", "ddd") }, /* 108 */
4858+ { svr4_hrtsys, Spl ITR(0, "hrtsys", "xxx") }, /* 109 */
4859+ { 0, 3 ITR(1, "acancel", "dxd") }, /* 110 */
4860+ { 0, Ukn ITR(1, "async", "") }, /* 111 */
4861+ { 0, Ukn ITR(1, "priocntlsys", "") }, /* 112 */
4862+ { svr4_pathconf, 2 ITR(1, "pathconf", "sd") }, /* 113 */
4863+ { 0, 3 ITR(1, "mincore", "xdx") }, /* 114 */
4864+ { svr4_mmap, 6 ITR(0, "mmap", "xxxxdx") },/* 115 */
4865+ { sys_mprotect, 3 ITR(0, "mprotect", "xdx") },/* 116 */
4866+ { sys_munmap, 2 ITR(0, "munmap", "xd") },/* 117 */
4867+ { svr4_fpathconf, 2 ITR(1, "fpathconf", "dd") }, /* 118 */
4868+ { abi_fork, Spl ITR(0, "vfork", "") }, /* 119 */
4869+ { sys_fchdir, 1 ITR(0, "fchdir", "d") }, /* 120 */
4870+ { sys_readv, 3 ITR(0, "readv", "dxd") }, /* 121 */
4871+ { sys_writev, 3 ITR(0, "writev", "dxd") }, /* 122 */
4872+ { svr4_xstat, 3 ITR(0, "xstat", "dsx") }, /* 123 */
4873+ { svr4_lxstat, 3 ITR(0, "lxstat", "dsx") }, /* 124 */
4874+ { svr4_fxstat, 3 ITR(0, "fxstat", "ddx") }, /* 125 */
4875+ { svr4_xmknod, 4 ITR(0, "xmknod", "dsox")}, /* 126 */
4876+ { 0, Spl ITR(0, "syslocal", "d") }, /* 127 */
4877+ { svr4_getrlimit, 2 ITR(0, "setrlimit", "dx") }, /* 128 */
4878+ { svr4_setrlimit, 2 ITR(0, "getrlimit", "dx") }, /* 129 */
4879+ { 0, 3 ITR(1, "lchown", "sdd") }, /* 130 */
4880+ { 0, Ukn ITR(1, "memcntl", "") }, /* 131 */
4881+#ifdef CONFIG_ABI_XTI
4882+ { svr4_getpmsg, 5 ITR(0, "getpmsg", "dxxxx")}, /* 132 */
4883+ { svr4_putpmsg, 5 ITR(0, "putpmsg", "dxxdd")}, /* 133 */
4884+#else
4885+ { 0, 5 ITR(0, "getpmsg", "dxxxx")}, /* 132 */
4886+ { 0, 5 ITR(0, "putpmsg", "dxxdd")}, /* 133 */
4887+#endif
4888+ { sys_rename, 2 ITR(0, "rename", "ss") }, /* 134 */
4889+ { abi_utsname, 1 ITR(0, "uname", "x") }, /* 135 */
4890+ { svr4_setegid, 1 ITR(1, "setegid", "d") }, /* 136 */
4891+ { svr4_sysconfig, 1 ITR(0, "sysconfig", "d") }, /* 137 */
4892+ { 0, Ukn ITR(1, "adjtime", "") }, /* 138 */
4893+ { svr4_sysinfo, 3 ITR(0, "systeminfo", "dsd") }, /* 139 */
4894+ { socksys_syscall, 1 ITR(0, "socksys_syscall","x") }, /* 140 */
4895+ { svr4_seteuid, 1 ITR(1, "seteuid", "d") }, /* 141 */
4896+ { 0, Ukn ITR(1, "vtrace", "") }, /* 142 */
4897+ { 0, Ukn ITR(1, "fork1", "") }, /* 143 */
4898+ { 0, Ukn ITR(1, "sigtimedwait", "") }, /* 144 */
4899+ { 0, Ukn ITR(1, "lwp_info", "") }, /* 145 */
4900+ { 0, Ukn ITR(1, "yield", "") }, /* 146 */
4901+ { 0, Ukn ITR(1, "lwp_sema_wait", "") }, /* 147 */
4902+ { 0, Ukn ITR(1, "lwp_sema_post", "") }, /* 148 */
4903+ { 0, Ukn ITR(1, "lwp_sema_trywait","") }, /* 149 */
4904+ { 0, Ukn ITR(1, "?", "") }, /* 150 */
4905+ { 0, Ukn ITR(1, "?", "") }, /* 151 */
4906+ { 0, Ukn ITR(1, "modctl", "") }, /* 152 */
4907+ { 0, Ukn ITR(1, "fchroot", "") }, /* 153 */
4908+ { 0, Ukn ITR(1, "utimes", "") }, /* 154 */
4909+ { 0, Ukn ITR(1, "vhangup", "") }, /* 155 */
4910+ { sys_gettimeofday, 2 ITR(0, "gettimeofday", "xx") }, /* 156 */
4911+ { sys_getitimer, 2 ITR(0, "getitimer", "dx") }, /* 157 */
4912+ { sys_setitimer, 3 ITR(0, "setitimer", "dxx") }, /* 158 */
4913+ { 0, Ukn ITR(1, "lwp_create", "") }, /* 159 */
4914+ { 0, Ukn ITR(1, "lwp_exit", "") }, /* 160 */
4915+ { 0, Ukn ITR(1, "lwp_suspend", "") }, /* 161 */
4916+ { 0, Ukn ITR(1, "lwp_continue", "") }, /* 162 */
4917+ { 0, Ukn ITR(1, "lwp_kill", "") }, /* 163 */
4918+ { 0, Ukn ITR(1, "lwp_self", "") }, /* 164 */
4919+ { 0, Ukn ITR(1, "lwp_setprivate","") }, /* 165 */
4920+ { 0, Ukn ITR(1, "lwp_getprivate","") }, /* 166 */
4921+ { 0, Ukn ITR(1, "lwp_wait", "") }, /* 167 */
4922+ { 0, Ukn ITR(1, "lwp_mutex_unlock","") }, /* 168 */
4923+ { 0, Ukn ITR(1, "lwp_mutex_lock","") }, /* 169 */
4924+ { 0, Ukn ITR(1, "lwp_cond_wait", "") }, /* 170 */
4925+ { 0, Ukn ITR(1, "lwp_cond_signal","") }, /* 171 */
4926+ { 0, Ukn ITR(1, "lwp_cond_broadcast","") }, /* 172 */
4927+ { sys_pread64, -4 ITR(1, "pread", "dpdd") }, /* 173 */
4928+ { sys_pwrite64, -4 ITR(1, "pwrite", "dpdd") }, /* 174 */
4929+ { sol_llseek, Spl ITR(1, "llseek", "dxxd") }, /* 175 */
4930+ { 0, Ukn ITR(1, "inst_sync", "") }, /* 176 */
4931+ { 0, Ukn ITR(1, "?", "") }, /* 177 */
4932+ { 0, Ukn ITR(1, "kaio", "") }, /* 178 */
4933+ { 0, Ukn ITR(1, "?", "") }, /* 179 */
4934+ { 0, Ukn ITR(1, "?", "") }, /* 180 */
4935+ { 0, Ukn ITR(1, "?", "") }, /* 181 */
4936+ { 0, Ukn ITR(1, "?", "") }, /* 182 */
4937+ { 0, Ukn ITR(1, "?", "") }, /* 183 */
4938+ { 0, Ukn ITR(1, "tsolsys", "") }, /* 184 */
4939+ { sol_acl, 4 ITR(1, "acl", "sddp") }, /* 185 */
4940+ { 0, Ukn ITR(1, "auditsys", "") }, /* 186 */
4941+ { 0, Ukn ITR(1, "processor_bind","") }, /* 187 */
4942+ { 0, Ukn ITR(1, "processor_info","") }, /* 188 */
4943+ { 0, Ukn ITR(1, "p_online", "") }, /* 189 */
4944+ { 0, Ukn ITR(1, "sigqueue", "") }, /* 190 */
4945+ { 0, Ukn ITR(1, "clock_gettime", "") }, /* 191 */
4946+ { 0, Ukn ITR(1, "clock_settime", "") }, /* 192 */
4947+ { 0, Ukn ITR(1, "clock_getres", "") }, /* 193 */
4948+ { 0, Ukn ITR(1, "timer_create", "") }, /* 194 */
4949+ { 0, Ukn ITR(1, "timer_delete", "") }, /* 195 */
4950+ { 0, Ukn ITR(1, "timer_settime", "") }, /* 196 */
4951+ { 0, Ukn ITR(1, "timer_gettime", "") }, /* 197 */
4952+ { 0, Ukn ITR(1, "timer_getoverrun","") }, /* 198 */
4953+ { sys_nanosleep, 2 ITR(1, "nanosleep", "pp") }, /* 199 */
4954+ { 0, Ukn ITR(1, "modstat", "") }, /* 200 */
4955+ { 0, Ukn ITR(1, "facl", "") }, /* 201 */
4956+ { sys_setreuid, 2 ITR(1, "setreuid", "dd") }, /* 202 */
4957+ { sys_setregid, 2 ITR(1, "setregid", "dd") }, /* 203 */
4958+ { 0, Ukn ITR(1, "install_utrap", "") }, /* 204 */
4959+ { 0, Ukn ITR(1, "signotify", "") }, /* 205 */
4960+ { 0, Ukn ITR(1, "schedctl", "") }, /* 206 */
4961+ { 0, Ukn ITR(1, "pset", "") }, /* 207 */
4962+ { 0, Ukn ITR(1, "?", "") }, /* 208 */
4963+ { 0, Ukn ITR(1, "resolvepath", "") }, /* 209 */
4964+ { 0, Ukn ITR(1, "signotifywait", "") }, /* 210 */
4965+ { 0, Ukn ITR(1, "lwp_sigredirect","") }, /* 211 */
4966+ { 0, Ukn ITR(1, "lwp_alarm", "") }, /* 212 */
4967+ { sol_getdents64, 3 ITR(0, "getdents64", "dxd") }, /* 213 */
4968+ { sol_mmap64, 7 ITR(1, "mmap64", "pxdddxx")}, /*214 */
4969+ { sol_stat64, 2 ITR(0, "stat64", "sp") }, /* 215 */
4970+ { sol_lstat64, 2 ITR(0, "lstat64", "sp") }, /* 216 */
4971+ { sol_fstat64, 2 ITR(0, "fstat64", "dp") }, /* 217 */
4972+ { 0, Ukn ITR(1, "statvfs64", "") }, /* 218 */
4973+ { 0, Ukn ITR(1, "fstatvfs64", "") }, /* 219 */
4974+ { 0, Ukn ITR(1, "setrlimit64", "") }, /* 220 */
4975+ { 0, Ukn ITR(1, "getrlimit64", "") }, /* 221 */
4976+ { 0, Ukn ITR(1, "pread64", "") }, /* 222 */
4977+ { 0, Ukn ITR(1, "pwrite64", "") }, /* 223 */
4978+ { 0, Ukn ITR(1, "creat64", "") }, /* 224 */
4979+ { sol_open64, 3 ITR(0, "open64", "soo") }, /* 225 */
4980+ { 0, Ukn ITR(1, "rpcsys", "") }, /* 226 */
4981+ { 0, Ukn ITR(1, "?", "") }, /* 227 */
4982+ { 0, Ukn ITR(1, "?", "") }, /* 228 */
4983+ { 0, Ukn ITR(1, "?", "") }, /* 229 */
4984+ { solaris_socket, 3 ITR(1, "so_socket", "ddd") }, /* 230 */
4985+ { solaris_socketpair,1 ITR(1, "so_socketpair", "dddx") }, /* 231 */
4986+ { solaris_bind, 3 ITR(1, "bind", "dxd") }, /* 232 */
4987+ { solaris_listen, 2 ITR(1, "listen", "dd") }, /* 233 */
4988+ { solaris_accept, 3 ITR(1, "accept", "dxx") }, /* 234 */
4989+ { solaris_connect, 3 ITR(1, "connect", "dxd") }, /* 235 */
4990+ { solaris_shutdown, 2 ITR(1, "shutdown", "dd") }, /* 236 */
4991+ { solaris_recv, 4 ITR(1, "recv", "dxdd") }, /* 237 */
4992+ { solaris_recvfrom, 6 ITR(1, "recvfrom", "dxddxd")}, /* 238 */
4993+ { solaris_recvmsg, 3 ITR(1, "recvmsg", "dxd") }, /* 239 */
4994+ { solaris_send, 4 ITR(1, "send", "dxdd") }, /* 240 */
4995+ { solaris_sendmsg, 3 ITR(0, "sendmsg", "dxd") }, /* 241 */
4996+ { solaris_sendto, 6 ITR(1, "sendto", "dxddxd")}, /* 242 */
4997+ { solaris_getpeername,3 ITR(1, "getpeername", "dxx") }, /* 243 */
4998+ { solaris_getsockname,3 ITR(1, "getsockname", "dxx") }, /* 244 */
4999+ { solaris_getsockopt,5 ITR(1, "getsockopt", "dddxx")}, /* 245 */
5000+ { solaris_setsockopt,5 ITR(1, "setsockopt", "dddxd")}, /* 246 */
5001+ { 0, Ukn ITR(1, "sockconfig", "") }, /* 247 */
5002+ { 0, Ukn ITR(1, "ntp_gettime", "") }, /* 248 */
5003+ { 0, Ukn ITR(0, "ntp_adjtime", "") }, /* 249 */
5004+ { 0, Ukn ITR(1, "?", "") }, /* 250 */
5005+ { 0, Ukn ITR(1, "?", "") }, /* 251 */
5006+ { 0, Ukn ITR(1, "?", "") }, /* 252 */
5007+ { 0, Ukn ITR(1, "?", "") }, /* 253 */
5008+ { 0, Ukn ITR(1, "?", "") }, /* 254 */
5009+ { 0, Ukn ITR(1, "?", "") } /* 255 */
5010+};
5011+
5012+static void solaris_lcall7(int segment, struct pt_regs * regs)
5013+{
5014+ int sysno = regs->eax & 0xff;
5015+
5016+ if (sysno >= ARRAY_SIZE(solaris_syscall_table))
5017+ set_error(regs, iABI_errors(-EINVAL));
5018+ else
5019+ lcall7_dispatch(regs, &solaris_syscall_table[sysno], 1);
5020+}
5021+
5022+static struct exec_domain solaris_exec_domain = {
5023+ name: "Solaris",
5024+ handler: solaris_lcall7,
5025+ pers_low: 13 /* PER_SOLARIS */,
5026+ pers_high: 13 /* PER_SOLARIS */,
5027+ signal_map: solaris_to_linux_signals,
5028+ signal_invmap: linux_to_solaris_signals,
5029+ err_map: solaris_err_map,
5030+ socktype_map: solaris_socktype_map,
5031+ sockopt_map: solaris_sockopt_map,
5032+ af_map: solaris_af_map,
5033+ module: THIS_MODULE,
5034+};
5035+
5036+
5037+static void __exit solaris_cleanup(void)
5038+{
5039+ unregister_exec_domain(&solaris_exec_domain);
5040+}
5041+
5042+static int __init solaris_init(void)
5043+{
5044+ return register_exec_domain(&solaris_exec_domain);
5045+}
5046+
5047+module_init(solaris_init);
5048+module_exit(solaris_cleanup);
5049diff -Nru linux-2.6.7/abi/svr4/consio.c linux-2.6.7-abi/abi/svr4/consio.c
5050--- linux-2.6.7/abi/svr4/consio.c 1970-01-01 01:00:00.000000000 +0100
5051+++ linux-2.6.7-abi/abi/svr4/consio.c 2004-07-22 17:44:20.000000000 +0200
5052@@ -0,0 +1,53 @@
5053+#ident "%W% %G%"
5054+
5055+#include <linux/errno.h>
5056+#include <linux/kernel.h>
5057+#include <linux/types.h>
5058+#include <linux/module.h>
5059+
5060+
5061+int
5062+svr4_console_ioctl(int fd, u_int cmd, caddr_t data)
5063+{
5064+ switch (cmd) {
5065+ case 0x6301: /* CONS_CURRENT: Get display adapter type */
5066+ case 0x6302: /* CONS_GET: Get display mode setting */
5067+ /*
5068+ * Always error so the application never tries
5069+ * anything overly fancy on the console.
5070+ */
5071+ return -EINVAL;
5072+ case 0x4304: /* _TTYDEVTYPE */
5073+ /* If on console then 1, if pseudo tty then 2 */
5074+ return 2;
5075+ }
5076+
5077+ printk(KERN_ERR "iBCS: console ioctl %d unsupported\n", cmd);
5078+ return -EINVAL;
5079+}
5080+
5081+int
5082+svr4_video_ioctl(int fd, u_int cmd, caddr_t data)
5083+{
5084+ switch (cmd) {
5085+ case 1: /* MAP_CLASS */
5086+ /* Get video memory map & IO privilege */
5087+ break;
5088+
5089+ /* This doesn't agree with my SCO 3.2.4 ???? */
5090+ case 4: /* C_IOC */
5091+ /* see /etc/conf/pack.d/cn/class.h on any SCO unix box :-) */
5092+ break;
5093+
5094+ default:
5095+ break;
5096+ }
5097+
5098+ printk(KERN_ERR "iBCS: video ioctl %d unsupported\n", cmd);
5099+ return -EINVAL;
5100+}
5101+
5102+#if defined(CONFIG_ABI_SYSCALL_MODULES)
5103+EXPORT_SYMBOL(svr4_console_ioctl);
5104+EXPORT_SYMBOL(svr4_video_ioctl);
5105+#endif
5106diff -Nru linux-2.6.7/abi/svr4/fcntl.c linux-2.6.7-abi/abi/svr4/fcntl.c
5107--- linux-2.6.7/abi/svr4/fcntl.c 1970-01-01 01:00:00.000000000 +0100
5108+++ linux-2.6.7-abi/abi/svr4/fcntl.c 2004-07-22 17:44:20.000000000 +0200
5109@@ -0,0 +1,195 @@
5110+/*
5111+ * Copyright (c) 2002 Caldera Deutschland GmbH.
5112+ * All rights reserved.
5113+ *
5114+ * This program is free software; you can redistribute it and/or modify
5115+ * it under the terms of the GNU General Public License as published by
5116+ * the Free Software Foundation; either version 2 of the License, or
5117+ * (at your option) any later version.
5118+ *
5119+ * This program is distributed in the hope that it will be useful,
5120+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5121+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5122+ * GNU General Public License for more details.
5123+ *
5124+ * You should have received a copy of the GNU General Public License
5125+ * along with this program; if not, write to the Free Software
5126+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
5127+ */
5128+
5129+#ident "@(#)fcntl.c 1.1 02/23/02"
5130+
5131+#include <linux/types.h>
5132+#include <linux/errno.h>
5133+#include <linux/fcntl.h>
5134+#include <linux/sched.h>
5135+#include <linux/kernel.h>
5136+#include <linux/syscalls.h>
5137+#include <linux/module.h>
5138+
5139+#include <asm/uaccess.h>
5140+#include <asm/ioctls.h>
5141+
5142+#include <abi/svr4/types.h>
5143+#include <abi/util/trace.h>
5144+#include <abi/util/map.h>
5145+
5146+
5147+struct svr4_flock {
5148+ int16_t l_type; /* numbers don't match */
5149+ int16_t l_whence;
5150+ svr4_off_t l_start;
5151+ svr4_off_t l_len; /* 0 means to end of file */
5152+ int16_t l_sysid;
5153+ int16_t l_pid;
5154+};
5155+
5156+
5157+/*
5158+ * ISC (at least) assumes O_CREAT if O_TRUNC is given.
5159+ * This is emulated here but is it correct for SVR4 in general?
5160+ */
5161+unsigned short fl_svr4_to_linux[] = {
5162+ 0x0001, 0x0002, 0x0800, 0x0400, 0x1000, 0x0000, 0x0000, 0x0800,
5163+ 0x0040, 0x0240, 0x0080, 0x0100, 0x0000, 0x0000, 0x0000, 0x0000
5164+};
5165+
5166+unsigned short fl_linux_to_svr4[] = {
5167+ 0x0001, 0x0002, 0x0000, 0x0000, 0x0000, 0x0000, 0x0100, 0x0400,
5168+ 0x0800, 0x0200, 0x0008, 0x0004, 0x0010, 0x0000, 0x0000, 0x0000
5169+};
5170+
5171+static inline int svr4_fcntl_flock(int fd, unsigned int cmd, unsigned long arg)
5172+{
5173+ struct svr4_flock fl, *flp = (struct svr4_flock *)arg;
5174+ struct flock l_fl;
5175+ mm_segment_t fs;
5176+ int rval;
5177+
5178+ /*
5179+ * We are not supposed to fail once the lock is set,
5180+ * thus we check the userspace pointer for writeaccess now.
5181+ */
5182+ rval = verify_area(VERIFY_WRITE, flp, sizeof(struct svr4_flock));
5183+ if (rval)
5184+ return -EFAULT;
5185+
5186+ rval = copy_from_user(&fl, flp, sizeof(struct svr4_flock));
5187+ if (rval)
5188+ return -EFAULT;
5189+
5190+ l_fl.l_type = fl.l_type - 1;
5191+ l_fl.l_whence = fl.l_whence;
5192+ l_fl.l_start = fl.l_start;
5193+ l_fl.l_len = fl.l_len;
5194+ l_fl.l_pid = fl.l_pid;
5195+
5196+#if defined(CONFIG_ABI_TRACE)
5197+ abi_trace(ABI_TRACE_API,
5198+ "lock l_type: %d l_whence: %d "
5199+ "l_start: %u l_len: %u "
5200+ "l_sysid: %d l_pid: %d\n",
5201+ fl.l_type, fl.l_whence,
5202+ fl.l_start, fl.l_len,
5203+ fl.l_sysid, fl.l_pid);
5204+#endif
5205+
5206+ fs = get_fs();
5207+ set_fs(get_ds());
5208+ rval = sys_fcntl(fd, cmd, (unsigned long)&l_fl);
5209+ set_fs(fs);
5210+
5211+ if (rval)
5212+ return rval;
5213+
5214+ fl.l_type = l_fl.l_type + 1;
5215+ fl.l_whence = l_fl.l_whence;
5216+ fl.l_start = l_fl.l_start;
5217+ fl.l_len = l_fl.l_len;
5218+ fl.l_sysid = 0;
5219+ fl.l_pid = l_fl.l_pid;
5220+
5221+ __copy_to_user(flp, &fl, sizeof(struct svr4_flock));
5222+ return 0;
5223+}
5224+
5225+int svr4_fcntl(int fd, unsigned int cmd, unsigned long arg)
5226+{
5227+ int rval;
5228+
5229+ switch (cmd) {
5230+ case 0: /* F_DUPFD */
5231+ case 1: /* F_GETFD */
5232+ case 2: /* F_SETFD */
5233+ return sys_fcntl(fd, cmd, arg);
5234+ case 3: /* F_GETFL */
5235+ rval = sys_fcntl(fd, cmd, arg);
5236+ return map_flags(rval, fl_linux_to_svr4);
5237+ case 4: /* F_SETFL */
5238+ arg = map_flags(arg, fl_svr4_to_linux);
5239+ return sys_fcntl(fd, cmd, arg);
5240+ case 14: /* F_GETLK SVR4 */
5241+ cmd = 5;
5242+ /*FALLTHROUGH*/
5243+ case 5: /* F_GETLK */
5244+ case 6: /* F_SETLK */
5245+ case 7: /* F_SETLKW */
5246+ return svr4_fcntl_flock(fd, cmd, arg);
5247+ case 10: /* F_ALLOCSP */
5248+ /* Extend allocation for specified portion of file. */
5249+ return 0;
5250+ case 11: /* F_FREESP */
5251+ /* Free a portion of a file. */
5252+ return 0;
5253+
5254+ /*
5255+ * These are intended to support the Xenix chsize() and
5256+ * rdchk() system calls. I don't know if these may be
5257+ * generated by applications or not.
5258+ */
5259+ case 0x6000: /* F_CHSIZE */
5260+ return sys_ftruncate(fd, arg);
5261+ case 0x6001: /* F_RDCHK */
5262+ {
5263+ mm_segment_t fs;
5264+ int nbytes;
5265+
5266+ fs = get_fs();
5267+ set_fs(get_ds());
5268+ rval = sys_ioctl(fd, FIONREAD, (long)&nbytes);
5269+ set_fs(fs);
5270+
5271+ if (rval < 0)
5272+ return rval;
5273+ return (nbytes ? 1 : 0);
5274+ }
5275+
5276+ case 8: /* F_CHKFL */
5277+ /*FALLTHROUGH*/
5278+
5279+ /*
5280+ * These are made from the Xenix locking() system call.
5281+ * According to available documentation these would
5282+ * never be generated by an application - only by the
5283+ * kernel Xenix support.
5284+ */
5285+ case 0x6300: /* F_LK_UNLCK */
5286+ case 0x7200: /* F_LK_LOCK */
5287+ case 0x6200: /* F_LK_NBLCK */
5288+ case 0x7100: /* F_LK_RLCK */
5289+ case 0x6100: /* F_LK_NBRLCK */
5290+ /*FALLTHROUGH*/
5291+
5292+ default:
5293+#if defined(CONFIG_ABI_TRACE)
5294+ abi_trace(ABI_TRACE_API,
5295+ "unsupported fcntl 0x%x, arg 0x%lx\n", cmd, arg);
5296+#endif
5297+ return -EINVAL;
5298+ }
5299+}
5300+
5301+#if defined(CONFIG_ABI_SYSCALL_MODULES)
5302+EXPORT_SYMBOL(fl_svr4_to_linux);
5303+EXPORT_SYMBOL(svr4_fcntl);
5304+#endif
5305diff -Nru linux-2.6.7/abi/svr4/filio.c linux-2.6.7-abi/abi/svr4/filio.c
5306--- linux-2.6.7/abi/svr4/filio.c 1970-01-01 01:00:00.000000000 +0100
5307+++ linux-2.6.7-abi/abi/svr4/filio.c 2004-07-22 17:44:20.000000000 +0200
5308@@ -0,0 +1,94 @@
5309+/*
5310+ * Copyright (c) 2001 Christoph Hellwig.
5311+ * All rights reserved.
5312+ *
5313+ * This program is free software; you can redistribute it and/or modify
5314+ * it under the terms of the GNU General Public License as published by
5315+ * the Free Software Foundation; either version 2 of the License, or
5316+ * (at your option) any later version.
5317+ *
5318+ * This program is distributed in the hope that it will be useful,
5319+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5320+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5321+ * GNU General Public License for more details.
5322+ *
5323+ * You should have received a copy of the GNU General Public License
5324+ * along with this program; if not, write to the Free Software
5325+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
5326+ */
5327+
5328+#ident "%W% %G%"
5329+
5330+/*
5331+ * SVR4 file ioctls.
5332+ */
5333+
5334+#include <linux/sched.h>
5335+#include <linux/file.h>
5336+#include <linux/sockios.h>
5337+#include <linux/syscalls.h>
5338+#include <linux/module.h>
5339+
5340+#include <asm/uaccess.h>
5341+#include <asm/ioctls.h>
5342+
5343+#include <abi/ioctl.h>
5344+
5345+
5346+int
5347+svr4_fil_ioctl(int fd, u_int cmd, caddr_t data)
5348+{
5349+ switch (cmd) {
5350+ /* FIOCLEX */
5351+ case BSD__IOV('f', 1):
5352+ case BSD__IO('f', 1):
5353+ FD_SET(fd, current->files->close_on_exec);
5354+ return 0;
5355+
5356+ /* FIONCLEX */
5357+ case BSD__IOV('f', 2):
5358+ case BSD__IO('f', 2):
5359+ FD_CLR(fd, current->files->close_on_exec);
5360+ return 0;
5361+
5362+ case BSD__IOV('f', 3):
5363+ case BSD__IO('f', 3): {
5364+ int error, nbytes;
5365+ mm_segment_t fs;
5366+
5367+ fs = get_fs();
5368+ set_fs(get_ds());
5369+ error = sys_ioctl(fd, FIONREAD, (long)&nbytes);
5370+ set_fs(fs);
5371+
5372+ return (error <= 0 ? error : nbytes);
5373+ }
5374+
5375+ /* FGETOWN */
5376+ case BSD__IOW('f', 123, int):
5377+ return sys_ioctl(fd, FIOGETOWN, (long)data);
5378+
5379+ /* FSETOWN */
5380+ case BSD__IOW('f', 124, int):
5381+ return sys_ioctl(fd, FIOSETOWN, (long)data);
5382+
5383+ /* FIOASYNC */
5384+ case BSD__IOW('f', 125, int):
5385+ return sys_ioctl(fd, FIOASYNC, (long)data);
5386+
5387+ /* FIONBIO */
5388+ case BSD__IOW('f', 126, int):
5389+ return sys_ioctl(fd, FIONBIO, (long)data);
5390+
5391+ /* FIONREAD */
5392+ case BSD__IOR('f', 127, int):
5393+ return sys_ioctl(fd, FIONREAD, (long)data);
5394+ }
5395+
5396+ printk(KERN_ERR "%s: file ioctl 0x%08x unsupported\n", __FUNCTION__, cmd);
5397+ return -EINVAL;
5398+}
5399+
5400+#if defined(CONFIG_ABI_SYSCALL_MODULES)
5401+EXPORT_SYMBOL(svr4_fil_ioctl);
5402+#endif
5403diff -Nru linux-2.6.7/abi/svr4/hrtsys.c linux-2.6.7-abi/abi/svr4/hrtsys.c
5404--- linux-2.6.7/abi/svr4/hrtsys.c 1970-01-01 01:00:00.000000000 +0100
5405+++ linux-2.6.7-abi/abi/svr4/hrtsys.c 2004-07-22 17:44:20.000000000 +0200
5406@@ -0,0 +1,192 @@
5407+/*
5408+ * Copyright (C) 1994 Eric Youngdale.
5409+ *
5410+ * The hrtsys interface is used by SVR4, and is effectively a way of doing
5411+ * itimer. I do not know why this is used instead of the regular itimer
5412+ * stuff, but it appears to be related to bsd programs/functionality.
5413+ */
5414+
5415+#ident "%W% %G%"
5416+
5417+#include <linux/module.h>
5418+#include <linux/ptrace.h>
5419+#include <linux/errno.h>
5420+#include <linux/mm.h>
5421+#include <linux/string.h>
5422+#include <linux/syscalls.h>
5423+#include <asm/uaccess.h>
5424+
5425+#include <asm/abi_machdep.h>
5426+#include <abi/util/trace.h>
5427+
5428+
5429+struct hrt_time_t {
5430+ unsigned long secs;
5431+ unsigned long sub_sec; /* Less than one second. */
5432+ unsigned long resolution; /* Resolution of timer */
5433+};
5434+
5435+struct hrtcmd {
5436+ int cmd;
5437+ int clk;
5438+ struct hrt_time_t interval;
5439+ struct hrt_time_t tod;
5440+ int flags;
5441+ int error;
5442+ int reserved[3];
5443+};
5444+
5445+static int
5446+ibcs_hrtcntl (struct pt_regs * regs)
5447+{
5448+ unsigned int param[4];
5449+ struct timeval * tv;
5450+ int i, error;
5451+
5452+ for (i=0; i<4; i++)
5453+ param[i] = get_syscall_parameter (regs, 1+i);
5454+
5455+ if (param[0] != 1 || param[1] != 1 || param[2] != 0)
5456+ return -EINVAL;
5457+
5458+ tv = (struct timeval *) param[3];
5459+
5460+#if defined(CONFIG_ABI_TRACE)
5461+ abi_trace(ABI_TRACE_API, "hrtcntl(0x%lx)\n", (u_long)tv);
5462+#endif
5463+
5464+ error = verify_area(VERIFY_WRITE, (char *) tv,sizeof *tv);
5465+ if (error)
5466+ return error;
5467+
5468+ return sys_gettimeofday(tv, NULL);
5469+}
5470+
5471+static int
5472+ibcs_hrtalarm (struct pt_regs * regs)
5473+{
5474+ struct itimerval get_buffer;
5475+ struct hrtcmd * hcmd;
5476+ int i, error, cmd, retval, which;
5477+ mm_segment_t old_fs = get_fs();
5478+
5479+ i = get_syscall_parameter (regs, 2);
5480+ if(i != 1)
5481+ return -EINVAL;
5482+
5483+ hcmd = (struct hrtcmd *) get_syscall_parameter (regs, 1);
5484+
5485+ error = verify_area (VERIFY_WRITE, (char *) hcmd,sizeof *hcmd);
5486+ if (error)
5487+ return error;
5488+
5489+ get_user (cmd, ((unsigned long *) hcmd));
5490+
5491+ /* Now figure out which clock we want to fiddle with */
5492+ get_user (which, ((unsigned long *) hcmd)+1);
5493+
5494+#if defined(CONFIG_ABI_TRACE)
5495+ abi_trace(ABI_TRACE_API, "hrtalarm(0x%lx %d)\n",
5496+ (u_long)cmd, which);
5497+#endif
5498+
5499+ switch (which) {
5500+ case 4:
5501+ which = 2;
5502+ break;
5503+ case 2:
5504+ which = 1;
5505+ break;
5506+ case 1:
5507+ which = 0;
5508+ break;
5509+ default:
5510+ return -EINVAL;
5511+ };
5512+
5513+ switch (cmd) {
5514+ case 0xc:
5515+ if(({long r; get_user(r, ((unsigned long *) hcmd)+4); r;}) != 1000000)
5516+ return -EINVAL;
5517+ copy_from_user(&get_buffer.it_value, ((unsigned long *) hcmd)+2,
5518+ sizeof(struct timeval));
5519+ memset(&get_buffer.it_interval, 0, sizeof(struct timeval));
5520+ set_fs(get_ds());
5521+ retval = sys_setitimer(which, &get_buffer, NULL);
5522+ set_fs(old_fs);
5523+ break;
5524+ case 0xd:
5525+ set_fs(get_ds());
5526+ retval = sys_getitimer(which, &get_buffer);
5527+ set_fs(old_fs);
5528+
5529+#if defined(CONFIG_ABI_TRACE)
5530+ abi_trace(ABI_TRACE_API, "hrtalarm(d %lx) %lx %lx %lx %lx\n",
5531+ (u_long)hcmd,
5532+ get_buffer.it_interval.tv_sec,
5533+ get_buffer.it_interval.tv_usec,
5534+ get_buffer.it_value.tv_sec,
5535+ get_buffer.it_value.tv_usec);
5536+#endif
5537+
5538+ put_user(1000000, &hcmd->interval.resolution);
5539+ copy_to_user(((unsigned long *) hcmd)+2, &get_buffer.it_interval,
5540+ sizeof(get_buffer));
5541+ retval = 1;
5542+ break;
5543+ case 0xf:
5544+ if(({long r; get_user(r, ((unsigned long *) hcmd)+4); r;}) != 1000000)
5545+ return -EINVAL;
5546+ if(({long r; get_user(r, ((unsigned long *) hcmd)+7); r;}) != 1000000)
5547+ return -EINVAL;
5548+ copy_from_user(&get_buffer.it_value, &hcmd->tod,
5549+ sizeof(struct timeval));
5550+ copy_from_user(&get_buffer.it_interval, &hcmd->interval,
5551+ sizeof(struct timeval));
5552+ set_fs(get_ds());
5553+ retval = sys_setitimer(which, &get_buffer, NULL);
5554+ set_fs(old_fs);
5555+ break;
5556+ case 0x10:
5557+ memset(&get_buffer, 0, sizeof(get_buffer));
5558+ set_fs(get_ds());
5559+ retval = sys_setitimer(which, &get_buffer, NULL);
5560+ set_fs(old_fs);
5561+ break;
5562+ default:
5563+ retval = -EINVAL;
5564+ };
5565+
5566+ return retval;
5567+}
5568+
5569+int
5570+svr4_hrtsys (struct pt_regs * regs)
5571+{
5572+ int func, retval;
5573+
5574+ func = get_syscall_parameter (regs, 0);
5575+
5576+#if defined(CONFIG_ABI_TRACE)
5577+ abi_trace(ABI_TRACE_API, "hrtsys(%d)\n", func);
5578+#endif
5579+
5580+ switch (func) {
5581+ case 0:
5582+ retval = ibcs_hrtcntl(regs);
5583+ break;
5584+ case 1:
5585+ retval = ibcs_hrtalarm(regs);
5586+ break;
5587+ case 2:
5588+ case 3:
5589+ default:
5590+ retval = -EINVAL;
5591+ }
5592+
5593+ return retval;
5594+}
5595+
5596+#if defined(CONFIG_ABI_SYSCALL_MODULES)
5597+EXPORT_SYMBOL(svr4_hrtsys);
5598+#endif
5599diff -Nru linux-2.6.7/abi/svr4/ioctl.c linux-2.6.7-abi/abi/svr4/ioctl.c
5600--- linux-2.6.7/abi/svr4/ioctl.c 1970-01-01 01:00:00.000000000 +0100
5601+++ linux-2.6.7-abi/abi/svr4/ioctl.c 2004-07-22 17:44:20.000000000 +0200
5602@@ -0,0 +1,198 @@
5603+/*
5604+ * Copyright (C) 1991, 1992 Linus Torvalds
5605+ *
5606+ * Written by Drew Sullivan.
5607+ * Rewritten by Mike Jagdis.
5608+ */
5609+
5610+#ident "%W% %G%"
5611+
5612+#include <linux/config.h>
5613+#include <linux/errno.h>
5614+#include <linux/kernel.h>
5615+#include <linux/module.h>
5616+#include <linux/syscalls.h>
5617+#include <asm/uaccess.h>
5618+
5619+#include <asm/abi_machdep.h>
5620+#include <abi/svr4/ioctl.h>
5621+
5622+
5623+/*
5624+ * __svr4_ioctl() is a meta mapper, that is
5625+ * it looks up the class of the ioctl and then
5626+ * dispatchs to lower level routines to handle the
5627+ * mapping of the actual ioctls
5628+ */
5629+int
5630+__svr4_ioctl(struct pt_regs *regs, int fd, unsigned long ioctl_num, void *arg)
5631+{
5632+ unsigned int class = ioctl_num >> 8;
5633+ char class_str[4];
5634+
5635+ switch (class) {
5636+
5637+ /*
5638+ * SCO ioctls on the pseudo NFS device probably.
5639+ */
5640+ case 0:
5641+ return abi_ioctl_socksys(fd, ioctl_num, arg);
5642+
5643+ /*
5644+ * SCO console keyboard stuff?
5645+ */
5646+ case 'A':
5647+ return -EINVAL;
5648+
5649+ case 't':
5650+ return svr4_tape_ioctl(fd, ioctl_num, arg);
5651+
5652+ case 'f':
5653+ return svr4_fil_ioctl(fd, ioctl_num, arg);
5654+
5655+ /*
5656+ * Xenix ioctl compatibility.
5657+ */
5658+ case 'T':
5659+ return svr4_term_ioctl(fd, ioctl_num & 0xFF, arg);
5660+
5661+ case 'C':
5662+ case 'c':
5663+ return svr4_console_ioctl(fd, ioctl_num, arg);
5664+
5665+ case ('i' << 16) | ('C' << 8): /* iBCS2 POSIX */
5666+ return svr4_video_ioctl(fd, ioctl_num & 0xFF, arg);
5667+
5668+ /*
5669+ * SCO 3.2.2 uses ('X'<<8)|1 for access to the video map
5670+ * and the 'X' set is also used for synchronous comm
5671+ * lines (I think?). SVR4 uses it for tty extensions to
5672+ * support hardware flow control and external clocks.
5673+ */
5674+ case 'X':
5675+ return svr4_termiox_ioctl(fd, ioctl_num & 0xFF, arg);
5676+
5677+ /*
5678+ * These aren't implemented and are never likely to be as they
5679+ * are specific to drivers for obscure hardware. (For those
5680+ * that don't know they're the JERQ ioctls. Says it all
5681+ * really!)
5682+ */
5683+ case 'j':
5684+ return -EINVAL;
5685+
5686+ /*
5687+ * The 'S' set could also be display mode switch
5688+ * ioctls in a SCO 3.2.x x<4 environment. It should
5689+ * depend on the descriptor they are applied to.
5690+ * According to ISC the Xenix STREAMS ioctls had the
5691+ * high bit set on the command to differentiate them
5692+ * from mode switch ioctls. Yuk, yuk, yuk...
5693+ */
5694+ case 'S':
5695+ return svr4_stream_ioctl(regs, fd, ioctl_num & 0x7F, arg);
5696+
5697+ /*
5698+ * These are STREAMS socket module ioctls.
5699+ */
5700+ case 'I':
5701+#if defined(CONFIG_ABI_XTI)
5702+ return svr4_sockmod_ioctl(fd, ioctl_num & 0xFF, arg);
5703+#else
5704+ return -EINVAL;
5705+#endif
5706+
5707+ /*
5708+ * EUC ioctls. These are something to do with chararcter
5709+ * code set conversions in SVR4. If we don't support
5710+ * them the correct thing to do is to return EINVAL.
5711+ */
5712+ case 'E' | 0x80:
5713+ return -EINVAL;
5714+
5715+ /*
5716+ * SCO channel mapping. I can't find any documentation
5717+ * for this. These are the LD?MAP ioctls defined in
5718+ * sys/termio.h and sys/emap.h. They are used by mapchan.
5719+ */
5720+ case 'D':
5721+ return -EINVAL;
5722+ }
5723+
5724+ /*
5725+ * If we haven't handled it yet it must be a BSD style ioctl
5726+ * with a (possible) argument description in the high word of
5727+ * the opcode.
5728+ */
5729+ switch (class & 0xff) {
5730+
5731+ /*
5732+ * From SVR4 as specified in sys/iocomm.h.
5733+ */
5734+ case 'f':
5735+ return svr4_fil_ioctl(fd, ioctl_num, arg);
5736+
5737+ /*
5738+ * BSD or V7 terminal ioctls.
5739+ */
5740+ case 't':
5741+ return bsd_ioctl_termios(fd, ioctl_num, arg);
5742+
5743+ /*
5744+ * "Traditional" BSD and Wyse V/386 3.2.1A TCP/IP ioctls.
5745+ */
5746+ case 's':
5747+ case 'r':
5748+ case 'i':
5749+ return abi_ioctl_socksys(fd, ioctl_num, arg);
5750+
5751+ /*
5752+ * SVR3 streams based socket TCP/IP ioctls.
5753+ *
5754+ * These are handed over to the standard ioctl
5755+ * handler since /dev/socksys is an emulated device
5756+ * and front ends any sockets created through it.
5757+ * Note that 'S' ioctls without the BSDish argument
5758+ * type in the high bytes are STREAMS ioctls and 'I'
5759+ * ioctls without the BSDish type in the high bytes
5760+ * are the STREAMS socket module ioctls. (see above).
5761+ */
5762+ case 'S':
5763+ case 'R':
5764+ case 'I':
5765+ return abi_ioctl_socksys(fd, ioctl_num, arg);
5766+ }
5767+
5768+ /*
5769+ * If nothing has handled it yet someone may have to do some
5770+ * more work...
5771+ */
5772+ class_str[0] = class & 0xFF0000 ? (char)((class >> 16) & 0xFF) : '.';
5773+ class_str[1] = class & 0x00FF00 ? (char)((class >> 8) & 0xFF) : '.';
5774+ class_str[2] = class & 0x0000FF ? (char)((class ) & 0xFF) : '.';
5775+ class_str[3] = 0;
5776+
5777+ printk(KERN_DEBUG "svr4: ioctl(%d, %lx[%s], 0x%p) unsupported\n",
5778+ fd, ioctl_num, class_str, arg);
5779+
5780+ return -EINVAL;
5781+}
5782+
5783+int
5784+svr4_ioctl(struct pt_regs * regs)
5785+{
5786+ u_int num;
5787+ int fd;
5788+ caddr_t data;
5789+
5790+ fd = (int)get_syscall_parameter(regs, 0);
5791+ num = (u_int)get_syscall_parameter(regs, 1);
5792+ data = (caddr_t)get_syscall_parameter(regs, 2);
5793+
5794+ return __svr4_ioctl(regs, fd, num, data);
5795+}
5796+
5797+#if defined(CONFIG_ABI_SYSCALL_MODULES)
5798+EXPORT_SYMBOL(__svr4_ioctl);
5799+EXPORT_SYMBOL(svr4_ioctl);
5800+#endif
5801diff -Nru linux-2.6.7/abi/svr4/ipc.c linux-2.6.7-abi/abi/svr4/ipc.c
5802--- linux-2.6.7/abi/svr4/ipc.c 1970-01-01 01:00:00.000000000 +0100
5803+++ linux-2.6.7-abi/abi/svr4/ipc.c 2004-07-22 17:44:20.000000000 +0200
5804@@ -0,0 +1,713 @@
5805+/*
5806+ * Copyright (C) 1994 Mike Jagdis (jaggy@purplet.demon.co.uk)
5807+ * Copyright (C) 2001 Christoph Hellwig (hch@caldera.de)
5808+ *
5809+ * Massive work over with a fine tooth comb, lots of rewriting. There
5810+ * were a *lot* of bugs in this - mismatched structs that weren't
5811+ * mapped, wrong pointers etc. I've tested this version with the
5812+ * demo programs from the Wyse V/386 IPC documentation which exercise
5813+ * all the functions. I don't have any major IPC using applications
5814+ * to test it with - as far as I know...
5815+ *
5816+ * Again rewritten for Linux 2.4 - Linux 2.4 changes a lot of structures
5817+ * and the cruft this file relied on has simply changed...
5818+ *
5819+ * Original copyright etc. follows:
5820+ *
5821+ * Copyright (C) 1993,1994 Joe Portman (baron@hebron.connected.com)
5822+ * First stab at ibcs shm, sem and msg handlers
5823+ *
5824+ * NOTE:
5825+ * Please contact the author above before blindly making changes
5826+ * to this file. You will break things.
5827+ *
5828+ * 04-15-1994 JLP III
5829+ * Still no msgsys, but IPC_STAT now works for shm calls
5830+ * Corrected argument order for sys_ipc calls, to accomodate Mike's
5831+ * changes, so that we can just call sys_ipc instead of the internal
5832+ * sys_* calls for ipc functions.
5833+ * Cleaned up translation of perm structures
5834+ * tstshm for Oracle now works.
5835+ *
5836+ * 04-23-1994 JLP III
5837+ * Added in msgsys calls, Tested and working
5838+ * Added translation for IPC_SET portions of all xxxctl functions.
5839+ * Added SHM_LOCK and SHM_UNLOCK to shmsys
5840+ *
5841+ * 04-28-1994 JLP III
5842+ * Special thanks to Brad Pepers for adding in the GETALL and SETALL
5843+ * case of semaphores. (pepersb@cuug.ab.ca)
5844+ */
5845+
5846+#ident "%W% %G%"
5847+
5848+#include <linux/module.h>
5849+#include <linux/errno.h>
5850+#include <linux/fs.h>
5851+#include <linux/kernel.h>
5852+#include <linux/personality.h>
5853+#include <linux/ptrace.h>
5854+#include <linux/sched.h>
5855+#include <linux/string.h>
5856+#define __KERNEL_SYSCALLS__
5857+#include <linux/unistd.h>
5858+#include <linux/syscalls.h>
5859+#include <linux/ipc.h>
5860+#include <linux/sem.h>
5861+#include <linux/shm.h>
5862+#include <linux/msg.h>
5863+
5864+#include <asm/uaccess.h>
5865+#include <asm/ipc.h>
5866+
5867+#include <abi/svr4/ipc.h>
5868+#include <abi/util/trace.h>
5869+#include <abi/util/errno.h>
5870+
5871+
5872+static __inline__ void
5873+ip_to_lp(struct ibcs2_ipc_perm *ip, struct ipc_perm *lp)
5874+{
5875+ lp->uid = ip->uid;
5876+ lp->gid = ip->gid;
5877+ lp->cuid = ip->cuid;
5878+ lp->cgid = ip->cgid;
5879+ lp->mode = ip->mode;
5880+ lp->seq = ip->seq;
5881+ lp->key = ip->key;
5882+}
5883+
5884+static __inline__ void
5885+lp_to_ip(struct ipc_perm *lp, struct ibcs2_ipc_perm *ip)
5886+{
5887+ ip->uid = lp->uid;
5888+ ip->gid = lp->gid;
5889+ ip->cuid = lp->cuid;
5890+ ip->cgid = lp->cgid;
5891+ ip->mode = lp->mode;
5892+ ip->seq = lp->seq;
5893+ ip->key = lp->key;
5894+}
5895+
5896+static __inline__ void
5897+ip_to_lp_l(struct abi4_ipc_perm *ip, struct ipc_perm *lp)
5898+{
5899+ lp->uid = ip->uid;
5900+ lp->gid = ip->gid;
5901+ lp->cuid = ip->cuid;
5902+ lp->cgid = ip->cgid;
5903+ lp->mode = ip->mode;
5904+ lp->seq = ip->seq;
5905+ lp->key = ip->key;
5906+}
5907+
5908+static __inline__ void
5909+lp_to_ip_l(struct ipc_perm *lp, struct abi4_ipc_perm *ip)
5910+{
5911+ ip->uid = lp->uid;
5912+ ip->gid = lp->gid;
5913+ ip->cuid = lp->cuid;
5914+ ip->cgid = lp->cgid;
5915+ ip->mode = lp->mode;
5916+ ip->seq = lp->seq;
5917+ ip->key = lp->key;
5918+}
5919+
5920+static void
5921+isem_to_lsem(struct ibcs2_semid_ds *is, struct semid_ds *ls)
5922+{
5923+ ip_to_lp(&is->sem_perm, &ls->sem_perm);
5924+
5925+ ls->sem_base = is->sem_base;
5926+ ls->sem_nsems = is->sem_nsems;
5927+ ls->sem_otime = is->sem_otime;
5928+ ls->sem_ctime = is->sem_ctime;
5929+}
5930+
5931+static void
5932+lsem_to_isem(struct semid_ds *ls, struct ibcs2_semid_ds *is)
5933+{
5934+ lp_to_ip(&ls->sem_perm, &is->sem_perm);
5935+
5936+ is->sem_base = ls->sem_base;
5937+ is->sem_nsems = ls->sem_nsems;
5938+ is->sem_otime = ls->sem_otime;
5939+ is->sem_ctime = ls->sem_ctime;
5940+}
5941+
5942+static void
5943+isem_to_lsem_l(struct abi4_semid_ds *is, struct semid_ds *ls)
5944+{
5945+ ip_to_lp_l(&is->sem_perm, &ls->sem_perm);
5946+
5947+ ls->sem_base = is->sem_base;
5948+ ls->sem_nsems = is->sem_nsems;
5949+ ls->sem_otime = is->sem_otime;
5950+ ls->sem_ctime = is->sem_ctime;
5951+}
5952+
5953+static void
5954+lsem_to_isem_l(struct semid_ds *ls, struct abi4_semid_ds *is)
5955+{
5956+ memset(is, 0, sizeof(*is));
5957+
5958+ lp_to_ip_l(&ls->sem_perm, &is->sem_perm);
5959+
5960+ is->sem_base = ls->sem_base;
5961+ is->sem_nsems = ls->sem_nsems;
5962+ is->sem_otime = ls->sem_otime;
5963+ is->sem_ctime = ls->sem_ctime;
5964+}
5965+
5966+static int
5967+__ibcs2_semctl(int first, int second, int third, union semun *fourth)
5968+{
5969+ struct ibcs2_semid_ds is, *isp;
5970+ struct semid_ds ls;
5971+ union semun lsemun;
5972+ mm_segment_t fs;
5973+ int err;
5974+
5975+ err = get_user(isp, (struct ibcs2_semid_ds **)&fourth->buf);
5976+ if (err)
5977+ return (err);
5978+
5979+ err = copy_from_user(&is, isp, sizeof(is)) ? -EFAULT : 0;
5980+ if (err)
5981+ return (err);
5982+
5983+ isem_to_lsem(&is, &ls);
5984+ lsemun.buf = &ls;
5985+
5986+ fs = get_fs();
5987+ set_fs(get_ds());
5988+ err = sys_ipc(SEMCTL, first, second, third, &lsemun,0);
5989+ set_fs(fs);
5990+
5991+ if (err < 0)
5992+ return (err);
5993+
5994+ lsem_to_isem(&ls, &is);
5995+ return copy_to_user(isp, &is, sizeof(is)) ? -EFAULT : 0;
5996+}
5997+
5998+static int
5999+__abi4_semctl(int first, int second, int third, union semun *fourth)
6000+{
6001+ struct abi4_semid_ds is, *isp;
6002+ struct semid_ds ls;
6003+ union semun lsemun;
6004+ mm_segment_t fs;
6005+ int err;
6006+
6007+ err = get_user(isp, (struct abi4_semid_ds **)&fourth->buf);
6008+ if (err)
6009+ return (err);
6010+
6011+ err = copy_from_user(&is, isp, sizeof(is)) ? -EFAULT : 0;
6012+ if (err)
6013+ return (err);
6014+
6015+ isem_to_lsem_l(&is, &ls);
6016+ lsemun.buf = &ls;
6017+
6018+ fs = get_fs();
6019+ set_fs(get_ds());
6020+ err = sys_ipc(SEMCTL, first, second, third, &lsemun,0);
6021+ set_fs(fs);
6022+
6023+ if (err < 0)
6024+ return (err);
6025+
6026+ lsem_to_isem_l(&ls, &is);
6027+ return copy_to_user(isp, &is, sizeof(is)) ? -EFAULT : 0;
6028+}
6029+
6030+static int
6031+svr4_semctl(int arg1, int arg2, int arg3, union semun *arg4)
6032+{
6033+ int cmd = svr4sem2linux[arg3];
6034+
6035+ switch (arg3) {
6036+ case SVR4_SEM_SETALL:
6037+ case SVR4_SEM_GETALL:
6038+ return __ibcs2_semctl(arg1, 0, cmd, arg4);
6039+ case SVR4_IPC_RMID:
6040+ case SVR4_IPC_RMID_L:
6041+ case SVR4_SEM_SETVAL:
6042+ case SVR4_SEM_GETVAL:
6043+ case SVR4_SEM_GETPID:
6044+ case SVR4_SEM_GETNCNT:
6045+ case SVR4_SEM_GETZCNT:
6046+ return sys_ipc(SEMCTL, arg1, arg2, cmd, arg4, 0);
6047+ case SVR4_IPC_SET:
6048+ case SVR4_IPC_STAT:
6049+ return __ibcs2_semctl(arg1, arg2, cmd, arg4);
6050+ case SVR4_IPC_STAT_L:
6051+ case SVR4_IPC_SET_L:
6052+ return __abi4_semctl(arg1, arg2, cmd, arg4);
6053+ }
6054+
6055+ __abi_trace("semctl: unsupported command %d\n", arg3);
6056+ return -EINVAL;
6057+}
6058+
6059+static int
6060+svr4_semget(int arg1, int arg2, int arg3)
6061+{
6062+#if defined(CONFIG_ABI_TRACE)
6063+ abi_trace(ABI_TRACE_API, "semget(%d, %d, %o)\n", arg1, arg2, arg3);
6064+#endif
6065+ return sys_semget(arg1, arg2, arg3);
6066+
6067+}
6068+
6069+static int
6070+svr4_semop(int arg1, struct sembuf *arg2, int arg3)
6071+{
6072+#if defined(CONFIG_ABI_TRACE)
6073+ if (abi_traced(ABI_TRACE_API)) {
6074+ struct sembuf tmp, *tp = arg2;
6075+ int i;
6076+
6077+ for (i = 0; i < arg3; i++) {
6078+ copy_from_user (&tmp, tp, sizeof(tmp));
6079+ __abi_trace("semop(%d, %d, 0%o)\n",
6080+ tmp.sem_num, tmp.sem_op,
6081+ tmp.sem_flg);
6082+ tp++;
6083+ }
6084+ }
6085+#endif
6086+
6087+ return sys_semop(arg1, arg2, arg3);
6088+}
6089+
6090+int
6091+svr4_semsys(struct pt_regs *regp)
6092+{
6093+ int which, arg1, arg2, arg3;
6094+ union semun *arg4;
6095+
6096+ which = get_syscall_parameter(regp, 0);
6097+ arg1 = get_syscall_parameter(regp, 1);
6098+ arg2 = get_syscall_parameter(regp, 2);
6099+ arg3 = get_syscall_parameter(regp, 3);
6100+
6101+ /*
6102+ * XXX - The value for arg4 depends on how union
6103+ * passing is implement on this architecture and
6104+ * compiler. The following is *only* known to be
6105+ * right for Intel (the default else case).
6106+ */
6107+#ifdef __sparc__
6108+ arg4 = (union semun *)get_syscall_parameter(regp, 4);
6109+#else
6110+ arg4 = (union semun *)(((u_long *)regp->esp) + (5));
6111+#endif
6112+
6113+ switch (which) {
6114+ case SVR4_semctl:
6115+ return svr4_semctl(arg1, arg2, arg3, arg4);
6116+ case SVR4_semget:
6117+ return svr4_semget(arg1, arg2, arg3);
6118+ case SVR4_semop:
6119+ return svr4_semop(arg1, (struct sembuf *)arg2, arg3);
6120+ }
6121+
6122+ return -EINVAL;
6123+}
6124+
6125+static void
6126+ishm_to_lshm(struct ibcs2_shmid_ds *is, struct shmid_ds *ls)
6127+{
6128+ ip_to_lp(&is->shm_perm, &ls->shm_perm);
6129+ ls->shm_segsz = is->shm_segsz;
6130+ ls->shm_lpid = is->shm_lpid;
6131+ ls->shm_cpid = is->shm_cpid;
6132+ ls->shm_nattch = is->shm_nattch;
6133+ ls->shm_atime = is->shm_atime;
6134+ ls->shm_dtime = is->shm_dtime;
6135+ ls->shm_ctime = is->shm_ctime;
6136+}
6137+
6138+static void
6139+lshm_to_ishm(struct shmid_ds *ls, struct ibcs2_shmid_ds *is)
6140+{
6141+ lp_to_ip(&ls->shm_perm, &is->shm_perm);
6142+ is->shm_segsz = ls->shm_segsz;
6143+ is->shm_lpid = ls->shm_lpid;
6144+ is->shm_cpid = ls->shm_cpid;
6145+ is->shm_nattch = ls->shm_nattch;
6146+ is->shm_atime = ls->shm_atime;
6147+ is->shm_dtime = ls->shm_dtime;
6148+ is->shm_ctime = ls->shm_ctime;
6149+}
6150+
6151+static void
6152+ishm_to_lshm_l(struct abi4_shmid_ds *is, struct shmid_ds *ls)
6153+{
6154+ ip_to_lp_l(&is->shm_perm, &ls->shm_perm);
6155+ ls->shm_segsz = is->shm_segsz;
6156+ ls->shm_lpid = is->shm_lpid;
6157+ ls->shm_cpid = is->shm_cpid;
6158+ ls->shm_nattch = is->shm_nattch;
6159+ ls->shm_atime = is->shm_atime;
6160+ ls->shm_dtime = is->shm_dtime;
6161+ ls->shm_ctime = is->shm_ctime;
6162+}
6163+
6164+static void
6165+lshm_to_ishm_l(struct shmid_ds *ls, struct abi4_shmid_ds *is)
6166+{
6167+ memset(is, 0, sizeof(*is));
6168+ lp_to_ip_l(&ls->shm_perm, &is->shm_perm);
6169+ is->shm_segsz = ls->shm_segsz;
6170+ is->shm_lpid = ls->shm_lpid;
6171+ is->shm_cpid = ls->shm_cpid;
6172+ is->shm_nattch = ls->shm_nattch;
6173+ is->shm_atime = ls->shm_atime;
6174+ is->shm_dtime = ls->shm_dtime;
6175+ is->shm_ctime = ls->shm_ctime;
6176+}
6177+
6178+static int
6179+svr4_shmdt(struct pt_regs *regp)
6180+{
6181+ caddr_t addr = (caddr_t)get_syscall_parameter(regp, 1);
6182+
6183+#if defined(CONFIG_ABI_TRACE)
6184+ abi_trace(ABI_TRACE_API, "shmdt(%p)\n", addr);
6185+#endif
6186+ return sys_shmdt(addr);
6187+}
6188+
6189+static int
6190+svr4_shmctl(int arg1, int cmd, char *arg3)
6191+{
6192+ struct ibcs2_shmid_ds is;
6193+ struct abi4_shmid_ds is4;
6194+ struct shmid_ds ls;
6195+ mm_segment_t fs;
6196+ int err;
6197+
6198+#if defined(CONFIG_ABI_TRACE)
6199+ abi_trace(ABI_TRACE_API, "shmctl(%d, %x, %p)\n", arg1, cmd, arg3);
6200+#endif
6201+
6202+ switch (cmd) {
6203+ case SVR4_SHM_LOCK:
6204+ return sys_shmctl(arg1, SHM_LOCK, (struct shmid_ds *)arg3);
6205+ case SVR4_SHM_UNLOCK:
6206+ return sys_shmctl(arg1, SHM_UNLOCK, (struct shmid_ds *)arg3);
6207+ case SVR4_IPC_SET:
6208+ err = copy_from_user(&is, arg3, sizeof(is)) ? -EFAULT : 0;
6209+ if (err)
6210+ break;
6211+ ishm_to_lshm(&is, &ls);
6212+
6213+ fs = get_fs();
6214+ set_fs(get_ds());
6215+ err = sys_shmctl(arg1, IPC_SET, &ls);
6216+ set_fs(fs);
6217+
6218+ if (err < 0)
6219+ break;
6220+ lshm_to_ishm(&ls, &is);
6221+ err = copy_to_user(arg3, &is, sizeof(is)) ? -EFAULT : 0;
6222+ break;
6223+ case SVR4_IPC_SET_L:
6224+ err = copy_from_user(&is4, arg3, sizeof(is4)) ? -EFAULT : 0;
6225+ if (err)
6226+ break;
6227+ ishm_to_lshm_l(&is4, &ls);
6228+
6229+ fs = get_fs();
6230+ set_fs(get_ds());
6231+ err = sys_shmctl(arg1, IPC_SET, &ls);
6232+ set_fs(fs);
6233+
6234+ if (err < 0)
6235+ break;
6236+ lshm_to_ishm_l(&ls, &is4);
6237+ err = copy_to_user(arg3, &is4, sizeof(is4)) ? -EFAULT : 0;
6238+ break;
6239+ case SVR4_IPC_RMID:
6240+ case SVR4_IPC_RMID_L:
6241+ return sys_shmctl(arg1, IPC_RMID, (struct shmid_ds *)arg3);
6242+ case SVR4_IPC_STAT:
6243+ fs = get_fs();
6244+ set_fs(get_ds());
6245+ err = sys_shmctl(arg1, IPC_STAT, &ls);
6246+ set_fs(fs);
6247+
6248+ if (err < 0)
6249+ break;
6250+
6251+ lshm_to_ishm(&ls, &is);
6252+ err = copy_to_user(arg3, &is, sizeof(is)) ? -EFAULT : 0;
6253+ break;
6254+ case SVR4_IPC_STAT_L:
6255+ fs = get_fs();
6256+ set_fs(get_ds());
6257+ err = sys_shmctl(arg1, IPC_STAT, &ls);
6258+ set_fs(fs);
6259+ if (err < 0)
6260+ break;
6261+
6262+ lshm_to_ishm_l(&ls, &is4);
6263+ err = copy_to_user((char *)arg3, &is4, sizeof(is4)) ? -EFAULT : 0;
6264+ break;
6265+ default:
6266+#if defined(CONFIG_ABI_TRACE)
6267+ __abi_trace("shmctl: unsupported command %d\n", cmd);
6268+#endif
6269+ err = -EINVAL;
6270+ }
6271+
6272+ return (err);
6273+}
6274+
6275+int
6276+svr4_shmsys(struct pt_regs *regp)
6277+{
6278+ int arg1, arg2, arg3, cmd, err = 0;
6279+ u_long raddr;
6280+ mm_segment_t fs;
6281+
6282+ cmd = get_syscall_parameter(regp, 0);
6283+ if (cmd == SVR4_shmdt) {
6284+ err = svr4_shmdt(regp);
6285+ goto out;
6286+ }
6287+
6288+ arg1 = get_syscall_parameter(regp, 1);
6289+ arg2 = get_syscall_parameter(regp, 2);
6290+ arg3 = get_syscall_parameter(regp, 3);
6291+
6292+ switch (cmd) {
6293+ case SVR4_shmat:
6294+#if defined(CONFIG_ABI_TRACE)
6295+ abi_trace(ABI_TRACE_API, "shmat(%d, %x, %o)\n", arg1, arg2, arg3);
6296+#endif
6297+
6298+ fs = get_fs();
6299+ set_fs(get_ds());
6300+ err = do_shmat(arg1, (caddr_t)arg2, arg3, &raddr);
6301+ set_fs(fs);
6302+ if (err >= 0)
6303+ err = (int)raddr;
6304+
6305+#if defined(CONFIG_ABI_TRACE)
6306+ abi_trace(ABI_TRACE_API, "shmat returns %x\n", err);
6307+#endif
6308+ break;
6309+ case SVR4_shmget:
6310+#if defined(CONFIG_ABI_TRACE)
6311+ abi_trace(ABI_TRACE_API, "shmget(%d, %x, %o)\n", arg1, arg2, arg3);
6312+#endif
6313+ err = sys_shmget(arg1, arg2, arg3);
6314+#if defined(CONFIG_ABI_TRACE)
6315+ abi_trace(ABI_TRACE_API, "shmget returns %d\n", err);
6316+#endif
6317+ break;
6318+ case SVR4_shmctl:
6319+ err = svr4_shmctl(arg1, arg2, (char *)arg3);
6320+ break;
6321+ default:
6322+#if defined(CONFIG_ABI_TRACE)
6323+ __abi_trace("shmsys: unsupported command: %x\n", cmd);
6324+#endif
6325+ err = -EINVAL;
6326+ }
6327+
6328+out:
6329+ if (err < 0 && err > -255) {
6330+ set_error(regp, iABI_errors(-err));
6331+ abi_trace(ABI_TRACE_API, "Error %d\n", get_result(regp));
6332+ return 0;
6333+ }
6334+
6335+ clear_error(regp);
6336+ set_result(regp, err);
6337+ return 0;
6338+}
6339+
6340+static void
6341+imsq_to_lmsq(struct ibcs2_msqid_ds * im, struct msqid_ds * lm)
6342+{
6343+ ip_to_lp(&im->msg_perm, &lm->msg_perm);
6344+ lm->msg_first = im->msg_first;
6345+ lm->msg_last = im->msg_last;
6346+ lm->msg_cbytes = im->msg_cbytes;
6347+ lm->msg_qnum = im->msg_qnum;
6348+ lm->msg_qbytes = im->msg_qbytes;
6349+ lm->msg_lspid = im->msg_lspid;
6350+ lm->msg_lrpid = im->msg_lrpid;
6351+ lm->msg_stime = im->msg_stime;
6352+ lm->msg_rtime = im->msg_rtime;
6353+ lm->msg_ctime = im->msg_ctime;
6354+}
6355+
6356+static void
6357+lmsq_to_imsq(struct msqid_ds *lm, struct ibcs2_msqid_ds *im)
6358+{
6359+ lp_to_ip(&lm->msg_perm, &im->msg_perm);
6360+ im->msg_first = lm->msg_first;
6361+ im->msg_last = lm->msg_last;
6362+ im->msg_cbytes = lm->msg_cbytes;
6363+ im->msg_qnum = lm->msg_qnum;
6364+ im->msg_qbytes = lm->msg_qbytes;
6365+ im->msg_lspid = lm->msg_lspid;
6366+ im->msg_lrpid = lm->msg_lrpid;
6367+ im->msg_stime = lm->msg_stime;
6368+ im->msg_rtime = lm->msg_rtime;
6369+ im->msg_ctime = lm->msg_ctime;
6370+}
6371+
6372+static void
6373+imsq_to_lmsq_l(struct abi4_msqid_ds *im, struct msqid_ds *lm)
6374+{
6375+ ip_to_lp_l(&im->msg_perm, &lm->msg_perm);
6376+ lm->msg_first = im->msg_first;
6377+ lm->msg_last = im->msg_last;
6378+ lm->msg_cbytes = im->msg_cbytes;
6379+ lm->msg_qnum = im->msg_qnum;
6380+ lm->msg_qbytes = im->msg_qbytes;
6381+ lm->msg_lspid = im->msg_lspid;
6382+ lm->msg_lrpid = im->msg_lrpid;
6383+ lm->msg_stime = im->msg_stime;
6384+ lm->msg_rtime = im->msg_rtime;
6385+ lm->msg_ctime = im->msg_ctime;
6386+}
6387+
6388+static void
6389+lmsq_to_imsq_l(struct msqid_ds *lm, struct abi4_msqid_ds *im)
6390+{
6391+ memset(im, 0, sizeof(*im));
6392+ lp_to_ip_l(&lm->msg_perm, &im->msg_perm);
6393+ im->msg_first = lm->msg_first;
6394+ im->msg_last = lm->msg_last;
6395+ im->msg_cbytes = lm->msg_cbytes;
6396+ im->msg_qnum = lm->msg_qnum;
6397+ im->msg_qbytes = lm->msg_qbytes;
6398+ im->msg_lspid = lm->msg_lspid;
6399+ im->msg_lrpid = lm->msg_lrpid;
6400+ im->msg_stime = lm->msg_stime;
6401+ im->msg_rtime = lm->msg_rtime;
6402+ im->msg_ctime = lm->msg_ctime;
6403+}
6404+
6405+static int
6406+svr4_msgctl(int arg1, int cmd, char *arg3)
6407+{
6408+ struct ibcs2_msqid_ds im;
6409+ struct abi4_msqid_ds im4;
6410+ struct msqid_ds lm;
6411+ mm_segment_t fs;
6412+ int err;
6413+
6414+ switch (cmd) {
6415+ case SVR4_IPC_SET:
6416+ err = copy_from_user(&im, arg3, sizeof(im)) ? -EFAULT : 0;
6417+ if (err)
6418+ break;
6419+
6420+ imsq_to_lmsq(&im, &lm);
6421+
6422+ fs = get_fs();
6423+ set_fs(get_ds());
6424+ err = sys_msgctl(arg1, IPC_SET, &lm);
6425+ set_fs(fs);
6426+
6427+ lmsq_to_imsq(&lm, &im);
6428+ err = copy_to_user(arg3, &im, sizeof(im)) ? -EFAULT : 0;
6429+ break;
6430+ case SVR4_IPC_SET_L:
6431+ err = copy_from_user(&im4, arg3, sizeof(im4)) ? -EFAULT : 0;
6432+ if (err)
6433+ break;
6434+ imsq_to_lmsq_l(&im4, &lm);
6435+
6436+ fs = get_fs();
6437+ set_fs(get_ds());
6438+ err = sys_msgctl(arg1, IPC_SET, &lm);
6439+ set_fs(fs);
6440+
6441+ lmsq_to_imsq_l(&lm, &im4);
6442+ err = copy_to_user(arg3, &im4, sizeof(im4)) ? -EFAULT : 0;
6443+ break;
6444+ case SVR4_IPC_RMID:
6445+ case SVR4_IPC_RMID_L:
6446+ return sys_msgctl(arg1, IPC_RMID, (struct msqid_ds *)arg3);
6447+ case SVR4_IPC_STAT:
6448+ fs = get_fs();
6449+ set_fs(get_ds());
6450+ err = sys_msgctl(arg1, IPC_STAT, &lm);
6451+ set_fs(fs);
6452+
6453+ if (err < 0)
6454+ break;
6455+
6456+ lmsq_to_imsq(&lm, &im);
6457+ err = copy_to_user(arg3, &im, sizeof(im)) ? -EFAULT : 0;
6458+ break;
6459+ case SVR4_IPC_STAT_L:
6460+ fs = get_fs();
6461+ set_fs(get_ds());
6462+ err = sys_msgctl(arg1, IPC_STAT, &lm);
6463+ set_fs(fs);
6464+
6465+ if (err < 0)
6466+ break;
6467+
6468+ lmsq_to_imsq_l(&lm, &im4);
6469+ err = copy_to_user(arg3, &im4, sizeof(im4)) ? -EFAULT : 0;
6470+ break;
6471+ default:
6472+ __abi_trace("msgctl: unsupported command: %x\n", cmd);
6473+ err = -EINVAL;
6474+ }
6475+
6476+ return (err);
6477+}
6478+
6479+int
6480+svr4_msgsys(struct pt_regs *regp)
6481+{
6482+ int err, cmd, arg1, arg2, arg3, arg4, arg5;
6483+
6484+ /*
6485+ * Special handling as msgrcv is ugly.
6486+ */
6487+ cmd = get_syscall_parameter(regp, 0);
6488+ arg1 = get_syscall_parameter(regp, 1);
6489+ arg2 = get_syscall_parameter(regp, 2);
6490+
6491+ switch (cmd) {
6492+ case SVR4_msgget:
6493+ return sys_msgget((key_t)arg1, arg2);
6494+ case SVR4_msgctl:
6495+ arg3 = get_syscall_parameter(regp, 3);
6496+ return svr4_msgctl(arg1, arg2, (caddr_t)arg3);
6497+ case SVR4_msgrcv:
6498+ arg3 = get_syscall_parameter(regp, 3);
6499+ arg4 = get_syscall_parameter(regp, 4);
6500+ arg5 = get_syscall_parameter(regp, 5);
6501+ return sys_msgrcv(arg1, (struct msgbuf *)arg2, arg3, arg4, arg5);
6502+ case SVR4_msgsnd:
6503+ arg3 = get_syscall_parameter(regp, 3);
6504+ arg4 = get_syscall_parameter(regp, 4);
6505+ err = sys_msgsnd(arg1, (struct msgbuf *)arg2, arg3, arg4);
6506+ return ((err > 0) ? 0 : err);
6507+ }
6508+
6509+ __abi_trace("msgsys: unsupported command: %x\n", cmd);
6510+ return -EINVAL;
6511+}
6512+
6513+#if defined(CONFIG_ABI_SYSCALL_MODULES)
6514+EXPORT_SYMBOL(svr4_msgsys);
6515+EXPORT_SYMBOL(svr4_semsys);
6516+EXPORT_SYMBOL(svr4_shmsys);
6517+#endif
6518diff -Nru linux-2.6.7/abi/svr4/Makefile linux-2.6.7-abi/abi/svr4/Makefile
6519--- linux-2.6.7/abi/svr4/Makefile 1970-01-01 01:00:00.000000000 +0100
6520+++ linux-2.6.7-abi/abi/svr4/Makefile 2004-07-22 17:44:20.000000000 +0200
6521@@ -0,0 +1,20 @@
6522+
6523+svr4-y := hrtsys.o ioctl.o ipc.o mmap.o open.o svr4.o sysconf.o \
6524+ sysfs.o sysinfo.o sysi86.o ulimit.o utsname.o stream.o \
6525+ stat.o socksys.o signal.o misc.o socket.o statvfs.o \
6526+ fcntl.o
6527+
6528+# emulations for all kinds of weird ioctls...
6529+svr4-y += filio.o termios.o consio.o tapeio.o sockio.o
6530+
6531+# networking
6532+svr4-$(CONFIG_ABI_XTI) += timod.o xti.o
6533+svr4-$(CONFIG_ABI_SPX) += timod.o
6534+
6535+abi-svr4-objs += $(sort $(svr4-y))
6536+
6537+
6538+obj-$(CONFIG_ABI_SVR4) += abi-svr4.o
6539+
6540+abi-svr4.o: $(abi-svr4-objs)
6541+ $(LD) -r -o $@ $(abi-svr4-objs)
6542diff -Nru linux-2.6.7/abi/svr4/misc.c linux-2.6.7-abi/abi/svr4/misc.c
6543--- linux-2.6.7/abi/svr4/misc.c 1970-01-01 01:00:00.000000000 +0100
6544+++ linux-2.6.7-abi/abi/svr4/misc.c 2004-07-22 17:44:20.000000000 +0200
6545@@ -0,0 +1,659 @@
6546+/*
6547+ * Copyright (C) 1993 Linus Torvalds
6548+ * Copyright (C) 2001 Caldera Deutschland GmbH
6549+ *
6550+ * Modified by Eric Youngdale to include all ibcs syscalls.
6551+ * Re-written by Drew Sullivan to handle lots more of the syscalls correctly.
6552+ */
6553+
6554+#ident "%W% %G%"
6555+
6556+#include <linux/module.h>
6557+#include <linux/types.h>
6558+#include <linux/errno.h>
6559+#include <linux/sched.h>
6560+#include <linux/kernel.h>
6561+#include <linux/mm.h>
6562+#include <linux/gfp.h>
6563+#include <linux/stat.h>
6564+#include <linux/stddef.h>
6565+#include <linux/unistd.h>
6566+#include <linux/ptrace.h>
6567+#include <linux/fcntl.h>
6568+#include <linux/time.h>
6569+#include <linux/personality.h>
6570+#include <linux/syscalls.h>
6571+
6572+#include <linux/fs.h>
6573+#include <linux/sys.h>
6574+#include <linux/slab.h>
6575+#include <linux/file.h>
6576+#include <linux/dirent.h>
6577+
6578+#include <asm/uaccess.h>
6579+#include <asm/system.h>
6580+
6581+#include <abi/signal.h>
6582+#include <abi/util/trace.h>
6583+
6584+#include <abi/svr4/types.h>
6585+
6586+
6587+MODULE_DESCRIPTION("common code for SVR3/SVR4 based personalities");
6588+MODULE_AUTHOR("Christoph Hellwig, partially taken from iBCS");
6589+MODULE_LICENSE("GPL");
6590+
6591+
6592+int
6593+abi_time(void)
6594+{
6595+ return sys_time(0);
6596+}
6597+
6598+int
6599+abi_brk(unsigned long brk)
6600+{
6601+ unsigned long newbrk = PAGE_ALIGN(brk), oldbrk, sysbrk;
6602+
6603+ down_read(&current->mm->mmap_sem);
6604+ if (!brk)
6605+ goto report;
6606+ oldbrk = PAGE_ALIGN(current->mm->brk);
6607+ up_read(&current->mm->mmap_sem);
6608+
6609+ if (newbrk != oldbrk) {
6610+ sysbrk = sys_brk(brk);
6611+ if (PAGE_ALIGN(sysbrk) != newbrk)
6612+ return -ENOMEM;
6613+ }
6614+ return 0;
6615+
6616+report:
6617+ /* return non-pagealigned old brk value */
6618+ oldbrk = current->mm->brk;
6619+ up_read(&current->mm->mmap_sem);
6620+ return oldbrk;
6621+}
6622+
6623+/*
6624+ * UNIX wants a 0-edx after fork and may have set
6625+ * the carry flag before calling fork.
6626+ */
6627+int
6628+abi_fork(struct pt_regs *regs)
6629+{
6630+ int retval;
6631+
6632+ regs->eflags &= ~1;
6633+ retval = do_fork(SIGCHLD, regs->esp, regs, 0,
6634+ /* parent_tidptr */NULL, /* child_tidptr */NULL);
6635+ regs->edx = 0;
6636+ return retval;
6637+}
6638+
6639+/*
6640+ * Unlike Linux, UNIX does not use C calling conventions
6641+ * for pipe().
6642+ */
6643+int
6644+abi_pipe(struct pt_regs *regs)
6645+{
6646+ int filedes[2], retval;
6647+
6648+ retval = do_pipe(filedes);
6649+ if (retval == 0) {
6650+ retval = filedes[0];
6651+ regs->edx = filedes[1];
6652+ }
6653+ return retval;
6654+}
6655+
6656+/*
6657+ * Note the double value return in eax and edx.
6658+ */
6659+int
6660+abi_getpid(struct pt_regs *regs)
6661+{
6662+ regs->edx = current->parent->pid;
6663+ return current->pid;
6664+}
6665+
6666+/*
6667+ * Note the double value return in eax and edx.
6668+ */
6669+int
6670+abi_getuid(struct pt_regs *regs)
6671+{
6672+ regs->edx = current->euid;
6673+ return current->uid;
6674+}
6675+
6676+/*
6677+ * Note the double value return in eax and edx.
6678+ */
6679+int
6680+abi_getgid(struct pt_regs *regs)
6681+{
6682+ regs->edx = current->egid;
6683+ return current->gid;
6684+}
6685+
6686+
6687+
6688+enum {
6689+ FLAG_ZF = 0x0040,
6690+ FLAG_PF = 0x0004,
6691+ FLAG_SF = 0x0080,
6692+ FLAG_OF = 0x0800,
6693+};
6694+
6695+#define MAGIC_WAITPID_FLAG (FLAG_ZF | FLAG_PF | FLAG_SF | FLAG_OF)
6696+
6697+int
6698+abi_wait(struct pt_regs * regs)
6699+{
6700+ mm_segment_t fs;
6701+ long result, kopt = 0;
6702+ int loc, opt;
6703+ pid_t pid;
6704+
6705+ /*
6706+ * Xenix wait() puts status to edx and returns pid.
6707+ *
6708+ * XXX xenix should get it's own syyent table so we can
6709+ * XXX rip this cruft out.
6710+ */
6711+ if (is_cur_personality(PER_XENIX)) {
6712+ fs = get_fs();
6713+ set_fs(get_ds());
6714+ result = sys_wait4(-1, &loc, 0, NULL);
6715+ set_fs(fs);
6716+
6717+ regs->edx = loc;
6718+ return result;
6719+ }
6720+
6721+ /*
6722+ * if ZF,PF,SF,and OF are set then it is waitpid
6723+ */
6724+ if ((regs->eflags & MAGIC_WAITPID_FLAG) == MAGIC_WAITPID_FLAG) {
6725+ get_user(pid, ((u_long *)regs->esp)+1);
6726+ get_user(loc, ((u_long *)regs->esp)+2);
6727+ get_user(opt, ((u_long *)regs->esp)+3);
6728+
6729+ /*
6730+ * Now translate the options from the SVr4 numbers
6731+ */
6732+ if (opt & 0100)
6733+ kopt |= WNOHANG;
6734+ if (opt & 4)
6735+ kopt |= WUNTRACED;
6736+
6737+ result = sys_wait4(pid, (u_int *)loc, kopt, NULL);
6738+ } else {
6739+ get_user(loc, ((u_long *)regs->esp)+1);
6740+ result = sys_wait4(-1, (u_int *)loc, WUNTRACED, NULL);
6741+ }
6742+
6743+ if (result < 0 || !loc)
6744+ return result;
6745+
6746+ get_user(regs->edx, (u_long *)loc);
6747+ if ((regs->edx & 0xff) == 0x7f) {
6748+ int sig;
6749+
6750+ sig = (regs->edx >> 8) & 0xff;
6751+ if (sig < NSIGNALS)
6752+ sig = current_thread_info()->exec_domain->signal_map[sig];
6753+ regs->edx = (regs->edx & (~0xff00)) | (sig << 8);
6754+ put_user(regs->edx, (u_long *)loc);
6755+ } else if (regs->edx && regs->edx == (regs->edx & 0xff)) {
6756+ if ((regs->edx & 0x7f) < NSIGNALS)
6757+ regs->edx = current_thread_info()->exec_domain->signal_map[regs->edx & 0x7f];
6758+ put_user(regs->edx, (u_long *)loc);
6759+ }
6760+ return result;
6761+}
6762+
6763+#if defined(CONFIG_ABI_TRACE)
6764+/*
6765+ * Trace arguments of exec().
6766+ *
6767+ * We show up to twenty arguments and enviroment variables.
6768+ * This could as well be sysctl configurable.
6769+ */
6770+static void
6771+trace_exec(struct pt_regs *regs, char *pgm, char **argv, char **envp)
6772+{
6773+ char **v, *p = NULL, *q = NULL;
6774+ int i;
6775+
6776+ q = getname(pgm);
6777+ if (IS_ERR(q)) {
6778+ __abi_trace("\tpgm: %p pointer error %ld\n", pgm, PTR_ERR(q));
6779+ } else {
6780+ __abi_trace("\tpgm: %p \"%s\"\n", pgm, q);
6781+ putname(q);
6782+ }
6783+
6784+ for (i = 0, v = argv; v && i < 20; v++, i++) {
6785+ if (get_user(p, v) || !p)
6786+ break;
6787+
6788+ q = getname(p);
6789+ if (IS_ERR(q)) {
6790+ __abi_trace("\targ: %p pointer error %ld\n",
6791+ p, PTR_ERR(q));
6792+ } else {
6793+ __abi_trace("\targ: %p \"%s\"\n", p, q);
6794+ putname(q);
6795+ }
6796+ }
6797+
6798+ if (v && p)
6799+ __abi_trace("\targ: ...\n");
6800+
6801+ for (i = 0, v = envp; v && i < 20; v++, i++) {
6802+ if (get_user(p, v) || !p)
6803+ break;
6804+
6805+ q = getname(p);
6806+ if (IS_ERR(q)) {
6807+ __abi_trace("\tenv: %p pointer error %ld\n",
6808+ p, PTR_ERR(q));
6809+ } else {
6810+ __abi_trace("\tenv: %p \"%s\"\n", p, q);
6811+ putname(q);
6812+ }
6813+ }
6814+
6815+ if (v && p)
6816+ __abi_trace("\tenv: ...\n");
6817+}
6818+#endif
6819+
6820+/*
6821+ * Execute a new program.
6822+ *
6823+ * The difference from the native version is that we
6824+ * optionally trace the arguments.
6825+ */
6826+int
6827+abi_exec(struct pt_regs *regs)
6828+{
6829+ char *pgm, **argv, **envp;
6830+ char *filename;
6831+ int error;
6832+
6833+ get_user((u_long)pgm, ((u_long *)regs->esp)+1);
6834+ get_user((u_long)argv, ((u_long *)regs->esp)+2);
6835+ get_user((u_long)envp, ((u_long *)regs->esp)+3);
6836+
6837+#if defined(CONFIG_ABI_TRACE)
6838+ if (abi_traced(ABI_TRACE_API))
6839+ trace_exec(regs, pgm, argv, envp);
6840+#endif
6841+
6842+ filename = getname(pgm);
6843+ if (!IS_ERR(filename)) {
6844+ error = do_execve(filename, argv, envp, regs);
6845+ putname (filename);
6846+ } else
6847+ error = PTR_ERR(filename);
6848+ return error;
6849+}
6850+
6851+/*
6852+ * Yet another crufy SysV multiplexed syscall.
6853+ * This time it's all the process group and session handling.
6854+ *
6855+ * NOTE: we return EPERM on get_user failures as EFAULT is not
6856+ * a valid return value for theses calls.
6857+ */
6858+int
6859+abi_procids(struct pt_regs *regs)
6860+{
6861+ int offset = 0, op;
6862+
6863+ if (get_user(op, ((u_long *)regs->esp)+1))
6864+ return -EPERM;
6865+
6866+ /* Remap op codes for current personality if necessary. */
6867+ switch (get_cur_personality_id()) {
6868+ case (PERID_SVR3):
6869+ case (PERID_SCOSVR3):
6870+ case (PERID_WYSEV386):
6871+ case (PERID_XENIX):
6872+ /*
6873+ * SCO at least uses an interesting library to
6874+ * syscall mapping that leaves an extra return
6875+ * address between the op code and the arguments.
6876+ *
6877+ * WTF does SCO at least mean?
6878+ * Could someone please verify this with another
6879+ * SVR3 derivate as I have none.
6880+ * --hch
6881+ */
6882+ offset = 1;
6883+
6884+ if (op < 0 || op > 5)
6885+ return -EINVAL;
6886+ op = "\000\001\005\003\377\377"[op];
6887+ }
6888+
6889+ switch (op) {
6890+ case 0: /* getpgrp */
6891+ return process_group(current);
6892+
6893+ case 1: /* setpgrp */
6894+ sys_setpgid(0, 0);
6895+ return process_group(current);
6896+
6897+ case 2: /* getsid */
6898+ {
6899+ pid_t pid;
6900+
6901+ if (get_user(pid, ((u_long *)regs->esp)+2 + offset))
6902+ return -EPERM;
6903+ return sys_getsid(pid);
6904+ }
6905+
6906+ case 3: /* setsid */
6907+ return sys_setsid();
6908+
6909+ case 4: /* getpgid */
6910+ {
6911+ pid_t pid;
6912+
6913+ if (get_user(pid, ((u_long *)regs->esp)+2 + offset))
6914+ return -EPERM;
6915+ return sys_getpgid(pid);
6916+ }
6917+
6918+ case 5: /* setpgid */
6919+ {
6920+ pid_t pid, pgid;
6921+
6922+ if (get_user(pid, ((u_long *)regs->esp)+2 + offset))
6923+ return -EPERM;
6924+ if (get_user(pgid, ((u_long *)regs->esp)+3 + offset))
6925+ return -EPERM;
6926+ return sys_setpgid(pid, pgid);
6927+ }
6928+ }
6929+
6930+ return -EINVAL;
6931+}
6932+
6933+
6934+/*
6935+ * Stupid bloody thing is trying to read a directory.
6936+ *
6937+ * Some old programs expect this to work. It works on SCO.
6938+ * To emulate it we have to map a dirent to a direct. This
6939+ * involves shrinking a long inode to a short. Fortunately
6940+ * nothing this archaic is likely to care about anything
6941+ * but the filenames of entries with non-zero inodes.
6942+ */
6943+int
6944+abi_read_dir(int fd, char *buf, int count)
6945+{
6946+ struct file *fp;
6947+ struct old_linux_dirent *de;
6948+ mm_segment_t fs;
6949+ int error, here;
6950+ int posn = 0, reclen = 0;
6951+
6952+
6953+ fp = fget(fd);
6954+ if (!fp)
6955+ return -EBADF;
6956+
6957+ error = -ENOMEM;
6958+ de = (struct old_linux_dirent *)__get_free_page(GFP_KERNEL);
6959+ if (!de)
6960+ goto out_fput;
6961+
6962+ error = 0;
6963+ while (posn + reclen < count) {
6964+ char *p;
6965+
6966+ /*
6967+ * Save the current position and get another dirent
6968+ */
6969+ here = fp->f_pos;
6970+
6971+ fs = get_fs();
6972+ set_fs (get_ds());
6973+ error = old_readdir(fd, de, 1);
6974+ set_fs(fs);
6975+
6976+ if (error <= 0)
6977+ break;
6978+
6979+ /*
6980+ * If it'll fit in the buffer save it.
6981+ * Otherwise back up so it is read next time around.
6982+ * Oh, if we're at the beginning of the buffer there's
6983+ * no chance that this entry will ever fit so don't
6984+ * copy it and don't back off - we'll just pretend it
6985+ * isn't here...
6986+ */
6987+
6988+ /*
6989+ * SCO (at least) handles long filenames by breaking
6990+ * them up in to 14 character chunks of which all
6991+ * but the last have the inode set to 0xffff.
6992+ * Those chunks will get aligned to a 4 byte boundary
6993+ * thus leaving two bytes in each entry for other purposes.
6994+ *
6995+ * Well, that's SCO E(A)FS.
6996+ * HTFS and DTFS should handle it better.
6997+ * --hch
6998+ */
6999+ reclen = 16 * ((de->d_namlen + 13) / 14);
7000+ if (posn + reclen > count) {
7001+ if (posn)
7002+ sys_lseek(fd, here, 0);
7003+ continue;
7004+ }
7005+
7006+ p = de->d_name;
7007+
7008+ /*
7009+ * Put all but the last chunk.
7010+ */
7011+ while (de->d_namlen > 14) {
7012+ put_user(0xffff, (u_short *)(buf+posn));
7013+ posn += 2;
7014+ if (copy_to_user(buf+posn, p, 14))
7015+ goto out_fault;
7016+ posn += 14;
7017+ p += 14;
7018+ de->d_namlen -= 14;
7019+ }
7020+
7021+ /*
7022+ * Put the last chunk. Note the we have to fold a
7023+ * long inode number down to a short avoiding
7024+ * giving a zero inode number since that indicates
7025+ * an unused directory slot. Note also that the
7026+ * folding used here must match that used in stat()
7027+ * or path finding programs that do read() on
7028+ * directories will fail.
7029+ */
7030+#if 0
7031+ /*
7032+ * This appears to match what SCO does for
7033+ * reads on a directory with long inodes.
7034+ */
7035+ if ((u_long)de->d_ino > 0xfffe) {
7036+ if (put_user(0xfffe, buf+posn))
7037+ goto out_fault;
7038+ } else {
7039+ if (put_user((short)de->d_ino, buf+posn))
7040+ goto out_fault;
7041+ }
7042+#else
7043+ /*
7044+ * This attempts to match the way stat and
7045+ * getdents fold long inodes to shorts.
7046+ */
7047+ if ((u_long)de->d_ino & 0xffff ) {
7048+ if (put_user((u_long)de->d_ino & 0xffff, buf+posn))
7049+ goto out_fault;
7050+ } else {
7051+ if (put_user(0xfffe, buf+posn))
7052+ goto out_fault;
7053+ }
7054+#endif
7055+ posn += 2;
7056+ if (copy_to_user(buf+posn, p, de->d_namlen))
7057+ goto out_fault;
7058+
7059+ /*
7060+ * Ensure that filenames that don't fill the array
7061+ * completely are null filled.
7062+ */
7063+ for (; de->d_namlen < 14; de->d_namlen++) {
7064+ if (put_user('\0', buf+posn+de->d_namlen))
7065+ goto out_fault;
7066+ }
7067+ posn += 14;
7068+ }
7069+
7070+ free_page((u_long)de);
7071+ fput(fp);
7072+
7073+ /*
7074+ * If we've put something in the buffer return the byte count
7075+ * otherwise return the error status.
7076+ */
7077+ return (posn ? posn : error);
7078+
7079+out_fault:
7080+ error = -EFAULT;
7081+ free_page((u_long)de);
7082+out_fput:
7083+ fput(fp);
7084+ return error;
7085+}
7086+
7087+/*
7088+ * We could use Linux read if there wouldn't be the
7089+ * read on directory issue..
7090+ */
7091+int
7092+abi_read(int fd, char *buf, int count)
7093+{
7094+ int error;
7095+
7096+ error = sys_read(fd, buf, count);
7097+ if (error == -EISDIR)
7098+ error = abi_read_dir(fd, buf, count);
7099+ return error;
7100+}
7101+
7102+/*
7103+ * Linux doesn't allow trailing slashes in mkdir.
7104+ * Old UNIX apps expect it work anyway, so we have
7105+ * to get rid of them here.
7106+ */
7107+int
7108+abi_mkdir(const char *fname, int mode)
7109+{
7110+ mm_segment_t fs;
7111+ char *tmp, *p;
7112+ int error;
7113+
7114+ tmp = getname(fname);
7115+ if (IS_ERR(tmp))
7116+ return PTR_ERR(tmp);
7117+
7118+ for (p = tmp; *p; p++);
7119+ p--;
7120+ if (*p == '/')
7121+ *p = '\0';
7122+
7123+ fs = get_fs();
7124+ set_fs(get_ds());
7125+ error = sys_mkdir(tmp, mode);
7126+ set_fs(fs);
7127+
7128+ putname(tmp);
7129+ return error;
7130+}
7131+
7132+/*
7133+ * Unlike UNIX Linux doesn't allow to create
7134+ * directories using mknod.
7135+ */
7136+int
7137+svr4_mknod(char *filename, svr4_o_mode_t mode, svr4_o_dev_t dev)
7138+{
7139+ if ((mode & 0017000) == 0040000)
7140+ return abi_mkdir(filename, mode);
7141+ return sys_mknod(filename, mode, dev);
7142+}
7143+
7144+static int
7145+svr4_do_xmknod(char *filename, svr4_mode_t mode, svr4_dev_t dev)
7146+{
7147+ u_int minor = (dev & 0x3ffff), major = (dev >> 18);
7148+
7149+ if (minor > 0xff || major > 0xff)
7150+ return -EINVAL;
7151+ return svr4_mknod(filename, mode, ((major << 8) | minor));
7152+}
7153+
7154+
7155+enum {SVR4_mknod = 1, SVR4_xmknod = 2};
7156+
7157+int
7158+svr4_xmknod(int vers, char *filename, svr4_mode_t mode, svr4_dev_t dev)
7159+{
7160+ switch (vers) {
7161+ case SVR4_mknod:
7162+ return svr4_mknod(filename, mode, dev);
7163+ case SVR4_xmknod:
7164+ return svr4_do_xmknod(filename, mode, dev);
7165+ }
7166+
7167+#if defined(CONFIG_ABI_TRACE)
7168+ abi_trace(ABI_TRACE_API, "xmknod version %d not supported\n", vers);
7169+#endif
7170+ return -EINVAL;
7171+}
7172+
7173+int
7174+abi_kill(int pid, int sig)
7175+{
7176+ int insig, outsig;
7177+
7178+ insig = (sig & 0xff);
7179+ outsig = current_thread_info()->exec_domain->signal_map[insig];
7180+
7181+#if defined(CONFIG_ABI_TRACE)
7182+ abi_trace(ABI_TRACE_SIGNAL, "kill: %d -> %d\n", insig, outsig);
7183+#endif
7184+
7185+ return sys_kill(pid, outsig);
7186+}
7187+
7188+#if defined(CONFIG_ABI_SYSCALL_MODULES)
7189+EXPORT_SYMBOL(abi_brk);
7190+EXPORT_SYMBOL(abi_exec);
7191+EXPORT_SYMBOL(abi_fork);
7192+EXPORT_SYMBOL(abi_getgid);
7193+EXPORT_SYMBOL(abi_getpid);
7194+EXPORT_SYMBOL(abi_getuid);
7195+EXPORT_SYMBOL(abi_kill);
7196+EXPORT_SYMBOL(abi_mkdir);
7197+EXPORT_SYMBOL(abi_pipe);
7198+EXPORT_SYMBOL(abi_procids);
7199+EXPORT_SYMBOL(abi_read);
7200+EXPORT_SYMBOL(abi_time);
7201+EXPORT_SYMBOL(abi_wait);
7202+EXPORT_SYMBOL(svr4_mknod);
7203+EXPORT_SYMBOL(svr4_xmknod);
7204+#endif
7205diff -Nru linux-2.6.7/abi/svr4/mmap.c linux-2.6.7-abi/abi/svr4/mmap.c
7206--- linux-2.6.7/abi/svr4/mmap.c 1970-01-01 01:00:00.000000000 +0100
7207+++ linux-2.6.7-abi/abi/svr4/mmap.c 2004-07-22 17:44:20.000000000 +0200
7208@@ -0,0 +1,75 @@
7209+/*
7210+ * Copyright (c) 2001 Christoph Hellwig.
7211+ * All rights reserved.
7212+ *
7213+ * This program is free software; you can redistribute it and/or modify
7214+ * it under the terms of the GNU General Public License as published by
7215+ * the Free Software Foundation; either version 2 of the License, or
7216+ * (at your option) any later version.
7217+ *
7218+ * This program is distributed in the hope that it will be useful,
7219+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7220+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7221+ * GNU General Public License for more details.
7222+ *
7223+ * You should have received a copy of the GNU General Public License
7224+ * along with this program; if not, write to the Free Software
7225+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
7226+ */
7227+
7228+#ident "%W% %G%"
7229+
7230+/*
7231+ * Support for mmap on SVR4 and derivates.
7232+ */
7233+#include <linux/mm.h>
7234+#include <linux/errno.h>
7235+#include <linux/file.h>
7236+#include <linux/mman.h>
7237+#include <linux/module.h>
7238+
7239+#include <asm/uaccess.h>
7240+
7241+#include <abi/svr4/mman.h>
7242+#include <abi/svr4/types.h>
7243+
7244+#include <abi/util/trace.h>
7245+
7246+
7247+u_long
7248+svr4_mmap(u_long addr, size_t len, int prot, int flags, int fd, svr4_off_t off)
7249+{
7250+ struct file *file = NULL;
7251+ u_long mapaddr;
7252+
7253+ if (flags & SVR4_MAP_UNIMPL) {
7254+#if defined(CONFIG_ABI_TRACE)
7255+ abi_trace(ABI_TRACE_UNIMPL,
7256+ "unsupported mmap flags: 0x%x\n", flags & SVR4_MAP_UNIMPL);
7257+#endif
7258+ flags &= ~SVR4_MAP_UNIMPL;
7259+ }
7260+
7261+ if (!(flags & SVR4_MAP_ANONYMOUS)) {
7262+ file = fget(fd);
7263+ if (!file)
7264+ goto Ebadfd;
7265+
7266+ flags &= ~SVR4_MAP_ANONYMOUS;
7267+ flags |= MAP_ANONYMOUS;
7268+ }
7269+
7270+ down_write(&current->mm->mmap_sem);
7271+ mapaddr = do_mmap(file, addr, len, prot, flags, off);
7272+ up_write(&current->mm->mmap_sem);
7273+
7274+ if (file)
7275+ fput(file);
7276+ return mapaddr;
7277+Ebadfd:
7278+ return -EBADFD;
7279+}
7280+
7281+#if defined(CONFIG_ABI_SYSCALL_MODULES)
7282+EXPORT_SYMBOL(svr4_mmap);
7283+#endif
7284diff -Nru linux-2.6.7/abi/svr4/open.c linux-2.6.7-abi/abi/svr4/open.c
7285--- linux-2.6.7/abi/svr4/open.c 1970-01-01 01:00:00.000000000 +0100
7286+++ linux-2.6.7-abi/abi/svr4/open.c 2004-07-22 17:44:20.000000000 +0200
7287@@ -0,0 +1,318 @@
7288+/*
7289+ * Copyright (c) 1993 Joe Portman (baron@hebron.connected.com)
7290+ * Copyright (c) 1993, 1994 Drew Sullivan (re-worked for iBCS2)
7291+ * Copyright (c) 2000 Christoph Hellwig (rewrote lookup-related code)
7292+ */
7293+
7294+#ident "%W% %G%"
7295+
7296+#include <linux/config.h>
7297+#include <linux/module.h>
7298+
7299+#include <linux/vfs.h>
7300+#include <linux/types.h>
7301+#include <linux/utime.h>
7302+#include <linux/errno.h>
7303+#include <linux/fcntl.h>
7304+#include <linux/stat.h>
7305+#include <linux/string.h>
7306+#include <linux/sched.h>
7307+#include <linux/kernel.h>
7308+#include <linux/signal.h>
7309+#include <linux/tty.h>
7310+#include <linux/time.h>
7311+#include <linux/slab.h>
7312+#include <linux/socket.h>
7313+#include <linux/net.h>
7314+#include <linux/un.h>
7315+#include <linux/file.h>
7316+#include <linux/dirent.h>
7317+#include <linux/personality.h>
7318+#include <linux/syscalls.h>
7319+#include <linux/namei.h>
7320+
7321+#include <asm/uaccess.h>
7322+#include <asm/bitops.h>
7323+
7324+#include <asm/abi_machdep.h>
7325+#include <abi/svr4/statfs.h>
7326+#include <abi/svr4/sysent.h>
7327+
7328+#include <abi/util/trace.h>
7329+#include <abi/util/map.h>
7330+
7331+
7332+static int
7333+copy_kstatfs(struct svr4_statfs *buf, struct kstatfs *st)
7334+{
7335+ struct svr4_statfs ibcsstat;
7336+
7337+ ibcsstat.f_type = st->f_type;
7338+ ibcsstat.f_bsize = st->f_bsize;
7339+ ibcsstat.f_frsize = 0;
7340+ ibcsstat.f_blocks = st->f_blocks;
7341+ ibcsstat.f_bfree = st->f_bfree;
7342+ ibcsstat.f_files = st->f_files;
7343+ ibcsstat.f_ffree = st->f_ffree;
7344+ memset(ibcsstat.f_fname, 0, sizeof(ibcsstat.f_fname));
7345+ memset(ibcsstat.f_fpack, 0, sizeof(ibcsstat.f_fpack));
7346+
7347+ /* Finally, copy it to the user's buffer */
7348+ return copy_to_user(buf, &ibcsstat, sizeof(struct svr4_statfs));
7349+}
7350+
7351+int svr4_statfs(const char * path, struct svr4_statfs * buf, int len, int fstype)
7352+{
7353+ struct svr4_statfs ibcsstat;
7354+
7355+ if (len > (int)sizeof(struct svr4_statfs))
7356+ return -EINVAL;
7357+
7358+ if (!fstype) {
7359+ struct nameidata nd;
7360+ int error;
7361+
7362+ error = user_path_walk(path, &nd);
7363+ if (!error) {
7364+ struct kstatfs tmp;
7365+
7366+ error = vfs_statfs(nd.dentry->d_inode->i_sb, &tmp);
7367+ if (!error && copy_kstatfs(buf, &tmp))
7368+ error = -EFAULT;
7369+ path_release(&nd);
7370+ }
7371+
7372+ return error;
7373+ }
7374+
7375+ /*
7376+ * Linux can't stat unmounted filesystems so we
7377+ * simply lie and claim 500MB of 8GB is free. Sorry.
7378+ */
7379+ ibcsstat.f_bsize = 1024;
7380+ ibcsstat.f_frsize = 0;
7381+ ibcsstat.f_blocks = 8 * 1024 * 1024; /* 8GB */
7382+ ibcsstat.f_bfree = 500 * 1024; /* 100MB */
7383+ ibcsstat.f_files = 60000;
7384+ ibcsstat.f_ffree = 50000;
7385+ memset(ibcsstat.f_fname, 0, sizeof(ibcsstat.f_fname));
7386+ memset(ibcsstat.f_fpack, 0, sizeof(ibcsstat.f_fpack));
7387+
7388+ /* Finally, copy it to the user's buffer */
7389+ return copy_to_user(buf, &ibcsstat, len) ? -EFAULT : 0;
7390+}
7391+
7392+int svr4_fstatfs(unsigned int fd, struct svr4_statfs * buf, int len, int fstype)
7393+{
7394+ struct svr4_statfs ibcsstat;
7395+
7396+ if (len > (int)sizeof(struct svr4_statfs))
7397+ return -EINVAL;
7398+
7399+ if (!fstype) {
7400+ struct file * file;
7401+ struct kstatfs tmp;
7402+ int error;
7403+
7404+ error = -EBADF;
7405+ file = fget(fd);
7406+ if (!file)
7407+ goto out;
7408+ error = vfs_statfs(file->f_dentry->d_inode->i_sb, &tmp);
7409+ if (!error && copy_kstatfs(buf, &tmp))
7410+ error = -EFAULT;
7411+ fput(file);
7412+
7413+out:
7414+ return error;
7415+ }
7416+
7417+ /*
7418+ * Linux can't stat unmounted filesystems so we
7419+ * simply lie and claim 500MB of 8GB is free. Sorry.
7420+ */
7421+ ibcsstat.f_bsize = 1024;
7422+ ibcsstat.f_frsize = 0;
7423+ ibcsstat.f_blocks = 8 * 1024 * 1024; /* 8GB */
7424+ ibcsstat.f_bfree = 500 * 1024; /* 100MB */
7425+ ibcsstat.f_files = 60000;
7426+ ibcsstat.f_ffree = 50000;
7427+ memset(ibcsstat.f_fname, 0, sizeof(ibcsstat.f_fname));
7428+ memset(ibcsstat.f_fpack, 0, sizeof(ibcsstat.f_fpack));
7429+
7430+ /* Finally, copy it to the user's buffer */
7431+ return copy_to_user(buf, &ibcsstat, len) ? -EFAULT : 0;
7432+}
7433+
7434+int svr4_open(const char *fname, int flag, int mode)
7435+{
7436+#ifdef __sparc__
7437+ return sys_open(fname, map_flags(flag, fl_svr4_to_linux), mode);
7438+#else
7439+ u_long args[3];
7440+ int error, fd;
7441+ struct file *file;
7442+ mm_segment_t old_fs;
7443+ char *p;
7444+ struct sockaddr_un addr;
7445+
7446+ fd = sys_open(fname, map_flags(flag, fl_svr4_to_linux), mode);
7447+ if (fd < 0)
7448+ return fd;
7449+
7450+ /* Sometimes a program may open a pathname which it expects
7451+ * to be a named pipe (or STREAMS named pipe) when the
7452+ * Linux domain equivalent is a Unix domain socket. (e.g.
7453+ * UnixWare uses a STREAMS named pipe /dev/X/Nserver.0 for
7454+ * X :0 but Linux uses a Unix domain socket /tmp/.X11-unix/X0)
7455+ * It isn't enough just to make the symlink because you cannot
7456+ * open() a socket and read/write it. If we spot the error we can
7457+ * switch to socket(), connect() and things will likely work
7458+ * as expected however.
7459+ */
7460+ file = fget(fd);
7461+ if (!file)
7462+ return fd; /* Huh?!? */
7463+ if (!S_ISSOCK(file->f_dentry->d_inode->i_mode)) {
7464+ fput(file);
7465+ return fd;
7466+ }
7467+ fput(file);
7468+
7469+ sys_close(fd);
7470+ args[0] = AF_UNIX;
7471+ args[1] = SOCK_STREAM;
7472+ args[2] = 0;
7473+ old_fs = get_fs();
7474+ set_fs(get_ds());
7475+ fd = sys_socketcall(SYS_SOCKET, args);
7476+ set_fs(old_fs);
7477+ if (fd < 0)
7478+ return fd;
7479+
7480+ p = getname(fname);
7481+ if (IS_ERR(p)) {
7482+ sys_close(fd);
7483+ return PTR_ERR(p);
7484+ }
7485+ if (strlen(p) >= UNIX_PATH_MAX) {
7486+ putname(p);
7487+ sys_close(fd);
7488+ return -E2BIG;
7489+ }
7490+ addr.sun_family = AF_UNIX;
7491+ strcpy(addr.sun_path, p);
7492+ putname(p);
7493+
7494+ args[0] = fd;
7495+ args[1] = (int)&addr;
7496+ args[2] = sizeof(struct sockaddr_un);
7497+ set_fs(get_ds());
7498+ error = sys_socketcall(SYS_CONNECT, args);
7499+ set_fs(old_fs);
7500+ if (error) {
7501+ sys_close(fd);
7502+ return error;
7503+ }
7504+
7505+ return fd;
7506+#endif
7507+}
7508+
7509+#define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
7510+#define ROUND_UP(x) (((x)+sizeof(long)-1) & ~(sizeof(long)-1))
7511+
7512+struct svr4_getdents_callback {
7513+ struct dirent * current_dir;
7514+ struct dirent * previous;
7515+ int count;
7516+ int error;
7517+};
7518+
7519+static int svr4_filldir(void * __buf, const char * name, int namlen,
7520+ loff_t offset, ino_t ino, unsigned int d_type)
7521+{
7522+ struct dirent * dirent;
7523+ struct svr4_getdents_callback * buf = (struct svr4_getdents_callback *) __buf;
7524+ int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
7525+
7526+ buf->error = -EINVAL; /* only used if we fail.. */
7527+ if (reclen > buf->count)
7528+ return -EINVAL;
7529+
7530+ dirent = buf->previous;
7531+ if (dirent)
7532+ put_user(offset, &dirent->d_off);
7533+ dirent = buf->current_dir;
7534+ buf->previous = dirent;
7535+
7536+ if (is_cur_personality_flag(PERF_SHORT_INODE)) {
7537+ /* read() on a directory only handles
7538+ * short inodes but cannot use 0 as that
7539+ * indicates an empty directory slot.
7540+ * Therefore stat() must also fold
7541+ * inode numbers avoiding 0. Which in
7542+ * turn means that getdents() must fold
7543+ * inodes avoiding 0 - if the program
7544+ * was built in a short inode environment.
7545+ * If we have short inodes in the dirent
7546+ * we also have a two byte pad so we
7547+ * can let the high word fall in the pad.
7548+ * This makes it a little more robust if
7549+ * we guessed the inode size wrong.
7550+ */
7551+ if (!((unsigned long)dirent->d_ino & 0xffff))
7552+ dirent->d_ino = 0xfffffffe;
7553+ }
7554+
7555+ put_user(ino, &dirent->d_ino);
7556+ put_user(reclen, &dirent->d_reclen);
7557+ copy_to_user(dirent->d_name, name, namlen);
7558+ put_user(0, dirent->d_name + namlen);
7559+ ((char *) dirent) += reclen;
7560+ buf->current_dir = dirent;
7561+ buf->count -= reclen;
7562+ return 0;
7563+}
7564+
7565+
7566+
7567+int svr4_getdents(int fd, char *dirent, int count)
7568+{
7569+ struct file * file;
7570+ struct dirent * lastdirent;
7571+ struct svr4_getdents_callback buf;
7572+ int error;
7573+
7574+ error = -EBADF;
7575+ file = fget(fd);
7576+ if (!file)
7577+ goto out;
7578+
7579+ buf.current_dir = (struct dirent *) dirent;
7580+ buf.previous = NULL;
7581+ buf.count = count;
7582+ buf.error = 0;
7583+ error = vfs_readdir(file, svr4_filldir, &buf);
7584+ if (error < 0)
7585+ goto out_putf;
7586+ error = buf.error;
7587+ lastdirent = buf.previous;
7588+ if (lastdirent) {
7589+ put_user(file->f_pos, &lastdirent->d_off);
7590+ error = count - buf.count;
7591+ }
7592+
7593+out_putf:
7594+ fput(file);
7595+
7596+out:
7597+ return error;
7598+}
7599+
7600+#if defined(CONFIG_ABI_SYSCALL_MODULES)
7601+EXPORT_SYMBOL(svr4_fstatfs);
7602+EXPORT_SYMBOL(svr4_getdents);
7603+EXPORT_SYMBOL(svr4_open);
7604+EXPORT_SYMBOL(svr4_statfs);
7605+#endif
7606diff -Nru linux-2.6.7/abi/svr4/signal.c linux-2.6.7-abi/abi/svr4/signal.c
7607--- linux-2.6.7/abi/svr4/signal.c 1970-01-01 01:00:00.000000000 +0100
7608+++ linux-2.6.7-abi/abi/svr4/signal.c 2004-07-22 17:44:20.000000000 +0200
7609@@ -0,0 +1,523 @@
7610+/*
7611+ * signal.c - signal emulation code
7612+ *
7613+ * This module does not go through the normal processing routines for
7614+ * ibcs. The reason for this is that for most events, the return is a
7615+ * procedure address for the previous setting. This procedure address
7616+ * may be negative which is not an error. Therefore, the return processing
7617+ * for standard functions is skipped by declaring this routine as a "special"
7618+ * module for the decoder and dealing with the register settings directly.
7619+ *
7620+ * Please consider this closely if you plan on changing this mode.
7621+ * -- Al Longyear
7622+ */
7623+
7624+#ident "%W% %G%"
7625+
7626+#include <linux/module.h>
7627+#include <linux/errno.h>
7628+#include <linux/sched.h>
7629+#include <linux/kernel.h>
7630+#include <linux/mm.h>
7631+#include <linux/stddef.h>
7632+#define __KERNEL_SYSCALLS__
7633+#include <linux/unistd.h>
7634+#include <linux/ptrace.h>
7635+#include <linux/fcntl.h>
7636+#include <linux/personality.h>
7637+#include <linux/fs.h>
7638+#include <linux/sys.h>
7639+#include <linux/signal.h>
7640+#include <linux/syscalls.h>
7641+
7642+#include <asm/system.h>
7643+#include <asm/uaccess.h>
7644+
7645+#include <abi/util/map.h>
7646+#include <abi/util/errno.h>
7647+#include <abi/util/trace.h>
7648+
7649+
7650+#define SIG_HOLD ((__sighandler_t)2) /* hold signal */
7651+
7652+#include <abi/signal.h>
7653+#include <abi/svr4/sigaction.h>
7654+
7655+typedef void (*pfn) (void); /* Completion function */
7656+
7657+/*
7658+ * Parameters to the signal functions have a common stack frame. This
7659+ * defines the stack frame.
7660+ */
7661+#define SIGNAL_NUMBER(regp) get_syscall_parameter((regp), 0)
7662+#define HIDDEN_PARAM(regp) (SIGNAL_NUMBER((regp)) & ~0xFF)
7663+#define SECOND_PARAM(regp) get_syscall_parameter((regp), 1)
7664+#define THIRD_PARAM(regp) ((u_long)(regp)->edx)
7665+
7666+/* Return a mask that includes SIG only. */
7667+#define __sigmask(sig) (1 << ((sig) - 1))
7668+#define _S(nr) (1 << ((nr) - 1))
7669+#define _BLOCKABLE (~(_S(IBCS_SIGKILL) | _S(IBCS_SIGSTOP)))
7670+
7671+
7672+void
7673+deactivate_signal(struct task_struct *task, int signum)
7674+{
7675+ spin_lock_irq(&task->sighand->siglock);
7676+ sigdelset(&task->pending.signal, signum);
7677+ recalc_sigpending();
7678+ spin_unlock_irq(&task->sighand->siglock);
7679+}
7680+
7681+/*
7682+ * Translate the signal number to the corresponding item for Linux.
7683+ */
7684+static __inline int
7685+abi_mapsig(int sig)
7686+{
7687+ if ((u_int)sig >= NSIGNALS)
7688+ return (-1);
7689+ return (current_thread_info()->exec_domain->signal_map[sig]);
7690+}
7691+
7692+/*
7693+ * Either we want this static or in a header...
7694+ */
7695+__inline int
7696+abi_signo(struct pt_regs *regp, int *sigp)
7697+{
7698+ int value;
7699+
7700+ value = abi_mapsig(SIGNAL_NUMBER(regp) & 0xFF);
7701+ if (value == -1) {
7702+ set_error(regp, iABI_errors(EINVAL));
7703+ return 0;
7704+ } else {
7705+ *sigp = value;
7706+ return 1;
7707+ }
7708+}
7709+
7710+/*
7711+ * Process the signal() function from iBCS
7712+ *
7713+ * This version appeared in "Advanced Programming in the Unix Environment"
7714+ * by W. Richard Stevens, page 298.
7715+ */
7716+void
7717+abi_sig_handler(struct pt_regs *regp, int sig,
7718+ __sighandler_t handler, int oneshot)
7719+{
7720+ struct sigaction act, oact;
7721+ mm_segment_t fs;
7722+ int error;
7723+
7724+ sigemptyset(&act.sa_mask);
7725+ act.sa_restorer = NULL;
7726+ act.sa_handler = handler;
7727+ act.sa_flags = 0;
7728+
7729+ if (oneshot)
7730+ act.sa_flags |= SA_ONESHOT | SA_NOMASK;
7731+
7732+ fs = get_fs();
7733+ set_fs(get_ds());
7734+ error = sys_rt_sigaction(sig, &act, &oact, sizeof(sigset_t));
7735+ set_fs(fs);
7736+
7737+ if (error < 0) {
7738+ set_error(regp, iABI_errors(-error));
7739+ } else {
7740+ set_result(regp, (int)oact.sa_handler);
7741+ }
7742+}
7743+
7744+/*
7745+ * Process the signal() function from iBCS
7746+ */
7747+int
7748+abi_signal(struct pt_regs *regp)
7749+{
7750+ __sighandler_t vec;
7751+ int sig;
7752+
7753+ if (abi_signo(regp, &sig)) {
7754+ vec = (__sighandler_t)SECOND_PARAM(regp);
7755+ abi_sig_handler(regp, sig, vec, 1);
7756+ }
7757+
7758+ return 0;
7759+}
7760+
7761+/*
7762+ * Process the SVR4 sigset function.
7763+ *
7764+ * This is basically the same as the signal() routine with the
7765+ * exception that it will accept a SIG_HOLD parameter.
7766+ *
7767+ * A SIG_HOLD will defer the processing of the signal until a sigrelse()
7768+ * function is called or the signal handler is set again using this function.
7769+ */
7770+int
7771+abi_sigset(struct pt_regs *regp)
7772+{
7773+ int sig, error;
7774+ sigset_t newmask, oldmask;
7775+ __sighandler_t vec;
7776+ mm_segment_t fs;
7777+ int action;
7778+
7779+
7780+ if (abi_signo(regp, &sig) == 0)
7781+ return 0;
7782+
7783+ vec = (__sighandler_t)SECOND_PARAM(regp);
7784+ action = SIG_BLOCK;
7785+
7786+ if (vec != SIG_HOLD) {
7787+ action = SIG_UNBLOCK;
7788+ deactivate_signal(current, sig);
7789+ abi_sig_handler(regp, sig, vec, 0);
7790+ }
7791+
7792+ /*
7793+ * Process the signal hold/unhold function.
7794+ */
7795+ sigemptyset(&newmask);
7796+ sigaddset(&newmask, sig);
7797+
7798+ fs = get_fs();
7799+ set_fs(get_ds());
7800+ error = sys_rt_sigprocmask(action, &newmask, &oldmask,
7801+ sizeof(sigset_t));
7802+ set_fs(fs);
7803+
7804+ if (error < 0)
7805+ set_error(regp, iABI_errors(-error));
7806+
7807+ return 0;
7808+}
7809+
7810+/*
7811+ * Process the iBCS sighold function.
7812+ *
7813+ * Suspend the signal from future recognition.
7814+ */
7815+void
7816+abi_sighold(struct pt_regs *regp)
7817+{
7818+ sigset_t newmask, oldmask;
7819+ int error, sig;
7820+ mm_segment_t fs;
7821+
7822+ if (!abi_signo(regp, &sig))
7823+ return;
7824+
7825+ sigemptyset(&newmask);
7826+ sigaddset(&newmask, sig);
7827+
7828+ fs = get_fs();
7829+ set_fs(get_ds());
7830+ error = sys_rt_sigprocmask(SIG_BLOCK, &newmask,
7831+ &oldmask, sizeof(sigset_t));
7832+ set_fs(fs);
7833+
7834+ if (error < 0)
7835+ set_error(regp, iABI_errors(-error));
7836+}
7837+
7838+/*
7839+ * Process the iBCS sigrelse.
7840+ *
7841+ * Re-enable the signal processing from a previously suspended
7842+ * signal. This may have been done by calling the sighold() function
7843+ * or a longjmp() during the signal processing routine. If you do a
7844+ * longjmp() function then it is expected that you will call sigrelse
7845+ * or set the handler again using sigset before going on with the program.
7846+ */
7847+void
7848+abi_sigrelse(struct pt_regs *regp)
7849+{
7850+ sigset_t newmask, oldmask;
7851+ int error, sig;
7852+ mm_segment_t fs;
7853+
7854+ if (!abi_signo(regp, &sig))
7855+ return;
7856+
7857+ sigemptyset(&newmask);
7858+ sigaddset(&newmask, sig);
7859+
7860+ fs = get_fs();
7861+ set_fs(get_ds());
7862+ error = sys_rt_sigprocmask(SIG_UNBLOCK, &newmask,
7863+ &oldmask, sizeof(sigset_t));
7864+ set_fs(fs);
7865+
7866+ if (error < 0)
7867+ set_error(regp, iABI_errors(-error));
7868+}
7869+
7870+/*
7871+ * Process the iBCS sigignore
7872+ *
7873+ * This is basically a signal (...,SIG_IGN) call.
7874+ */
7875+void
7876+abi_sigignore(struct pt_regs *regp)
7877+{
7878+ struct sigaction act, oact;
7879+ int error, sig;
7880+ mm_segment_t fs;
7881+
7882+ if (!abi_signo(regp, &sig))
7883+ return;
7884+
7885+ sigemptyset(&act.sa_mask);
7886+
7887+ act.sa_restorer = NULL;
7888+ act.sa_handler = SIG_IGN;
7889+ act.sa_flags = 0;
7890+
7891+ fs = get_fs();
7892+ set_fs(get_ds());
7893+ error = sys_rt_sigaction(sig, &act, &oact, sizeof(sigset_t));
7894+ set_fs(fs);
7895+
7896+ if (error < 0)
7897+ set_error(regp, iABI_errors(-error));
7898+}
7899+
7900+/*
7901+ * Process the iBCS sigpause
7902+ *
7903+ * Wait for the signal indicated to arrive before resuming the
7904+ * processing. I do not know if the signal is processed first using
7905+ * the normal event processing before the return. If someone can
7906+ * shed some light on this then please correct this code. I block
7907+ * the signal and look for it to show up in the pending list.
7908+ */
7909+void
7910+abi_sigpause(struct pt_regs *regs)
7911+{
7912+ old_sigset_t newset;
7913+ int error, sig;
7914+
7915+ if (!abi_signo(regs, &sig))
7916+ return;
7917+ newset = (~0UL) & (1UL << (sig-1));
7918+
7919+ if ((error = sys_sigsuspend(0, current->blocked.sig[0], newset) < 0))
7920+ set_error(regs, iABI_errors(-error));
7921+}
7922+
7923+/*
7924+ * This is the service routine for the syscall #48 (signal funcs).
7925+ *
7926+ * Examine the request code and branch on the request to the appropriate
7927+ * function.
7928+ */
7929+int
7930+abi_sigfunc(struct pt_regs *regp)
7931+{
7932+ int sig_type = (int)HIDDEN_PARAM(regp);
7933+
7934+#if defined(CONFIG_ABI_TRACE)
7935+ abi_trace(ABI_TRACE_SIGNAL|ABI_TRACE_SIGNAL_F,
7936+ "sig%s(%ld, 0x%08lx, 0x%08lx)\n",
7937+ sig_type == 0 ? "nal"
7938+ : (sig_type == 0x100 ? "set"
7939+ : (sig_type == 0x200 ? "hold"
7940+ : (sig_type == 0x400 ? "relse"
7941+ : (sig_type == 0x800 ? "ignore"
7942+ : (sig_type == 0x1000 ? "pause"
7943+ : "???" ))))),
7944+ SIGNAL_NUMBER(regp) & 0xff,
7945+ SECOND_PARAM(regp),
7946+ THIRD_PARAM(regp));
7947+#endif
7948+
7949+ regp->eflags &= ~1;
7950+ regp->eax = 0;
7951+
7952+ switch (sig_type) {
7953+ case 0x0000:
7954+ abi_signal(regp);
7955+ break;
7956+ case 0x0100:
7957+ abi_sigset(regp);
7958+ break;
7959+ case 0x0200:
7960+ abi_sighold(regp);
7961+ break;
7962+ case 0x0400:
7963+ abi_sigrelse(regp);
7964+ break;
7965+ case 0x0800:
7966+ abi_sigignore(regp);
7967+ break;
7968+ case 0x1000:
7969+ abi_sigpause(regp);
7970+ break;
7971+ default:
7972+ set_error(regp, EINVAL);
7973+
7974+#if defined(CONFIG_ABI_TRACE)
7975+ abi_trace(ABI_TRACE_SIGNAL|ABI_TRACE_SIGNAL_F,
7976+ "sigfunc(%x, %ld, %lx, %lx) unsupported\n",
7977+ sig_type, SIGNAL_NUMBER(regp),
7978+ SECOND_PARAM(regp), THIRD_PARAM(regp));
7979+#endif
7980+ return 0;
7981+ }
7982+
7983+#if defined(CONFIG_ABI_TRACE)
7984+ abi_trace(ABI_TRACE_SIGNAL|ABI_TRACE_SIGNAL_F,
7985+ "returns %d\n", get_result(regp));
7986+#endif
7987+ return 0;
7988+}
7989+
7990+/*
7991+ * This function is used to handle the sigaction call from SVr4 binaries.
7992+ *
7993+ * If anyone else uses this, this function needs to be modified since the
7994+ * order and size of the ibcs_sigaction structure is different in ibcs
7995+ * and the SVr4 ABI
7996+ */
7997+asmlinkage int
7998+abi_sigaction(int abi_signum, const struct abi_sigaction *action,
7999+ struct abi_sigaction *oldaction)
8000+{
8001+ struct abi_sigaction new_sa, old_sa;
8002+ struct sigaction nsa, osa;
8003+ mm_segment_t fs;
8004+ int error, signo;
8005+
8006+ signo = abi_mapsig(abi_signum);
8007+ if (signo == -1)
8008+ return -EINVAL;
8009+
8010+ if (oldaction) {
8011+ error = verify_area(VERIFY_WRITE, oldaction,
8012+ sizeof(struct abi_sigaction));
8013+ if (error)
8014+ return (-EFAULT);
8015+ }
8016+
8017+ if (action) {
8018+ error = copy_from_user(&new_sa, action,
8019+ sizeof(struct abi_sigaction));
8020+ if (error)
8021+ return (-EFAULT);
8022+ nsa.sa_restorer = NULL;
8023+ nsa.sa_handler = new_sa.sa_handler;
8024+ nsa.sa_mask = map_sigvec_to_kernel(new_sa.sa_mask,
8025+ current_thread_info()->exec_domain->signal_map);
8026+ if (new_sa.sa_flags & ABI_SA_ONSTACK)
8027+ nsa.sa_flags |= SA_ONSTACK;
8028+ if (new_sa.sa_flags & ABI_SA_RESTART)
8029+ nsa.sa_flags |= SA_RESTART;
8030+ if (new_sa.sa_flags & ABI_SA_NODEFER)
8031+ nsa.sa_flags |= SA_NODEFER;
8032+ if (new_sa.sa_flags & ABI_SA_RESETHAND)
8033+ nsa.sa_flags |= SA_RESETHAND;
8034+ if (new_sa.sa_flags & ABI_SA_NOCLDSTOP)
8035+ nsa.sa_flags |= SA_NOCLDSTOP;
8036+ if (new_sa.sa_flags & ABI_SA_NOCLDWAIT)
8037+ nsa.sa_flags |= SA_NOCLDWAIT;
8038+ }
8039+
8040+ fs = get_fs();
8041+ set_fs(get_ds());
8042+ error = sys_rt_sigaction(signo, action ? &nsa : NULL,
8043+ oldaction ? &osa : NULL, sizeof(sigset_t));
8044+ set_fs(fs);
8045+
8046+ if (error || !oldaction)
8047+ return (error);
8048+
8049+ old_sa.sa_handler = osa.sa_handler;
8050+ old_sa.sa_mask = map_sigvec_from_kernel(osa.sa_mask,
8051+ current_thread_info()->exec_domain->signal_invmap);
8052+ old_sa.sa_flags = 0;
8053+ if (osa.sa_flags & SA_ONSTACK)
8054+ old_sa.sa_flags |= ABI_SA_ONSTACK;
8055+ if (osa.sa_flags & SA_RESTART)
8056+ old_sa.sa_flags |= ABI_SA_RESTART;
8057+ if (osa.sa_flags & SA_NODEFER)
8058+ old_sa.sa_flags |= ABI_SA_NODEFER;
8059+ if (osa.sa_flags & SA_RESETHAND)
8060+ old_sa.sa_flags |= ABI_SA_RESETHAND;
8061+ if (osa.sa_flags & SA_NOCLDSTOP)
8062+ old_sa.sa_flags |= ABI_SA_NOCLDSTOP;
8063+ if (osa.sa_flags & SA_NOCLDWAIT)
8064+ old_sa.sa_flags |= ABI_SA_NOCLDWAIT;
8065+ /*
8066+ * We already did the verify_area at the beginning.
8067+ */
8068+ __copy_to_user(oldaction, &old_sa, sizeof(struct abi_sigaction));
8069+ return 0;
8070+}
8071+
8072+
8073+static short int howcnv[] = {SIG_SETMASK, SIG_BLOCK, SIG_UNBLOCK, SIG_SETMASK};
8074+
8075+asmlinkage int
8076+abi_sigprocmask(int how, u_long *abinset, u_long *abioset)
8077+{
8078+ sigset_t new_set, *nset = NULL;
8079+ sigset_t old_set, *oset = NULL;
8080+ u_long new_set_abi, old_set_abi;
8081+ mm_segment_t fs;
8082+ int error;
8083+
8084+ if (abinset) {
8085+ get_user(new_set_abi, abinset);
8086+ new_set = map_sigvec_to_kernel(new_set_abi,
8087+ current_thread_info()->exec_domain->signal_map);
8088+ nset = &new_set;
8089+ }
8090+
8091+ if (abioset)
8092+ oset = &old_set;
8093+
8094+ fs = get_fs();
8095+ set_fs(get_ds());
8096+ error = sys_rt_sigprocmask(howcnv[how], nset, oset, sizeof(sigset_t));
8097+ set_fs(fs);
8098+
8099+ if (!error && abioset) {
8100+ old_set_abi = map_sigvec_from_kernel(old_set,
8101+ current_thread_info()->exec_domain->signal_invmap);
8102+ put_user(old_set_abi, abioset);
8103+ }
8104+
8105+ return (error);
8106+}
8107+
8108+int
8109+abi_sigsuspend(struct pt_regs *regs)
8110+{
8111+ u_long abi_mask, *abi_maskp;
8112+ old_sigset_t mask;
8113+
8114+ abi_maskp = (u_long *)SIGNAL_NUMBER(regs);
8115+ if (get_user(abi_mask, abi_maskp))
8116+ return -EFAULT;
8117+
8118+ mask = map_bitvec(abi_mask, current_thread_info()->exec_domain->signal_map);
8119+#if defined(CONFIG_ABI_TRACE)
8120+ abi_trace(ABI_TRACE_SIGNAL,
8121+ "sigsuspend(mask = %lx)\n", mask);
8122+#endif
8123+ return sys_sigsuspend(0, current->blocked.sig[0], mask);
8124+}
8125+
8126+#if defined(CONFIG_ABI_SYSCALL_MODULES)
8127+EXPORT_SYMBOL(abi_sigaction);
8128+EXPORT_SYMBOL(abi_sigfunc);
8129+EXPORT_SYMBOL(abi_sigprocmask);
8130+EXPORT_SYMBOL(abi_sigsuspend);
8131+EXPORT_SYMBOL(deactivate_signal);
8132+#endif
8133diff -Nru linux-2.6.7/abi/svr4/socket.c linux-2.6.7-abi/abi/svr4/socket.c
8134--- linux-2.6.7/abi/svr4/socket.c 1970-01-01 01:00:00.000000000 +0100
8135+++ linux-2.6.7-abi/abi/svr4/socket.c 2004-07-22 17:44:20.000000000 +0200
8136@@ -0,0 +1,259 @@
8137+/*
8138+ * Copyright (c) 1994,1996 Mike Jagdis (jaggy@purplet.demon.co.uk)
8139+ */
8140+
8141+#ident "%W% %G%"
8142+
8143+#include <linux/module.h>
8144+#include <linux/fs.h>
8145+#include <linux/mm.h>
8146+#include <linux/net.h>
8147+#include <linux/personality.h>
8148+#include <linux/ptrace.h>
8149+#include <linux/socket.h>
8150+#include <linux/syscalls.h>
8151+#include <linux/types.h>
8152+#include <asm/uaccess.h>
8153+#include <asm/ioctls.h>
8154+
8155+#include <abi/util/map.h>
8156+#include <abi/util/trace.h>
8157+#include <abi/util/socket.h>
8158+
8159+
8160+int
8161+abi_do_setsockopt(unsigned long *sp)
8162+{
8163+ int error;
8164+ int level, optname;
8165+
8166+ error = verify_area(VERIFY_READ,
8167+ ((unsigned long *)sp),
8168+ 5*sizeof(long));
8169+ if (error)
8170+ return error;
8171+
8172+ get_user(level, ((unsigned long *)sp)+1);
8173+ get_user(optname, ((unsigned long *)sp)+2);
8174+
8175+#if defined(CONFIG_ABI_TRACE)
8176+ if (abi_traced(ABI_TRACE_STREAMS|ABI_TRACE_SOCKSYS)) {
8177+ u_long optval, optlen;
8178+
8179+ get_user(optval, ((u_long *)sp) + 3);
8180+ get_user(optlen, ((u_long *)sp) + 4);
8181+ __abi_trace("setsockopt level=%d, optname=%d, "
8182+ "optval=0x%08lx, optlen=0x%08lx\n",
8183+ level, optname, optval, optlen);
8184+ }
8185+#endif
8186+
8187+ switch (level) {
8188+ case 0: /* IPPROTO_IP aka SOL_IP */
8189+ /* This is correct for the SCO family. Hopefully
8190+ * it is correct for other SYSV...
8191+ */
8192+ optname--;
8193+ if (optname == 0)
8194+ optname = 4;
8195+ if (optname > 4) {
8196+ optname += 24;
8197+ if (optname <= 33)
8198+ optname--;
8199+ if (optname < 32 || optname > 36)
8200+ return -EINVAL;
8201+ }
8202+ put_user(optname, ((unsigned long *)sp)+2);
8203+ break;
8204+
8205+ case 0xffff:
8206+ put_user(SOL_SOCKET, ((unsigned long *)sp)+1);
8207+ optname = map_value(current_thread_info()->exec_domain->sockopt_map, optname, 0);
8208+ put_user(optname, ((unsigned long *)sp)+2);
8209+
8210+ switch (optname) {
8211+ case SO_LINGER: {
8212+ unsigned long optlen;
8213+
8214+ /* SO_LINGER takes a struct linger
8215+ * as the argument but some code
8216+ * uses an int and expects to get
8217+ * away without an error. Sigh...
8218+ */
8219+ get_user(optlen, ((unsigned long *)sp)+4);
8220+ if (optlen == sizeof(int))
8221+ return 0;
8222+ break;
8223+ }
8224+
8225+ /* The following are not currently implemented
8226+ * under Linux so we must fake them in
8227+ * reasonable ways. (Only SO_PROTOTYPE is
8228+ * documented in SCO's man page).
8229+ */
8230+ case SO_PROTOTYPE:
8231+ case SO_ORDREL:
8232+ case SO_SNDTIMEO:
8233+ case SO_RCVTIMEO:
8234+ return -ENOPROTOOPT;
8235+
8236+ case SO_USELOOPBACK:
8237+ case SO_SNDLOWAT:
8238+ case SO_RCVLOWAT:
8239+ return 0;
8240+
8241+ /* The following are not currenty implemented
8242+ * under Linux and probably aren't settable
8243+ * anyway.
8244+ */
8245+ case SO_IMASOCKET:
8246+ return -ENOPROTOOPT;
8247+ }
8248+
8249+ default:
8250+ /* FIXME: We assume everything else uses the
8251+ * same level and option numbers. This is true
8252+ * for IPPROTO_TCP(/SOL_TCP) and TCP_NDELAY
8253+ * but is known to be incorrect for other
8254+ * potential options :-(.
8255+ */
8256+ break;
8257+ }
8258+
8259+ return sys_socketcall(SYS_SETSOCKOPT, sp);
8260+}
8261+
8262+int
8263+abi_do_getsockopt(unsigned long *sp)
8264+{
8265+ int error;
8266+ int level, optname;
8267+ char *optval;
8268+ long *optlen;
8269+
8270+ error = verify_area(VERIFY_READ,
8271+ ((unsigned long *)sp),
8272+ 5*sizeof(long));
8273+ if (error)
8274+ return error;
8275+
8276+ get_user((unsigned long) level, ((unsigned long *)sp)+1);
8277+ get_user((unsigned long) optname, ((unsigned long *)sp)+2);
8278+ get_user((unsigned long) optval, ((unsigned long *)sp)+3);
8279+ get_user((unsigned long) optlen, ((unsigned long *)sp)+4);
8280+
8281+#if defined(CONFIG_ABI_TRACE)
8282+ if (abi_traced(ABI_TRACE_STREAMS|ABI_TRACE_SOCKSYS)) {
8283+ long l;
8284+
8285+ get_user(l, optlen);
8286+ __abi_trace("getsockopt level=%d, optname=%d, optval=0x%08lx, "
8287+ "optlen=0x%08lx[%ld]\n", level, optname,
8288+ (u_long)optval, (u_long)optlen, l);
8289+ }
8290+#endif
8291+
8292+ switch (level) {
8293+ case 0: /* IPPROTO_IP aka SOL_IP */
8294+ /* This is correct for the SCO family. Hopefully
8295+ * it is correct for other SYSV...
8296+ */
8297+ optname--;
8298+ if (optname == 0)
8299+ optname = 4;
8300+ if (optname > 4) {
8301+ optname += 24;
8302+ if (optname <= 33)
8303+ optname--;
8304+ if (optname < 32 || optname > 36)
8305+ return -EINVAL;
8306+ }
8307+ put_user(optname, ((unsigned long *)sp)+2);
8308+ break;
8309+
8310+ case 0xffff:
8311+ put_user(SOL_SOCKET, ((unsigned long *)sp)+1);
8312+ optname = map_value(current_thread_info()->exec_domain->sockopt_map, optname, 0);
8313+ put_user(optname, ((unsigned long *)sp)+2);
8314+
8315+ switch (optname) {
8316+ case SO_LINGER: {
8317+ long l;
8318+
8319+ /* SO_LINGER takes a struct linger
8320+ * as the argument but some code
8321+ * uses an int and expects to get
8322+ * away without an error. Sigh...
8323+ */
8324+ get_user(l, optlen);
8325+ if (l == sizeof(int)) {
8326+ put_user(0, (long *)optval);
8327+ return 0;
8328+ }
8329+ break;
8330+ }
8331+
8332+ /* The following are not currently implemented
8333+ * under Linux so we must fake them in
8334+ * reasonable ways. (Only SO_PROTOTYPE is
8335+ * documented in SCO's man page).
8336+ */
8337+ case SO_PROTOTYPE: {
8338+ unsigned long len;
8339+ error = get_user(len, optlen);
8340+ if (error)
8341+ return error;
8342+ if (len < sizeof(long))
8343+ return -EINVAL;
8344+
8345+ error = verify_area(VERIFY_WRITE,
8346+ (char *)optval,
8347+ sizeof(long));
8348+ if (!error) {
8349+ put_user(0, (long *)optval);
8350+ put_user(sizeof(long),
8351+ optlen);
8352+ }
8353+ return error;
8354+ }
8355+
8356+ case SO_ORDREL:
8357+ case SO_SNDTIMEO:
8358+ case SO_RCVTIMEO:
8359+ return -ENOPROTOOPT;
8360+
8361+ case SO_USELOOPBACK:
8362+ case SO_SNDLOWAT:
8363+ case SO_RCVLOWAT:
8364+ case SO_IMASOCKET: {
8365+ unsigned long len;
8366+ error = get_user(len, optlen);
8367+ if (error)
8368+ return error;
8369+ if (len < sizeof(long))
8370+ return -EINVAL;
8371+
8372+ error = verify_area(VERIFY_WRITE,
8373+ (char *)optval,
8374+ sizeof(long));
8375+ if (!error) {
8376+ put_user(1, (long *)optval);
8377+ put_user(sizeof(long),
8378+ optlen);
8379+ }
8380+ return error;
8381+ }
8382+ }
8383+
8384+ default:
8385+ /* FIXME: We assume everything else uses the
8386+ * same level and option numbers. This is true
8387+ * for IPPROTO_TCP(/SOL_TCP) and TCP_NDELAY
8388+ * but is known to be incorrect for other
8389+ * potential options :-(.
8390+ */
8391+ break;
8392+ }
8393+
8394+ return sys_socketcall(SYS_GETSOCKOPT, sp);
8395+}
8396diff -Nru linux-2.6.7/abi/svr4/sockio.c linux-2.6.7-abi/abi/svr4/sockio.c
8397--- linux-2.6.7/abi/svr4/sockio.c 1970-01-01 01:00:00.000000000 +0100
8398+++ linux-2.6.7-abi/abi/svr4/sockio.c 2004-07-22 17:44:20.000000000 +0200
8399@@ -0,0 +1,307 @@
8400+/* $Id$ */
8401+
8402+#include <linux/config.h>
8403+#include <linux/errno.h>
8404+#include <linux/fs.h>
8405+#include <linux/sched.h>
8406+#include <linux/kernel.h>
8407+#include <linux/sockios.h>
8408+#include <linux/file.h>
8409+#include <linux/slab.h>
8410+#include <linux/syscalls.h>
8411+#include <asm/uaccess.h>
8412+#include <asm/ioctls.h>
8413+
8414+#include <abi/stream.h>
8415+#include <abi/tli.h>
8416+#include <abi/socksys.h> /* for socksys_fdinit */
8417+
8418+#include <abi/svr4/ioctl.h>
8419+#include <abi/util/trace.h>
8420+
8421+
8422+/*
8423+ * Check if the inode belongs to /dev/socksys.
8424+ */
8425+#define IS_SOCKSYS(ip) (MAJOR((ip)->i_rdev) == SOCKSYS_MAJOR)
8426+
8427+
8428+static int
8429+i_nread(u_int fd, struct file *fp, struct inode *ip,
8430+ void *data, struct pt_regs *regs)
8431+{
8432+ int error;
8433+
8434+ error = verify_area(VERIFY_WRITE, data, sizeof(u_long));
8435+ if (error)
8436+ goto fput;
8437+
8438+#if defined(CONFIG_ABI_XTI)
8439+ if (ip->i_sock) {
8440+ struct T_private *ti = Priv(fp);
8441+
8442+ if (IS_SOCKSYS(ip))
8443+ timod_update_socket(fd, fp, regs);
8444+
8445+ if (ti && ti->pfirst) {
8446+ put_user(ti->pfirst->length, (u_long *)data);
8447+ fput(fp);
8448+ return 1; /* at least 1... (FIXME) */
8449+ }
8450+ }
8451+#endif
8452+ fput(fp);
8453+
8454+ error = sys_ioctl(fd, TIOCINQ, (long)data);
8455+ if (error == -EINVAL)
8456+ return 0;
8457+ else if (error)
8458+ return error;
8459+
8460+ __get_user(error, (u_long *)data);
8461+ return !!error;
8462+fput:
8463+ fput(fp);
8464+ return error;
8465+}
8466+
8467+static int
8468+i_peek(u_int fd, struct file *fp, struct inode *ip,
8469+ void *data, struct pt_regs *regs)
8470+{
8471+#if !defined(CONFIG_ABI_XTI)
8472+ fput(fp);
8473+ return 0;
8474+#else
8475+ struct T_private *ti = Priv(fp);
8476+ struct T_primsg *tp;
8477+ struct strpeek buf, *uap = data;
8478+ int error = -EFAULT;
8479+
8480+ if (copy_from_user(&buf, uap, sizeof(buf)))
8481+ goto fput;
8482+
8483+ error = 0;
8484+ if (!ip->i_sock)
8485+ goto fput;
8486+
8487+ if (IS_SOCKSYS(ip))
8488+ timod_update_socket(fd, fp, regs);
8489+
8490+ if (!ti || !ti->pfirst)
8491+ goto fput;
8492+ tp = ti->pfirst;
8493+
8494+ error = -EFAULT;
8495+ if (!buf.flags || buf.flags == tp->pri) {
8496+ int l;
8497+
8498+
8499+
8500+ if (buf.ctl.maxlen <= tp->length)
8501+ l = buf.ctl.maxlen;
8502+ else
8503+ l = tp->length;
8504+
8505+ if (copy_to_user(buf.ctl.buf,
8506+ ((char *)&tp->type) + ti->offset, l))
8507+ goto fput;
8508+
8509+ if (put_user(l, &uap->ctl.len))
8510+ goto fput;
8511+
8512+ if (buf.dat.maxlen >= 0 && put_user(0, &uap->dat.len))
8513+ goto fput;
8514+
8515+ if (put_user(tp->pri, &uap->flags))
8516+ goto fput;
8517+
8518+ error = 1;
8519+ }
8520+fput:
8521+ fput(fp);
8522+ return error;
8523+#endif /* CONFIG_ABI_XTI */
8524+}
8525+
8526+static int
8527+i_str(u_int fd, struct file *fp, struct inode *ip,
8528+ void *data, struct pt_regs *regs)
8529+{
8530+ int cmd;
8531+ /*
8532+ * Unpack the ioctl data and forward as a normal
8533+ * ioctl. Timeouts are not handled (yet?).
8534+ */
8535+ struct strioctl {
8536+ int cmd, timeout, len;
8537+ char *data;
8538+ } it, *uap = data;
8539+
8540+ if (copy_from_user(&it, uap, sizeof(struct strioctl)))
8541+ return -EFAULT;
8542+ cmd = it.cmd >> 8;
8543+
8544+#if defined(CONFIG_ABI_TRACE)
8545+ abi_trace(ABI_TRACE_STREAMS, "STREAMS I_STR ioctl(%d, 0x%08x, %p)\n",
8546+ fd, it.cmd, it.data);
8547+#endif
8548+
8549+#ifdef CONFIG_ABI_XTI
8550+ if (cmd == 'T')
8551+ return timod_ioctl(regs, fd, it.cmd & 0xff, it.data, it.len,
8552+ &uap->len);
8553+#endif
8554+ return __svr4_ioctl(regs, fd, it.cmd, it.data);
8555+}
8556+
8557+int
8558+svr4_stream_ioctl(struct pt_regs *regs, int fd, u_int cmd, caddr_t data)
8559+{
8560+ struct file *fp;
8561+ struct inode *ip;
8562+ int error;
8563+
8564+ fp = fget(fd);
8565+ if (!fp)
8566+ return -EBADF;
8567+ ip = fp->f_dentry->d_inode;
8568+
8569+ /*
8570+ * Special hack^H^Hndling for socksys fds
8571+ */
8572+ if (ip->i_sock == 0 && IS_SOCKSYS(ip)) {
8573+ error = socksys_fdinit(fd, 0, NULL, NULL);
8574+ if (error < 0)
8575+ return error;
8576+ fput(fp);
8577+ fp = fget(fd);
8578+ if (!fp)
8579+ return -EBADF;
8580+ ip = fp->f_dentry->d_inode;
8581+ }
8582+
8583+ switch (cmd) {
8584+ case 001: /* I_NREAD */
8585+ return i_nread(fd, fp, ip, data, regs);
8586+
8587+ case 017: /* I_PEEK */
8588+ return i_peek(fd, fp, ip, data, regs);
8589+ }
8590+
8591+ fput(fp);
8592+
8593+ switch (cmd) {
8594+ case 010: /* I_STR */
8595+ return i_str(fd, fp, ip, data, regs);
8596+ case 002: { /* I_PUSH */
8597+ char *tmp;
8598+
8599+ /* Get the name anyway to validate it. */
8600+ tmp = getname(data);
8601+ if (IS_ERR(tmp))
8602+ return PTR_ERR(tmp);
8603+
8604+#if defined(CONFIG_ABI_TRACE)
8605+ abi_trace(ABI_TRACE_STREAMS,
8606+ "%d STREAMS I_PUSH %s\n", fd, tmp);
8607+#endif
8608+
8609+ putname(tmp);
8610+ return 0;
8611+ }
8612+ case 003: /* I_POP */
8613+#if defined(CONFIG_ABI_TRACE)
8614+ abi_trace(ABI_TRACE_STREAMS, "%d STREAMS I_POP\n", fd);
8615+#endif
8616+ return 0;
8617+
8618+ case 005: /* I_FLUSH */
8619+ return 0;
8620+
8621+ case 013: { /* I_FIND */
8622+ char *tmp;
8623+
8624+ /* Get the name anyway to validate it. */
8625+ tmp = getname(data);
8626+ if (IS_ERR(tmp))
8627+ return PTR_ERR(tmp);
8628+
8629+#if defined(CONFIG_ABI_TRACE)
8630+ abi_trace(ABI_TRACE_STREAMS,
8631+ "%d STREAMS I_FIND %s\n", fd, tmp);
8632+#endif
8633+#ifdef CONFIG_ABI_XTI
8634+ if (!strcmp(tmp, "timod")) {
8635+ putname(tmp);
8636+ return 1;
8637+ }
8638+#endif
8639+ putname(tmp);
8640+ return 0;
8641+ }
8642+
8643+ /* FIXME: These are bogus. */
8644+ case 011: /* I_SETSIG */
8645+ return sys_ioctl(fd, FIOSETOWN, (long)current->pid);
8646+ case 012: /* I_GETSIG */
8647+ return sys_ioctl(fd, FIOGETOWN, (long)data);
8648+
8649+ case 020: /* I_FDINSERT */
8650+#ifdef CONFIG_ABI_XTI
8651+ return stream_fdinsert(regs, fd,
8652+ (struct strfdinsert *)data);
8653+#else
8654+ return -EINVAL;
8655+#endif
8656+
8657+ case 004: /* I_LOOK */
8658+ case 006: /* I_SRDOPT */
8659+ case 007: /* I_GRDOPT */
8660+ case 014: /* I_LINK */
8661+ case 015: /* I_UNLINK */
8662+ case 021: /* I_SENDFD */
8663+ case 022: /* I_RECVFD */
8664+ case 023: /* I_SWROPT */
8665+ case 040: /* I_SETCLTIME */
8666+ return 0; /* Lie... */
8667+ case 042: /* I_CANPUT */
8668+ /*
8669+ * Arg is the priority band in question. We only
8670+ * support one priority band so data must be 0.
8671+ * If the band is writable we should return 1, if
8672+ * the band is flow controlled we should return 0.
8673+ */
8674+ if (data)
8675+ return -EINVAL;
8676+
8677+ /* FIXME: How can we test if a write would block? */
8678+ return 1;
8679+
8680+ case 024: /* I_GWROPT */
8681+ case 025: /* I_LIST */
8682+ case 026: /* I_PLINK */
8683+ case 027: /* I_PUNLINK */
8684+ case 030: /* I_SETEV */
8685+ case 031: /* I_GETEV */
8686+ case 032: /* I_STREV */
8687+ case 033: /* I_UNSTREV */
8688+ case 034: /* I_FLUSHBAND */
8689+ case 035: /* I_CKBAND */
8690+ case 036: /* I_GETBAND */
8691+ case 037: /* I_ATMARK */
8692+ case 041: /* I_GETCLTIME */
8693+ /* Unsupported - drop out. */
8694+ break;
8695+
8696+ default:
8697+ break;
8698+ }
8699+
8700+ printk(KERN_ERR "iBCS: STREAMS ioctl 0%o unsupported\n", cmd);
8701+ return -EINVAL;
8702+}
8703+
8704+#if defined(CONFIG_ABI_SYSCALL_MODULES)
8705+EXPORT_SYMBOL(svr4_stream_ioctl);
8706+#endif
8707diff -Nru linux-2.6.7/abi/svr4/socksys.c linux-2.6.7-abi/abi/svr4/socksys.c
8708--- linux-2.6.7/abi/svr4/socksys.c 1970-01-01 01:00:00.000000000 +0100
8709+++ linux-2.6.7-abi/abi/svr4/socksys.c 2004-07-22 17:44:20.000000000 +0200
8710@@ -0,0 +1,1232 @@
8711+/*
8712+ * socksys.c - SVR4 /dev/socksys emulation
8713+ *
8714+ * Copyright (c) 1994-1996 Mike Jagdis (jaggy@purplet.demon.co.uk)
8715+ * Copyright (c) 2001 Caldera Deutschland GmbH
8716+ * Copyright (c) 2001 Christoph Hellwig
8717+ */
8718+
8719+#ident "%W% %G%"
8720+
8721+#include <linux/config.h>
8722+#include <linux/module.h>
8723+
8724+#include <linux/types.h>
8725+#include <linux/errno.h>
8726+#include <linux/fs.h>
8727+#include <linux/fcntl.h>
8728+#include <linux/major.h>
8729+#include <linux/kernel.h>
8730+#include <linux/in.h>
8731+#include <linux/net.h>
8732+#include <linux/sched.h>
8733+#include <linux/signal.h>
8734+#include <linux/socket.h>
8735+#include <net/sock.h>
8736+#include <linux/slab.h>
8737+#include <linux/mm.h>
8738+#include <linux/un.h>
8739+#include <linux/utsname.h>
8740+#include <linux/time.h>
8741+#include <linux/termios.h>
8742+#include <linux/sys.h>
8743+#include <linux/file.h>
8744+#include <linux/poll.h>
8745+#include <linux/capability.h>
8746+#include <linux/personality.h>
8747+#include <linux/init.h>
8748+#include <linux/syscalls.h>
8749+#include <linux/namei.h>
8750+
8751+#include <asm/uaccess.h>
8752+
8753+#include <abi/stream.h>
8754+#include <abi/socksys.h>
8755+#include <abi/svr4/sockio.h>
8756+#include <abi/svr4/sysent.h>
8757+#include <abi/tli.h>
8758+
8759+#include <abi/util/map.h>
8760+#include <abi/util/trace.h>
8761+#include <abi/util/revalidate.h>
8762+
8763+
8764+/*
8765+ * External declarations.
8766+ */
8767+struct svr4_stat;
8768+
8769+/*
8770+ * Forward declarations.
8771+ */
8772+static int socksys_open(struct inode *ip, struct file *fp);
8773+#if defined(CONFIG_ABI_XTI)
8774+static int socksys_release(struct inode *ip, struct file *fp);
8775+static u_int socksys_poll(struct file *fp, struct poll_table_struct *wait);
8776+#endif
8777+static int socksys_read(struct file *fp, char *buf,
8778+ size_t count, loff_t *ppos);
8779+static int socksys_write(struct file *fp, const char *buf,
8780+ size_t count, loff_t *ppos);
8781+
8782+/*
8783+ * The socksys socket file operations.
8784+ * This gets filled in on module initialization.
8785+ */
8786+static struct file_operations socksys_socket_fops = {
8787+ /* NOTHING */
8788+};
8789+
8790+/*
8791+ * File operations for the user-visible device files.
8792+ *
8793+ * While open the files are handled as sockets.
8794+ */
8795+static struct file_operations socksys_fops = {
8796+ owner: THIS_MODULE,
8797+ open: socksys_open,
8798+ read: socksys_read,
8799+ write: socksys_write,
8800+#ifdef CONFIG_ABI_XTI
8801+ poll: socksys_poll,
8802+ release: socksys_release,
8803+#endif
8804+};
8805+
8806+
8807+void
8808+inherit_socksys_funcs(u_int fd, int state)
8809+{
8810+ struct file *fp;
8811+ struct inode *ip;
8812+#ifdef CONFIG_ABI_XTI
8813+ struct T_private *tp;
8814+#endif
8815+ struct socket *sp;
8816+
8817+ fp = fget(fd);
8818+ if (fp == NULL)
8819+ return;
8820+ ip = fp->f_dentry->d_inode;
8821+
8822+ /*
8823+ * SYSV sockets are BSD like with respect to ICMP errors
8824+ * with UDP rather than RFC conforming. I think.
8825+ */
8826+ sp = SOCKET_I(ip); /* inode -> socket */
8827+ if (sp->sk)
8828+ sock_set_flag(sp->sk, SOCK_BSDISM);
8829+
8830+ ip->i_mode = 0020000; /* S_IFCHR */
8831+ ip->i_rdev = MKDEV(SOCKSYS_MAJOR, 0);
8832+
8833+#ifdef CONFIG_ABI_XTI
8834+ tp = kmalloc(sizeof(struct T_private), GFP_KERNEL);
8835+ if (tp) {
8836+ tp->magic = XTI_MAGIC;
8837+ tp->state = state;
8838+ tp->offset = 0;
8839+ tp->pfirst = NULL;
8840+ tp->plast = NULL;
8841+ }
8842+ fp->private_data = tp;
8843+#endif
8844+
8845+ fp->f_op = &socksys_socket_fops;
8846+ fput(fp);
8847+}
8848+
8849+static int
8850+spx_connect(u_int fd, int spxnum)
8851+{
8852+ struct sockaddr_un sun;
8853+ int newfd, err;
8854+ mm_segment_t fs;
8855+
8856+#if defined(CONFIG_ABI_TRACE)
8857+ abi_trace(ABI_TRACE_SOCKSYS,
8858+ "SPX: %u choose service %d\n", fd, spxnum);
8859+#endif
8860+
8861+ /*
8862+ * Rather than use an explicit path to the X :0 server
8863+ * socket we should use the given number to look up a path
8864+ * name to use (we can't rely on servers registering their
8865+ * sockets either - for one thing we don't emulate that yet
8866+ * and for another thing different OS binaries do things in
8867+ * different ways but all must interoperate).
8868+ * I suggest putting the mapping in, say, /dev/spx.map/%d
8869+ * where each file is a symlink containing the path of the
8870+ * socket to use. Then we can just do a readlink() here to
8871+ * get the pathname.
8872+ * Hey, this is what we do here now!
8873+ */
8874+ sun.sun_family = AF_UNIX;
8875+ sprintf(sun.sun_path, "/dev/spx.map/%u", spxnum);
8876+
8877+ fs = get_fs();
8878+ set_fs(get_ds());
8879+ err = sys_readlink(sun.sun_path, sun.sun_path, strlen(sun.sun_path));
8880+ set_fs(fs);
8881+
8882+ if (err == -ENOENT) {
8883+#if defined(CONFIG_ABI_TRACE)
8884+ abi_trace(ABI_TRACE_SOCKSYS,
8885+ "SPX: %u no symlink \"%s\", try X :0\n",
8886+ fd, sun.sun_path);
8887+#endif
8888+ strcpy(sun.sun_path, "/tmp/.X11-unix/X0");
8889+ } else if (err < 0) {
8890+#if defined(CONFIG_ABI_TRACE)
8891+ abi_trace(ABI_TRACE_SOCKSYS,
8892+ "SPX: readlink failed with %d\n", err);
8893+#endif
8894+ return (err);
8895+ } else
8896+ sun.sun_path[err] = '\0';
8897+
8898+ set_fs(get_ds());
8899+ newfd = sys_socket(AF_UNIX, SOCK_STREAM, 0);
8900+ set_fs(fs);
8901+
8902+ if (newfd < 0) {
8903+#if defined(CONFIG_ABI_TRACE)
8904+ abi_trace(ABI_TRACE_SOCKSYS,
8905+ "SPX: %u got no UNIX domain socket (err=%d)\n",
8906+ fd, err);
8907+#endif
8908+ return (newfd);
8909+ }
8910+
8911+#if defined(CONFIG_ABI_TRACE)
8912+ abi_trace(ABI_TRACE_SOCKSYS,
8913+ "SPX: %u got a UNIX domain socket\n", fd);
8914+#endif
8915+
8916+ set_fs(get_ds());
8917+ err = sys_connect(newfd, (struct sockaddr *)&sun, sizeof(struct sockaddr_un));
8918+ set_fs(fs);
8919+
8920+ if (err) {
8921+#if defined(CONFIG_ABI_TRACE)
8922+ abi_trace(ABI_TRACE_SOCKSYS,
8923+ "SPX: %u connect to \"%s\" failed (err = %d)\n",
8924+ fd, sun.sun_path, err);
8925+#endif
8926+ sys_close(newfd);
8927+ return (err);
8928+ }
8929+
8930+#if defined(CONFIG_ABI_TRACE)
8931+ abi_trace(ABI_TRACE_SOCKSYS,
8932+ "SPX: %u connect to \"%s\"\n",
8933+ fd, sun.sun_path);
8934+#endif
8935+ return (newfd);
8936+}
8937+
8938+/*
8939+ * XTI to Linux protocol table.
8940+ */
8941+static int inet_prot[16] = {
8942+ IPPROTO_ICMP, IPPROTO_ICMP,
8943+ IPPROTO_IGMP, IPPROTO_IPIP,
8944+ IPPROTO_TCP, IPPROTO_EGP,
8945+ IPPROTO_PUP, IPPROTO_UDP,
8946+ IPPROTO_IDP, IPPROTO_RAW,
8947+};
8948+
8949+static int inet_type[16] = {
8950+ SOCK_RAW, SOCK_RAW,
8951+ SOCK_RAW, SOCK_RAW,
8952+ SOCK_STREAM, SOCK_RAW,
8953+ SOCK_RAW, SOCK_DGRAM,
8954+ SOCK_RAW, SOCK_RAW,
8955+};
8956+
8957+
8958+static int
8959+xti_connect(struct file *fp, u_int fd, dev_t dev)
8960+{
8961+ int family, type, prot = 0, i, s;
8962+ mm_segment_t fs;
8963+
8964+#if defined(CONFIG_ABI_TRACE)
8965+ abi_trace(ABI_TRACE_SOCKSYS,
8966+ "XTI: %d get socket for transport end point "
8967+ "(dev = 0x%04x)\n", fd, dev);
8968+#endif
8969+
8970+ switch ((family = ((MINOR(dev) >> 4) & 0x0f))) {
8971+ case AF_UNIX:
8972+ type = SOCK_STREAM;
8973+ break;
8974+ case AF_INET:
8975+ i = MINOR(dev) & 0x0f;
8976+ type = inet_type[i];
8977+ prot = inet_prot[i];
8978+ break;
8979+ default:
8980+ type = SOCK_RAW;
8981+ break;
8982+ }
8983+
8984+ fput(fp);
8985+
8986+#if defined(CONFIG_ABI_TRACE)
8987+ abi_trace(ABI_TRACE_SOCKSYS,
8988+ "XTI: %d socket %d %d %d\n",
8989+ fd, family, type, prot);
8990+#endif
8991+
8992+ fs = get_fs();
8993+ set_fs(get_ds());
8994+ s = sys_socket(family, type, prot);
8995+ set_fs(fs);
8996+
8997+ return (s);
8998+}
8999+
9000+int
9001+socksys_fdinit(int fd, int rw, const char *buf, int *count)
9002+{
9003+ struct file *fp;
9004+ struct inode *ip;
9005+ int sockfd, error = -EINVAL;
9006+
9007+#if defined(CONFIG_ABI_TRACE)
9008+ abi_trace(ABI_TRACE_SOCKSYS, "socksys: fd=%d initializing\n", fd);
9009+#endif
9010+
9011+ fp = fget(fd);
9012+ if (!fp)
9013+ return -EBADF;
9014+ ip = fp->f_dentry->d_inode;
9015+
9016+ /*
9017+ * Minor = 0 is the socksys device itself. No special handling
9018+ * will be needed as it is controlled by the application
9019+ * via ioctls.
9020+ */
9021+ if (MINOR(ip->i_rdev) == 0)
9022+ goto fput;
9023+
9024+ /*
9025+ * Minor = 1 is the spx device. This is the client side of a
9026+ * streams pipe to the X server. Under SCO and friends
9027+ * the library code messes around setting the connection
9028+ * up itself. We do it ourselves - this means we don't
9029+ * need to worry about the implementation of the server
9030+ * side (/dev/X0R - which must exist but can be a link
9031+ * to /dev/null) nor do we need to actually implement
9032+ * getmsg/putmsg.
9033+ */
9034+ if (MINOR(ip->i_rdev) == 1) {
9035+ int unit = 1;
9036+
9037+ /*
9038+ * It seems early spx implementations were just a
9039+ * quick hack to get X to work. They only supported
9040+ * one destination and connected automatically.
9041+ * Later versions take a single byte write, the
9042+ * value of the byte telling them which destination
9043+ * to connect to. Hence this quick hack to work
9044+ * with both. If the first write is a single byte
9045+ * it's a connect request otherwise we auto-connect
9046+ * to destination 1.
9047+ */
9048+#if 0
9049+ if (rw == 1 && *count == 1) {
9050+ error = get_user(unit, buf);
9051+ if (error)
9052+ goto fput;
9053+ (*count)--;
9054+ }
9055+#endif
9056+
9057+ fput(fp);
9058+
9059+ sockfd = spx_connect(fd, unit);
9060+ } else {
9061+ /*
9062+ * Otherwise the high 4 bits specify the address/protocol
9063+ * family (AF_INET, AF_UNIX etc.) and the low 4 bits determine
9064+ * the protocol (IPPROTO_IP, IPPROTO_UDP, IPPROTO_TCP etc.)
9065+ * although not using a one-to-one mapping as the minor number
9066+ * is not big enough to hold everything directly. The socket
9067+ * type is inferrred from the protocol.
9068+ */
9069+ sockfd = xti_connect(fp, fd, ip->i_rdev);
9070+ }
9071+
9072+ /*
9073+ * Give up if we weren't able to allocate a socket.
9074+ * There is no sense in plying our funny game without a new fd.
9075+ */
9076+ if (sockfd < 0)
9077+ return sockfd;
9078+
9079+ /*
9080+ * Redirect operations on the socket fd via our emulation
9081+ * handlers then swap the socket fd and the original fd,
9082+ * discarding the original fd.
9083+ */
9084+ inherit_socksys_funcs(sockfd, TS_UNBND);
9085+
9086+#if defined(CONFIG_ABI_TRACE)
9087+ abi_trace(ABI_TRACE_SOCKSYS, "XTI: %d -> %d\n", fd, sockfd);
9088+#endif
9089+
9090+ sys_dup2(sockfd, fd);
9091+ sys_close(sockfd);
9092+ return 1;
9093+
9094+fput:
9095+ fput(fp);
9096+ return error;
9097+}
9098+
9099+static int
9100+socksys_open(struct inode *ip, struct file *fp)
9101+{
9102+#if defined(CONFIG_ABI_TRACE)
9103+ abi_trace(ABI_TRACE_SOCKSYS,
9104+ "socksys: fp=0x%p, ip=0x%p opening\n", fp, ip);
9105+#endif
9106+ return 0;
9107+}
9108+
9109+#ifdef CONFIG_ABI_XTI
9110+static int
9111+socksys_release(struct inode *ip, struct file *fp)
9112+{
9113+ int error = 0;
9114+
9115+ /*
9116+ * Not being a socket is not an error - it is probably
9117+ * just the pseudo device transport provider.
9118+ */
9119+ if (!ip || !ip->i_sock)
9120+ goto out;
9121+
9122+ if (fp->private_data) {
9123+ struct T_primsg *it;
9124+
9125+ it = ((struct T_private *)fp->private_data)->pfirst;
9126+ while (it) {
9127+ struct T_primsg *tmp = it;
9128+ it = it->next;
9129+ kfree(tmp);
9130+ }
9131+ kfree(fp->private_data);
9132+ }
9133+ error = socket_file_ops.release(ip, fp);
9134+out:
9135+#if defined(CONFIG_ABI_TRACE)
9136+ abi_trace(ABI_TRACE_SOCKSYS, "socksys: %p closed\n", fp);
9137+#endif
9138+ return error;
9139+}
9140+
9141+static u_int
9142+socksys_poll(struct file *fp, struct poll_table_struct *wait)
9143+{
9144+ struct inode *ip = fp->f_dentry->d_inode;
9145+ u_int mask = 0;
9146+
9147+ /*
9148+ * If this is a timod transport end point and there
9149+ * is a control message queued we have readable data.
9150+ */
9151+ if (ip && ip->i_sock && MINOR(ip->i_rdev) != 1) {
9152+ if (Priv(fp) && Priv(fp)->pfirst) {
9153+ if (Priv(fp)->pfirst->pri == MSG_HIPRI)
9154+ mask |= POLLPRI;
9155+ else
9156+ mask |= POLLIN;
9157+ }
9158+ }
9159+
9160+ return (mask | socket_file_ops.poll(fp, wait));
9161+}
9162+#endif
9163+
9164+static int
9165+socksys_read(struct file *fp, char *buf, size_t count, loff_t *ppos)
9166+{
9167+ int fd, error;
9168+
9169+ if (fp->f_dentry->d_inode->i_sock)
9170+ BUG();
9171+
9172+ for (fd = 0; fd < current->files->max_fdset; fd++) {
9173+ if (fcheck(fd) == fp) {
9174+ error = socksys_fdinit(fd, 0, NULL, NULL);
9175+ if (error < 0)
9176+ return error;
9177+ fput(fp);
9178+ fp = fget(fd);
9179+ return fp->f_op->read(fp, buf, count, ppos);
9180+ }
9181+ }
9182+
9183+ return -EINVAL;
9184+}
9185+
9186+static int
9187+socksys_write(struct file *fp, const char *buf, size_t count, loff_t *ppos)
9188+{
9189+ int fd, error;
9190+
9191+ if (fp->f_dentry->d_inode->i_sock)
9192+ BUG();
9193+
9194+ for (fd = 0; fd < current->files->max_fdset; fd++) {
9195+ if (fcheck(fd) == fp) {
9196+ error = socksys_fdinit(fd, 1, buf, &count);
9197+ if (error < 0)
9198+ return error;
9199+ fput(fp);
9200+ fp = fget(fd);
9201+ if (count == 1)
9202+ return 1;
9203+ printk("count=%d\n", count);
9204+ return fp->f_op->write(fp, buf, count, ppos);
9205+ }
9206+ }
9207+
9208+ return -EINVAL;
9209+}
9210+
9211+
9212+/*
9213+ * Get a socket but replace the socket file
9214+ * operations with our own so we can do the
9215+ * right thing for ioctls.
9216+ */
9217+static int
9218+socksys_socket(u_long *sp)
9219+{
9220+ u_long x;
9221+ int fd;
9222+
9223+ get_user(x, ((u_long *)sp)+0);
9224+ put_user(map_value(current_thread_info()->exec_domain->af_map, x, 0), sp+0);
9225+ get_user(x, ((u_long *)sp)+1);
9226+ put_user(map_value(current_thread_info()->exec_domain->socktype_map, x, 0), sp+1);
9227+
9228+ fd = sys_socketcall(SYS_SOCKET, sp);
9229+ if (fd >= 0)
9230+ inherit_socksys_funcs(fd, TS_UNBND);
9231+ return fd;
9232+}
9233+
9234+static int
9235+socksys_accept(u_long *sp)
9236+{
9237+ int fd;
9238+
9239+ fd = sys_socketcall(SYS_ACCEPT, sp);
9240+ if (fd >= 0)
9241+ inherit_socksys_funcs(fd, TS_DATA_XFER);
9242+ return fd;
9243+}
9244+
9245+static int
9246+socksys_getipdomain(u_long *sp)
9247+{
9248+ char *name, *p;
9249+ int error, len;
9250+
9251+ error = get_user((u_long)name, (char *)(sp+0));
9252+ if (error)
9253+ return error;
9254+
9255+ get_user(len, sp+1);
9256+ if (error)
9257+ return error;
9258+
9259+ down_read(&uts_sem);
9260+ error = verify_area(VERIFY_WRITE, name, len);
9261+ if (!error) {
9262+ --len;
9263+ for (p = system_utsname.nodename; *p && *p != '.'; p++)
9264+ ;
9265+ if (*p == '.')
9266+ p++;
9267+ else
9268+ p = system_utsname.domainname;
9269+
9270+ if (strcmp(p, "(none)")) {
9271+ for (; *p && len > 0; p++,len--) {
9272+ __put_user(*p, name);
9273+ name++;
9274+ }
9275+ }
9276+ __put_user('\0', name);
9277+ }
9278+ up_read(&uts_sem);
9279+ return error;
9280+}
9281+
9282+static int
9283+socksys_setipdomain(u_long *sp)
9284+{
9285+ char *name, *p;
9286+ int error, len, togo;
9287+
9288+ if (!capable(CAP_SYS_ADMIN))
9289+ return -EPERM;
9290+
9291+ error = get_user((unsigned long) name, (char *)(sp+0));
9292+ if (error)
9293+ return error;
9294+
9295+ error = get_user(len, sp+1);
9296+ if (error)
9297+ return error;
9298+
9299+ down_write(&uts_sem);
9300+ togo = __NEW_UTS_LEN;
9301+ for (p = system_utsname.nodename; *p && *p != '.'; p++,togo--)
9302+ ;
9303+ if (*p == '.')
9304+ p++,togo--;
9305+
9306+ error = -EINVAL;
9307+ if (len <= togo) {
9308+ while (len-- > 0) {
9309+ get_user(*p, name);
9310+ p++;
9311+ name++;
9312+ }
9313+ *p = '\0';
9314+ error = 0;
9315+ }
9316+ up_write(&uts_sem);
9317+ return error;
9318+}
9319+
9320+static int
9321+socksys_setreugid(int cmd, u_long *sp)
9322+{
9323+ uid_t ruid, euid;
9324+ int error;
9325+
9326+ error = get_user(ruid, sp+0);
9327+ if (error)
9328+ return error;
9329+
9330+ error = get_user(euid, sp+1);
9331+ if (error)
9332+ return error;
9333+
9334+ return (cmd == SSYS_SO_SETREUID) ?
9335+ sys_setreuid16(ruid, euid) :
9336+ sys_setregid16(ruid, euid);
9337+}
9338+
9339+/*
9340+ * Get a socketpair but replace the socket file
9341+ * operations with our own so we can do the
9342+ * right thing for ioctls.
9343+ */
9344+static int
9345+socksys_socketpair(u_long *sp)
9346+{
9347+ struct file *fp;
9348+ struct inode *ip;
9349+ mm_segment_t fs;
9350+ int pairin[2], pairout[2];
9351+ int error;
9352+
9353+ /*
9354+ * The first two arguments are file descriptors
9355+ * of sockets which have already been opened
9356+ * and should now be connected back to back.
9357+ */
9358+ error = get_user(pairin[0], sp+0);
9359+ if (!error)
9360+ error = get_user(pairin[1], sp+1);
9361+ if (error)
9362+ return error;
9363+
9364+ fp = fget(pairin[0]);
9365+ if (!fp)
9366+ return -EBADF;
9367+ ip = fp->f_dentry->d_inode;
9368+
9369+ fput(fp); /* this looks boguos */
9370+ if (!ip || !ip->i_sock)
9371+ return -EBADF;
9372+
9373+
9374+ /*
9375+ * XXX Do we need to close these here?
9376+ * XXX If we fail to connect them should they be open?
9377+ */
9378+ sys_close(pairin[0]);
9379+ sys_close(pairin[1]);
9380+
9381+ fs = get_fs();
9382+ set_fs(get_ds());
9383+ error = sys_socketpair(AF_UNIX, SOCKET_I(ip)->type, 0, pairout);
9384+ set_fs(fs);
9385+
9386+ if (error < 0)
9387+ return error;
9388+
9389+ if (pairout[0] != pairin[0]) {
9390+ sys_dup2(pairout[0], pairin[0]);
9391+ sys_close(pairout[0]);
9392+ }
9393+
9394+ if (pairout[1] != pairin[1]) {
9395+ sys_dup2(pairout[1], pairin[1]);
9396+ sys_close(pairout[1]);
9397+ }
9398+
9399+ inherit_socksys_funcs(pairin[0], TS_DATA_XFER);
9400+ inherit_socksys_funcs(pairin[1], TS_DATA_XFER);
9401+ return 0;
9402+}
9403+
9404+int
9405+socksys_syscall(u_long *sp)
9406+{
9407+ int error, cmd;
9408+
9409+ error = get_user(cmd, sp);
9410+ if (error)
9411+ return error;
9412+ sp++;
9413+
9414+#if defined(CONFIG_ABI_TRACE)
9415+ if (abi_traced(ABI_TRACE_SOCKSYS)) {
9416+ u_long a0, a1, a2, a3, a4, a5;
9417+ static const char * const cmd_map[] = {
9418+ "", "accept", "bind", "connect", "getpeername",
9419+ "getsockname", "getsockopt", "listen", "recv",
9420+ "recvfrom", "send", "sendto", "setsockopt", "shutdown",
9421+ "socket", "select", "getipdomain", "setipdomain",
9422+ "adjtime", "setreuid", "setregid", "gettimeofday",
9423+ "settimeofday", "getitimer", "setitimer",
9424+ "recvmsg", "sendmsg", "sockpair"
9425+ };
9426+
9427+ get_user(a0, sp+0);
9428+ get_user(a1, sp+1);
9429+ get_user(a2, sp+2);
9430+ get_user(a3, sp+3);
9431+ get_user(a4, sp+4);
9432+ get_user(a5, sp+5);
9433+
9434+ __abi_trace("socksys: %s (%d) "
9435+ "<0x%lx,0x%lx,0x%lx,0x%lx,0x%lx,0x%lx>\n",
9436+ (cmd >= 0 &&
9437+ cmd < sizeof(cmd_map) / sizeof(cmd_map[0]))
9438+ ? cmd_map[cmd] : "???", cmd,
9439+ a0, a1, a2, a3, a4, a5);
9440+ }
9441+#endif
9442+
9443+ switch (cmd) {
9444+ case SSYS_SO_SOCKET:
9445+ return socksys_socket(sp);
9446+ case SSYS_SO_ACCEPT:
9447+ return socksys_accept(sp);
9448+ case SSYS_SO_BIND:
9449+ return sys_socketcall(SYS_BIND, sp);
9450+ case SSYS_SO_CONNECT:
9451+ return sys_socketcall(SYS_CONNECT, sp);
9452+ case SSYS_SO_GETPEERNAME:
9453+ return sys_socketcall(SYS_GETPEERNAME, sp);
9454+ case SSYS_SO_GETSOCKNAME:
9455+ return sys_socketcall(SYS_GETSOCKNAME, sp);
9456+ case SSYS_SO_GETSOCKOPT:
9457+ return abi_do_getsockopt((u_long *)sp);
9458+ case SSYS_SO_LISTEN:
9459+ return sys_socketcall(SYS_LISTEN, sp);
9460+ case SSYS_SO_RECV:
9461+ if ((error = sys_socketcall(SYS_RECV, sp)) == -EAGAIN)
9462+ return -EWOULDBLOCK;
9463+ return error;
9464+ case SSYS_SO_RECVFROM:
9465+ if ((error = sys_socketcall(SYS_RECVFROM, sp)) == -EAGAIN)
9466+ return -EWOULDBLOCK;
9467+ return error;
9468+ case SSYS_SO_SEND:
9469+ if ((error = sys_socketcall(SYS_SEND, sp)) == -EAGAIN)
9470+ error = -EWOULDBLOCK;
9471+ return error;
9472+ case SSYS_SO_SENDTO:
9473+ if ((error = sys_socketcall(SYS_SENDTO, sp)) == -EAGAIN)
9474+ error = -EWOULDBLOCK;
9475+ return error;
9476+ case SSYS_SO_SETSOCKOPT:
9477+ return abi_do_setsockopt(sp);
9478+ case SSYS_SO_SHUTDOWN:
9479+ return sys_socketcall(SYS_SHUTDOWN, sp);
9480+ case SSYS_SO_GETIPDOMAIN:
9481+ return socksys_getipdomain(sp);
9482+ case SSYS_SO_SETIPDOMAIN:
9483+ return socksys_setipdomain(sp);
9484+ case SSYS_SO_SETREUID:
9485+ case SSYS_SO_SETREGID:
9486+ return socksys_setreugid(cmd, sp);
9487+ case SSYS_SO_GETTIME:
9488+ case SSYS_SO_SETTIME:
9489+ {
9490+ struct timeval *tv;
9491+ struct timezone *tz;
9492+
9493+ error = get_user((unsigned long) tv, sp+0);
9494+ if (!error)
9495+ error = get_user((unsigned long) tz, sp+1);
9496+ if (error)
9497+ return error;
9498+ return (cmd == SSYS_SO_GETTIME)
9499+ ? sys_gettimeofday(tv, tz)
9500+ : sys_settimeofday(tv, tz);
9501+ }
9502+
9503+ case SSYS_SO_GETITIMER:
9504+ {
9505+ int which;
9506+ struct itimerval *value;
9507+
9508+ error = get_user((unsigned long) which, sp+0);
9509+ if (!error)
9510+ error = get_user((unsigned long) value, sp+1);
9511+ if (error)
9512+ return error;
9513+ return sys_getitimer(which, value);
9514+ }
9515+ case SSYS_SO_SETITIMER:
9516+ {
9517+ int which;
9518+ struct itimerval *value, *ovalue;
9519+
9520+ error = get_user((unsigned long) which, sp+0);
9521+ if (!error)
9522+ error = get_user((unsigned long) value, sp+1);
9523+ if (!error)
9524+ error = get_user((unsigned long) ovalue, sp+2);
9525+ if (error)
9526+ return error;
9527+ return sys_setitimer(which, value, ovalue);
9528+ }
9529+
9530+#if BUGGY
9531+ case SSYS_SO_SELECT:
9532+ /*
9533+ * This may be wrong? I don't know how to trigger
9534+ * this case. Select seems to go via the Xenix
9535+ * select entry point.
9536+ */
9537+ return sys_select(sp);
9538+#endif
9539+
9540+ case SSYS_SO_ADJTIME:
9541+ return -EINVAL;
9542+
9543+ /*
9544+ * These appear in SCO 3.2v5. I assume that the format of
9545+ * a msghdr is identical with Linux. I have not checked.
9546+ */
9547+ case SSYS_SO_RECVMSG:
9548+ if ((error = sys_socketcall(SYS_RECVMSG, sp)) == -EAGAIN)
9549+ error = -EWOULDBLOCK;
9550+ return error;
9551+ case SSYS_SO_SENDMSG:
9552+ if ((error = sys_socketcall(SYS_SENDMSG, sp)) == -EAGAIN)
9553+ error = -EWOULDBLOCK;
9554+ return error;
9555+ case SSYS_SO_SOCKPAIR:
9556+ return socksys_socketpair(sp);
9557+ }
9558+
9559+ return -EINVAL;
9560+}
9561+
9562+static int
9563+socksys_getdomainname(caddr_t arg)
9564+{
9565+ struct domnam_args dn;
9566+ char *p;
9567+ int error;
9568+
9569+ if (copy_from_user(&dn, arg, sizeof(struct domnam_args)))
9570+ return -EFAULT;
9571+
9572+ down_read(&uts_sem);
9573+ error = verify_area(VERIFY_WRITE, dn.name, dn.namelen);
9574+ if (!error) {
9575+ --dn.namelen;
9576+ for (p = system_utsname.domainname; *p && dn.namelen > 0; p++) {
9577+ __put_user(*p, dn.name);
9578+ dn.name++;
9579+ dn.namelen--;
9580+ }
9581+ __put_user('\0', dn.name);
9582+ }
9583+ up_read(&uts_sem);
9584+ return error;
9585+}
9586+
9587+static int
9588+socksys_setdomainname(caddr_t arg)
9589+{
9590+ struct domnam_args dn;
9591+
9592+ if (copy_from_user(&dn, arg, sizeof(struct domnam_args)))
9593+ return -EFAULT;
9594+ return sys_setdomainname(dn.name, dn.namelen);
9595+}
9596+
9597+/*
9598+ * I think this was used before symlinks were added
9599+ * to the base SCO OS?
9600+ */
9601+static int
9602+socksys_lstat(caddr_t arg)
9603+{
9604+ struct lstat_args st;
9605+
9606+ if (copy_from_user(&st, arg, sizeof(struct lstat_args)))
9607+ return -EFAULT;
9608+ return svr4_lstat(st.fname, st.statb);
9609+}
9610+
9611+static int
9612+socksys_getfh(caddr_t arg)
9613+{
9614+ struct getfh_args gf;
9615+ struct nameidata nd;
9616+ int error;
9617+
9618+ if (!capable(CAP_SYS_ADMIN))
9619+ return -EPERM;
9620+
9621+ if (copy_from_user(&gf, arg, sizeof(struct getfh_args)))
9622+ return -EFAULT;
9623+
9624+ error = verify_area(VERIFY_WRITE, gf.fhp, sizeof(fhandle_t));
9625+ if (error)
9626+ return error;
9627+
9628+ error = user_path_walk(gf.fname, &nd);
9629+ if (error)
9630+ return error;
9631+
9632+ error = do_revalidate(nd.dentry);
9633+ if (!error) {
9634+ struct inode *ip = nd.dentry->d_inode;
9635+
9636+ __put_user(ip->i_rdev, &gf.fhp->fh.fsid);
9637+ __put_user(ip->i_ino, &gf.fhp->fh.fno);
9638+ __put_user(0L, &gf.fhp->fh.fgen);
9639+ __put_user(ip->i_rdev, &gf.fhp->fh.ex_fsid);
9640+ __put_user(ip->i_ino, &gf.fhp->fh.ex_fno);
9641+ __put_user(0L, &gf.fhp->fh.ex_fgen);
9642+ error = 0;
9643+ }
9644+ path_release(&nd);
9645+ return error;
9646+}
9647+
9648+static int
9649+socksys_getpeername(int fd, caddr_t arg)
9650+{
9651+ struct sockaddr uaddr;
9652+ int addrlen;
9653+ mm_segment_t fs;
9654+ int error;
9655+
9656+ addrlen = sizeof(struct sockaddr);
9657+
9658+ error = verify_area(VERIFY_WRITE, arg, addrlen);
9659+ if (error)
9660+ return error;
9661+
9662+ fs = get_fs();
9663+ set_fs(get_ds());
9664+ error = sys_getpeername(fd, &uaddr, &addrlen);
9665+ set_fs(fs);
9666+
9667+ if (error >= 0)
9668+ copy_to_user(arg, &uaddr, addrlen);
9669+ return error;
9670+}
9671+
9672+static int
9673+socksys_getsockname(int fd, caddr_t arg)
9674+{
9675+ struct sockaddr uaddr;
9676+ int addrlen;
9677+ mm_segment_t fs;
9678+ int error;
9679+
9680+ addrlen = sizeof(struct sockaddr);
9681+
9682+ error = verify_area(VERIFY_WRITE, arg, addrlen);
9683+ if (error)
9684+ return error;
9685+
9686+ fs = get_fs();
9687+ set_fs(get_ds());
9688+ error = sys_getsockname(fd, &uaddr, &addrlen);
9689+ set_fs(fs);
9690+
9691+ if (error >= 0)
9692+ copy_to_user(arg, &uaddr, addrlen);
9693+ return error;
9694+}
9695+
9696+static int
9697+socksys_gifonep(caddr_t data)
9698+{
9699+ return -EOPNOTSUPP;
9700+}
9701+
9702+static int
9703+socksys_sifonep(caddr_t data)
9704+{
9705+#if 0
9706+ struct svr4_ifreq *ifr = (struct svr4_ifreq *)data;
9707+
9708+ printk("SIOCSIFONEP (spsize = %x, spthresh = %x) not supported\n",
9709+ ifr->svr4_ifr_onepacket.spsize,
9710+ ifr->svr4_ifr_onepacket.spthresh);
9711+#endif
9712+ return -EOPNOTSUPP;
9713+}
9714+
9715+int
9716+abi_ioctl_socksys(int fd, unsigned int cmd, caddr_t arg)
9717+{
9718+ int error;
9719+
9720+ switch (cmd) {
9721+ /*
9722+ * Strictly the ip domain and nis domain are separate and
9723+ * distinct under SCO but Linux only has the one domain.
9724+ */
9725+ case NIOCGETDOMNAM:
9726+ return socksys_getdomainname(arg);
9727+ case NIOCSETDOMNAM:
9728+ return socksys_setdomainname(arg);
9729+ case NIOCLSTAT:
9730+ return socksys_lstat(arg);
9731+ case NIOCOLDGETFH:
9732+ case NIOCGETFH:
9733+ return socksys_getfh(arg);
9734+ case NIOCNFSD:
9735+ case NIOCASYNCD:
9736+ case NIOCCLNTHAND:
9737+ case NIOCEXPORTFS:
9738+ return -EINVAL;
9739+
9740+ case SSYS_SIOCSOCKSYS: /* Pseudo socket syscall */
9741+ case SVR4_SIOCSOCKSYS:
9742+ return socksys_syscall((u_long *)arg);
9743+
9744+ case SSYS_SIOCSHIWAT: /* set high watermark */
9745+ case SVR4_SIOCSHIWAT:
9746+ case SSYS_SIOCSLOWAT: /* set low watermark */
9747+ case SVR4_SIOCSLOWAT:
9748+ /*
9749+ * Linux doesn't support them but lie anyway
9750+ * or some things take it as fatal (why?)
9751+ *
9752+ * FIXME: actually we can do this now...
9753+ */
9754+ return 0;
9755+ case SSYS_SIOCGHIWAT: /* get high watermark */
9756+ case SVR4_SIOCGHIWAT:
9757+ case SSYS_SIOCGLOWAT: /* get low watermark */
9758+ case SVR4_SIOCGLOWAT:
9759+ /*
9760+ * Linux doesn't support them but lie anyway
9761+ * or some things take it as fatal (why?)
9762+ *
9763+ * FIXME: actually we can do this now...
9764+ */
9765+ if ((error = verify_area(VERIFY_WRITE, arg, sizeof(u_long))))
9766+ return error;
9767+ put_user(0, (u_long *)arg);
9768+ return 0;
9769+ case SSYS_SIOCATMARK: /* at oob mark? */
9770+ case SVR4_SIOCATMARK:
9771+ return sys_ioctl(fd, SIOCATMARK, (long)arg);
9772+
9773+ case SSYS_SIOCSPGRP: /* set process group */
9774+ case SVR4_SIOCSPGRP:
9775+ return sys_ioctl(fd, SIOCSPGRP, (long)arg);
9776+ case SSYS_SIOCGPGRP: /* get process group */
9777+ case SVR4_SIOCGPGRP:
9778+ return sys_ioctl(fd, SIOCGPGRP, (long)arg);
9779+
9780+ case FIONREAD:
9781+ case SSYS_FIONREAD: /* BSD compatibilty */
9782+ error = sys_ioctl(fd, TIOCINQ, (long)arg);
9783+#if defined(CONFIG_ABI_TRACE)
9784+ if (!error && abi_traced(ABI_TRACE_SOCKSYS)) {
9785+ u_long n;
9786+
9787+ get_user(n, (u_long *)arg);
9788+ __abi_trace("socksys: %d FIONREAD "
9789+ "found %lu bytes ready\n",
9790+ fd, n);
9791+ }
9792+#endif
9793+ return error;
9794+ case SSYS_FIONBIO: /* BSD compatibilty */
9795+ return sys_ioctl(fd, FIONBIO, (long)arg);
9796+ case SSYS_FIOASYNC: /* BSD compatibilty */
9797+ return sys_ioctl(fd, FIOASYNC, (long)arg);
9798+ case SSYS_SIOCADDRT: /* add route */
9799+ case SVR4_SIOCADDRT:
9800+ return sys_ioctl(fd, SIOCADDRT, (long)arg);
9801+ case SSYS_SIOCDELRT: /* delete route */
9802+ case SVR4_SIOCDELRT:
9803+ return sys_ioctl(fd, SIOCDELRT, (long)arg);
9804+ case SSYS_SIOCSIFADDR: /* set ifnet address */
9805+ case SVR4_SIOCSIFADDR:
9806+ return sys_ioctl(fd, SIOCSIFADDR, (long)arg);
9807+ case SSYS_SIOCGIFADDR: /* get ifnet address */
9808+ case SVR4_SIOCGIFADDR:
9809+ return sys_ioctl(fd, SIOCGIFADDR, (long)arg);
9810+ case SSYS_SIOCSIFDSTADDR: /* set p-p address */
9811+ case SVR4_SIOCSIFDSTADDR:
9812+ return sys_ioctl(fd, SIOCSIFDSTADDR, (long)arg);
9813+ case SSYS_SIOCGIFDSTADDR: /* get p-p address */
9814+ case SVR4_SIOCGIFDSTADDR:
9815+ return sys_ioctl(fd, SIOCGIFDSTADDR, (long)arg);
9816+ case SSYS_SIOCSIFFLAGS: /* set ifnet flags */
9817+ case SVR4_SIOCSIFFLAGS:
9818+ return sys_ioctl(fd, SIOCSIFFLAGS, (long)arg);
9819+ case SSYS_SIOCGIFFLAGS: /* get ifnet flags */
9820+ case SVR4_SIOCGIFFLAGS:
9821+#if 0
9822+ case SVRX_SIOCGIFFLAGS:
9823+#endif
9824+ return sys_ioctl(fd, SIOCGIFFLAGS, (long)arg);
9825+ case SSYS_SIOCGIFCONF: /* get ifnet list */
9826+ case SVR4_SIOCGIFCONF:
9827+#if 0
9828+ case SVRX_SIOCGIFCONF:
9829+#endif
9830+ return sys_ioctl(fd, SIOCGIFCONF, (long)arg);
9831+ case SSYS_SIOCGIFBRDADDR: /* get broadcast addr */
9832+ case SVR4_SIOCGIFBRDADDR:
9833+ return sys_ioctl(fd, SIOCGIFBRDADDR, (long)arg);
9834+ case SSYS_SIOCSIFBRDADDR: /* set broadcast addr */
9835+ case SVR4_SIOCSIFBRDADDR:
9836+ return sys_ioctl(fd, SIOCSIFBRDADDR, (long)arg);
9837+ case SSYS_SIOCGIFNETMASK: /* get net addr mask */
9838+ case SVR4_SIOCGIFNETMASK:
9839+ return sys_ioctl(fd, SIOCGIFNETMASK, (long)arg);
9840+ case SSYS_SIOCSIFNETMASK: /* set net addr mask */
9841+ return sys_ioctl(fd, SIOCSIFNETMASK, (long)arg);
9842+ case SSYS_SIOCGIFMETRIC: /* get IF metric */
9843+ case SVR4_SIOCGIFMETRIC:
9844+ return sys_ioctl(fd, SIOCGIFMETRIC, (long)arg);
9845+ case SSYS_SIOCSIFMETRIC: /* set IF metric */
9846+ case SVR4_SIOCSIFMETRIC:
9847+ return sys_ioctl(fd, SIOCSIFMETRIC, (long)arg);
9848+ case SSYS_SIOCSARP: /* set arp entry */
9849+ case SVR4_SIOCSARP:
9850+ return sys_ioctl(fd, SIOCSARP, (long)arg);
9851+ case SSYS_SIOCGARP: /* get arp entry */
9852+ case SVR4_SIOCGARP:
9853+ return sys_ioctl(fd, SIOCGARP, (long)arg);
9854+ case SSYS_SIOCDARP: /* delete arp entry */
9855+ case SVR4_SIOCDARP:
9856+ return sys_ioctl(fd, SIOCDARP, (long)arg);
9857+ case SSYS_SIOCGENADDR: /* Get ethernet addr */
9858+ case SVR4_SIOCGENADDR:
9859+ return sys_ioctl(fd, SIOCGIFHWADDR, (long)arg);
9860+ case SSYS_SIOCSIFMTU: /* get if_mtu */
9861+ case SVR4_SIOCSIFMTU:
9862+ return sys_ioctl(fd, SIOCSIFMTU, (long)arg);
9863+ case SSYS_SIOCGIFMTU: /* set if_mtu */
9864+ case SVR4_SIOCGIFMTU:
9865+ return sys_ioctl(fd, SIOCGIFMTU, (long)arg);
9866+
9867+ case SSYS_SIOCGETNAME: /* getsockname */
9868+ case SVR4_SIOCGETNAME:
9869+ return socksys_getsockname(fd, arg);
9870+ case SSYS_SIOCGETPEER: /* getpeername */
9871+ case SVR4_SIOCGETPEER:
9872+ return socksys_getpeername(fd, arg);
9873+
9874+ case SSYS_IF_UNITSEL: /* set unit number */
9875+ case SVR4_IF_UNITSEL:
9876+ case SSYS_SIOCXPROTO: /* empty proto table */
9877+ case SVR4_SIOCXPROTO:
9878+
9879+ case SSYS_SIOCIFDETACH: /* detach interface */
9880+ case SVR4_SIOCIFDETACH:
9881+ case SSYS_SIOCGENPSTATS: /* get ENP stats */
9882+ case SVR4_SIOCGENPSTATS:
9883+
9884+ case SSYS_SIOCSIFNAME: /* set interface name */
9885+ case SVR4_SIOCSIFNAME:
9886+
9887+ case SSYS_SIOCPROTO: /* link proto */
9888+ case SVR4_SIOCPROTO:
9889+ case SSYS_SIOCX25XMT:
9890+ case SVR4_SIOCX25XMT:
9891+ case SSYS_SIOCX25RCV:
9892+ case SVR4_SIOCX25RCV:
9893+ case SSYS_SIOCX25TBL:
9894+ case SVR4_SIOCX25TBL:
9895+
9896+ case SSYS_SIOCGIFONEP: /* get one-packet params */
9897+ return socksys_gifonep(arg);
9898+ case SSYS_SIOCSIFONEP: /* set one-packet params */
9899+ return socksys_sifonep(arg);
9900+
9901+ default:
9902+ printk(KERN_DEBUG "%d iBCS: socksys: %d: ioctl 0x%x with argument 0x%p requested\n",
9903+ current->pid, fd, cmd, arg);
9904+ break;
9905+ }
9906+
9907+ return -EINVAL;
9908+}
9909+
9910+static int __init
9911+socksys_init(void)
9912+{
9913+ int ret;
9914+
9915+ if ((ret = register_chrdev(SOCKSYS_MAJOR, "socksys", &socksys_fops))) {
9916+ printk(KERN_ERR "abi: unable register socksys char major\n");
9917+ return (ret);
9918+ }
9919+
9920+ fops_get(&socket_file_ops);
9921+ socksys_socket_fops = socket_file_ops;
9922+#ifdef CONFIG_ABI_XTI
9923+ socksys_socket_fops.release = socksys_release;
9924+ socksys_socket_fops.poll = socksys_poll;
9925+#endif
9926+ return (0);
9927+}
9928+
9929+static void __exit
9930+socksys_exit(void)
9931+{
9932+ fops_put(&socket_file_ops);
9933+ unregister_chrdev(SOCKSYS_MAJOR, "socksys");
9934+}
9935+
9936+module_init(socksys_init);
9937+module_exit(socksys_exit);
9938+
9939+#if defined(CONFIG_ABI_SYSCALL_MODULES)
9940+EXPORT_SYMBOL(abi_ioctl_socksys);
9941+EXPORT_SYMBOL(socksys_syscall);
9942+#endif
9943diff -Nru linux-2.6.7/abi/svr4/stat.c linux-2.6.7-abi/abi/svr4/stat.c
9944--- linux-2.6.7/abi/svr4/stat.c 1970-01-01 01:00:00.000000000 +0100
9945+++ linux-2.6.7-abi/abi/svr4/stat.c 2004-07-22 17:44:21.000000000 +0200
9946@@ -0,0 +1,223 @@
9947+/*
9948+ * Copyright (c) 2001 Caldera Deutschland GmbH.
9949+ * Copyright (c) 2001 Christoph Hellwig.
9950+ * All rights reserved.
9951+ *
9952+ * This program is free software; you can redistribute it and/or modify
9953+ * it under the terms of the GNU General Public License as published by
9954+ * the Free Software Foundation; either version 2 of the License, or
9955+ * (at your option) any later version.
9956+ *
9957+ * This program is distributed in the hope that it will be useful,
9958+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9959+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9960+ * GNU General Public License for more details.
9961+ *
9962+ * You should have received a copy of the GNU General Public License
9963+ * along with this program; if not, write to the Free Software
9964+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
9965+ */
9966+
9967+#ident "%W% %G%"
9968+
9969+/*
9970+ * SVR4 stat & friends support.
9971+ */
9972+#include <linux/kernel.h>
9973+#include <linux/fs.h>
9974+#include <linux/sched.h>
9975+#include <linux/file.h>
9976+#include <linux/string.h>
9977+#include <linux/module.h>
9978+#include <asm/uaccess.h>
9979+
9980+#include <abi/svr4/types.h>
9981+#include <abi/svr4/stat.h>
9982+
9983+#include <abi/util/stat.h>
9984+#include <abi/util/trace.h>
9985+
9986+
9987+enum {SVR4_stat = 1, SVR4_xstat = 2};
9988+
9989+int
9990+report_svr4_stat(struct kstat *stp, struct svr4_stat *bufp)
9991+{
9992+ struct svr4_stat buf;
9993+
9994+ memset(&buf, 0, sizeof(struct svr4_stat));
9995+
9996+
9997+ buf.st_dev = linux_to_svr4_o_dev_t(stp->dev);
9998+ buf.st_ino = linux_to_svr4_o_ino_t(stp->ino);
9999+ buf.st_mode = stp->mode;
10000+ buf.st_nlink = stp->nlink;
10001+ buf.st_uid = linux_to_svr4_o_uid_t(stp->uid);
10002+ buf.st_gid = linux_to_svr4_o_gid_t(stp->gid);
10003+ buf.st_rdev = linux_to_svr4_o_dev_t(stp->rdev);
10004+
10005+ if (stp->size > MAX_NON_LFS)
10006+ return -EOVERFLOW; /* XXX: what to return for SVR4?? */
10007+
10008+ buf.st_size = stp->size;
10009+
10010+ buf.st_atime = stp->atime.tv_sec;
10011+ buf.st_mtime = stp->mtime.tv_sec;
10012+ buf.st_ctime = stp->ctime.tv_sec;
10013+
10014+ if (copy_to_user(bufp, &buf, sizeof(struct svr4_stat)))
10015+ return -EFAULT;
10016+ return 0;
10017+}
10018+
10019+int
10020+report_svr4_xstat(struct kstat *stp, struct svr4_xstat *bufp)
10021+{
10022+ struct svr4_xstat buf;
10023+
10024+ memset(&buf, 0, sizeof(struct svr4_xstat));
10025+
10026+
10027+ buf.st_dev = linux_to_svr4_dev_t(stp->dev);
10028+ buf.st_ino = linux_to_svr4_ino_t(stp->ino);
10029+ buf.st_mode = stp->mode;
10030+ buf.st_nlink = stp->nlink;
10031+ buf.st_uid = linux_to_svr4_uid_t(stp->uid);
10032+ buf.st_gid = linux_to_svr4_gid_t(stp->gid);
10033+ buf.st_rdev = linux_to_svr4_dev_t(stp->rdev);
10034+
10035+ if (stp->size > MAX_NON_LFS)
10036+ return -EOVERFLOW; /* XXX: what to return for SVR4?? */
10037+
10038+ buf.st_size = stp->size;
10039+
10040+ buf.st_atim.tv_sec = stp->atime.tv_sec;
10041+ buf.st_atim.tv_usec = stp->atime.tv_nsec / 1000;
10042+ buf.st_mtim.tv_sec = stp->mtime.tv_sec;
10043+ buf.st_mtim.tv_usec = stp->mtime.tv_nsec / 1000;
10044+ buf.st_ctim.tv_sec = stp->ctime.tv_sec;
10045+ buf.st_ctim.tv_usec = stp->ctime.tv_nsec / 1000;
10046+
10047+ buf.st_blksize = stp->blksize;
10048+ buf.st_blocks = stp->blocks;
10049+
10050+ if (copy_to_user(bufp, &buf, sizeof(struct svr4_xstat)))
10051+ return -EFAULT;
10052+ return 0;
10053+}
10054+
10055+int
10056+svr4_stat(char *filename, struct svr4_stat *bufp)
10057+{
10058+ struct kstat st;
10059+ int error;
10060+
10061+ error = vfs_stat(filename, &st);
10062+ if (!error)
10063+ error = report_svr4_stat(&st, bufp);
10064+ return error;
10065+}
10066+
10067+int
10068+svr4_lstat(char *filename, struct svr4_stat *bufp)
10069+{
10070+ struct kstat st;
10071+ int error;
10072+
10073+ error = vfs_lstat(filename, &st);
10074+ if (!error)
10075+ error = report_svr4_stat(&st, bufp);
10076+ return error;
10077+}
10078+
10079+int
10080+svr4_fstat(int fd, struct svr4_stat *bufp)
10081+{
10082+ struct kstat st;
10083+ int error;
10084+
10085+ error = vfs_fstat(fd, &st);
10086+ if (!error)
10087+ error = report_svr4_stat(&st, bufp);
10088+ return error;
10089+}
10090+
10091+int
10092+svr4_xstat(int vers, char *filename, void *bufp)
10093+{
10094+ struct kstat st;
10095+ int error;
10096+
10097+ error = vfs_stat(filename, &st);
10098+ if (error)
10099+ return error;
10100+
10101+ switch (vers) {
10102+ case SVR4_stat:
10103+ return report_svr4_stat(&st, bufp);
10104+ case SVR4_xstat:
10105+ return report_svr4_xstat(&st, bufp);
10106+ }
10107+
10108+#if defined(CONFIG_ABI_TRACE)
10109+ abi_trace(ABI_TRACE_API, "xstat version %d not supported\n", vers);
10110+#endif
10111+ return -EINVAL;
10112+}
10113+
10114+int
10115+svr4_lxstat(int vers, char *filename, void *bufp)
10116+{
10117+ struct kstat st;
10118+ int error;
10119+
10120+ error = vfs_lstat(filename, &st);
10121+ if (error)
10122+ return error;
10123+
10124+ switch (vers) {
10125+ case SVR4_stat:
10126+ return report_svr4_stat(&st, bufp);
10127+ case SVR4_xstat:
10128+ return report_svr4_xstat(&st, bufp);
10129+ }
10130+
10131+#if defined(CONFIG_ABI_TRACE)
10132+ abi_trace(ABI_TRACE_API, "lxstat version %d not supported\n", vers);
10133+#endif
10134+ return -EINVAL;
10135+}
10136+
10137+int
10138+svr4_fxstat(int vers, int fd, void *bufp)
10139+{
10140+ struct kstat st;
10141+ int error;
10142+
10143+ error = vfs_fstat(fd, &st);
10144+ if (error)
10145+ return error;
10146+
10147+ switch (vers) {
10148+ case SVR4_stat:
10149+ return report_svr4_stat(&st, bufp);
10150+ case SVR4_xstat:
10151+ return report_svr4_xstat(&st, bufp);
10152+ }
10153+
10154+#if defined(CONFIG_ABI_TRACE)
10155+ abi_trace(ABI_TRACE_API, "fxstat version %d not supported\n", vers);
10156+#endif
10157+ return -EINVAL;
10158+}
10159+
10160+#if defined(CONFIG_ABI_SYSCALL_MODULES)
10161+EXPORT_SYMBOL(report_svr4_stat);
10162+EXPORT_SYMBOL(report_svr4_xstat);
10163+EXPORT_SYMBOL(svr4_fstat);
10164+EXPORT_SYMBOL(svr4_fxstat);
10165+EXPORT_SYMBOL(svr4_lstat);
10166+EXPORT_SYMBOL(svr4_lxstat);
10167+EXPORT_SYMBOL(svr4_stat);
10168+EXPORT_SYMBOL(svr4_xstat);
10169+#endif
10170diff -Nru linux-2.6.7/abi/svr4/statvfs.c linux-2.6.7-abi/abi/svr4/statvfs.c
10171--- linux-2.6.7/abi/svr4/statvfs.c 1970-01-01 01:00:00.000000000 +0100
10172+++ linux-2.6.7-abi/abi/svr4/statvfs.c 2004-07-22 17:44:21.000000000 +0200
10173@@ -0,0 +1,124 @@
10174+/*
10175+ * Copyright (c) 2001 Caldera Deutschland GmbH.
10176+ * Copyright (c) 2001 Christoph Hellwig.
10177+ * All rights reserved.
10178+ *
10179+ * This program is free software; you can redistribute it and/or modify
10180+ * it under the terms of the GNU General Public License as published by
10181+ * the Free Software Foundation; either version 2 of the License, or
10182+ * (at your option) any later version.
10183+ *
10184+ * This program is distributed in the hope that it will be useful,
10185+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10186+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10187+ * GNU General Public License for more details.
10188+ *
10189+ * You should have received a copy of the GNU General Public License
10190+ * along with this program; if not, write to the Free Software
10191+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
10192+ */
10193+
10194+#ident "%W% %G%"
10195+
10196+/*
10197+ * SVR4 statvfs/fstatvfs support.
10198+ */
10199+#include <linux/kernel.h>
10200+#include <linux/fs.h>
10201+#include <linux/statfs.h>
10202+#include <linux/mount.h>
10203+#include <linux/sched.h>
10204+#include <linux/file.h>
10205+#include <linux/string.h>
10206+#include <linux/namei.h>
10207+#include <linux/module.h>
10208+#include <asm/uaccess.h>
10209+
10210+
10211+struct svr4_statvfs {
10212+ u_int32_t f_bsize;
10213+ u_int32_t f_frsize;
10214+ u_int32_t f_blocks;
10215+ u_int32_t f_bfree;
10216+ u_int32_t f_bavail;
10217+ u_int32_t f_files;
10218+ u_int32_t f_free;
10219+ u_int32_t f_sid;
10220+ char f_basetype[16];
10221+ u_int32_t f_flag;
10222+ u_int32_t f_namemax;
10223+ char f_fstr[32];
10224+ u_int32_t f_filler[16];
10225+};
10226+
10227+static int
10228+report_statvfs(struct vfsmount *mnt, struct inode *ip, struct svr4_statvfs *bufp)
10229+{
10230+ struct svr4_statvfs buf;
10231+ struct kstatfs s;
10232+ int error;
10233+
10234+ error = vfs_statfs(mnt->mnt_sb, &s);
10235+ if (error)
10236+ return error;
10237+
10238+ memset(&buf, 0, sizeof(struct svr4_statvfs));
10239+
10240+ buf.f_bsize = s.f_bsize;
10241+ buf.f_frsize = s.f_bsize;
10242+ buf.f_blocks = s.f_blocks;
10243+ buf.f_bfree = s.f_bfree;
10244+ buf.f_bavail = s.f_bavail;
10245+ buf.f_files = s.f_files;
10246+ buf.f_free = s.f_ffree;
10247+ buf.f_sid = ip->i_sb->s_dev;
10248+
10249+ /* Get the name of the filesystem */
10250+ strcpy(buf.f_basetype, ip->i_sb->s_type->name);
10251+
10252+ /* Check for a few flags statvfs wants but statfs doesn't have. */
10253+ if (IS_RDONLY(ip))
10254+ buf.f_flag |= 1;
10255+ if (mnt->mnt_flags & MNT_NOSUID)
10256+ buf.f_flag |= 2;
10257+
10258+ buf.f_namemax = s.f_namelen;
10259+
10260+ if (copy_to_user(bufp, &buf, sizeof(struct svr4_statvfs)))
10261+ return -EFAULT;
10262+ return 0;
10263+}
10264+
10265+int
10266+svr4_statvfs(char *filename, struct svr4_statvfs *bufp)
10267+{
10268+ struct nameidata nd;
10269+ int error;
10270+
10271+ error = user_path_walk(filename, &nd);
10272+ if (!error) {
10273+ error = report_statvfs(nd.mnt, nd.dentry->d_inode, bufp);
10274+ path_release(&nd);
10275+ }
10276+ return error;
10277+}
10278+
10279+int
10280+svr4_fstatvfs(int fd, struct svr4_statvfs *bufp)
10281+{
10282+ struct file *fp;
10283+ int error = -EBADF;
10284+
10285+ fp = fget(fd);
10286+ if (fp) {
10287+ error = report_statvfs(fp->f_vfsmnt,
10288+ fp->f_dentry->d_inode, bufp);
10289+ fput(fp);
10290+ }
10291+ return error;
10292+}
10293+
10294+#if defined(CONFIG_ABI_SYSCALL_MODULES)
10295+EXPORT_SYMBOL(svr4_statvfs);
10296+EXPORT_SYMBOL(svr4_fstatvfs);
10297+#endif
10298diff -Nru linux-2.6.7/abi/svr4/stream.c linux-2.6.7-abi/abi/svr4/stream.c
10299--- linux-2.6.7/abi/svr4/stream.c 1970-01-01 01:00:00.000000000 +0100
10300+++ linux-2.6.7-abi/abi/svr4/stream.c 2004-07-22 17:44:21.000000000 +0200
10301@@ -0,0 +1,114 @@
10302+/*
10303+ * Copyright 1994,1995 Mike Jagdis (jaggy@purplet.demon.co.uk)
10304+ */
10305+
10306+#ident "%W% %G%"
10307+
10308+#include <linux/config.h>
10309+#include <linux/errno.h>
10310+#include <linux/ptrace.h>
10311+#include <linux/sched.h>
10312+#include <linux/file.h>
10313+#include <linux/fs.h>
10314+#include <linux/module.h>
10315+#include <asm/uaccess.h>
10316+
10317+#include <asm/abi_machdep.h>
10318+#include <abi/tli.h>
10319+
10320+
10321+#if !defined(CONFIG_ABI_XTI) && !defined(CONFIG_ABI_SPX)
10322+# define timod_getmsg(fd, ino, is_pmsg, regs) 0
10323+# define timod_putmsg(fd, ino, is_pmsg, regs) 0
10324+#endif
10325+
10326+/*
10327+ * Check if the inode belongs to /dev/spx.
10328+ */
10329+#define IS_SPX(ip) ((MAJOR((ip)->i_rdev) == 30 && MINOR((ip)->i_rdev) == 1))
10330+
10331+
10332+int
10333+svr4_getmsg(struct pt_regs *regs)
10334+{
10335+ struct file *fp;
10336+ struct inode *ip;
10337+ int fd;
10338+ int error = -EBADF;
10339+
10340+ fd = (int)get_syscall_parameter(regs, 0);
10341+ fp = fget(fd);
10342+ if (fp) {
10343+ ip = fp->f_dentry->d_inode;
10344+ if (ip->i_sock)
10345+ error = timod_getmsg(fd, ip, 0, regs);
10346+ fput(fp);
10347+ }
10348+ return error;
10349+}
10350+
10351+int
10352+svr4_putmsg(struct pt_regs *regs)
10353+{
10354+ struct file *fp;
10355+ struct inode *ip;
10356+ int fd;
10357+ int error = -EBADF;
10358+
10359+ fd = (int)get_syscall_parameter(regs, 0);
10360+ fp = fget(fd);
10361+ if (fp) {
10362+ ip = fp->f_dentry->d_inode;
10363+ if (ip->i_sock || IS_SPX(ip))
10364+ error = timod_putmsg(fd, ip, 0, regs);
10365+ fput(fp);
10366+ }
10367+ return error;
10368+}
10369+
10370+#ifdef CONFIG_ABI_XTI
10371+int
10372+svr4_getpmsg(struct pt_regs *regs)
10373+{
10374+ struct file *fp;
10375+ struct inode *ip;
10376+ int fd;
10377+ int error = -EBADF;
10378+
10379+ fd = (int)get_syscall_parameter(regs, 0);
10380+ fp = fget(fd);
10381+ if (fp) {
10382+ ip = fp->f_dentry->d_inode;
10383+ if (ip->i_sock)
10384+ error = timod_getmsg(fd, ip, 1, regs);
10385+ fput(fp);
10386+ }
10387+ return error;
10388+}
10389+
10390+int
10391+svr4_putpmsg(struct pt_regs *regs)
10392+{
10393+ struct file *fp;
10394+ struct inode *ip;
10395+ int fd;
10396+ int error = -EBADF;
10397+
10398+ fd = (int)get_syscall_parameter(regs, 0);
10399+ fp = fget(fd);
10400+ if (fp) {
10401+ ip = fp->f_dentry->d_inode;
10402+ if (ip->i_sock || IS_SPX(ip))
10403+ error = timod_putmsg(fd, ip, 1, regs);
10404+ fput(fp);
10405+ }
10406+ return error;
10407+}
10408+#endif /* CONFIG_ABI_XTI */
10409+
10410+#if defined(CONFIG_ABI_SYSCALL_MODULES)
10411+EXPORT_SYMBOL(svr4_getmsg);
10412+EXPORT_SYMBOL(svr4_getpmsg);
10413+EXPORT_SYMBOL(svr4_putmsg);
10414+EXPORT_SYMBOL(svr4_putpmsg);
10415+#endif
10416diff -Nru linux-2.6.7/abi/svr4/svr4.c linux-2.6.7-abi/abi/svr4/svr4.c
10417--- linux-2.6.7/abi/svr4/svr4.c 1970-01-01 01:00:00.000000000 +0100
10418+++ linux-2.6.7-abi/abi/svr4/svr4.c 2004-07-22 17:44:21.000000000 +0200
10419@@ -0,0 +1,332 @@
10420+/*
10421+ * Copyright (C) 1995 Mike Jagdis
10422+ */
10423+
10424+#ident "%W% %G%"
10425+
10426+#include <linux/types.h>
10427+#include <linux/errno.h>
10428+#include <linux/sched.h>
10429+#include <linux/kernel.h>
10430+#include <linux/mm.h>
10431+#include <linux/stddef.h>
10432+#include <linux/unistd.h>
10433+#include <linux/ptrace.h>
10434+#include <linux/fcntl.h>
10435+#include <linux/time.h>
10436+#include <linux/fs.h>
10437+#include <linux/statfs.h>
10438+#include <linux/sys.h>
10439+#include <linux/slab.h>
10440+#include <linux/personality.h>
10441+#include <linux/syscalls.h>
10442+#include <linux/module.h>
10443+#include <asm/uaccess.h>
10444+
10445+#include <asm/abi_machdep.h>
10446+#include <abi/svr4/sigset.h>
10447+#include <abi/svr4/siginfo.h>
10448+
10449+#include <abi/util/trace.h>
10450+
10451+
10452+/*
10453+ * Interactive SVR4's /bin/sh calls access(... 011) but Linux returns
10454+ * EINVAL if the access mode has any other bits than 007 set.
10455+ */
10456+
10457+int
10458+svr4_access(char *path, int mode)
10459+{
10460+ return sys_access(path, mode & 007);
10461+}
10462+
10463+
10464+enum {
10465+ SVR4_CLD_EXITED = 1,
10466+ SVR4_CLD_KILLED = 2,
10467+ SVR4_CLD_DUMPED = 3,
10468+ SVR4_CLD_TRAPPED = 4,
10469+ SVR4_CLD_STOPPED = 5,
10470+ SVR4_CLD_CONTINUED = 6
10471+};
10472+
10473+int
10474+svr4_waitid(int idtype, int id, struct svr4_siginfo *infop, int options)
10475+{
10476+ long result, kopt;
10477+ mm_segment_t old_fs;
10478+ int pid, status;
10479+
10480+ switch (idtype) {
10481+ case 0: /* P_PID */
10482+ pid = id;
10483+ break;
10484+
10485+ case 1: /* P_PGID */
10486+ pid = -id;
10487+ break;
10488+
10489+ case 7: /* P_ALL */
10490+ pid = -1;
10491+ break;
10492+
10493+ default:
10494+ return -EINVAL;
10495+ }
10496+
10497+ if (infop) {
10498+ result = verify_area(VERIFY_WRITE, infop,
10499+ sizeof(struct svr4_siginfo));
10500+ if (result)
10501+ return result;
10502+ }
10503+
10504+ kopt = 0;
10505+ if (options & 0100) kopt |= WNOHANG;
10506+ if (options & 4) kopt |= WUNTRACED;
10507+
10508+ old_fs = get_fs();
10509+ set_fs(get_ds());
10510+ result = sys_wait4(pid, &status, kopt, NULL);
10511+ set_fs(old_fs);
10512+ if (result < 0)
10513+ return result;
10514+
10515+ if (infop) {
10516+ unsigned long op, st;
10517+
10518+ put_user(current_thread_info()->exec_domain->signal_map[SIGCHLD],
10519+ &infop->si_signo);
10520+ put_user(result,
10521+ &infop->_data._proc._pid);
10522+
10523+ if ((status & 0xff) == 0) {
10524+ /* Normal exit. */
10525+ op = SVR4_CLD_EXITED;
10526+ st = status >> 8;
10527+ } else if ((status & 0xff) == 0x7f) {
10528+ /* Stopped. */
10529+ st = (status & 0xff00) >> 8;
10530+ op = (st == SIGSTOP || st == SIGTSTP)
10531+ ? SVR4_CLD_STOPPED
10532+ : SVR4_CLD_CONTINUED;
10533+ st = current_thread_info()->exec_domain->signal_invmap[st];
10534+ } else {
10535+ st = (status & 0xff00) >> 8;
10536+ op = (status & 0200)
10537+ ? SVR4_CLD_DUMPED
10538+ : SVR4_CLD_KILLED;
10539+ st = current_thread_info()->exec_domain->signal_invmap[st];
10540+ }
10541+ put_user(op, &infop->si_code);
10542+ put_user(st, &infop->_data._proc._pdata._cld._status);
10543+ }
10544+ return 0;
10545+}
10546+
10547+int
10548+svr4_seteuid(int uid)
10549+{
10550+ return sys_setreuid16(-1, uid);
10551+}
10552+
10553+int
10554+svr4_setegid(int gid)
10555+{
10556+ return sys_setregid16(-1, gid);
10557+}
10558+
10559+/* POSIX.1 names */
10560+#define _PC_LINK_MAX 1
10561+#define _PC_MAX_CANON 2
10562+#define _PC_MAX_INPUT 3
10563+#define _PC_NAME_MAX 4
10564+#define _PC_PATH_MAX 5
10565+#define _PC_PIPE_BUF 6
10566+#define _PC_NO_TRUNC 7
10567+#define _PC_VDISABLE 8
10568+#define _PC_CHOWN_RESTRICTED 9
10569+/* POSIX.4 names */
10570+#define _PC_ASYNC_IO 10
10571+#define _PC_PRIO_IO 11
10572+#define _PC_SYNC_IO 12
10573+
10574+int
10575+svr4_pathconf(char *path, int name)
10576+{
10577+ switch (name) {
10578+ case _PC_LINK_MAX:
10579+ /* Although Linux headers define values on a per
10580+ * filesystem basis there is no way to access
10581+ * these without hard coding fs information here
10582+ * so for now we use a bogus value.
10583+ */
10584+ return LINK_MAX;
10585+
10586+ case _PC_MAX_CANON:
10587+ return MAX_CANON;
10588+
10589+ case _PC_MAX_INPUT:
10590+ return MAX_INPUT;
10591+
10592+ case _PC_PATH_MAX:
10593+ return PATH_MAX;
10594+
10595+ case _PC_PIPE_BUF:
10596+ return PIPE_BUF;
10597+
10598+ case _PC_CHOWN_RESTRICTED:
10599+ /* We should really think about this and tell
10600+ * the truth.
10601+ */
10602+ return 0;
10603+
10604+ case _PC_NO_TRUNC:
10605+ /* Not sure... It could be fs dependent? */
10606+ return 1;
10607+
10608+ case _PC_VDISABLE:
10609+ return 1;
10610+
10611+ case _PC_NAME_MAX: {
10612+ struct statfs buf;
10613+ char *p;
10614+ int error;
10615+ mm_segment_t old_fs;
10616+
10617+ p = getname(path);
10618+ error = PTR_ERR(p);
10619+ if (!IS_ERR(p)) {
10620+ old_fs = get_fs();
10621+ set_fs (get_ds());
10622+ error = sys_statfs(p, &buf);
10623+ set_fs(old_fs);
10624+ putname(p);
10625+ if (!error)
10626+ return buf.f_namelen;
10627+ }
10628+ return error;
10629+ }
10630+ }
10631+
10632+ return -EINVAL;
10633+}
10634+
10635+int
10636+svr4_fpathconf(int fildes, int name)
10637+{
10638+ switch (name) {
10639+ case _PC_LINK_MAX:
10640+ /* Although Linux headers define values on a per
10641+ * filesystem basis there is no way to access
10642+ * these without hard coding fs information here
10643+ * so for now we use a bogus value.
10644+ */
10645+ return LINK_MAX;
10646+
10647+ case _PC_MAX_CANON:
10648+ return MAX_CANON;
10649+
10650+ case _PC_MAX_INPUT:
10651+ return MAX_INPUT;
10652+
10653+ case _PC_PATH_MAX:
10654+ return PATH_MAX;
10655+
10656+ case _PC_PIPE_BUF:
10657+ return PIPE_BUF;
10658+
10659+ case _PC_CHOWN_RESTRICTED:
10660+ /* We should really think about this and tell
10661+ * the truth.
10662+ */
10663+ return 0;
10664+
10665+ case _PC_NO_TRUNC:
10666+ /* Not sure... It could be fs dependent? */
10667+ return 1;
10668+
10669+ case _PC_VDISABLE:
10670+ return 1;
10671+
10672+ case _PC_NAME_MAX: {
10673+ struct statfs buf;
10674+ int error;
10675+ mm_segment_t old_fs;
10676+
10677+ old_fs = get_fs();
10678+ set_fs (get_ds());
10679+ error = sys_fstatfs(fildes, &buf);
10680+ set_fs(old_fs);
10681+ if (!error)
10682+ return buf.f_namelen;
10683+ return error;
10684+ }
10685+ }
10686+
10687+ return -EINVAL;
10688+}
10689+
10690+int
10691+svr4_sigpending(int which_routine, svr4_sigset_t *set)
10692+{
10693+ /* Solaris multiplexes on this one */
10694+ /* Which routine has the actual routine that should be called */
10695+
10696+ switch (which_routine){
10697+ case 1: /* sigpending */
10698+ printk ("iBCS/Intel: sigpending not implemented\n");
10699+ return -EINVAL;
10700+
10701+ case 2: /* sigfillset */
10702+ set->setbits [0] = ~0;
10703+ set->setbits [1] = 0;
10704+ set->setbits [2] = 0;
10705+ set->setbits [3] = 0;
10706+ return 0;
10707+ }
10708+ return -EINVAL;
10709+}
10710+
10711+typedef void svr4_ucontext_t;
10712+
10713+static int
10714+svr4_setcontext(svr4_ucontext_t *c, struct pt_regs *regs)
10715+{
10716+ printk (KERN_DEBUG "Getting context\n");
10717+ return 0;
10718+}
10719+
10720+static int
10721+svr4_getcontext(svr4_ucontext_t *c, struct pt_regs *regs)
10722+{
10723+ printk (KERN_DEBUG "Setting context\n");
10724+ return 0;
10725+}
10726+
10727+int
10728+svr4_context(struct pt_regs *regs)
10729+{
10730+ int context_fn = get_syscall_parameter (regs, 0);
10731+ struct svr4_ucontext_t *uc = (void *) get_syscall_parameter (regs, 1);
10732+
10733+ switch (context_fn){
10734+ case 0: /* getcontext */
10735+ return svr4_getcontext (uc, regs);
10736+
10737+ case 1: /* setcontext */
10738+ return svr4_setcontext (uc, regs);
10739+ }
10740+ return -EINVAL;
10741+}
10742+
10743+#if defined(CONFIG_ABI_SYSCALL_MODULES)
10744+EXPORT_SYMBOL(svr4_context);
10745+EXPORT_SYMBOL(svr4_fpathconf);
10746+EXPORT_SYMBOL(svr4_pathconf);
10747+EXPORT_SYMBOL(svr4_setegid);
10748+EXPORT_SYMBOL(svr4_seteuid);
10749+EXPORT_SYMBOL(svr4_sigpending);
10750+EXPORT_SYMBOL(svr4_waitid);
10751+#endif
10752diff -Nru linux-2.6.7/abi/svr4/sysconf.c linux-2.6.7-abi/abi/svr4/sysconf.c
10753--- linux-2.6.7/abi/svr4/sysconf.c 1970-01-01 01:00:00.000000000 +0100
10754+++ linux-2.6.7-abi/abi/svr4/sysconf.c 2004-07-22 17:44:21.000000000 +0200
10755@@ -0,0 +1,186 @@
10756+/*
10757+ * sysconf.c - sysv sysconf(2) and sysconfig(2) emulation
10758+ *
10759+ * Copyright (C) 1994 Mike Jagdis (jaggy@purplet.demon.co.uk)
10760+ */
10761+
10762+#ident "%W% %G%"
10763+
10764+#include <linux/module.h>
10765+#include <linux/errno.h>
10766+#include <linux/sched.h>
10767+#include <linux/kernel.h>
10768+#include <linux/mm.h>
10769+#include <linux/stddef.h>
10770+#include <linux/limits.h>
10771+#include <linux/unistd.h>
10772+#include <linux/ptrace.h>
10773+#include <linux/fcntl.h>
10774+#include <linux/smp.h>
10775+#include <linux/swap.h>
10776+#include <linux/fs.h>
10777+#include <linux/sys.h>
10778+#include <asm/uaccess.h>
10779+#include <asm/system.h>
10780+
10781+#include <abi/svr4/sysconf.h>
10782+#include <abi/util/trace.h>
10783+
10784+
10785+/* The sysconf() call is supposed to give applications access to various
10786+ * kernel parameters. According to SCO's man page this a POSIX mandated
10787+ * function. Perhaps it should be moved across as a native Linux call?
10788+ *
10789+ * N.B. SCO only has sysconf in the Xenix group. Therefore this is based
10790+ * on the Xenix spec. Is SVR4 the same? Wyse Unix V.3.2.1A doesn't have
10791+ * sysconf documented at all.
10792+ *
10793+ * N.B. 0-7 are required (by who?). Other values may be defined for
10794+ * various systems but there appears no guarantee that they match across
10795+ * platforms. Thus, unless we can identify what system the executable
10796+ * was compiled for, we probably prefer to have extensions fail. Hell,
10797+ * nothing important is going to use this obscure stuff anyway...
10798+ */
10799+#define _SC_ARG_MAX 0
10800+#define _SC_CHILD_MAX 1
10801+#define _SC_CLK_TCK 2
10802+#define _SC_NGROUPS_MAX 3
10803+#define _SC_OPEN_MAX 4
10804+#define _SC_JOB_CONTROL 5
10805+#define _SC_SAVED_IDS 6
10806+#define _SC_VERSION 7
10807+
10808+#define _SC_PAGESIZE 11
10809+#define _SCO_SC_PAGESIZE 34
10810+
10811+
10812+/* This is an SVR4 system call that is undocumented except for some
10813+ * hints in a header file. It appears to be a forerunner to the
10814+ * POSIX sysconf() call.
10815+ */
10816+int svr4_sysconfig(int name)
10817+{
10818+ switch (name) {
10819+ case _CONFIG_NGROUPS:
10820+ /* From limits.h */
10821+ return (NGROUPS_MAX);
10822+
10823+ case _CONFIG_CHILD_MAX:
10824+ /* From limits.h */
10825+ return (CHILD_MAX);
10826+
10827+ case _CONFIG_OPEN_FILES:
10828+ /* From limits.h */
10829+ return (OPEN_MAX);
10830+
10831+ case _CONFIG_POSIX_VER:
10832+ /* The version of the POSIX standard we conform
10833+ * to. SCO defines _POSIX_VERSION as 198808L
10834+ * sys/unistd.h. What are we? We are 199009L.
10835+ */
10836+ return (199009L);
10837+
10838+ case _CONFIG_PAGESIZE:
10839+ return (PAGE_SIZE);
10840+
10841+ case _CONFIG_CLK_TCK:
10842+ return (HZ);
10843+
10844+ case _CONFIG_XOPEN_VER:
10845+ return 4;
10846+
10847+ case _CONFIG_NACLS_MAX:
10848+ return 0;
10849+
10850+ case _CONFIG_NPROC:
10851+ return 4000; /* max_threads */
10852+
10853+ case _CONFIG_NENGINE:
10854+ case _CONFIG_NENGINE_ONLN:
10855+ return (num_online_cpus());
10856+
10857+ case _CONFIG_TOTAL_MEMORY:
10858+ return (max_mapnr << (PAGE_SHIFT-10));
10859+
10860+ case _CONFIG_USEABLE_MEMORY:
10861+ case _CONFIG_GENERAL_MEMORY:
10862+ return (max_mapnr << (PAGE_SHIFT-10));
10863+/* return ((unsigned long) (nr_free_pages()) << (PAGE_SHIFT-10)); */
10864+
10865+ case _CONFIG_DEDICATED_MEMORY:
10866+ return 0;
10867+
10868+ case _CONFIG_NCGS_CONF:
10869+ case _CONFIG_NCGS_ONLN:
10870+ case _CONFIG_MAX_ENG_PER_CG:
10871+ return 1; /* no NUMA-Q support on Linux yet */
10872+ /* well, there is. we lie anyway --hch */
10873+
10874+ case _CONFIG_CACHE_LINE:
10875+ return 32; /* XXX is there a more accurate way? */
10876+
10877+ case _CONFIG_KERNEL_VM:
10878+ return -EINVAL;
10879+
10880+ case _CONFIG_ARG_MAX:
10881+ /* From limits.h */
10882+ return (ARG_MAX);
10883+ }
10884+
10885+#if defined(CONFIG_ABI_TRACE)
10886+ abi_trace(ABI_TRACE_API, "unsupported sysconfig call %d\n", name);
10887+#endif
10888+ return -EINVAL;
10889+}
10890+
10891+
10892+int ibcs_sysconf(int name)
10893+{
10894+ switch (name) {
10895+ case _SC_ARG_MAX:
10896+ /* From limits.h */
10897+ return (ARG_MAX);
10898+
10899+ case _SC_CHILD_MAX:
10900+ /* From limits.h */
10901+ return (CHILD_MAX);
10902+
10903+ case _SC_CLK_TCK:
10904+ return (HZ);
10905+
10906+ case _SC_NGROUPS_MAX:
10907+ /* From limits.h */
10908+ return (NGROUPS_MAX);
10909+
10910+ case _SC_OPEN_MAX:
10911+ /* From limits.h */
10912+ return (OPEN_MAX);
10913+
10914+ case _SC_JOB_CONTROL:
10915+ return (1);
10916+
10917+ case _SC_SAVED_IDS:
10918+ return (1);
10919+
10920+ case _SC_PAGESIZE:
10921+ case _SCO_SC_PAGESIZE:
10922+ return PAGE_SIZE;
10923+
10924+ case _SC_VERSION:
10925+ /* The version of the POSIX standard we conform
10926+ * to. SCO defines _POSIX_VERSION as 198808L
10927+ * sys/unistd.h. What are we?
10928+ */
10929+ return (198808L);
10930+ }
10931+
10932+#if defined(CONFIG_ABI_TRACE)
10933+ abi_trace(ABI_TRACE_API, "unsupported sysconf call %d\n", name);
10934+#endif
10935+ return -EINVAL;
10936+}
10937+
10938+#if defined(CONFIG_ABI_SYSCALL_MODULES)
10939+EXPORT_SYMBOL(ibcs_sysconf);
10940+EXPORT_SYMBOL(svr4_sysconfig);
10941+#endif
10942diff -Nru linux-2.6.7/abi/svr4/sysfs.c linux-2.6.7-abi/abi/svr4/sysfs.c
10943--- linux-2.6.7/abi/svr4/sysfs.c 1970-01-01 01:00:00.000000000 +0100
10944+++ linux-2.6.7-abi/abi/svr4/sysfs.c 2004-07-22 17:44:21.000000000 +0200
10945@@ -0,0 +1,130 @@
10946+/*
10947+ * Copyright (C) 1994 Mike Jagdis (jaggy@purplet.demon.co.uk)
10948+ */
10949+
10950+#ident "%W% %G%"
10951+
10952+#include <linux/module.h>
10953+#include <linux/personality.h>
10954+#include <linux/sched.h>
10955+#include <linux/syscalls.h>
10956+#include <asm/uaccess.h>
10957+
10958+#include <abi/util/trace.h>
10959+
10960+/*
10961+ * The kernel sysfs() code is almost all we need but, apparently,
10962+ * the SCO (at least) sysfs() will also accept a "magic number"
10963+ * as an index argument and will return the name of the relevant
10964+ * file system. Since Linux doesn't have any concept of fs magic
10965+ * numbers outside the file system code themselves there is no
10966+ * clean way to do it in the kernel. There isn't a clean way to
10967+ * to it here either but it needs to be done somehow :-(.
10968+ */
10969+enum {
10970+ GETFSIND = 1,
10971+ GETFSTYP = 2,
10972+ GETNFSTYP = 3
10973+};
10974+
10975+int
10976+svr4_sysfs(int cmd, int arg1, int arg2)
10977+{
10978+ if (cmd == GETFSIND)
10979+ return sys_sysfs(cmd, arg1, arg2);
10980+
10981+ if (cmd == GETNFSTYP)
10982+ return sys_sysfs(cmd, arg1, arg2);
10983+
10984+ if (cmd == GETFSTYP) {
10985+ char *buf = (char *)arg2;
10986+ int error;
10987+
10988+ if (arg1 & 0x80000000)
10989+ arg1 &= 0x0000ffff;
10990+ if (arg1 >= 0 && arg1 < sys_sysfs(GETNFSTYP,0,0))
10991+ return sys_sysfs(cmd, arg1-1, arg2);
10992+
10993+ /*
10994+ * Kludge alert! Hardcoded known magic numbers!
10995+ */
10996+ switch (arg1) {
10997+ case 0xef53: case 0xffffef53:
10998+ case 0xef51: case 0xffffef51:
10999+ /*
11000+ * Some SCO programs (i.e. Informix Dynamic
11001+ * Server are using this to detect "real"
11002+ * filesystems by checking type names :-(.
11003+ * So we lie :-).
11004+ */
11005+ if (is_cur_personality(PER_SCOSVR3))
11006+ error = copy_to_user(buf, "HTFS", 5);
11007+ else
11008+ error = copy_to_user(buf, "ext2", 5);
11009+ break;
11010+ case 0x137d:
11011+ error = copy_to_user(buf, "ext", 4);
11012+ break;
11013+ case 0x9660: case 0xffff9660:
11014+ error = copy_to_user(buf, "iso9660", 8);
11015+ break;
11016+ case 0x4d44:
11017+ error = copy_to_user(buf, "msdos", 6);
11018+ break;
11019+ case 0x6969:
11020+ error = copy_to_user(buf, "nfs", 4);
11021+ break;
11022+ case 0x9fa0: case 0xffff9fa0:
11023+ error = copy_to_user(buf, "proc", 5);
11024+ break;
11025+ case 0xf995e849:
11026+ case 0xe849: case 0xffffe849:
11027+ error = copy_to_user(buf, "hpfs", 5);
11028+ break;
11029+ case 0x137f: /* original */
11030+ case 0x138f: /* original + 30 char names */
11031+ case 0x2468: /* V2 */
11032+ case 0x2478: /* V2 + 30 char names */
11033+ error = copy_to_user(buf, "minix", 6);
11034+ break;
11035+ case 0x564c:
11036+ error = copy_to_user(buf, "ncpfs", 6);
11037+ break;
11038+ case 0x517b:
11039+ error = copy_to_user(buf, "smbfs", 6);
11040+ break;
11041+ case 0x00011954:
11042+ error = copy_to_user(buf, "ufs", 4);
11043+ break;
11044+ case 0x012fd16d: case 0xffffd16d:
11045+ error = copy_to_user(buf, "xiafs", 6);
11046+ break;
11047+ case 0x012ff7b3+1: case 0xfffff7b3+1:
11048+ error = copy_to_user(buf, "xenix", 6);
11049+ break;
11050+ case 0x012ff7b3+2: case 0xfffff7b3+2:
11051+ case 0x012ff7b3+3: case 0xfffff7b3+3:
11052+ error = copy_to_user(buf, "sysv", 5);
11053+ break;
11054+ case 0x012ff7b3+4: case 0xfffff7b3+4:
11055+ error = copy_to_user(buf, "coherent", 9);
11056+ break;
11057+ default:
11058+ error = copy_to_user(buf, "", 1);
11059+ break;
11060+ }
11061+
11062+ if (error)
11063+ return -EFAULT;
11064+ return 0;
11065+ }
11066+
11067+#if defined(CONFIG_ABI_TRACE)
11068+ abi_trace(ABI_TRACE_API, "unsupported sysfs call %d\n", cmd);
11069+#endif
11070+ return -EINVAL;
11071+}
11072+
11073+#if defined(CONFIG_ABI_SYSCALL_MODULES)
11074+EXPORT_SYMBOL(svr4_sysfs);
11075+#endif
11076diff -Nru linux-2.6.7/abi/svr4/sysi86.c linux-2.6.7-abi/abi/svr4/sysi86.c
11077--- linux-2.6.7/abi/svr4/sysi86.c 1970-01-01 01:00:00.000000000 +0100
11078+++ linux-2.6.7-abi/abi/svr4/sysi86.c 2004-07-22 17:44:21.000000000 +0200
11079@@ -0,0 +1,180 @@
11080+/*
11081+ * Copyright 1994,1995 Mike Jagdis <jaggy@purplet.demon.co.uk>
11082+ * Copyright 2002 Caldera Deutschland GmbH
11083+ */
11084+
11085+#ident "%W% %G%"
11086+
11087+#include <linux/sched.h>
11088+#include <linux/kernel.h>
11089+#include <linux/ptrace.h>
11090+#include <linux/syscalls.h>
11091+#include <linux/mm.h>
11092+#include <linux/module.h>
11093+#include <asm/uaccess.h>
11094+
11095+#include <abi/util/trace.h>
11096+
11097+
11098+/*
11099+ * The sysi86() call is used for machine specific functions. Only the
11100+ * most basic are implemented here.
11101+ */
11102+#define SI86SWPI 1 /* General swap functions. */
11103+#define SI86SYM 2 /* Get symbol table */
11104+#define SI86CONF 4 /* Get configuration table */
11105+#define SI86BOOT 5 /* Get timestamp and name of program
11106+ * booted.
11107+ */
11108+#define SI86DMM 7 /* Double-map data segment for
11109+ * read/write/execute support
11110+ */
11111+#define SI86AUTO 9 /* Was an auto-config boot done? */
11112+#define SI86EDT 10 /* Copy contents of EDT to user */
11113+#define SI86SWAP 12 /* Declare swap space */
11114+#define SI86FPHW 40 /* what (if any?) floating-point hardware */
11115+# define FP_NO 0 /* No fp at all */
11116+# define FP_SW 1 /* using emulator */
11117+# define FP_HW 2 /* using hardware */
11118+# define FP_287 2 /* using a 287 */
11119+# define FP_387 3 /* using a 387 */
11120+#define GRNON 52 /* set green light to solid on state */
11121+#define GRNFLASH 53 /* start green light flashing */
11122+#define STIME 54 /* set internal time */
11123+#define SETNAME 56 /* rename the system */
11124+#define RNVR 58 /* read NVRAM */
11125+#define WNVR 59 /* write NVRAM */
11126+#define RTODC 60 /* read time of day clock */
11127+#define CHKSER 61 /* check soft serial number */
11128+#define SI86NVPRT 62 /* print an xtra_nvr structure */
11129+#define SANUPD 63 /* sanity update of kernel buffers */
11130+#define SI86KSTR 64 /* make a copy of a kernel string */
11131+#define SI86MEM 65 /* return the memory size of system */
11132+#define SI86TODEMON 66 /* Transfer control to firmware. */
11133+#define SI86CCDEMON 67 /* Control character access to demon. */
11134+#define SI86CACHE 68 /* Turn cache on and off. */
11135+#define SI86DELMEM 69 /* Delete available memory for testing. */
11136+#define SI86ADDMEM 70 /* Add back deleted memory. */
11137+/* 71 through 74 reserved for VPIX */
11138+#define SI86V86 71 /* V86 system calls (see v86.h) */
11139+#define SI86SLTIME 72 /* Set local time correction */
11140+#define SI86DSCR 75 /* Set a segment or gate descriptor */
11141+#define RDUBLK 76 /* Read U Block */
11142+/* #ifdef MERGE386 */
11143+/* NFA entry point */
11144+#define SI86NFA 77 /* make nfa_sys system call */
11145+#define SI86VM86 81
11146+#define SI86VMENABLE 82
11147+/* #endif MERGE386 */
11148+#define SI86VM86 81
11149+#define SI86VMENABLE 82
11150+#define SI86LIMUSER 91 /* liscense interface */
11151+#define SI86RDID 92 /* ROM BIOS Machid ID */
11152+#define SI86RDBOOT 93 /* Bootable Non-SCSI Hard Disk */
11153+/* Merged Product defines */
11154+#define SI86SHFIL 100 /* map a file into addr space of a proc */
11155+#define SI86PCHRGN 101 /* make globally visible change to a region */
11156+#define SI86BADVISE 102 /* badvise subcommand - see below for */
11157+ /* badvise subfunction definitions */
11158+#define SI86SHRGN 103 /* enable/disable XENIX small model shared */
11159+ /* data context switching */
11160+#define SI86CHIDT 104 /* set user level int 0xf0, ... 0xff handlers */
11161+#define SI86EMULRDA 105 /* remove special emulator read access */
11162+#define SI86GETPIPE 106 /* return the pipe filesystem */
11163+#define SI86SETPIPE 107 /* set the pipe filesystem */
11164+#define SI86SETPIPE_NM 108 /* set the pipe filesystem -non mountable */
11165+#define SI86GETNPIPE 109 /* get # of pipe filesystems */
11166+#define SI86GETPIPE_ALL 110 /* get data on all of pipe filesystems */
11167+#define SI86POPPIPE 111 /* pop pipe file system off stack */
11168+#define SI86APM 112 /* get APM information passed by boot(HW) */
11169+#define SI86TIMECHG 113 /* get time before/after last timechange */
11170+#define SI86GETFEATURES 114 /* get os features vector */
11171+
11172+/* The SI86BADVISE command is used to set Xenix behaviour. */
11173+#define SI86B_SET 0x0100 /* Set badvise bits */
11174+#define SI86B_GET 0x0200 /* Get badvise bits */
11175+#define SI86B_LOCK 0x0001 /* XENIX advisory locking bit */
11176+#define SI86B_PRE_SV 0x0008 /* follow pre-System V x.out behavior */
11177+#define SI86B_XOUT 0x0010 /* follow XENIX x.out behavior */
11178+#define SI86B_XSDSWTCH 0x0080 /* XENIX small model shared data */
11179+ /* context switching enabled */
11180+
11181+/*
11182+ * The SI86DSCR subcommand of the sysi86() system call
11183+ * sets a segment or gate descriptor in the kernel.
11184+ * The following descriptor types are accepted:
11185+ * - executable and data segments in the LDT at DPL 3
11186+ * - a call gate in the GDT at DPL 3 that points to a segment in the LDT
11187+ * The request structure declared below is used to pass the values
11188+ * to be placed in the descriptor. A pointer to the structure is
11189+ * passed as the second argument of the system call.
11190+ * If acc1 is zero, the descriptor is cleared.
11191+ */
11192+struct ssd {
11193+ uint32_t sel; /* descriptor selector */
11194+ uint32_t bo; /* segment base or gate offset */
11195+ uint32_t ls; /* segment limit or gate selector */
11196+ uint32_t acc1; /* access byte 5 */
11197+ uint32_t acc2; /* access bits in byte 6 or gate count */
11198+};
11199+
11200+
11201+int
11202+svr4_sysi86(int cmd, void *arg1, int arg2)
11203+{
11204+ switch (cmd) {
11205+ case SI86FPHW:
11206+ /*
11207+ * If we remove the 'static' from the definition
11208+ * of fpu_error in linux/init/main.c we can tell
11209+ * whether we are using hardware or software at
11210+ * least. For now let's lie...
11211+ * (actually SCO Unix 3.4 gives me -1...)
11212+ */
11213+ return put_user(FP_387, (unsigned long *)arg1);
11214+ case STIME:
11215+ /*
11216+ * Set the system time. The argument is a long,
11217+ * sys_stime() expects a pointer to a long...
11218+ */
11219+ return sys_stime(arg1);
11220+ case SETNAME:
11221+ /*
11222+ * The name is required to be string of no more
11223+ * than 7 characters. We don't get passed the
11224+ * length so we are depending upon the current
11225+ * implementation of sys_sethostname() here.
11226+ */
11227+ return sys_sethostname(arg1, 7);
11228+ case SI86MEM:
11229+ {
11230+ /*
11231+ * Returns the size of physical memory.
11232+ */
11233+ struct sysinfo i;
11234+
11235+ si_meminfo(&i);
11236+ return (i.totalram << PAGE_SHIFT);
11237+ }
11238+ case SI86DSCR:
11239+ {
11240+ struct ssd s;
11241+
11242+ if (copy_from_user(&s, arg1, sizeof(struct ssd)))
11243+ return -EFAULT;
11244+
11245+ printk("SI86DSCR(%x,%x,%x,%x,%x)\n",
11246+ s.sel, s.bo, s.ls, s.acc1, s.acc2);
11247+ return -EINVAL;
11248+ }
11249+ default:
11250+#if defined(CONFIG_ABI_TRACE)
11251+ abi_trace(ABI_TRACE_API, "unsupported sysi86 subcall %d\n", cmd);
11252+#endif
11253+ return -EINVAL;
11254+ }
11255+}
11256+
11257+#if defined(CONFIG_ABI_SYSCALL_MODULES)
11258+EXPORT_SYMBOL(svr4_sysi86);
11259+#endif
11260diff -Nru linux-2.6.7/abi/svr4/sysinfo.c linux-2.6.7-abi/abi/svr4/sysinfo.c
11261--- linux-2.6.7/abi/svr4/sysinfo.c 1970-01-01 01:00:00.000000000 +0100
11262+++ linux-2.6.7-abi/abi/svr4/sysinfo.c 2004-07-22 17:44:21.000000000 +0200
11263@@ -0,0 +1,128 @@
11264+/*
11265+ * Copyright (C) 1995 Eric Youngdale
11266+ */
11267+
11268+#ident "%W% %G%"
11269+
11270+#include <linux/module.h>
11271+#include <linux/version.h>
11272+#include <linux/compile.h>
11273+#include <linux/mm.h>
11274+#include <linux/errno.h>
11275+#include <linux/sched.h>
11276+#include <linux/utsname.h>
11277+#include <asm/uaccess.h>
11278+
11279+#include <abi/util/trace.h>
11280+
11281+
11282+#define __O_SI_SYSNAME 1 /* return name of operating system */
11283+#define __O_SI_HOSTNAME 2 /* return name of node */
11284+#define SI_RELEASE 3 /* return release of operating system */
11285+#define SI_VERSION 4 /* return version field of utsname */
11286+#define __O_SI_MACHINE 5 /* return kind of machine */
11287+#define __O_SI_ARCHITECTURE 6 /* return instruction set arch */
11288+#define SI_HW_SERIAL 7 /* return hardware serial number */
11289+#define __O_SI_HW_PROVIDER 8 /* return hardware manufacturer */
11290+#define SI_SRPC_DOMAIN 9 /* return secure RPC domain */
11291+#define SI_INITTAB_NAME 10 /* return name of inittab file used */
11292+#define SI_ARCHITECTURE 100 /* return instruction set arch */
11293+#define SI_BUSTYPES 101 /* return list of bus types */
11294+#define SI_HOSTNAME 102 /* return fully-qualified node name */
11295+#define SI_HW_PROVIDER 103 /* return hardware manufacturer */
11296+#define SI_KERNEL_STAMP 104 /* return kernel generation timestamp */
11297+#define SI_MACHINE 105 /* return kind of machine */
11298+#define SI_OS_BASE 106 /* return base operating system */
11299+#define SI_OS_PROVIDER 107 /* return operating system provider */
11300+#define SI_SYSNAME 108 /* return name of operating system */
11301+#define SI_USER_LIMIT 109 /* return maximum number of users */
11302+
11303+
11304+
11305+int svr4_sysinfo(int cmd, char * buf, long count)
11306+{
11307+ char * return_string;
11308+ static unsigned int serial_number = 0;
11309+ char buffer[16];
11310+ int error;
11311+ int slen;
11312+
11313+ return_string = NULL;
11314+
11315+ switch(cmd) {
11316+ case __O_SI_SYSNAME:
11317+ case SI_SYSNAME:
11318+ return_string = system_utsname.sysname;
11319+ break;
11320+ case __O_SI_HOSTNAME:
11321+ case SI_HOSTNAME:
11322+ return_string = system_utsname.nodename;
11323+ break;
11324+ case SI_VERSION:
11325+ return_string = "2";
11326+ break;
11327+ case SI_RELEASE:
11328+ return_string = system_utsname.release;
11329+ break;
11330+ case SI_MACHINE:
11331+ case __O_SI_MACHINE:
11332+ return_string = system_utsname.machine;
11333+ break;
11334+ case __O_SI_ARCHITECTURE:
11335+ case SI_ARCHITECTURE:
11336+ return_string = "IA32"; /* XXX: this seems wrong, the name ia32 is very new ... -- ch */
11337+ break;
11338+ case SI_BUSTYPES:
11339+ return_string = "PCI ISA";
11340+ break;
11341+ case __O_SI_HW_PROVIDER:
11342+ case SI_HW_PROVIDER:
11343+ return_string = "Generic AT";
11344+ break;
11345+ case SI_KERNEL_STAMP:
11346+ return_string = UTS_VERSION;
11347+ break;
11348+ case SI_INITTAB_NAME:
11349+ return_string = "/etc/inittab";
11350+ break;
11351+ case SI_HW_SERIAL:
11352+ if(serial_number == 0)
11353+ serial_number = 0xdeadbeef;
11354+ sprintf(buffer,"%8.8x", serial_number);
11355+ return_string = buffer;
11356+ break;
11357+ case SI_OS_BASE:
11358+ return_string = "Linux";
11359+ break;
11360+ case SI_OS_PROVIDER:
11361+ return_string = "LBT"; /* someone's initials ? */
11362+ break;
11363+ case SI_SRPC_DOMAIN:
11364+ return_string = system_utsname.domainname;
11365+ break;
11366+ case SI_USER_LIMIT:
11367+ /* have you seen a Linux box with more than 500000 users? */
11368+ return_string = "500000";
11369+ break;
11370+ default:
11371+#if defined(CONFIG_ABI_TRACE)
11372+ abi_trace(ABI_TRACE_API,
11373+ "unsupported sysinfo call %d\n", cmd);
11374+#endif
11375+ return -EINVAL;
11376+ }
11377+
11378+ if (!return_string)
11379+ return 0;
11380+
11381+ down_read(&uts_sem);
11382+ slen = (count < strlen(return_string) + 1 ? count : strlen(return_string) + 1);
11383+ error = copy_to_user(buf, return_string, slen);
11384+ up_read(&uts_sem);
11385+
11386+ return error ? -EFAULT : slen;
11387+}
11388+
11389+#if defined(CONFIG_ABI_SYSCALL_MODULES)
11390+EXPORT_SYMBOL(svr4_sysinfo);
11391+#endif
11392diff -Nru linux-2.6.7/abi/svr4/tapeio.c linux-2.6.7-abi/abi/svr4/tapeio.c
11393--- linux-2.6.7/abi/svr4/tapeio.c 1970-01-01 01:00:00.000000000 +0100
11394+++ linux-2.6.7-abi/abi/svr4/tapeio.c 2004-07-22 17:44:21.000000000 +0200
11395@@ -0,0 +1,92 @@
11396+#ident "%W% %G%"
11397+
11398+#include <linux/errno.h>
11399+#include <linux/kernel.h>
11400+#include <linux/mtio.h>
11401+#include <linux/syscalls.h>
11402+#include <asm/uaccess.h>
11403+
11404+
11405+int
11406+svr4_tape_ioctl(int fd, u_int cmd, caddr_t data)
11407+{
11408+ mm_segment_t fs;
11409+ int error;
11410+ struct mtop mtop;
11411+
11412+ mtop.mt_count = 1;
11413+
11414+ switch (cmd & 0xff) {
11415+ case 1: /* MT_RETEN */
11416+ mtop.mt_op = MTRETEN;
11417+ break;
11418+ case 2: /* MT_REWIND */
11419+ mtop.mt_op = MTREW;
11420+ break;
11421+ case 3: /* MT_ERASE */
11422+ mtop.mt_op = MTERASE;
11423+ break;
11424+ case 4: /* MT_WFM */
11425+ mtop.mt_op = MTWEOF;
11426+ break;
11427+ case 5: /* MT_RESET */
11428+ mtop.mt_op = MTRESET;
11429+ break;
11430+ case 7: /* T_SFF */
11431+ mtop.mt_op = MTFSF;
11432+ break;
11433+ case 8: /* T_SBF */
11434+ mtop.mt_op = MTBSF;
11435+ break;
11436+ case 9: /* T_LOAD */
11437+ mtop.mt_op = MTLOAD;
11438+ break;
11439+ case 10: /* MT_UNLOAD */
11440+ mtop.mt_op = MTOFFL;
11441+ break;
11442+ case 15: /* T_WRBLKLEN */
11443+ mtop.mt_op = MTLOCK;
11444+ mtop.mt_count = (int)data;
11445+ break;
11446+ case 16: /* T_PREVMV */
11447+ mtop.mt_op = MTLOCK;
11448+ break;
11449+ case 17: /* T_ALLOMV */
11450+ mtop.mt_op = MTUNLOCK;
11451+ break;
11452+ case 20: /* T_EOD */
11453+ mtop.mt_op = MTEOM;
11454+ mtop.mt_count = (int)data;
11455+ break;
11456+ case 21: /* T_SSFB */
11457+ mtop.mt_op = MTBSFM;
11458+ mtop.mt_count = (int)data;
11459+ break;
11460+ case 22: /* T_SSFF */
11461+ mtop.mt_op = MTFSFM;
11462+ mtop.mt_count = (int)data;
11463+ break;
11464+ case 24: /* T_STD */
11465+ mtop.mt_op = MTSETDENSITY;
11466+ mtop.mt_count = (int)data;
11467+ break;
11468+
11469+#if 0
11470+ case 6: /* T_STATUS */
11471+ case 14: /* T_RDBLKLEN */
11472+ case 18: /* T_SBB */
11473+ case 19: /* T_SFB */
11474+ case 23: /* T_STS */
11475+#endif
11476+ default:
11477+ printk (KERN_ERR "iBCS: SYSV tape ioctl func=%d arg=%x unsupported\n",
11478+ cmd & 0xff, (int)data);
11479+ return -EINVAL;
11480+ }
11481+
11482+ fs = get_fs();
11483+ set_fs(get_ds());
11484+ error = sys_ioctl(fd, MTIOCTOP, (long)&mtop);
11485+ set_fs (fs);
11486+ return (error);
11487+}
11488diff -Nru linux-2.6.7/abi/svr4/termios.c linux-2.6.7-abi/abi/svr4/termios.c
11489--- linux-2.6.7/abi/svr4/termios.c 1970-01-01 01:00:00.000000000 +0100
11490+++ linux-2.6.7-abi/abi/svr4/termios.c 2004-07-22 17:44:21.000000000 +0200
11491@@ -0,0 +1,982 @@
11492+#ident "%W% %G%"
11493+
11494+#include <linux/kernel.h>
11495+#include <linux/unistd.h>
11496+#include <linux/termios.h>
11497+#include <linux/syscalls.h>
11498+#include <asm/uaccess.h>
11499+
11500+#include <abi/svr4/ioctl.h>
11501+#include <abi/svr4/termios.h>
11502+
11503+
11504+static int
11505+svr_to_linux_termio(int fd, int op, struct svr_termio *it)
11506+{
11507+ struct termio t;
11508+ mm_segment_t fs;
11509+ char eof;
11510+ u_short lflag;
11511+ int error;
11512+
11513+ error = verify_area(VERIFY_READ, it, sizeof(struct svr_termio));
11514+ if (error)
11515+ return (error);
11516+
11517+ fs = get_fs();
11518+ set_fs(get_ds());
11519+ error = sys_ioctl(fd, TCGETA, (long)&t);
11520+ set_fs(fs);
11521+
11522+ if (error)
11523+ return (error);
11524+
11525+ /* Save things we may need later. */
11526+ eof = t.c_cc[4];
11527+ lflag = t.c_lflag;
11528+
11529+ /* Copy the entire structure then fix up as necessary. */
11530+ copy_from_user(&t, it, sizeof(struct svr_termio));
11531+
11532+ /* If ICANON isn't set then we've been given VMIN in place
11533+ * of VEOF.
11534+ */
11535+ if (!(t.c_lflag & 0000002)) {
11536+ t.c_cc[6] = t.c_cc[4];
11537+ t.c_cc[4] = eof;
11538+ }
11539+
11540+ if (t.c_cflag & 0100000) /* CRTSFL - SCO only? */
11541+ t.c_cflag |= CRTSCTS;
11542+ t.c_cflag &= ~0170000; /* LOBLK|CTSFLOW|RTSFLOW|CRTSFL */
11543+
11544+ set_fs(get_ds());
11545+ error = sys_ioctl(fd, op, (long)&t);
11546+ set_fs(fs);
11547+
11548+ return (error);
11549+}
11550+
11551+static int
11552+linux_to_svr_termio(int fd, struct svr_termio *it)
11553+{
11554+ struct termio t;
11555+ mm_segment_t fs;
11556+ int error;
11557+
11558+ error = verify_area(VERIFY_WRITE, it, sizeof(struct svr_termio));
11559+ if (error)
11560+ return (error);
11561+
11562+ fs = get_fs();
11563+ set_fs(get_ds());
11564+ error = sys_ioctl(fd, TCGETA, (long)&t);
11565+ set_fs(fs);
11566+
11567+ if (error)
11568+ return (error);
11569+
11570+ /* If ICANON isn't set then we substitute VEOF with VMIN. */
11571+ if (!(t.c_lflag & 0000002))
11572+ t.c_cc[4] = t.c_cc[6];
11573+
11574+ /* Copy to the user supplied structure. */
11575+ copy_to_user(it, &t, sizeof(struct svr_termio));
11576+
11577+ return (error);
11578+}
11579+
11580+static int
11581+svr4_to_linux_termios(int fd, int op, struct svr4_termios *it)
11582+{
11583+ struct termios t;
11584+ mm_segment_t fs;
11585+ u_short lflag, r;
11586+ char svr4_cc[SVR4_NCCS];
11587+ int error;
11588+
11589+ error = verify_area(VERIFY_READ, it, sizeof(struct svr4_termios));
11590+ if (error)
11591+ return (error);
11592+
11593+ fs = get_fs();
11594+ set_fs(get_ds());
11595+ error = sys_ioctl(fd, TCGETS, (long)&t);
11596+ set_fs(fs);
11597+
11598+ if (error)
11599+ return (error);
11600+
11601+ __get_user(t.c_iflag, &it->c_iflag);
11602+ t.c_iflag &= ~0100000; /* DOSMODE */
11603+
11604+ __get_user(t.c_oflag, &it->c_oflag);
11605+ __get_user(t.c_cflag, &it->c_cflag);
11606+
11607+ if (t.c_cflag & 0100000) /* CRTSFL - SCO only? */
11608+ t.c_cflag |= CRTSCTS;
11609+
11610+ t.c_cflag &= ~0170000; /* LOBLK|CTSFLOW|RTSFLOW|CRTSFL */
11611+
11612+ lflag = t.c_lflag;
11613+ t.c_lflag &= ~0100777;
11614+ __get_user(r, &it->c_lflag);
11615+ t.c_lflag |= r;
11616+
11617+ if ((t.c_lflag & 0100000))
11618+ sys_ioctl(fd, TIOCEXCL, 0);
11619+ else
11620+ sys_ioctl(fd, TIOCNXCL, 0);
11621+
11622+ t.c_lflag &= ~0100000;
11623+ t.c_lflag |= (t.c_lflag & 0000400) << 7; /* Move IEXTEN */
11624+ t.c_lflag &= ~0000400;
11625+ t.c_lflag |= (t.c_lflag & 0001000) >> 1; /* Move TOSTOP */
11626+ t.c_lflag &= ~0001000;
11627+ t.c_lflag |= (lflag & 0001000); /* Restore ECHOCTL */
11628+
11629+ copy_from_user(svr4_cc, &it->c_cc, SVR4_NCCS);
11630+ t.c_cc[0] = svr4_cc[0];
11631+ t.c_cc[1] = svr4_cc[1];
11632+ t.c_cc[2] = svr4_cc[2];
11633+ t.c_cc[3] = svr4_cc[3];
11634+ t.c_cc[7] = svr4_cc[7];
11635+ t.c_cc[8] = svr4_cc[8];
11636+ t.c_cc[9] = svr4_cc[9];
11637+ t.c_cc[10] = svr4_cc[10];
11638+ t.c_cc[12] = svr4_cc[12];
11639+ t.c_cc[13] = svr4_cc[13];
11640+ t.c_cc[14] = svr4_cc[14];
11641+ t.c_cc[15] = svr4_cc[15];
11642+ t.c_cc[16] = svr4_cc[16];
11643+
11644+ if (t.c_lflag & ICANON) {
11645+ t.c_cc[4] = svr4_cc[4];
11646+ t.c_cc[11] = svr4_cc[5];
11647+ } else {
11648+ t.c_cc[5] = svr4_cc[5];
11649+ t.c_cc[6] = svr4_cc[4];
11650+ t.c_cc[11] = svr4_cc[6];
11651+ }
11652+
11653+ set_fs(get_ds());
11654+ error = sys_ioctl(fd, op, (long)&t);
11655+ set_fs(fs);
11656+
11657+ return (error);
11658+}
11659+
11660+static int
11661+linux_to_svr4_termios(int fd, int op, struct svr4_termios *it)
11662+{
11663+ struct termios t;
11664+ char svr4_cc[SVR4_NCCS];
11665+ mm_segment_t fs;
11666+ int error;
11667+
11668+ error = verify_area(VERIFY_WRITE, it, sizeof(struct svr4_termios));
11669+ if (error)
11670+ return (error);
11671+
11672+ fs = get_fs();
11673+ set_fs(get_ds());
11674+ error = sys_ioctl(fd, op, (long)&t);
11675+ set_fs(fs);
11676+
11677+ if (error)
11678+ return (error);
11679+
11680+ put_user(t.c_iflag & 0017777, &it->c_iflag);
11681+ put_user(t.c_oflag & 0177777, &it->c_oflag);
11682+
11683+ if (t.c_cflag & CRTSCTS)
11684+ t.c_cflag |= 0100000; /* CRTSFL - SCO only? */
11685+ put_user(t.c_cflag & 0177777, &it->c_cflag);
11686+
11687+ t.c_lflag &= ~0001000;
11688+ t.c_lflag |= (t.c_lflag & 0000400) << 1;
11689+ t.c_lflag &= ~0000400;
11690+ t.c_lflag |= (t.c_lflag & 0100000) >> 7;
11691+ t.c_lflag &= ~0100000;
11692+ put_user(t.c_lflag & 0001777, &it->c_lflag);
11693+
11694+ svr4_cc[0] = t.c_cc[0];
11695+ svr4_cc[1] = t.c_cc[1];
11696+ svr4_cc[2] = t.c_cc[2];
11697+ svr4_cc[3] = t.c_cc[3];
11698+ svr4_cc[6] = t.c_cc[16];
11699+ svr4_cc[7] = t.c_cc[7];
11700+ svr4_cc[8] = t.c_cc[8];
11701+ svr4_cc[9] = t.c_cc[9];
11702+ svr4_cc[10] = t.c_cc[10];
11703+ svr4_cc[11] = t.c_cc[10];
11704+ svr4_cc[12] = t.c_cc[12];
11705+ svr4_cc[13] = t.c_cc[13];
11706+ svr4_cc[14] = t.c_cc[14];
11707+ svr4_cc[15] = t.c_cc[15];
11708+
11709+ if (t.c_lflag & ICANON) {
11710+ svr4_cc[4] = t.c_cc[4];
11711+ svr4_cc[5] = t.c_cc[11];
11712+ } else {
11713+ svr4_cc[4] = t.c_cc[6];
11714+ svr4_cc[5] = t.c_cc[5];
11715+ }
11716+
11717+ copy_to_user(&it->c_cc, svr4_cc, SVR4_NCCS);
11718+
11719+ return (error);
11720+}
11721+
11722+int
11723+svr4_term_ioctl(int fd, u_int cmd, caddr_t data)
11724+{
11725+ switch (cmd) {
11726+ case 1: /* TCGETA (TIOC|1) */
11727+ return linux_to_svr_termio(fd,
11728+ (struct svr_termio *)data);
11729+ case 2: /* TCSETA (TIOC|2) */
11730+ return svr_to_linux_termio(fd, TCSETA,
11731+ (struct svr_termio *)data);
11732+ case 3: /* TCSETAW (TIOC|3) */
11733+ return svr_to_linux_termio(fd, TCSETAW,
11734+ (struct svr_termio *)data);
11735+ case 4: /* TCSETAF (TIOC|4) */
11736+ return svr_to_linux_termio(fd, TCSETAF,
11737+ (struct svr_termio *)data);
11738+ case 5: /* TCSBRK (TIOC|5) */
11739+ return sys_ioctl(fd, TCSBRK, (long)data);
11740+ case 6: /* TCXONC (TIOC|6) */
11741+ return sys_ioctl(fd, TCXONC, (long)data);
11742+ case 7: /* TCFLSH (TIOC|7) */
11743+ return sys_ioctl(fd, TCFLSH, (long)data);
11744+ /* This group appear in SVR4 but not SVR3 (SCO). */
11745+ case 8: /* TIOCKBON */
11746+ case 9: /* TIOCKBOF */
11747+ case 10: /* KBENABLED */
11748+ return -EINVAL;
11749+
11750+ /* This set is used by SVR4 for termios ioctls. */
11751+ case 13: /* TCGETS */
11752+ return linux_to_svr4_termios(fd, TCGETS,
11753+ (struct svr4_termios *)data);
11754+ case 14: /* TCSETS */
11755+ return svr4_to_linux_termios(fd, TCSETS,
11756+ (struct svr4_termios *)data);
11757+ case 15: /* TCSETSW */
11758+ return svr4_to_linux_termios(fd, TCSETSW,
11759+ (struct svr4_termios *)data);
11760+ case 16: /* TCSETSF */
11761+ return svr4_to_linux_termios(fd, TCSETSF,
11762+ (struct svr4_termios *)data);
11763+
11764+ /* These two are specific to ISC. */
11765+ case 20: /* TCSETPGRP (TIOC|20) set pgrp of tty */
11766+ return sys_ioctl(fd, TIOCSPGRP, (long)data);
11767+ case 21: /* TCGETPGRP (TIOC|21) get pgrp of tty */
11768+ return sys_ioctl(fd, TIOCGPGRP, (long)data);
11769+
11770+ case 34: /* TCGETSC (TIOC|34) ioctl for scancodes */
11771+ return 0x04; /* Translates scancode to ascii */
11772+ case 35: /* TCSETSC (TIOC|35) ioctl for scancodes */
11773+ return 0;
11774+
11775+ case 103: /* TIOCSWINSZ (TIOC|103) */
11776+ return sys_ioctl(fd, TIOCSWINSZ, (long)data);
11777+ case 104: /* TIOCGWINSZ (TIOC|104) */
11778+ return sys_ioctl(fd, TIOCGWINSZ, (long)data);
11779+
11780+ case 118: /* TIOCSPGRP (TIOC|118) set pgrp of tty */
11781+ return sys_ioctl(fd, TIOCSPGRP, (long)data);
11782+ case 119: /* TIOCGPGRP (TIOC|119) get pgrp of tty */
11783+ return sys_ioctl(fd, TIOCGPGRP, (long)data);
11784+
11785+ case 32: /* TCDSET (TIOC|32) */
11786+ case 33: /* RTS_TOG (TIOC|33) 386 - "RTS" toggle define 8A1 protocol */
11787+
11788+ case 120: /* TIOSETSAK (TIOC|120) set SAK sequence for tty */
11789+ case 121: /* TIOGETSAK (TIOC|121) get SAK sequence for tty */
11790+ printk(KERN_ERR "iBCS: termio ioctl %d unimplemented\n", cmd);
11791+ return -EINVAL;
11792+ }
11793+
11794+ printk(KERN_ERR "iBCS: termio ioctl %d unsupported\n", cmd);
11795+ return -EINVAL;
11796+}
11797+
11798+struct termiox {
11799+ unsigned short x_hflag;
11800+ unsigned short x_cflag;
11801+ unsigned short x_rflag[5];
11802+ unsigned short x_sflag;
11803+};
11804+
11805+#define RTSXOFF 0x0001
11806+#define CTSXON 0x0002
11807+
11808+int
11809+svr4_termiox_ioctl(int fd, u_int cmd, caddr_t data)
11810+{
11811+ struct termios t;
11812+ struct termiox tx;
11813+ mm_segment_t fs;
11814+ int error;
11815+
11816+ if (cmd < 1 || cmd > 4)
11817+ return -EINVAL;
11818+
11819+ error = verify_area(cmd == 1 ? VERIFY_WRITE : VERIFY_READ,
11820+ data, sizeof(struct termiox));
11821+ if (error)
11822+ return (error);
11823+
11824+ fs = get_fs();
11825+ set_fs(get_ds());
11826+ error = sys_ioctl(fd, TCGETS, (long)&t);
11827+ set_fs(fs);
11828+
11829+ if (error)
11830+ return (error);
11831+
11832+ if (cmd == 1) { /* TCGETX */
11833+ memset(&tx, '\0', sizeof(struct termiox));
11834+ if (t.c_cflag & CRTSCTS)
11835+ tx.x_hflag = RTSXOFF|CTSXON;
11836+ copy_to_user(data, &tx, sizeof(struct termiox));
11837+ return 0;
11838+ }
11839+
11840+ copy_from_user(&tx, data, sizeof(struct termiox));
11841+ if ((tx.x_hflag != 0 && tx.x_hflag != (RTSXOFF|CTSXON))
11842+ || tx.x_cflag || tx.x_rflag[0] || tx.x_rflag[1]
11843+ || tx.x_rflag[2] || tx.x_rflag[3] || tx.x_rflag[4]
11844+ || tx.x_sflag)
11845+ return -EINVAL;
11846+
11847+ if (tx.x_hflag)
11848+ t.c_cflag |= CRTSCTS;
11849+ else
11850+ t.c_cflag &= (~CRTSCTS);
11851+
11852+ fs = get_fs();
11853+ set_fs(get_ds());
11854+ switch (cmd) {
11855+ case 2: /* TCSETX */
11856+ error = sys_ioctl(fd, TCSETS, (long)&t);
11857+ break;
11858+ case 3: /* TCSETXW */
11859+ error = sys_ioctl(fd, TCSETSW, (long)&t);
11860+ break;
11861+ case 4: /* TCSETXF */
11862+ error = sys_ioctl(fd, TCSETSF, (long)&t);
11863+ break;
11864+ }
11865+ set_fs(fs);
11866+ return (error);
11867+}
11868+
11869+#define BSD_NCCS 20
11870+struct bsd_termios {
11871+ unsigned long c_iflag;
11872+ unsigned long c_oflag;
11873+ unsigned long c_cflag;
11874+ unsigned long c_lflag;
11875+ unsigned char c_cc[BSD_NCCS];
11876+ long c_ispeed;
11877+ long c_ospeed;
11878+};
11879+static unsigned long speed_map[] = {
11880+ 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400,
11881+ 4800, 9600, 19200, 38400
11882+};
11883+
11884+static unsigned long
11885+bsd_to_linux_speed(unsigned long s)
11886+{
11887+ unsigned int i;
11888+
11889+#ifdef B57600
11890+ if (s == 57600)
11891+ return B57600;
11892+#endif
11893+#ifdef B115200
11894+ if (s == 115200)
11895+ return B115200;
11896+#endif
11897+
11898+ for (i=0; i<sizeof(speed_map)/sizeof(speed_map[0]); i++)
11899+ if (s <= speed_map[i])
11900+ return i;
11901+ return B38400;
11902+}
11903+
11904+static unsigned long
11905+linux_to_bsd_speed(unsigned long s)
11906+{
11907+#ifdef B57600
11908+ if (s == B57600)
11909+ return 57600;
11910+#endif
11911+#ifdef B115200
11912+ if (s == B115200)
11913+ return 115200;
11914+#endif
11915+ return speed_map[s];
11916+}
11917+
11918+
11919+
11920+
11921+static int
11922+bsd_to_linux_termios(int fd, int op, struct bsd_termios *it)
11923+{
11924+ struct termios t;
11925+ mm_segment_t old_fs;
11926+ unsigned long temp;
11927+ char bsd_cc[BSD_NCCS];
11928+ int error;
11929+
11930+ error = verify_area(VERIFY_READ, it, sizeof(struct bsd_termios));
11931+ if (error)
11932+ return error;
11933+
11934+ old_fs = get_fs();
11935+ set_fs(get_ds());
11936+ error = sys_ioctl(fd, TCGETS, (long)&t);
11937+ set_fs(old_fs);
11938+ if (error)
11939+ return error;
11940+
11941+ __get_user(t.c_iflag, &it->c_iflag);
11942+ t.c_iflag = (t.c_iflag & ~0xc00)
11943+ | ((t.c_iflag & 0x400) << 1)
11944+ | ((t.c_iflag & 0x800) >> 1);
11945+
11946+ get_user(temp, &it->c_oflag);
11947+ t.c_oflag = (t.c_oflag & ~0x1805)
11948+ | (temp & 9)
11949+ | ((temp & 2) << 1)
11950+ | ((temp & 4) << 10)
11951+ | ((temp & 4) << 9);
11952+
11953+ get_user(temp, &it->c_cflag);
11954+ t.c_cflag = (t.c_cflag & ~0xfff)
11955+ | ((temp & 0xff00) >> 4);
11956+ if (t.c_cflag & 0x30000)
11957+ t.c_cflag |= 020000000000;
11958+ t.c_cflag |= bsd_to_linux_speed(({long s; get_user(s, &it->c_ospeed); s;}))
11959+ | (bsd_to_linux_speed(({long s; get_user(s, &it->c_ispeed); s;})) << 16);
11960+
11961+ get_user(temp, &it->c_lflag);
11962+ t.c_lflag = (t.c_lflag & ~0157663)
11963+ | ((temp & 1) << 12)
11964+ | ((temp & 0x46) << 3)
11965+ | ((temp & 0x420) << 5)
11966+ | ((temp & 0x180) >> 7)
11967+ | ((temp & 0x400000) >> 14)
11968+ | ((temp & 0x2800000) >> 11)
11969+ | ((temp & 0x80000000) >> 24);
11970+
11971+ copy_from_user(bsd_cc, &it->c_cc, BSD_NCCS);
11972+ t.c_cc[VEOF] = bsd_cc[0];
11973+ t.c_cc[VEOL] = bsd_cc[1];
11974+ t.c_cc[VEOL2] = bsd_cc[2];
11975+ t.c_cc[VERASE] = bsd_cc[3];
11976+ t.c_cc[VWERASE] = bsd_cc[4];
11977+ t.c_cc[VKILL] = bsd_cc[5];
11978+ t.c_cc[VREPRINT] = bsd_cc[6];
11979+ t.c_cc[VSWTC] = bsd_cc[7];
11980+ t.c_cc[VINTR] = bsd_cc[8];
11981+ t.c_cc[VQUIT] = bsd_cc[9];
11982+ t.c_cc[VSUSP] = bsd_cc[10];
11983+/* t.c_cc[VDSUSP] = bsd_cc[11];*/
11984+ t.c_cc[VSTART] = bsd_cc[12];
11985+ t.c_cc[VSTOP] = bsd_cc[13];
11986+ t.c_cc[VLNEXT] = bsd_cc[14];
11987+ t.c_cc[VDISCARD] = bsd_cc[15];
11988+ t.c_cc[VMIN] = bsd_cc[16];
11989+ t.c_cc[VTIME] = bsd_cc[17];
11990+/* t.c_cc[VSTATUS] = bsd_cc[18];*/
11991+
11992+ set_fs(get_ds());
11993+ error = sys_ioctl(fd, op, (long)&t);
11994+ set_fs(old_fs);
11995+
11996+ return error;
11997+}
11998+
11999+
12000+static int
12001+linux_to_bsd_termios(int fd, int op, struct bsd_termios *it)
12002+{
12003+ struct termios t;
12004+ char bsd_cc[BSD_NCCS];
12005+ mm_segment_t old_fs;
12006+ int error;
12007+
12008+ error = verify_area(VERIFY_WRITE, it, sizeof(struct bsd_termios));
12009+ if (error)
12010+ return error;
12011+
12012+ old_fs = get_fs();
12013+ set_fs(get_ds());
12014+ error = sys_ioctl(fd, op, (long)&t);
12015+ set_fs(old_fs);
12016+ if (error)
12017+ return error;
12018+
12019+ put_user((t.c_iflag & 0777)
12020+ | ((t.c_iflag & 02000) >> 1)
12021+ | ((t.c_iflag & 010000) >> 2)
12022+ | ((t.c_iflag & 020000) >> 4),
12023+ &it->c_iflag);
12024+
12025+ put_user((t.c_oflag & 1)
12026+ | ((t.c_oflag & 04) >> 1)
12027+ | ((t.c_oflag & 014000) == 014000 ? 4 : 0),
12028+ &it->c_oflag);
12029+
12030+ put_user((t.c_cflag & ~020000007777)
12031+ | ((t.c_cflag & 0xff0) << 4)
12032+ | ((t.c_cflag & 020000000000) ? 0x30000 : 0),
12033+ &it->c_cflag);
12034+
12035+ put_user(linux_to_bsd_speed(t.c_cflag & CBAUD), &it->c_ospeed);
12036+ if ((t.c_cflag & CIBAUD) != 0)
12037+ put_user(linux_to_bsd_speed((t.c_cflag & CIBAUD) >> 16),
12038+ &it->c_ispeed);
12039+ else
12040+ put_user(linux_to_bsd_speed(t.c_cflag & CBAUD),
12041+ &it->c_ispeed);
12042+
12043+ put_user((t.c_lflag & 07777626010)
12044+ | ((t.c_lflag & 03) << 7)
12045+ | ((t.c_lflag & 01160) >> 3)
12046+ | ((t.c_lflag & 0400) << 14)
12047+ | ((t.c_lflag & 02000) >> 4)
12048+ | ((t.c_lflag & 04000) >> 11)
12049+ | ((t.c_lflag & 010000) << 11)
12050+ | ((t.c_lflag & 040000) << 15)
12051+ | ((t.c_lflag & 0100000) >> 5),
12052+ &it->c_lflag);
12053+
12054+ bsd_cc[0] = t.c_cc[VEOF];
12055+ bsd_cc[1] = t.c_cc[VEOL];
12056+ bsd_cc[2] = t.c_cc[VEOL2];
12057+ bsd_cc[3] = t.c_cc[VERASE];
12058+ bsd_cc[4] = t.c_cc[VWERASE];
12059+ bsd_cc[5] = t.c_cc[VKILL];
12060+ bsd_cc[6] = t.c_cc[VREPRINT];
12061+ bsd_cc[7] = t.c_cc[VSWTC];
12062+ bsd_cc[8] = t.c_cc[VINTR];
12063+ bsd_cc[9] = t.c_cc[VQUIT];
12064+ bsd_cc[10] = t.c_cc[VSUSP];
12065+ bsd_cc[11] = t.c_cc[VSUSP];
12066+ bsd_cc[12] = t.c_cc[VSTART];
12067+ bsd_cc[13] = t.c_cc[VSTOP];
12068+ bsd_cc[14] = t.c_cc[VLNEXT];
12069+ bsd_cc[15] = t.c_cc[VDISCARD];
12070+ bsd_cc[16] = t.c_cc[VMIN];
12071+ bsd_cc[17] = t.c_cc[VTIME];
12072+ bsd_cc[18] = 0; /* t.c_cc[VSTATUS]; */
12073+ bsd_cc[19] = 0;
12074+
12075+ copy_to_user(&it->c_cc, bsd_cc, BSD_NCCS);
12076+
12077+ return error;
12078+}
12079+
12080+
12081+
12082+
12083+struct v7_sgttyb {
12084+ unsigned char sg_ispeed;
12085+ unsigned char sg_ospeed;
12086+ unsigned char sg_erase;
12087+ unsigned char sg_kill;
12088+ int sg_flags;
12089+};
12090+
12091+struct v7_tchars {
12092+ char t_intrc;
12093+ char t_quitc;
12094+ char t_startc;
12095+ char t_stopc;
12096+ char t_eofc;
12097+ char t_brkc;
12098+};
12099+
12100+struct v7_ltchars {
12101+ char t_suspc;
12102+ char t_dsuspc;
12103+ char t_rprntc;
12104+ char t_flushc;
12105+ char t_werasc;
12106+ char t_lnextc;
12107+};
12108+
12109+
12110+int bsd_ioctl_termios(int fd, unsigned int func, void *data)
12111+{
12112+ switch (func & 0xff) {
12113+ case 0: { /* TIOCGETD */
12114+ unsigned long ldisc;
12115+ mm_segment_t old_fs;
12116+ int error;
12117+
12118+ error = verify_area(VERIFY_WRITE, data,
12119+ sizeof(unsigned short));
12120+ if (error)
12121+ return error;
12122+
12123+ old_fs = get_fs();
12124+ set_fs(get_ds());
12125+ error = sys_ioctl(fd, TIOCGETD, (long)&ldisc);
12126+ set_fs(old_fs);
12127+ if (!error)
12128+ put_user(ldisc, (unsigned short *)data);
12129+ return error;
12130+ }
12131+ case 1: { /* TIOCSETD */
12132+ unsigned long ldisc;
12133+ mm_segment_t old_fs;
12134+ int error;
12135+
12136+ error = verify_area(VERIFY_READ, data,
12137+ sizeof(unsigned short));
12138+ if (error)
12139+ return error;
12140+
12141+ get_user(ldisc, (unsigned short *)data);
12142+ old_fs = get_fs();
12143+ set_fs(get_ds());
12144+ error = sys_ioctl(fd, TIOCSETD, (long)&ldisc);
12145+ set_fs(old_fs);
12146+ return error;
12147+ }
12148+
12149+ case 2: { /* TIOCHPCL */
12150+ int error;
12151+ mm_segment_t old_fs;
12152+ struct termios t;
12153+
12154+ old_fs = get_fs();
12155+ set_fs(get_ds());
12156+ error = sys_ioctl(fd, TCGETS, (long)&t);
12157+ set_fs(old_fs);
12158+ if (error)
12159+ return error;
12160+
12161+ if (data)
12162+ t.c_cflag |= HUPCL;
12163+ else
12164+ t.c_cflag &= ~HUPCL;
12165+
12166+ old_fs = get_fs();
12167+ set_fs(get_ds());
12168+ error = sys_ioctl(fd, TCSETS, (long)&t);
12169+ set_fs(old_fs);
12170+ return error;
12171+ }
12172+
12173+ case 8: { /* TIOCGETP */
12174+ int error;
12175+ mm_segment_t old_fs;
12176+ struct termios t;
12177+ struct v7_sgttyb sg;
12178+
12179+ error = verify_area(VERIFY_WRITE, data, sizeof(sg));
12180+ if (error)
12181+ return error;
12182+
12183+ old_fs = get_fs();
12184+ set_fs(get_ds());
12185+ error = sys_ioctl(fd, TCGETS, (long)&t);
12186+ set_fs(old_fs);
12187+ if (error)
12188+ return error;
12189+
12190+ sg.sg_ispeed = sg.sg_ospeed = 0;
12191+ sg.sg_erase = t.c_cc[VERASE];
12192+ sg.sg_kill = t.c_cc[VKILL];
12193+ sg.sg_flags =
12194+ /* Old - became TANDEM instead.
12195+ * ((t.c_cflag & HUPCL) >> 10)
12196+ * |
12197+ */
12198+/* O_ODDP */ ((t.c_cflag & PARODD) >> 3)
12199+/* O_EVENP */ | ((t.c_cflag & PARENB) >> 1)
12200+/* LITOUT */ | ((t.c_cflag & OPOST) ? 0 : 0x200000)
12201+/* O_CRMOD */ | ((t.c_oflag & ONLCR) << 2)
12202+/* O_NL1|O_VTDELAY */ | (t.c_oflag & (NL1|VTDLY))
12203+/* O_TBDELAY */ | ((t.c_oflag & TABDLY) ? 02000 : 0)
12204+/* O_CRDELAY */ | ((t.c_oflag & CRDLY) << 3)
12205+/* O_BSDELAY */ | ((t.c_oflag & BSDLY) << 2)
12206+/* O_ECHO|O_LCASE */ | (t.c_lflag & (XCASE|ECHO))
12207+ | ((t.c_lflag & ICANON)
12208+/* O_CBREAK or O_RAW */ ? 0 : ((t.c_lflag & ISIG) ? 0x02 : 0x20))
12209+ /* Incomplete... */
12210+ ;
12211+
12212+ copy_to_user(data, &sg, sizeof(sg));
12213+ return 0;
12214+ }
12215+
12216+ case 9: /* TIOCSETP */
12217+ case 10: { /* TIOCSETN */
12218+ int error;
12219+ mm_segment_t old_fs;
12220+ struct termios t;
12221+ struct v7_sgttyb sg;
12222+
12223+ error = verify_area(VERIFY_READ, data, sizeof(sg));
12224+ if (error)
12225+ return error;
12226+ copy_from_user(&sg, data, sizeof(sg));
12227+
12228+ old_fs = get_fs();
12229+ set_fs(get_ds());
12230+ error = sys_ioctl(fd, TCGETS, (long)&t);
12231+ set_fs(old_fs);
12232+ if (error)
12233+ return error;
12234+
12235+ t.c_cc[VERASE] = sg.sg_erase;
12236+ t.c_cc[VKILL] = sg.sg_kill;
12237+ t.c_iflag = ICRNL | IXON;
12238+ t.c_oflag = 0;
12239+ t.c_lflag = ISIG | ICANON;
12240+ if (sg.sg_flags & 0x02) /* O_CBREAK */
12241+ t.c_lflag &= (~ICANON);
12242+ if (sg.sg_flags & 0x08) /* O_ECHO */
12243+ t.c_lflag |= ECHO|ECHOE|ECHOK|ECHOCTL|ECHOKE|IEXTEN;
12244+ if (sg.sg_flags & 0x10) /* O_CRMOD */
12245+ t.c_oflag |= OPOST|ONLCR;
12246+ if (sg.sg_flags & 0x20) { /* O_RAW */
12247+ t.c_iflag = 0;
12248+ t.c_lflag &= ~(ISIG|ICANON);
12249+ }
12250+ if (sg.sg_flags & 0x200000) /* LITOUT */
12251+ t.c_oflag &= (~OPOST);
12252+ if (!(t.c_lflag & ICANON)) {
12253+ t.c_cc[VMIN] = 1;
12254+ t.c_cc[VTIME] = 0;
12255+ }
12256+
12257+ old_fs = get_fs();
12258+ set_fs(get_ds());
12259+ error = sys_ioctl(fd, TCSETS, (long)&t);
12260+ set_fs(old_fs);
12261+ return error;
12262+ }
12263+
12264+ case 17: { /* TIOCSETC */
12265+ int error;
12266+ mm_segment_t old_fs;
12267+ struct termios t;
12268+ struct v7_tchars tc;
12269+
12270+ error = verify_area(VERIFY_READ, data, sizeof(tc));
12271+ if (error)
12272+ return error;
12273+ copy_from_user(&tc, data, sizeof(tc));
12274+
12275+ old_fs = get_fs();
12276+ set_fs(get_ds());
12277+ error = sys_ioctl(fd, TCGETS, (long)&t);
12278+ set_fs(old_fs);
12279+ if (error)
12280+ return error;
12281+
12282+ t.c_cc[VINTR] = tc.t_intrc;
12283+ t.c_cc[VQUIT] = tc.t_quitc;
12284+ t.c_cc[VSTART] = tc.t_startc;
12285+ t.c_cc[VSTOP] = tc.t_stopc;
12286+ t.c_cc[VEOF] = tc.t_eofc;
12287+ t.c_cc[VEOL2] = tc.t_brkc;
12288+
12289+ old_fs = get_fs();
12290+ set_fs(get_ds());
12291+ error = sys_ioctl(fd, TCSETS, (long)&t);
12292+ set_fs(old_fs);
12293+ return error;
12294+ }
12295+
12296+ case 18: { /* TIOCGETC */
12297+ int error;
12298+ mm_segment_t old_fs;
12299+ struct termios t;
12300+ struct v7_tchars tc;
12301+
12302+ error = verify_area(VERIFY_WRITE, data, sizeof(tc));
12303+ if (error)
12304+ return error;
12305+
12306+ old_fs = get_fs();
12307+ set_fs(get_ds());
12308+ error = sys_ioctl(fd, TCGETS, (long)&t);
12309+ set_fs(old_fs);
12310+ if (error)
12311+ return error;
12312+
12313+ tc.t_intrc = t.c_cc[VINTR];
12314+ tc.t_quitc = t.c_cc[VQUIT];
12315+ tc.t_startc = t.c_cc[VSTART];
12316+ tc.t_stopc = t.c_cc[VSTOP];
12317+ tc.t_eofc = t.c_cc[VEOF];
12318+ tc.t_brkc = t.c_cc[VEOL2];
12319+
12320+ copy_to_user(data, &tc, sizeof(tc));
12321+ return 0;
12322+ }
12323+
12324+ case 116: { /* TIOCGLTC */
12325+ int error;
12326+ mm_segment_t old_fs;
12327+ struct termios t;
12328+ struct v7_ltchars tc;
12329+
12330+ error = verify_area(VERIFY_WRITE, data, sizeof(tc));
12331+ if (error)
12332+ return error;
12333+
12334+ old_fs = get_fs();
12335+ set_fs(get_ds());
12336+ error = sys_ioctl(fd, TCGETS, (long)&t);
12337+ set_fs(old_fs);
12338+ if (error)
12339+ return error;
12340+
12341+ tc.t_suspc = t.c_cc[VSUSP];
12342+ tc.t_dsuspc = t.c_cc[VSUSP];
12343+ tc.t_rprntc = t.c_cc[VREPRINT];
12344+ tc.t_flushc = t.c_cc[VEOL2];
12345+ tc.t_werasc = t.c_cc[VWERASE];
12346+ tc.t_lnextc = t.c_cc[VLNEXT];
12347+
12348+ copy_to_user(data, &tc, sizeof(tc));
12349+ return 0;
12350+ }
12351+
12352+ case 117: { /* TIOCSLTC */
12353+ int error;
12354+ mm_segment_t old_fs;
12355+ struct termios t;
12356+ struct v7_ltchars tc;
12357+
12358+ error = verify_area(VERIFY_READ, data, sizeof(tc));
12359+ if (error)
12360+ return error;
12361+ copy_from_user(&tc, data, sizeof(tc));
12362+
12363+ old_fs = get_fs();
12364+ set_fs(get_ds());
12365+ error = sys_ioctl(fd, TCGETS, (long)&t);
12366+ set_fs(old_fs);
12367+ if (error)
12368+ return error;
12369+
12370+ t.c_cc[VSUSP] = tc.t_suspc;
12371+ t.c_cc[VEOL2] = tc.t_dsuspc;
12372+ t.c_cc[VREPRINT] = tc.t_rprntc;
12373+ t.c_cc[VEOL2] = tc.t_flushc;
12374+ t.c_cc[VWERASE] = tc.t_werasc;
12375+ t.c_cc[VLNEXT] = tc.t_lnextc;
12376+
12377+ old_fs = get_fs();
12378+ set_fs(get_ds());
12379+ error = sys_ioctl(fd, TCSETS, (long)&t);
12380+ set_fs(old_fs);
12381+ return error;
12382+ }
12383+
12384+ case 13: /* TIOEXCL */
12385+ return sys_ioctl(fd, TIOCEXCL, (long)data);
12386+
12387+ case 14: /* TIOCNXCL */
12388+ return sys_ioctl(fd, TIOCNXCL, (long)data);
12389+
12390+ case 16: /* TIOCFLUSH */
12391+ return sys_ioctl(fd, TCFLSH, (long)data);
12392+
12393+
12394+ /* ISC (maybe SVR4 in general?) has some extensions over
12395+ * the sgtty stuff. So do later BSDs. Needless to say they
12396+ * both have different extensions.
12397+ */
12398+ case 20: /* TCSETPGRP (TIOC|20) set pgrp of tty */
12399+ return bsd_to_linux_termios(fd, TCSETS, data);
12400+
12401+ case 21: /* TCGETPGRP (TIOC|21) get pgrp of tty */
12402+ return bsd_to_linux_termios(fd, TCSETSW, data);
12403+
12404+ case 19: /* TIOCGETA */
12405+ return linux_to_bsd_termios(fd, TCGETS, data);
12406+
12407+ case 22: /* TIOCSETAF */
12408+ return bsd_to_linux_termios(fd, TCSETSF, data);
12409+
12410+ case 26: /* TIOCGETD */
12411+ return sys_ioctl(fd, TIOCGETD, (long)data);
12412+
12413+ case 27: /* TIOCSETD */
12414+ return sys_ioctl(fd, TIOCSETD, (long)data);
12415+
12416+ case 97: /* TIOCSCTTY */
12417+ return sys_ioctl(fd, TIOCSCTTY, (long)data);
12418+
12419+ case 103: /* TIOCSWINSZ */
12420+ return sys_ioctl(fd, TIOCSWINSZ, (long)data);
12421+
12422+ case 104: /* TIOCGWINSZ */
12423+ return sys_ioctl(fd, TIOCGWINSZ, (long)data);
12424+
12425+ case 113: /* TIOCNOTTY */
12426+ return sys_ioctl(fd, TIOCNOTTY, (long)data);
12427+
12428+ case 118: /* TIOCSPGRP */
12429+ return sys_ioctl(fd, TIOCSPGRP, (long)data);
12430+
12431+ case 119: /* TIOCGPGRP */
12432+ return sys_ioctl(fd, TIOCGPGRP, (long)data);
12433+
12434+ case 123: /* TIOCSBRK */
12435+ return sys_ioctl(fd, TCSBRK, (long)data);
12436+
12437+ case 124: /* TIOCLGET */
12438+ case 125: /* TIOCLSET */
12439+ return 0;
12440+
12441+
12442+ case 3: /* TIOCMODG */
12443+ case 4: /* TIOCMODS */
12444+ case 94: /* TIOCDRAIN */
12445+ case 95: /* TIOCSIG */
12446+ case 96: /* TIOCEXT */
12447+ case 98: /* TIOCCONS */
12448+ case 102: /* TIOCUCNTL */
12449+ case 105: /* TIOCREMOTE */
12450+ case 106: /* TIOCMGET */
12451+ case 107: /* TIOCMBIC */
12452+ case 108: /* TIOCMBIS */
12453+ case 109: /* TIOCMSET */
12454+ case 110: /* TIOCSTART */
12455+ case 111: /* TIOCSTOP */
12456+ case 112: /* TIOCPKT */
12457+ case 114: /* TIOCSTI */
12458+ case 115: /* TIOCOUTQ */
12459+ case 120: /* TIOCCDTR */
12460+ case 121: /* TIOCSDTR */
12461+ case 122: /* TIOCCBRK */
12462+ break;
12463+ }
12464+
12465+ printk(KERN_ERR "BSD/V7: terminal ioctl 0x%08lx unsupported\n",
12466+ (unsigned long)func);
12467+ return -EINVAL;
12468+}
12469+
12470+#if defined(CONFIG_ABI_SYSCALL_MODULES)
12471+EXPORT_SYMBOL(bsd_ioctl_termios);
12472+EXPORT_SYMBOL(svr4_term_ioctl);
12473+#endif
12474diff -Nru linux-2.6.7/abi/svr4/timod.c linux-2.6.7-abi/abi/svr4/timod.c
12475--- linux-2.6.7/abi/svr4/timod.c 1970-01-01 01:00:00.000000000 +0100
12476+++ linux-2.6.7-abi/abi/svr4/timod.c 2004-07-22 17:44:21.000000000 +0200
12477@@ -0,0 +1,200 @@
12478+/*
12479+ * Copyright 1995, 1996 Mike Jagdis (jaggy@purplet.demon.co.uk)
12480+ */
12481+
12482+#ident "%W% %G%"
12483+
12484+#include <linux/config.h>
12485+#include <linux/types.h>
12486+#include <linux/errno.h>
12487+#include <linux/fs.h>
12488+#include <linux/ptrace.h>
12489+#include <linux/sched.h>
12490+#include <linux/kernel.h>
12491+#include <linux/slab.h>
12492+#include <linux/mm.h>
12493+#include <linux/fcntl.h>
12494+#include <linux/socket.h>
12495+#include <linux/in.h>
12496+#include <linux/un.h>
12497+#include <linux/file.h>
12498+#include <linux/personality.h>
12499+#include <linux/poll.h>
12500+#include <linux/syscalls.h>
12501+#include <asm/uaccess.h>
12502+
12503+#include <net/sock.h>
12504+
12505+#include <asm/abi_machdep.h>
12506+#include <abi/stream.h>
12507+#include <abi/tli.h>
12508+
12509+#include <abi/svr4/ioctl.h>
12510+#include <abi/util/trace.h>
12511+
12512+
12513+/*
12514+ * Check if the inode belongs to /dev/socksys.
12515+ */
12516+#define IS_SOCKSYS(ip) (MAJOR((ip)->i_rdev) == SOCKSYS_MAJOR)
12517+
12518+
12519+int
12520+timod_getmsg(int fd, struct inode *ip, int pmsg, struct pt_regs *regs)
12521+{
12522+ struct strbuf ctl, *ctlp, dat, *datp;
12523+ int flags, *flagsp, *bandp;
12524+ int error;
12525+
12526+ ctlp = (struct strbuf *)get_syscall_parameter(regs, 1);
12527+ datp = (struct strbuf *)get_syscall_parameter(regs, 2);
12528+
12529+ if (pmsg) {
12530+ bandp = (int *)get_syscall_parameter(regs, 3);
12531+ flagsp = (int *)get_syscall_parameter(regs, 4);
12532+ } else
12533+ flagsp = (int *)get_syscall_parameter (regs, 3);
12534+
12535+ if (ctlp) {
12536+ if (copy_from_user(&ctl, ctlp, sizeof(ctl)))
12537+ return -EFAULT;
12538+ if ((error = put_user(-1, &ctlp->len)))
12539+ return error;
12540+ } else
12541+ ctl.maxlen = -1;
12542+
12543+ if (datp) {
12544+ if (copy_from_user(&dat, datp, sizeof(dat)))
12545+ return -EFAULT;
12546+ if ((error = put_user(-1, &datp->len)))
12547+ return error;
12548+ } else
12549+ dat.maxlen = -1;
12550+
12551+ if ((error = get_user(flags, flagsp)))
12552+ return error;
12553+
12554+#ifdef CONFIG_ABI_SPX
12555+ if (IS_SOCKSYS(ip) && MINOR(ip->i_rdev) == 1) {
12556+
12557+#if defined(CONFIG_ABI_TRACE)
12558+ abi_trace(ABI_TRACE_STREAMS,
12559+ "SPX: getmsg offers descriptor %d\n", fd);
12560+#endif
12561+
12562+ if ((error = put_user(fd, ctl.buf)))
12563+ return error;
12564+ if ((error = put_user(4, &ctlp->len)))
12565+ return error;
12566+
12567+ return 0;
12568+ }
12569+#endif /* CONFIG_ABI_SPX */
12570+
12571+#ifdef CONFIG_ABI_XTI
12572+ if (flags == 0 || flags == MSG_HIPRI ||
12573+ flags == MSG_ANY || flags == MSG_BAND) {
12574+ struct file *fp;
12575+
12576+ fp = fget(fd);
12577+ error = do_getmsg(fd, regs, ctl.buf, ctl.maxlen, &ctlp->len,
12578+ dat.buf, dat.maxlen, &datp->len, &flags);
12579+ fput(fp);
12580+
12581+ if (error >= 0)
12582+ error = put_user(flags, flagsp);
12583+ return error;
12584+ }
12585+
12586+#if defined(CONFIG_ABI_TRACE)
12587+ abi_trace(ABI_TRACE_STREAMS,
12588+ "XTI: getmsg flags value bad (%d) for %d\n",
12589+ flags, fd);
12590+#endif /* CONFIG_ABI_TRACE */
12591+#endif /* CONFIG_ABI_XTI */
12592+ return -EINVAL;
12593+}
12594+
12595+
12596+int
12597+timod_putmsg(int fd, struct inode *ip, int pmsg, struct pt_regs *regs)
12598+{
12599+ struct strbuf ctl, *ctlp, dat, *datp;
12600+ int flags, band;
12601+ int error;
12602+
12603+ ctlp = (struct strbuf *)get_syscall_parameter(regs, 1);
12604+ datp = (struct strbuf *)get_syscall_parameter(regs, 2);
12605+ if (pmsg) {
12606+ band = get_syscall_parameter(regs, 3);
12607+ flags = get_syscall_parameter(regs, 4);
12608+ } else
12609+ flags = get_syscall_parameter(regs, 3);
12610+
12611+ if (ctlp) {
12612+ if (copy_from_user(&ctl, ctlp, sizeof(ctl)))
12613+ return -EFAULT;
12614+ if (ctl.len < 0 && flags)
12615+ return -EINVAL;
12616+ } else {
12617+ ctl.len = 0;
12618+ ctl.buf = NULL;
12619+ }
12620+
12621+ if (datp) {
12622+ if (copy_from_user(&dat, datp, sizeof(dat)))
12623+ return -EFAULT;
12624+ } else {
12625+ dat.len = 0;
12626+ dat.buf = NULL;
12627+ }
12628+
12629+#ifdef CONFIG_ABI_SPX
12630+ if (IS_SOCKSYS(ip) && MINOR(ip->i_rdev) == 1) {
12631+ int newfd;
12632+
12633+ if (ctl.len != 4)
12634+ return -EIO;
12635+
12636+ error = get_user(newfd, ctl.buf);
12637+ if (error)
12638+ return error;
12639+
12640+#if defined(CONFIG_ABI_TRACE)
12641+ abi_trace(ABI_TRACE_STREAMS,
12642+ "SPX: putmsg on %d dups descriptor %d\n",
12643+ fd, newfd);
12644+#endif
12645+ error = sys_dup2(newfd, fd);
12646+
12647+ return (error < 0 ? error : 0);
12648+ }
12649+#endif /* CONFIG_ABI_SPX */
12650+
12651+#ifdef CONFIG_ABI_XTI
12652+ return do_putmsg(fd, regs, ctl.buf, ctl.len,
12653+ dat.buf, dat.len, flags);
12654+#endif
12655+ return -EINVAL;
12656+}
12657+
12658+int
12659+stream_fdinsert(struct pt_regs *regs, int fd, struct strfdinsert *arg)
12660+{
12661+ struct strfdinsert sfd;
12662+
12663+ if (copy_from_user(&sfd, arg, sizeof(sfd)))
12664+ return -EFAULT;
12665+
12666+#if defined(CONFIG_ABI_TRACE)
12667+ abi_trace(ABI_TRACE_STREAMS,
12668+ "%u fdinsert: flags=%ld, fildes=%u, offset=%d\n",
12669+ fd, sfd.flags, sfd.fildes, sfd.offset);
12670+#endif
12671+#ifdef CONFIG_ABI_XTI
12672+ return do_putmsg(fd, regs, sfd.ctlbuf.buf, sfd.ctlbuf.len,
12673+ sfd.datbuf.buf, sfd.datbuf.len, sfd.fildes);
12674+#else
12675+ return -EINVAL;
12676+#endif
12677+}
12678diff -Nru linux-2.6.7/abi/svr4/ulimit.c linux-2.6.7-abi/abi/svr4/ulimit.c
12679--- linux-2.6.7/abi/svr4/ulimit.c 1970-01-01 01:00:00.000000000 +0100
12680+++ linux-2.6.7-abi/abi/svr4/ulimit.c 2004-07-22 17:44:21.000000000 +0200
12681@@ -0,0 +1,154 @@
12682+/*
12683+ * Copyright (C) 1993 Joe Portman (baron@hebron.connected.com)
12684+ * First stab at ulimit
12685+ *
12686+ * April 9 1994, corrected file size passed to/from setrlimit/getrlimit
12687+ * -- Graham Adams (gadams@ddrive.demon.co.uk)
12688+ *
12689+ */
12690+
12691+#ident "%W% %G%"
12692+
12693+#include <linux/module.h>
12694+#include <linux/errno.h>
12695+#include <linux/sched.h>
12696+#include <linux/kernel.h>
12697+#include <linux/unistd.h>
12698+#include <linux/fs.h>
12699+#include <linux/resource.h>
12700+#include <linux/syscalls.h>
12701+#include <asm/uaccess.h>
12702+
12703+#include <abi/util/trace.h>
12704+
12705+
12706+/*
12707+ * Arguments to ulimit - it's one of the stupid multipled calls...
12708+ */
12709+#define U_GETFSIZE (1) /* get max file size in blocks */
12710+#define U_SETFSIZE (2) /* set max file size in blocks */
12711+#define U_GETMEMLIM (3) /* get process size limit */
12712+#define U_GETMAXOPEN (4) /* get max open files for this process */
12713+#define U_GTXTOFF (64) /* get text offset */
12714+
12715+/*
12716+ * Define nominal block size parameters.
12717+ */
12718+#define ULIM_BLOCKSIZE_BITS 9 /* block size = 512 */
12719+#define ULIM_MAX_BLOCKSIZE (INT_MAX >> ULIM_BLOCKSIZE_BITS)
12720+
12721+
12722+int
12723+svr4_ulimit (int cmd, int val)
12724+{
12725+ switch (cmd) {
12726+ case U_GETFSIZE:
12727+ return (current->rlim[RLIMIT_FSIZE].rlim_cur) >> ULIM_BLOCKSIZE_BITS;
12728+
12729+ case U_SETFSIZE:
12730+ if ((val > ULIM_MAX_BLOCKSIZE) || (val < 0))
12731+ return -ERANGE;
12732+ val <<= ULIM_BLOCKSIZE_BITS;
12733+ if (val > current->rlim[RLIMIT_FSIZE].rlim_max) {
12734+ if (!capable(CAP_SYS_RESOURCE))
12735+ return -EPERM;
12736+ current->rlim[RLIMIT_FSIZE].rlim_max = val;
12737+ }
12738+ current->rlim[RLIMIT_FSIZE].rlim_cur = val;
12739+ return 0;
12740+
12741+ case U_GETMEMLIM:
12742+ return current->rlim[RLIMIT_DATA].rlim_cur;
12743+
12744+ case U_GETMAXOPEN:
12745+ return current->rlim[RLIMIT_NOFILE].rlim_cur;
12746+
12747+ default:
12748+#if defined(CONFIG_ABI_TRACE)
12749+ abi_trace(ABI_TRACE_API, "unsupported ulimit call %d\n", cmd);
12750+#endif
12751+ return -EINVAL;
12752+ }
12753+}
12754+
12755+/*
12756+ * getrlimit/setrlimit args.
12757+ */
12758+#define U_RLIMIT_CPU 0
12759+#define U_RLIMIT_FSIZE 1
12760+#define U_RLIMIT_DATA 2
12761+#define U_RLIMIT_STACK 3
12762+#define U_RLIMIT_CORE 4
12763+#define U_RLIMIT_NOFILE 5
12764+#define U_RLIMIT_AS 6
12765+
12766+
12767+int
12768+svr4_getrlimit(int cmd, void *val)
12769+{
12770+ switch (cmd) {
12771+ case U_RLIMIT_CPU:
12772+ cmd = RLIMIT_CPU;
12773+ break;
12774+ case U_RLIMIT_FSIZE:
12775+ cmd = RLIMIT_FSIZE;
12776+ break;
12777+ case U_RLIMIT_DATA:
12778+ cmd = RLIMIT_DATA;
12779+ break;
12780+ case U_RLIMIT_STACK:
12781+ cmd = RLIMIT_STACK;
12782+ break;
12783+ case U_RLIMIT_CORE:
12784+ cmd = RLIMIT_CORE;
12785+ break;
12786+ case U_RLIMIT_NOFILE:
12787+ cmd = RLIMIT_NOFILE;
12788+ break;
12789+ case U_RLIMIT_AS:
12790+ cmd = RLIMIT_AS;
12791+ break;
12792+ default:
12793+ return -EINVAL;
12794+ }
12795+
12796+ return sys_getrlimit(cmd, val);
12797+}
12798+
12799+int
12800+svr4_setrlimit(int cmd, void *val)
12801+{
12802+ switch (cmd) {
12803+ case U_RLIMIT_CPU:
12804+ cmd = RLIMIT_CPU;
12805+ break;
12806+ case U_RLIMIT_FSIZE:
12807+ cmd = RLIMIT_FSIZE;
12808+ break;
12809+ case U_RLIMIT_DATA:
12810+ cmd = RLIMIT_DATA;
12811+ break;
12812+ case U_RLIMIT_STACK:
12813+ cmd = RLIMIT_STACK;
12814+ break;
12815+ case U_RLIMIT_CORE:
12816+ cmd = RLIMIT_CORE;
12817+ break;
12818+ case U_RLIMIT_NOFILE:
12819+ cmd = RLIMIT_NOFILE;
12820+ break;
12821+ case U_RLIMIT_AS:
12822+ cmd = RLIMIT_AS;
12823+ break;
12824+ default:
12825+ return -EINVAL;
12826+ }
12827+
12828+ return sys_getrlimit(cmd, val);
12829+}
12830+
12831+#if defined(CONFIG_ABI_SYSCALL_MODULES)
12832+EXPORT_SYMBOL(svr4_getrlimit);
12833+EXPORT_SYMBOL(svr4_setrlimit);
12834+EXPORT_SYMBOL(svr4_ulimit);
12835+#endif
12836diff -Nru linux-2.6.7/abi/svr4/utsname.c linux-2.6.7-abi/abi/svr4/utsname.c
12837--- linux-2.6.7/abi/svr4/utsname.c 1970-01-01 01:00:00.000000000 +0100
12838+++ linux-2.6.7-abi/abi/svr4/utsname.c 2004-07-22 17:44:21.000000000 +0200
12839@@ -0,0 +1,87 @@
12840+/*
12841+ * Copyright (C) 1994 Mike Jagdis (jaggy@purplet.demon.co.uk)
12842+ * Copyright (C) 1994 Eric Youngdale.
12843+ */
12844+
12845+#ident "%W% %G%"
12846+
12847+#include <linux/mm.h>
12848+#include <linux/sched.h>
12849+#include <linux/utsname.h>
12850+#include <linux/module.h>
12851+#include <asm/uaccess.h>
12852+
12853+
12854+struct v7_utsname {
12855+ char sysname[9];
12856+ char nodename[9];
12857+ char release[9];
12858+ char version[9];
12859+ char machine[9];
12860+};
12861+
12862+#define SVR4_NMLN 257
12863+struct svr4_utsname {
12864+ char sysname[SVR4_NMLN];
12865+ char nodename[SVR4_NMLN];
12866+ char release[SVR4_NMLN];
12867+ char version[SVR4_NMLN];
12868+ char machine[SVR4_NMLN];
12869+};
12870+
12871+
12872+#define set_utsfield(to, from, dotchop) \
12873+ { \
12874+ char *p; \
12875+ int i, len = (sizeof(to) > sizeof(from) ? sizeof(from) : sizeof(to)); \
12876+ __copy_to_user(to, from, len); \
12877+ if (dotchop) \
12878+ for (p=from,i=0; *p && *p != '.' && --len; p++,i++); \
12879+ else \
12880+ i = len - 1; \
12881+ __put_user('\0', to+i); \
12882+ }
12883+
12884+
12885+int v7_utsname(unsigned long addr)
12886+{
12887+ int error;
12888+ struct v7_utsname *it = (struct v7_utsname *)addr;
12889+
12890+ down_read(&uts_sem);
12891+ error = verify_area(VERIFY_WRITE, it, sizeof (struct v7_utsname));
12892+ if (!error) {
12893+ set_utsfield(it->sysname, system_utsname.nodename, 1);
12894+ set_utsfield(it->nodename, system_utsname.nodename, 1);
12895+ set_utsfield(it->release, system_utsname.release, 0);
12896+ set_utsfield(it->version, system_utsname.version, 0);
12897+ set_utsfield(it->machine, system_utsname.machine, 0);
12898+ }
12899+ up_read(&uts_sem);
12900+
12901+ return error;
12902+}
12903+
12904+int abi_utsname(unsigned long addr)
12905+{
12906+ int error;
12907+ struct svr4_utsname *it = (struct svr4_utsname *)addr;
12908+
12909+ down_read(&uts_sem);
12910+ error = verify_area(VERIFY_WRITE, it, sizeof (struct svr4_utsname));
12911+ if (!error) {
12912+ set_utsfield(it->sysname, system_utsname.sysname, 0);
12913+ set_utsfield(it->nodename, system_utsname.nodename, 0);
12914+ set_utsfield(it->release, system_utsname.release, 0);
12915+ set_utsfield(it->version, system_utsname.version, 0);
12916+ set_utsfield(it->machine, system_utsname.machine, 0);
12917+ }
12918+ up_read(&uts_sem);
12919+
12920+ return error;
12921+}
12922+
12923+#if defined(CONFIG_ABI_SYSCALL_MODULES)
12924+EXPORT_SYMBOL(abi_utsname);
12925+EXPORT_SYMBOL(v7_utsname);
12926+#endif
12927diff -Nru linux-2.6.7/abi/svr4/xti.c linux-2.6.7-abi/abi/svr4/xti.c
12928--- linux-2.6.7/abi/svr4/xti.c 1970-01-01 01:00:00.000000000 +0100
12929+++ linux-2.6.7-abi/abi/svr4/xti.c 2004-07-22 17:44:21.000000000 +0200
12930@@ -0,0 +1,1572 @@
12931+/*
12932+ * Copyright 1995, 1996 Mike Jagdis (jaggy@purplet.demon.co.uk)
12933+ */
12934+
12935+#ident "%W% %G%"
12936+
12937+#include <linux/config.h>
12938+#include <linux/types.h>
12939+#include <linux/errno.h>
12940+#include <linux/fs.h>
12941+#include <linux/ptrace.h>
12942+#include <linux/sched.h>
12943+#include <linux/kernel.h>
12944+#include <linux/slab.h>
12945+#include <linux/mm.h>
12946+#include <linux/fcntl.h>
12947+#include <linux/socket.h>
12948+#include <linux/in.h>
12949+#include <linux/un.h>
12950+#include <linux/file.h>
12951+#include <linux/personality.h>
12952+#include <linux/poll.h>
12953+#include <linux/syscalls.h>
12954+#include <asm/uaccess.h>
12955+
12956+#include <net/sock.h>
12957+
12958+#include <abi/stream.h>
12959+#include <abi/tli.h>
12960+
12961+#include <abi/socksys.h> /* for socksys_fdinit */
12962+
12963+#include <abi/svr4/sockio.h>
12964+#include <abi/util/trace.h>
12965+#include <abi/util/errno.h>
12966+
12967+
12968+/*
12969+ * This is because TLI and XTI options buffers are incompatible and there
12970+ * is no clear way to detect which format we are dealing with here.
12971+ * Existing systems appear to have TLI options management implemented
12972+ * but return TNOTSUPPORT for XTI requests.
12973+ */
12974+#if defined(CONFIG_ABI_XTI_OPTMGMT) && defined(CONFIG_ABI_TLI_OPTMGMT)
12975+# error "unable to support _both_ TLI and XTI option management"
12976+#endif
12977+
12978+
12979+#if defined(CONFIG_ABI_TRACE)
12980+static char *const xti_tab[] = {
12981+ "T_CONN_REQ", "T_CONN_RES",
12982+ "T_DISCON_REQ", "T_DATA_REQ",
12983+ "T_EXDATA_REQ", "T_INFO_REQ",
12984+ "T_BIND_REQ", "T_UNBIND_REQ",
12985+ "T_UNITDATA_REQ", "T_OPTMGMT_REQ",
12986+ "T_ORDREL_REQ","T_CONN_IND",
12987+ "T_CONN_CON", "T_DISCON_IND",
12988+ "T_DATA_IND", "T_EXDATA_IND",
12989+ "T_INFO_ACK", "T_BIND_ACK",
12990+ "T_ERROR_ACK","T_OK_ACK",
12991+ "T_UNITDATA_IND", "T_UDERROR_IND",
12992+ "T_OPTMGMT_ACK", "T_ORDREL_IND"
12993+};
12994+static char xti_unknown[] = "<unknown>";
12995+
12996+static char *
12997+xti_prim(int n)
12998+{
12999+ if (n < 0 || n >= ARRAY_SIZE(xti_tab))
13000+ return xti_unknown;
13001+ return xti_tab[n];
13002+}
13003+#endif
13004+
13005+
13006+#define timod_mkctl(len) kmalloc(sizeof(struct T_primsg)-sizeof(long)+len, \
13007+ GFP_KERNEL)
13008+
13009+
13010+static void
13011+timod_socket_wakeup(struct file *fp)
13012+{
13013+ struct socket *sock;
13014+
13015+ sock = SOCKET_I(fp->f_dentry->d_inode);
13016+ wake_up_interruptible(&sock->wait);
13017+
13018+ read_lock(&sock->sk->sk_callback_lock);
13019+ if (sock->fasync_list && !test_bit(SOCK_ASYNC_WAITDATA, &sock->flags))
13020+ __kill_fasync(sock->fasync_list, SIGIO, POLL_IN);
13021+ read_unlock(&sock->sk->sk_callback_lock);
13022+}
13023+
13024+
13025+static void
13026+timod_ok(int fd, int prim)
13027+{
13028+ struct file *fp;
13029+ struct T_primsg *it;
13030+ struct T_ok_ack *ok;
13031+
13032+#if defined(CONFIG_ABI_TRACE)
13033+ abi_trace(ABI_TRACE_STREAMS, "TI: %u ok ack prim=%d\n", fd, prim);
13034+#endif
13035+
13036+ fp = fcheck(fd);
13037+ it = timod_mkctl(sizeof(struct T_ok_ack));
13038+ if (!it)
13039+ return;
13040+
13041+ ok = (struct T_ok_ack *)&it->type;
13042+ ok->PRIM_type = T_OK_ACK;
13043+ ok->CORRECT_prim = prim;
13044+
13045+ it->pri = MSG_HIPRI;
13046+ it->length = sizeof(struct T_ok_ack);
13047+ it->next = Priv(fp)->pfirst;
13048+
13049+ Priv(fp)->pfirst = it;
13050+ if (!Priv(fp)->plast)
13051+ Priv(fp)->plast = it;
13052+ timod_socket_wakeup(fp);
13053+}
13054+
13055+static void
13056+timod_error(int fd, int prim, int terr, int uerr)
13057+{
13058+ struct file *fp;
13059+ struct T_primsg *it;
13060+ struct T_error_ack *err;
13061+
13062+#if defined(CONFIG_ABI_TRACE)
13063+ abi_trace(ABI_TRACE_STREAMS, "TI: %u error prim=%d, TLI=%d, UNIX=%d\n",
13064+ fd, prim, terr, uerr);
13065+#endif
13066+
13067+ fp = fcheck(fd);
13068+ it = timod_mkctl(sizeof(struct T_error_ack));
13069+ if (!it)
13070+ return;
13071+
13072+ err = (struct T_error_ack *)&it->type;
13073+ err->PRIM_type = T_ERROR_ACK;
13074+ err->ERROR_prim = prim;
13075+ err->TLI_error = terr;
13076+ err->UNIX_error = iABI_errors(uerr);
13077+
13078+ it->pri = MSG_HIPRI;
13079+ it->length = sizeof(struct T_error_ack);
13080+ it->next = Priv(fp)->pfirst;
13081+
13082+ Priv(fp)->pfirst = it;
13083+ if (!Priv(fp)->plast)
13084+ Priv(fp)->plast = it;
13085+ timod_socket_wakeup(fp);
13086+}
13087+
13088+
13089+#if defined(CONFIG_ABI_XTI_OPTMGMT) || defined(CONFIG_ABI_TLI_OPTMGMT)
13090+/*
13091+ * XXX: this function is a _horrible_ mess.
13092+ */
13093+static int
13094+timod_optmgmt(int fd, struct pt_regs * regs, int flag,
13095+ char * opt_buf, int opt_len, int do_ret)
13096+{
13097+ struct file * fp = fcheck(fd);
13098+ char *ret_buf, *ret_base;
13099+ u_long old_esp, *tsp;
13100+ int is_tli, error, failed;
13101+ int ret_len, ret_space;
13102+
13103+ if (opt_buf && opt_len > 0) {
13104+ error = verify_area(VERIFY_READ, opt_buf, opt_len);
13105+ if (error)
13106+ return error;
13107+ }
13108+
13109+ /*
13110+ * FIXME:
13111+ * We should be able to detect the difference between
13112+ * TLI and XTI requests at run time?
13113+ */
13114+ is_tli = CONFIG_ABI_TLI_OPTMGMT;
13115+
13116+ if (!do_ret && (!opt_buf || opt_len <= 0))
13117+ return 0;
13118+
13119+ /*
13120+ * Grab some space on the user stack to work with. We need 6 longs
13121+ * to build an argument frame for [gs]etsockopt calls. We also
13122+ * need space to build the return buffer. This will be at least
13123+ * as big as the given options buffer but the given options
13124+ * buffer may not include space for option values so we allow two
13125+ * longs for each option multiple of the option header size
13126+ * and hope that big options will not exhaust our space and
13127+ * trash the stack.
13128+ */
13129+ ret_space = 1024 + opt_len
13130+ + 2*sizeof(long)*(opt_len / (is_tli ? sizeof(struct opthdr) : sizeof(struct t_opthdr)));
13131+ ret_buf = ret_base = (char *)(regs->esp - ret_space);
13132+ ret_len = 0;
13133+
13134+ old_esp = regs->esp;
13135+ regs->esp -= ret_space + 6*sizeof(long);
13136+ tsp = (unsigned long *)(regs->esp);
13137+ error = verify_area(VERIFY_WRITE, tsp, 6*sizeof(long));
13138+ if (error) {
13139+ regs->esp = old_esp;
13140+ return error;
13141+ }
13142+
13143+ failed = 0;
13144+
13145+#ifndef CONFIG_ABI_TLI_OPTMGMT
13146+ if (is_tli) {
13147+ printk(KERN_WARNING
13148+ "%d iBCS: TLI optmgmt requested but not supported\n",
13149+ current->pid);
13150+ }
13151+#else
13152+ if (is_tli)
13153+ while (opt_len >= sizeof(struct opthdr)) {
13154+ struct opthdr opt;
13155+
13156+#if defined(CONFIG_ABI_TRACE)
13157+ abi_trace(ABI_TRACE_STREAMS, "TLI optmgmt opt_len=%d, "
13158+ "ret_buf=0x%08lx, ret_len=%d, ret_space=%d\n",
13159+ opt_len, (unsigned long)ret_buf,
13160+ ret_len, ret_space);
13161+#endif
13162+
13163+ copy_from_user(&opt, opt_buf, sizeof(struct opthdr));
13164+
13165+ /* Idiot check... */
13166+ if (opt.len > opt_len) {
13167+ failed = TBADOPT;
13168+ break;
13169+ }
13170+
13171+ if (abi_traced(ABI_TRACE_STREAMS)) {
13172+ unsigned long v;
13173+ get_user(v, (unsigned long *)(opt_buf+sizeof(struct opthdr)));
13174+#if defined(CONFIG_ABI_TRACE)
13175+ __abi_trace("TLI optmgmt fd=%d, level=%ld, "
13176+ "name=%ld, value=%ld\n",
13177+ fd, opt.level, opt.name, v);
13178+#endif
13179+ }
13180+
13181+ /* Check writable space in the return buffer. */
13182+ error = verify_area(VERIFY_WRITE, ret_buf, sizeof(struct opthdr));
13183+ if (error) {
13184+ failed = TSYSERR;
13185+ break;
13186+ }
13187+
13188+ /* Flag values:
13189+ * T_NEGOTIATE means try and set it.
13190+ * T_DEFAULT means get the default value.
13191+ * (return the current for now)
13192+ * T_CHECK means get the current value.
13193+ */
13194+ error = 0;
13195+ if (flag == T_NEGOTIATE) {
13196+ put_user(fd, tsp);
13197+ put_user(opt.level, tsp+1);
13198+ put_user(opt.name, tsp+2);
13199+ put_user((int)(opt_buf+sizeof(struct opthdr)), tsp+3);
13200+ put_user(opt.len, tsp+4);
13201+ error = abi_do_setsockopt(tsp);
13202+
13203+ if (error) {
13204+#if defined(CONFIG_ABI_TRACE)
13205+ abi_trace(ABI_TRACE_STREAMS,
13206+ "setsockopt failed: %d\n", error);
13207+#endif
13208+ failed = TBADOPT;
13209+ break;
13210+ }
13211+ }
13212+ if (!error) {
13213+ int len;
13214+
13215+ put_user(fd, tsp);
13216+ put_user(opt.level, tsp+1);
13217+ put_user(opt.name, tsp+2);
13218+ put_user((int)(ret_buf+sizeof(struct opthdr)), tsp+3);
13219+ put_user((int)(tsp+5), tsp+4);
13220+ put_user(ret_space, tsp+5);
13221+ error = abi_do_getsockopt(tsp);
13222+
13223+ if (error) {
13224+#if defined(CONFIG_ABI_TRACE)
13225+ abi_trace(ABI_TRACE_STREAMS,
13226+ "getsockopt failed: %d\n", error);
13227+#endif
13228+ failed = TBADOPT;
13229+ break;
13230+ }
13231+
13232+ get_user(len, tsp+5);
13233+ copy_to_user(ret_buf, &opt, sizeof(opt));
13234+ put_user(len,
13235+ &((struct opthdr *)opt_buf)->len);
13236+ ret_space -= sizeof(struct opthdr) + len;
13237+ ret_len += sizeof(struct opthdr) + len;
13238+ ret_buf += sizeof(struct opthdr) + len;
13239+ }
13240+
13241+ opt_len -= sizeof(struct opthdr) + opt.len;
13242+ opt_buf += sizeof(struct opthdr) + opt.len;
13243+ }
13244+#endif /* CONFIG_ABI_TLI_OPTMGMT */
13245+#ifndef CONFIG_ABI_XTI_OPTMGMT
13246+ else {
13247+ printk(KERN_WARNING
13248+ "%d iBCS: XTI optmgmt requested but not supported\n",
13249+ current->pid);
13250+ }
13251+#else
13252+ else while (opt_len >= sizeof(struct t_opthdr)) {
13253+ struct t_opthdr opt;
13254+
13255+ copy_from_user(&opt, opt_buf, sizeof(struct t_opthdr));
13256+ if (opt.len > opt_len) {
13257+ failed = 1;
13258+ break;
13259+ }
13260+
13261+ if (abi_traced(ABI_TRACE_STREAMS)) {
13262+ unsigned long v;
13263+ get_user(v, (unsigned long *)(opt_buf+sizeof(struct t_opthdr)));
13264+#if defined(CONFIG_ABI_TRACE)
13265+ __abi_trace("XTI optmgmt fd=%d, level=%ld, "
13266+ "name=%ld, value=%ld\n",
13267+ fd, opt.level, opt.name, v);
13268+#endif
13269+ }
13270+
13271+ /* Check writable space in the return buffer. */
13272+ if (verify_area(VERIFY_WRITE, ret_buf, sizeof(struct t_opthdr))) {
13273+ failed = 1;
13274+ break;
13275+ }
13276+
13277+ /* Flag values:
13278+ * T_NEGOTIATE means try and set it.
13279+ * T_CHECK means see if we could set it.
13280+ * (so we just set it for now)
13281+ * T_DEFAULT means get the default value.
13282+ * (return the current for now)
13283+ * T_CURRENT means get the current value (SCO xti.h has
13284+ * no T_CURRENT???).
13285+ */
13286+ error = 0;
13287+ if (flag == T_NEGOTIATE || flag == T_CHECK) {
13288+ put_user(fd, tsp);
13289+ put_user(opt.level, tsp+1);
13290+ put_user(opt.name, tsp+2);
13291+ put_user((int)(opt_buf+sizeof(struct t_opthdr)), tsp+3);
13292+ put_user(opt.len-sizeof(struct t_opthdr), tsp+4);
13293+ error = abi_do_setsockopt(tsp);
13294+ }
13295+ if (!error) {
13296+ put_user(fd, tsp);
13297+ put_user(opt.level, tsp+1);
13298+ put_user(opt.name, tsp+2);
13299+ put_user((int)(ret_buf+sizeof(struct t_opthdr)), tsp+3);
13300+ put_user((int)(tsp+5), tsp+4);
13301+ put_user(ret_space, tsp+5);
13302+ error = abi_do_getsockopt(tsp);
13303+ if (!error) {
13304+ int len;
13305+ get_user(len, tsp+5);
13306+ /* FIXME: opt.status should be set... */
13307+ copy_to_user(ret_buf, &opt, sizeof(opt));
13308+ put_user(len+sizeof(struct t_opthdr),
13309+ &((struct t_opthdr *)opt_buf)->len);
13310+ ret_space -= sizeof(struct t_opthdr) + len;
13311+ ret_len += sizeof(struct t_opthdr) + len;
13312+ ret_buf += sizeof(struct t_opthdr) + len;
13313+ }
13314+ }
13315+
13316+ failed |= error;
13317+ opt_len -= opt.len;
13318+ opt_buf += opt.len;
13319+ }
13320+#endif /* CONFIG_ABI_XTI_OPTMGMT */
13321+
13322+#if 0
13323+ /* If there is left over data the supplied options buffer was
13324+ * formatted incorrectly. But we might have done some work so
13325+ * we must fall through and return an acknowledgement I think.
13326+ */
13327+ if (opt_len) {
13328+ regs->esp = old_esp;
13329+ return -EINVAL;
13330+ }
13331+#endif
13332+
13333+ if (do_ret) {
13334+ struct T_primsg *it;
13335+
13336+ if (failed) {
13337+ timod_error(fd, T_OPTMGMT_REQ, failed, -error);
13338+ regs->esp = old_esp;
13339+ return 0;
13340+ }
13341+
13342+#if defined(CONFIG_ABI_TRACE)
13343+ abi_trace(ABI_TRACE_STREAMS,
13344+ "optmgmt returns %d bytes, failed=%d\n",
13345+ ret_len, failed);
13346+#endif
13347+
13348+ /* Convert the return buffer in the user stack to a
13349+ * T_OPTMGMT_ACK
13350+ * message and queue it.
13351+ */
13352+ it = timod_mkctl(sizeof(struct T_optmgmt_ack) + ret_len);
13353+ if (it) {
13354+ struct T_optmgmt_ack *ack
13355+ = (struct T_optmgmt_ack *)&it->type;
13356+ ack->PRIM_type = T_OPTMGMT_ACK;
13357+ ack->OPT_length = ret_len;
13358+ ack->OPT_offset = sizeof(struct T_optmgmt_ack);
13359+ ack->MGMT_flags = (failed ? T_FAILURE : flag);
13360+ copy_from_user(((char *)ack)+sizeof(struct T_optmgmt_ack),
13361+ ret_base, ret_len);
13362+ it->pri = MSG_HIPRI;
13363+ it->length = sizeof(struct T_optmgmt_ack) + ret_len;
13364+ it->next = Priv(fp)->pfirst;
13365+ Priv(fp)->pfirst = it;
13366+ if (!Priv(fp)->plast)
13367+ Priv(fp)->plast = it;
13368+ timod_socket_wakeup(fp);
13369+ }
13370+ }
13371+
13372+ regs->esp = old_esp;
13373+ return 0;
13374+}
13375+
13376+#else /* no CONFIG_ABI_XTI_OPTMGMT or CONFIG_ABI_TLI_OPTMGMT */
13377+
13378+static int
13379+timod_optmgmt(int fd, struct pt_regs * regs, int flag,
13380+ char * opt_buf, int opt_len, int do_ret)
13381+{
13382+ return -EINVAL;
13383+}
13384+
13385+#endif /* CONFIG_ABI_XTI_OPTMGMT or CONFIG_ABI_TLI_OPTMGMT */
13386+
13387+#define T_PRIV(fp) Priv(fp)
13388+
13389+int
13390+timod_update_socket(int fd, struct file * fp, struct pt_regs * regs)
13391+{
13392+ struct socket * sock;
13393+ struct T_private * priv;
13394+ struct T_primsg * it;
13395+ struct T_conn_ind * ind;
13396+ u_long old_esp, * tsp, alen;
13397+ u_short oldflags;
13398+ int error = 0;
13399+
13400+ sock = SOCKET_I(fp->f_dentry->d_inode);
13401+ priv = T_PRIV(fp);
13402+
13403+ /*
13404+ * If this a SOCK_STREAM and is in the TS_WRES_CIND state
13405+ * we are supposed to be looking for an incoming connection.
13406+ */
13407+ if (sock->type != SOCK_STREAM || priv->state != TS_WRES_CIND)
13408+ goto out;
13409+
13410+ old_esp = regs->esp;
13411+ regs->esp -= 1024;
13412+ tsp = (unsigned long *)regs->esp;
13413+ error = verify_area(VERIFY_WRITE, tsp,
13414+ 3*sizeof(long)+sizeof(struct sockaddr));
13415+ if (error) {
13416+ regs->esp = old_esp;
13417+ goto out;
13418+ }
13419+
13420+ put_user(fd, tsp);
13421+ put_user((unsigned long)(tsp+4), tsp+1);
13422+ put_user((unsigned long)(tsp+3), tsp+2);
13423+ put_user(sizeof(struct sockaddr), tsp+3);
13424+
13425+ /*
13426+ * We don't want to block in the accept(). Any
13427+ * blocking necessary must be handled earlier.
13428+ */
13429+ oldflags = fp->f_flags;
13430+ fp->f_flags |= O_NONBLOCK;
13431+ error = sys_socketcall(SYS_ACCEPT, tsp);
13432+ fp->f_flags = oldflags;
13433+
13434+ if (error < 0)
13435+ goto out_set;
13436+
13437+ /* The new fd needs to be fixed up
13438+ * with the iBCS file functions and a
13439+ * timod state block.
13440+ */
13441+ inherit_socksys_funcs(error, TS_DATA_XFER);
13442+
13443+ /* Generate a T_CONN_IND and queue it. */
13444+ get_user(alen, tsp+3);
13445+ it = timod_mkctl(sizeof(struct T_conn_ind) + alen);
13446+ if (!it) {
13447+ /* Oops, just drop the connection I guess. */
13448+ sys_close(error);
13449+ goto out_set;
13450+ }
13451+
13452+ ind = (struct T_conn_ind *)&it->type;
13453+ ind->PRIM_type = T_CONN_IND;
13454+ ind->SRC_length = alen;
13455+ ind->SRC_offset = sizeof(struct T_conn_ind);
13456+ ind->OPT_length = ind->OPT_offset = 0;
13457+ ind->SEQ_number = error;
13458+
13459+ copy_from_user(((char *)ind)+sizeof(struct T_conn_ind), tsp+4, alen);
13460+#if 0
13461+ it->pri = MSG_HIPRI;
13462+#endif
13463+ it->length = sizeof(struct T_conn_ind) + alen;
13464+ it->next = Priv(fp)->pfirst;
13465+ Priv(fp)->pfirst = it;
13466+ if (!Priv(fp)->plast)
13467+ Priv(fp)->plast = it;
13468+ timod_socket_wakeup(fp);
13469+
13470+out_set:
13471+ regs->esp = old_esp;
13472+out:
13473+ return (error);
13474+}
13475+
13476+
13477+int
13478+do_getmsg(int fd, struct pt_regs *regs, char *ctl_buf,
13479+ int ctl_maxlen, int *ctl_len, char *dat_buf,
13480+ int dat_maxlen, int *dat_len, int *flags_p)
13481+{
13482+ int error;
13483+ long old_esp;
13484+ unsigned long *tsp;
13485+ unsigned short oldflags;
13486+ struct T_unitdata_ind udi;
13487+ struct file *filep;
13488+
13489+ /*
13490+ * It may not be obvious but we are always holding an fget(fd)
13491+ * at this point so we can use fcheck(fd) rather than fget...fput.
13492+ */
13493+ filep = fcheck(fd);
13494+
13495+ if (!Priv(filep) && Priv(filep)->magic != XTI_MAGIC) {
13496+ printk("putmsg on non-STREAMS fd %d by %s\n",fd, current->comm);
13497+ return -EINVAL;
13498+ }
13499+
13500+#if defined(CONFIG_ABI_TRACE)
13501+ abi_trace(ABI_TRACE_STREAMS,
13502+ "getmsg %d, 0x%lx[%d], 0x%lx[%d], %x\n",
13503+ fd, (u_long)ctl_buf, ctl_maxlen,
13504+ (u_long)dat_buf, dat_maxlen, *flags_p);
13505+#endif
13506+
13507+ /*
13508+ * We need some user space to build syscall argument vectors
13509+ * later. Set it up now and page it in if necessary. This will
13510+ * avoid (most?) potential blocking after the select().
13511+ */
13512+ old_esp = regs->esp;
13513+ regs->esp -= 1024;
13514+ tsp = (unsigned long *)regs->esp;
13515+ error = verify_area(VERIFY_WRITE, tsp, 6*sizeof(long));
13516+ regs->esp = old_esp;
13517+ if (error)
13518+ return error;
13519+
13520+ /*
13521+ * If the TEP is not non-blocking we must test for
13522+ * something to do. We don't necessarily know what order
13523+ * events will be happening on the socket so we have to
13524+ * watch for evrything at once.
13525+ * N.B. If we weren't asked for data we should only be looking
13526+ * for connection requests. There are socket type issues to
13527+ * consider here.
13528+ */
13529+ if (!(filep->f_flags & O_NONBLOCK)) {
13530+ struct poll_wqueues wait_queue;
13531+ poll_table *wait;
13532+ unsigned long mask = (POLLIN | POLLRDNORM | POLLHUP | POLLERR);
13533+
13534+ if (*flags_p == MSG_HIPRI)
13535+ mask |= POLLPRI;
13536+
13537+ poll_initwait(&wait_queue);
13538+ wait = &wait_queue.pt;
13539+
13540+ /*
13541+ * N.B. We need to be sure to recheck after a schedule()
13542+ * so that when we proceed it is because there is
13543+ * something to do and nothing else can get there
13544+ * before us.
13545+ */
13546+ while (!(filep->f_op->poll(filep, wait) & mask)
13547+ && !signal_pending(current)) {
13548+ current->state = TASK_INTERRUPTIBLE;
13549+ wait = NULL;
13550+ schedule();
13551+ }
13552+
13553+ current->state = TASK_RUNNING;
13554+ poll_freewait(&wait_queue);
13555+
13556+ if (signal_pending(current))
13557+ return -EINTR;
13558+ }
13559+
13560+ if (ctl_maxlen >= 0 && !Priv(filep)->pfirst)
13561+ timod_update_socket(fd, filep, regs);
13562+
13563+ /*
13564+ * If we were asked for a control part and there is an outstanding
13565+ * message queued as a result of some other operation we'll
13566+ * return that.
13567+ */
13568+ if (ctl_maxlen >= 0 && Priv(filep)->pfirst) {
13569+ int l = ctl_maxlen <= Priv(filep)->pfirst->length
13570+ ? ctl_maxlen : Priv(filep)->pfirst->length;
13571+ error = verify_area(VERIFY_WRITE, ctl_buf, l);
13572+ if (error)
13573+ return error;
13574+
13575+#if defined(CONFIG_ABI_TRACE)
13576+ abi_trace(ABI_TRACE_STREAMS,
13577+ "priority message %ld %s\n",
13578+ Priv(filep)->pfirst->type,
13579+ xti_prim(Priv(filep)->pfirst->type));
13580+#endif
13581+
13582+ copy_to_user(ctl_buf, ((char *)&Priv(filep)->pfirst->type)
13583+ + Priv(filep)->offset, l);
13584+ put_user(l, ctl_len);
13585+ if (dat_maxlen >= 0)
13586+ put_user(0, dat_len);
13587+ *flags_p = Priv(filep)->pfirst->pri;
13588+ Priv(filep)->pfirst->length -= l;
13589+
13590+#if defined(CONFIG_ABI_TRACE)
13591+ if (abi_traced(ABI_TRACE_STREAMS) && ctl_buf && l > 0) {
13592+ int i = -1;
13593+
13594+ for (i = 0; i < l && i < 64; i += 4) {
13595+ u_long v;
13596+
13597+ get_user(v, (u_long *)(ctl_buf + i));
13598+ __abi_trace("ctl: 0x%08lx\n", v);
13599+ }
13600+ if (i != l)
13601+ __abi_trace("ctl: ...\n");
13602+ }
13603+#endif
13604+
13605+ if (Priv(filep)->pfirst->length) {
13606+ Priv(filep)->offset += l;
13607+
13608+#if defined(CONFIG_ABI_TRACE)
13609+ abi_trace(ABI_TRACE_STREAMS,
13610+ "MORECTL %d bytes",
13611+ Priv(filep)->pfirst->length);
13612+#endif
13613+ return MORECTL;
13614+ } else {
13615+ struct T_primsg *it = Priv(filep)->pfirst;
13616+ Priv(filep)->pfirst = it->next;
13617+ if (!Priv(filep)->pfirst)
13618+ Priv(filep)->plast = NULL;
13619+ kfree(it);
13620+ Priv(filep)->offset = 0;
13621+ return 0;
13622+ }
13623+ }
13624+
13625+ *flags_p = 0;
13626+
13627+ /* If we weren't asked for data there is nothing more to do. */
13628+ if (dat_maxlen <= 0) {
13629+ if (dat_maxlen == 0)
13630+ put_user(0, dat_len);
13631+ if (ctl_maxlen >= 0)
13632+ put_user(0, ctl_len);
13633+ return -EAGAIN;
13634+ }
13635+
13636+ /* If the select() slept we may have had our temp space paged
13637+ * out. The re-verify_area is only really needed for pre-486
13638+ * chips which don't handle write faults from kernel mode.
13639+ */
13640+ regs->esp = (unsigned long)tsp;
13641+ error = verify_area(VERIFY_WRITE, tsp, 6*sizeof(long));
13642+ if (error) {
13643+ regs->esp = old_esp;
13644+ return error;
13645+ }
13646+ put_user(fd, tsp);
13647+ put_user((unsigned long)dat_buf, tsp+1);
13648+ put_user((dat_maxlen < 0 ? 0 : dat_maxlen), tsp+2);
13649+ put_user(0, tsp+3);
13650+ if (ctl_maxlen > (int)sizeof(udi) && Priv(filep)->state == TS_IDLE) {
13651+ put_user((unsigned long)ctl_buf+sizeof(udi), tsp+4);
13652+ put_user(ctl_maxlen-sizeof(udi), ctl_len);
13653+ put_user((int)ctl_len, tsp+5);
13654+ } else {
13655+ put_user(0, tsp+4);
13656+ put_user(0, ctl_len);
13657+ put_user((int)ctl_len, tsp+5);
13658+ }
13659+
13660+ /* We don't want to block in the recvfrom(). Any blocking is
13661+ * handled by the select stuff above.
13662+ */
13663+ oldflags = filep->f_flags;
13664+ filep->f_flags |= O_NONBLOCK;
13665+ error = sys_socketcall(SYS_RECVFROM, tsp);
13666+ filep->f_flags = oldflags;
13667+
13668+ regs->esp = old_esp;
13669+ if (error < 0)
13670+ return error;
13671+ if (error
13672+ && ctl_maxlen > (int)sizeof(udi)
13673+ && Priv(filep)->state == TS_IDLE) {
13674+ udi.PRIM_type = T_UNITDATA_IND;
13675+ get_user(udi.SRC_length, ctl_len);
13676+ udi.SRC_offset = sizeof(udi);
13677+ udi.OPT_length = udi.OPT_offset = 0;
13678+ copy_to_user(ctl_buf, &udi, (int)sizeof(udi));
13679+ put_user(sizeof(udi)+udi.SRC_length, ctl_len);
13680+#if 0
13681+#if defined(CONFIG_ABI_TRACE)
13682+ if (abi_traced(ABI_TRACE_STREAMS) &&
13683+ ctl_buf && udi.SRC_length > 0) {
13684+ char * buf = ctl_buf + sizeof(udi);
13685+ int i = -1;
13686+
13687+ for (i = 0; i < udi.SRC_length &&
13688+ i < 64; i += 4) {
13689+ u_long v;
13690+
13691+ get_user(v, (u_long *)(buf+i));
13692+ __abi_trace("dat: 0x%08lx\n", v);
13693+ }
13694+ if (i != udi.SRC_length)
13695+ __abi_trace("dat: ...\n");
13696+ }
13697+#endif
13698+#endif
13699+ } else {
13700+ put_user(0, ctl_len);
13701+ }
13702+ put_user(error, dat_len);
13703+
13704+ return 0;
13705+}
13706+
13707+
13708+int
13709+do_putmsg(int fd, struct pt_regs *regs, char *ctl_buf, int ctl_len,
13710+ char *dat_buf, int dat_len, int flags)
13711+{
13712+ struct file *filep;
13713+ int error, terror;
13714+ unsigned long cmd;
13715+
13716+ /* It may not be obvious but we are always holding an fget(fd)
13717+ * at this point so we can use fcheck(fd) rather than fget...fput.
13718+ */
13719+ filep = fcheck(fd);
13720+
13721+ if (!Priv(filep) && Priv(filep)->magic != XTI_MAGIC) {
13722+ printk("putmsg on non-STREAMS fd %d by %s\n",fd, current->comm);
13723+ return -EINVAL;
13724+ }
13725+
13726+#if defined(CONFIG_ABI_TRACE)
13727+ if (abi_traced(ABI_TRACE_STREAMS)) {
13728+ u_long v;
13729+ __abi_trace("putmsg %d, 0x%lx[%d], 0x%lx[%d], %x\n",
13730+ fd, (u_long)ctl_buf, ctl_len,
13731+ (u_long)dat_buf, dat_len, flags);
13732+
13733+ get_user(v, ctl_buf);
13734+ __abi_trace("putmsg prim: %ld %s\n", v, xti_prim(v));
13735+
13736+ if (ctl_buf && ctl_len > 0) {
13737+ int i = -1;
13738+
13739+ for (i = 0; i < ctl_len && i < 64; i += 4) {
13740+ u_long v;
13741+
13742+ get_user(v, (u_long *)(ctl_buf + i));
13743+ __abi_trace("ctl: 0x%08lx\n", v);
13744+ }
13745+ if (i != ctl_len)
13746+ __abi_trace("ctl: ...\n");
13747+ }
13748+
13749+ if (dat_buf && dat_len > 0) {
13750+ int i = -1;
13751+
13752+ for (i = 0; i < dat_len && i < 64; i += 4) {
13753+ u_long v;
13754+
13755+ get_user(v, (u_long *)(dat_buf + i));
13756+ __abi_trace("dat: 0x%08lx\n", v);
13757+ }
13758+ if (i != dat_len)
13759+ __abi_trace("dat: ...");
13760+ }
13761+ }
13762+#endif
13763+
13764+ error = get_user(cmd, (unsigned long *)ctl_buf);
13765+ if (error)
13766+ return error;
13767+
13768+ switch (cmd) {
13769+ case T_BIND_REQ: {
13770+ struct T_bind_req req;
13771+ long old_esp;
13772+ unsigned long *tsp;
13773+
13774+#if defined(CONFIG_ABI_TRACE)
13775+ abi_trace(ABI_TRACE_STREAMS, "%u bind req\n", fd);
13776+#endif
13777+ error = verify_area(VERIFY_READ, ctl_buf, sizeof(req));
13778+ if (error)
13779+ return error;
13780+
13781+ if (Priv(filep)->state != TS_UNBND) {
13782+ timod_error(fd, T_BIND_REQ, TOUTSTATE, 0);
13783+ return 0;
13784+ }
13785+
13786+ old_esp = regs->esp;
13787+ regs->esp -= 1024;
13788+ tsp = (unsigned long *)(regs->esp);
13789+ error = verify_area(VERIFY_WRITE, tsp, 3*sizeof(long));
13790+ if (error) {
13791+ timod_error(fd, T_BIND_REQ, TSYSERR, -error);
13792+ regs->esp = old_esp;
13793+ return 0;
13794+ }
13795+
13796+ copy_from_user(&req, ctl_buf, sizeof(req));
13797+ if (req.ADDR_offset && req.ADDR_length) {
13798+ struct sockaddr_in *sin;
13799+ unsigned short family;
13800+
13801+#if 1 /* Wheee... Kludge time... */
13802+ sin = (struct sockaddr_in *)(ctl_buf
13803+ + req.ADDR_offset);
13804+ get_user(family, &sin->sin_family);
13805+
13806+ /* Sybase seems to have set up the address
13807+ * struct with sa->sa_family = htons(AF_?)
13808+ * which is bollocks. I have no idea why it
13809+ * apparently works on SCO?!?
13810+ */
13811+ if (family && !(family & 0x00ff))
13812+ put_user(ntohs(family), &sin->sin_family);
13813+#endif
13814+
13815+ put_user(fd, tsp);
13816+ put_user((unsigned long)ctl_buf
13817+ + req.ADDR_offset, tsp+1);
13818+ /* For TLI/XTI the length may be the 8 *used*
13819+ * bytes, for (IP?) sockets it must be the 16
13820+ * *total* bytes in a sockaddr_in.
13821+ */
13822+ put_user(req.ADDR_length == 8
13823+ ? 16 : req.ADDR_length,
13824+ tsp+2);
13825+ error = sys_socketcall(SYS_BIND, tsp);
13826+
13827+ if (!error) {
13828+ if (req.CONIND_number) {
13829+
13830+#if defined(CONFIG_ABI_TRACE)
13831+ abi_trace(ABI_TRACE_STREAMS,
13832+ "%u listen backlog=%lu\n",
13833+ fd, req.CONIND_number);
13834+#endif
13835+
13836+ put_user(fd, tsp);
13837+ put_user(req.CONIND_number, tsp+1);
13838+ sys_socketcall(SYS_LISTEN, tsp);
13839+ Priv(filep)->state = TS_WRES_CIND;
13840+ } else {
13841+ Priv(filep)->state = TS_IDLE;
13842+ }
13843+ }
13844+ } else {
13845+ error = 0;
13846+ }
13847+
13848+ regs->esp = old_esp;
13849+
13850+ if (!error) {
13851+ struct T_primsg *it;
13852+ it = timod_mkctl(ctl_len);
13853+ if (it) {
13854+ struct T_bind_ack *ack = (struct T_bind_ack *)&it->type;
13855+ copy_from_user(ack, ctl_buf, ctl_len);
13856+ ack->PRIM_type = T_BIND_ACK;
13857+ it->pri = MSG_HIPRI;
13858+ it->length = ctl_len;
13859+ it->next = NULL;
13860+ timod_ok(fd, T_BIND_REQ);
13861+ Priv(filep)->plast->next = it;
13862+ Priv(filep)->plast = it;
13863+ return 0;
13864+ }
13865+ }
13866+ switch (error) {
13867+ case -EINVAL:
13868+ terror = TOUTSTATE;
13869+ error = 0;
13870+ break;
13871+ case -EACCES:
13872+ terror = TACCES;
13873+ error = 0;
13874+ break;
13875+ case -EADDRNOTAVAIL:
13876+ case -EADDRINUSE:
13877+ terror = TNOADDR;
13878+ error = 0;
13879+ break;
13880+ default:
13881+ terror = TSYSERR;
13882+ break;
13883+ }
13884+ timod_error(fd, T_BIND_REQ, terror, -error);
13885+ return 0;
13886+ }
13887+ case T_CONN_RES: {
13888+ struct T_conn_res *res = (struct T_conn_res *)ctl_buf;
13889+ unsigned int conn_fd;
13890+
13891+ error = get_user(conn_fd, &res->SEQ_number);
13892+ if (error)
13893+ return error;
13894+
13895+#if defined(CONFIG_ABI_TRACE)
13896+ abi_trace(ABI_TRACE_STREAMS,
13897+ "%u accept: conn fd=%u, use fd=%u\n",
13898+ fd, conn_fd, flags);
13899+#endif
13900+
13901+ if (conn_fd != flags) {
13902+ error = sys_dup2(conn_fd, flags);
13903+ sys_close(conn_fd);
13904+ if (error < 0)
13905+ return error;
13906+ }
13907+ timod_ok(fd, T_CONN_RES);
13908+ return 0;
13909+ }
13910+ case T_CONN_REQ: {
13911+ struct T_conn_req req;
13912+ long old_esp;
13913+ unsigned short oldflags;
13914+ unsigned long *tsp;
13915+ struct T_primsg *it;
13916+ struct sockaddr_in *sin;
13917+ unsigned short family;
13918+
13919+#if defined(CONFIG_ABI_TRACE)
13920+ abi_trace(ABI_TRACE_STREAMS, "%u connect req\n", fd);
13921+#endif
13922+ error = verify_area(VERIFY_READ, ctl_buf, sizeof(req));
13923+ if (error)
13924+ return error;
13925+
13926+ if (Priv(filep)->state != TS_UNBND
13927+ && Priv(filep)->state != TS_IDLE) {
13928+ timod_error(fd, T_CONN_REQ, TOUTSTATE, 0);
13929+ return 0;
13930+ }
13931+
13932+ old_esp = regs->esp;
13933+ regs->esp -= 1024;
13934+ tsp = (unsigned long *)(regs->esp);
13935+ error = verify_area(VERIFY_WRITE, tsp, 3*sizeof(long));
13936+ if (error) {
13937+ timod_error(fd, T_CONN_REQ, TSYSERR, -error);
13938+ regs->esp = old_esp;
13939+ return 0;
13940+ }
13941+ copy_from_user(&req, ctl_buf, sizeof(req));
13942+ put_user(fd, tsp);
13943+ put_user((unsigned long)ctl_buf + req.DEST_offset, tsp+1);
13944+ /* For TLI/XTI the length may be the 8 *used*
13945+ * bytes, for (IP?) sockets it must be the 16
13946+ * *total* bytes in a sockaddr_in.
13947+ */
13948+ put_user(req.DEST_length == 8
13949+ ? 16 : req.DEST_length,
13950+ tsp+2);
13951+
13952+#if 1 /* Wheee... Kludge time... */
13953+ sin = (struct sockaddr_in *)(ctl_buf
13954+ + req.DEST_offset);
13955+ get_user(family, &sin->sin_family);
13956+
13957+ /* Sybase seems to have set up the address
13958+ * struct with sa->sa_family = htons(AF_?)
13959+ * which is bollocks. I have no idea why it
13960+ * apparently works on SCO?!?
13961+ */
13962+ if (family && !(family & 0x00ff)) {
13963+ family = ntohs(family);
13964+ put_user(family, &sin->sin_family);
13965+ }
13966+
13967+ /* Sheesh... ISC telnet seems to give the port
13968+ * number low byte first as I expected but the
13969+ * X programs seem to be giving high byte first.
13970+ * One is broken of course but clearly both
13971+ * should work. No, I don't understand this
13972+ * either but I can at least try...
13973+ * A better solution would be for you to change
13974+ * the definition of xserver0 in ISC's /etc/services
13975+ * but then it wouldn't work out of the box...
13976+ */
13977+ if (is_cur_personality(PER_SVR4) && family == AF_INET) {
13978+ get_user(family, &sin->sin_port);
13979+ if (family == 0x1770)
13980+ put_user(htons(family),
13981+ &sin->sin_port);
13982+ }
13983+#endif
13984+ /* FIXME: We should honour non-blocking mode
13985+ * here but that means that the select probe
13986+ * needs to know that if select returns ok and
13987+ * we are in T_OUTCON we have a connection
13988+ * completion. This isn't so bad but the real
13989+ * problem is that the connection acknowledgement
13990+ * is supposed to contain the destination
13991+ * address.
13992+ */
13993+ oldflags = filep->f_flags;
13994+ filep->f_flags &= ~O_NONBLOCK;
13995+ error = sys_socketcall(SYS_CONNECT, tsp);
13996+ filep->f_flags = oldflags;
13997+ regs->esp = old_esp;
13998+
13999+ if (!error) {
14000+ struct T_conn_con *con;
14001+
14002+ it = timod_mkctl(ctl_len);
14003+ if (!it)
14004+ return -ENOMEM;
14005+ it->length = ctl_len;
14006+ con = (struct T_conn_con *)&it->type;
14007+ copy_from_user(con, ctl_buf, ctl_len);
14008+ con->PRIM_type = T_CONN_CON;
14009+ Priv(filep)->state = TS_DATA_XFER;
14010+ } else {
14011+ struct T_discon_ind *dis;
14012+
14013+#if defined(CONFIG_ABI_TRACE)
14014+ abi_trace(ABI_TRACE_STREAMS,
14015+ "%u connect failed (errno=%d)\n",
14016+ fd, error);
14017+#endif
14018+
14019+ it = timod_mkctl(sizeof(struct T_discon_ind));
14020+ if (!it)
14021+ return -ENOMEM;
14022+ it->length = sizeof(struct T_discon_ind);
14023+ dis = (struct T_discon_ind *)&it->type;
14024+ dis->PRIM_type = T_DISCON_IND;
14025+ dis->DISCON_reason = iABI_errors(-error);
14026+ dis->SEQ_number = 0;
14027+ }
14028+ timod_ok(fd, T_CONN_REQ);
14029+ it->pri = 0;
14030+ it->next = NULL;
14031+ Priv(filep)->plast->next = it;
14032+ Priv(filep)->plast = it;
14033+ return 0;
14034+ }
14035+
14036+ case T_DISCON_REQ: {
14037+ struct T_discon_req *req;
14038+
14039+ req = (struct T_discon_req *)ctl_buf;
14040+ error = get_user(fd, &req->SEQ_number);
14041+ if (error)
14042+ return error;
14043+
14044+#if defined(CONFIG_ABI_TRACE)
14045+ abi_trace(ABI_TRACE_STREAMS, "disconnect %u\n", fd);
14046+#endif
14047+ /* Fall through... */
14048+ }
14049+ case T_ORDREL_REQ: {
14050+ sys_close(fd);
14051+ return 0;
14052+ }
14053+
14054+ case T_DATA_REQ: {
14055+ long old_esp;
14056+ unsigned long *tsp;
14057+
14058+#if defined(CONFIG_ABI_TRACE)
14059+ abi_trace(ABI_TRACE_STREAMS, "%u data req\n", fd);
14060+#endif
14061+
14062+ if (Priv(filep)->state != TS_DATA_XFER) {
14063+ return 0;
14064+ }
14065+
14066+ old_esp = regs->esp;
14067+ regs->esp -= 1024;
14068+ tsp = (unsigned long *)(regs->esp);
14069+ error = verify_area(VERIFY_WRITE, tsp, 6*sizeof(long));
14070+ if (error) {
14071+ regs->esp = old_esp;
14072+ return 0;
14073+ }
14074+ put_user(fd, tsp);
14075+ put_user((unsigned long)dat_buf, tsp+1);
14076+ put_user(dat_len, tsp+2);
14077+ put_user(0, tsp+3);
14078+ error = sys_socketcall(SYS_SEND, tsp);
14079+ regs->esp = old_esp;
14080+ return error;
14081+ }
14082+
14083+ case T_UNITDATA_REQ: {
14084+ struct T_unitdata_req req;
14085+ long old_esp;
14086+ unsigned long *tsp;
14087+
14088+#if defined(CONFIG_ABI_TRACE)
14089+ abi_trace(ABI_TRACE_STREAMS, "%u unitdata req\n", fd);
14090+#endif
14091+ error = verify_area(VERIFY_READ, ctl_buf, sizeof(req));
14092+ if (error)
14093+ return error;
14094+
14095+ if (Priv(filep)->state != TS_IDLE
14096+ && Priv(filep)->state != TS_DATA_XFER) {
14097+ timod_error(fd, T_UNITDATA_REQ, TOUTSTATE, 0);
14098+ return 0;
14099+ }
14100+
14101+ old_esp = regs->esp;
14102+ regs->esp -= 1024;
14103+ tsp = (unsigned long *)(regs->esp);
14104+ error = verify_area(VERIFY_WRITE, tsp, 6*sizeof(long));
14105+ if (error) {
14106+ timod_error(fd, T_UNITDATA_REQ, TSYSERR, -error);
14107+ regs->esp = old_esp;
14108+ return 0;
14109+ }
14110+ put_user(fd, tsp);
14111+ put_user((unsigned long)dat_buf, tsp+1);
14112+ put_user(dat_len, tsp+2);
14113+ put_user(0, tsp+3);
14114+ copy_from_user(&req, ctl_buf, sizeof(req));
14115+ if (req.DEST_length > 0) {
14116+ put_user((unsigned long)(ctl_buf+req.DEST_offset), tsp+4);
14117+ put_user(req.DEST_length, tsp+5);
14118+ error = sys_socketcall(SYS_SENDTO, tsp);
14119+ regs->esp = old_esp;
14120+ return error;
14121+ }
14122+ error = sys_socketcall(SYS_SEND, tsp);
14123+ regs->esp = old_esp;
14124+ return error;
14125+ }
14126+
14127+ case T_UNBIND_REQ:
14128+ Priv(filep)->state = TS_UNBND;
14129+ timod_ok(fd, T_UNBIND_REQ);
14130+ return 0;
14131+
14132+ case T_OPTMGMT_REQ: {
14133+ struct T_optmgmt_req req;
14134+
14135+#if defined(CONFIG_ABI_TRACE)
14136+ abi_trace(ABI_TRACE_STREAMS, "%u optmgmt req\n", fd);
14137+#endif
14138+ error = verify_area(VERIFY_READ, ctl_buf, sizeof(req));
14139+ if (error)
14140+ return error;
14141+ copy_from_user(&req, ctl_buf, sizeof(req));
14142+
14143+ return timod_optmgmt(fd, regs, req.MGMT_flags,
14144+ req.OPT_offset > 0
14145+ ? ctl_buf+req.OPT_offset
14146+ : NULL,
14147+ req.OPT_length,
14148+ 1);
14149+ }
14150+ }
14151+
14152+#if defined(CONFIG_ABI_TRACE)
14153+ if (abi_traced(ABI_TRACE_STREAMS))
14154+ {
14155+
14156+ if (ctl_buf && ctl_len > 0) {
14157+ int i;
14158+
14159+ for (i = 0; i < ctl_len && i < 32; i += 4) {
14160+ u_long v;
14161+
14162+ get_user(v, (u_long *)(ctl_buf + i));
14163+ __abi_trace("ctl: 0x%08lx\n", v);
14164+ }
14165+ if (i != ctl_len)
14166+ __abi_trace("ctl: ...\n");
14167+ }
14168+ if (dat_buf && dat_len > 0) {
14169+ int i;
14170+ for (i = 0; i < dat_len && i < 32; i += 4) {
14171+ u_long v;
14172+
14173+ get_user(v, (u_long *)(dat_buf + i));
14174+ __abi_trace("dat: 0x%08lx\n", v);
14175+ }
14176+ if (i != dat_len)
14177+ __abi_trace("dat: ...\n");
14178+ }
14179+ }
14180+#endif
14181+ return -EINVAL;
14182+}
14183+
14184+/* this function needs to be cleaned up badly. --hch */
14185+int
14186+timod_ioctl(struct pt_regs *regs,
14187+ int fd, unsigned int func, void *arg, int len, int *len_p)
14188+{
14189+ struct file *filep;
14190+ struct inode *ino;
14191+ int error;
14192+
14193+ func &= 0xff;
14194+
14195+ filep = fget(fd);
14196+ if (!filep)
14197+ return TBADF;
14198+
14199+ error = verify_area(VERIFY_WRITE, len_p, sizeof(int));
14200+ if (error) {
14201+ fput(filep);
14202+ return (-error << 8) | TSYSERR;
14203+ }
14204+
14205+ ino = filep->f_dentry->d_inode;
14206+
14207+ /* SCO/SVR3 starts at 100, ISC/SVR4 starts at 140. */
14208+ switch (func >= 140 ? func-140 : func-100) {
14209+ case 0: /* TI_GETINFO */
14210+ {
14211+ struct T_info_ack it;
14212+ unsigned long v;
14213+
14214+#if defined(CONFIG_ABI_TRACE)
14215+ abi_trace(ABI_TRACE_STREAMS, "%u getinfo\n", fd);
14216+#endif
14217+ /* The pre-SVR4 T_info_ack structure didn't have
14218+ * the PROVIDER_flag on the end.
14219+ */
14220+ error = verify_area(VERIFY_WRITE, arg,
14221+ func == 140
14222+ ? sizeof(struct T_info_ack)
14223+ : sizeof(struct T_info_ack)-sizeof(long));
14224+ if (error) {
14225+ fput(filep);
14226+ return (-error << 8) | TSYSERR;
14227+ }
14228+
14229+ __get_user(v, &((struct T_info_req *)arg)->PRIM_type);
14230+ if (v != T_INFO_REQ) {
14231+ fput(filep);
14232+ return (EINVAL << 8) | TSYSERR;
14233+ }
14234+
14235+ it.PRIM_type = T_INFO_ACK;
14236+ it.CURRENT_state = Priv(filep)->state;
14237+ it.CDATA_size = -2;
14238+ it.DDATA_size = -2;
14239+ it.OPT_size = -1;
14240+ it.TIDU_size = 16384;
14241+ switch ((MINOR(ino->i_rdev)>>4) & 0x0f) {
14242+ case AF_UNIX:
14243+ it.ADDR_size = sizeof(struct sockaddr_un);
14244+ break;
14245+ case AF_INET:
14246+ it.ADDR_size = sizeof(struct sockaddr_in);
14247+ break;
14248+ default:
14249+ /* Uh... dunno... play safe(?) */
14250+ it.ADDR_size = 1024;
14251+ break;
14252+ }
14253+ switch (SOCKET_I(ino)->type) {
14254+ case SOCK_STREAM:
14255+ it.ETSDU_size = 1;
14256+ it.TSDU_size = 0;
14257+ it.SERV_type = 2;
14258+ break;
14259+ default:
14260+ it.ETSDU_size = -2;
14261+ it.TSDU_size = 16384;
14262+ it.SERV_type = 3;
14263+ break;
14264+ }
14265+
14266+ fput(filep);
14267+
14268+ /* The pre-SVR4 T_info_ack structure didn't have
14269+ * the PROVIDER_flag on the end.
14270+ */
14271+ if (func == 140) {
14272+ it.PROVIDER_flag = 0;
14273+ copy_to_user(arg, &it, sizeof(it));
14274+ put_user(sizeof(it), len_p);
14275+ return 0;
14276+ }
14277+ copy_to_user(arg, &it, sizeof(it)-sizeof(long));
14278+ put_user(sizeof(it)-sizeof(long), len_p);
14279+ return 0;
14280+ }
14281+
14282+ case 2: /* TI_BIND */
14283+ {
14284+ int i;
14285+ long prim;
14286+
14287+#if defined(CONFIG_ABI_TRACE)
14288+ abi_trace(ABI_TRACE_STREAMS, "%u bind\n", fd);
14289+#endif
14290+ error = do_putmsg(fd, regs, arg, len,
14291+ NULL, -1, 0);
14292+ if (error) {
14293+ fput(filep);
14294+ return (-error << 8) | TSYSERR;
14295+ }
14296+
14297+ /* Get the response. This should be either
14298+ * T_OK_ACK or T_ERROR_ACK.
14299+ */
14300+ i = MSG_HIPRI;
14301+ error = do_getmsg(fd, regs,
14302+ arg, len, len_p,
14303+ NULL, -1, NULL,
14304+ &i);
14305+ if (error) {
14306+ fput(filep);
14307+ return (-error << 8) | TSYSERR;
14308+ }
14309+
14310+ get_user(prim, (unsigned long *)arg);
14311+ if (prim == T_ERROR_ACK) {
14312+ unsigned long a, b;
14313+ fput(filep);
14314+ get_user(a, ((unsigned long *)arg)+3);
14315+ get_user(b, ((unsigned long *)arg)+2);
14316+ return (a << 8) | b;
14317+ }
14318+ if (prim != T_OK_ACK) {
14319+ fput(filep);
14320+ return TBADSEQ;
14321+ }
14322+
14323+ /* Get the response to the bind request. */
14324+ i = MSG_HIPRI;
14325+ error = do_getmsg(fd, regs,
14326+ arg, len, len_p,
14327+ NULL, -1, NULL,
14328+ &i);
14329+ fput(filep);
14330+ if (error)
14331+ return (-error << 8) | TSYSERR;
14332+
14333+ return 0;
14334+ }
14335+
14336+ case 3: /* TI_UNBIND */
14337+ if (Priv(filep)->state != TS_IDLE) {
14338+ fput(filep);
14339+ return TOUTSTATE;
14340+ }
14341+ Priv(filep)->state = TS_UNBND;
14342+ fput(filep);
14343+ return 0;
14344+
14345+ case 1: { /* TI_OPTMGMT */
14346+#if defined(CONFIG_ABI_XTI_OPTMGMT) || defined(CONFIG_ABI_TLI_OPTMGMT)
14347+ int i;
14348+ long prim;
14349+
14350+#if defined(CONFIG_ABI_TRACE)
14351+ abi_trace(ABI_TRACE_STREAMS, "%u optmgmt\n", fd);
14352+#endif
14353+ error = do_putmsg(fd, regs, arg, len,
14354+ NULL, -1, 0);
14355+ if (error) {
14356+ fput(filep);
14357+ return (-error << 8) | TSYSERR;
14358+ }
14359+
14360+ /* Get the response to the optmgmt request. */
14361+ i = MSG_HIPRI;
14362+ error = do_getmsg(fd, regs,
14363+ arg, len, len_p,
14364+ NULL, -1, NULL,
14365+ &i);
14366+ if (error > 0) {
14367+ /* If there is excess data in the response
14368+ * our buffer is too small which implies
14369+ * the application is broken. SO_LINGER
14370+ * is a common fault. Because it works
14371+ * on other systems we attempt to recover
14372+ * by discarding the excess.
14373+ */
14374+ struct T_primsg *it = Priv(filep)->pfirst;
14375+ Priv(filep)->pfirst = it->next;
14376+ if (!Priv(filep)->pfirst)
14377+ Priv(filep)->plast = NULL;
14378+ kfree(it);
14379+ Priv(filep)->offset = 0;
14380+
14381+#if defined(CONFIG_ABI_TRACE)
14382+ abi_trace(ABI_TRACE_STREAMS,
14383+ "excess discarded\n");
14384+#endif
14385+ }
14386+
14387+ fput(filep);
14388+
14389+ if (error < 0)
14390+ return (-error << 8) | TSYSERR;
14391+
14392+ __get_user(prim, (unsigned long *)arg);
14393+ if (prim == T_ERROR_ACK) {
14394+ unsigned long a, b;
14395+ __get_user(a, ((unsigned long *)arg)+3);
14396+ __get_user(b, ((unsigned long *)arg)+2);
14397+ return (a << 8) | b;
14398+ }
14399+
14400+ return 0;
14401+#else /* no CONFIG_ABI_XTI_OPTMGMT or CONFIG_ABI_TLI_OPTMGMT */
14402+ fput(filep);
14403+ return TNOTSUPPORT;
14404+#endif /* CONFIG_ABI_XTI_OPTMGMT or CONFIG_ABI_TLI_OPTMGMT */
14405+ }
14406+
14407+ case 4: /* TI_GETMYNAME */
14408+ case 5: /* TI_SETPEERNAME */
14409+ case 6: /* TI_GETMYNAME */
14410+ case 7: /* TI_SETPEERNAME */
14411+ break;
14412+ }
14413+
14414+#if defined(CONFIG_ABI_TRACE)
14415+ abi_trace(ABI_TRACE_STREAMS,
14416+ "STREAMS timod op %d not supported\n", func);
14417+#endif
14418+ fput(filep);
14419+ return TNOTSUPPORT;
14420+}
14421+
14422+
14423+int
14424+svr4_sockmod_ioctl(int fd, u_int cmd, caddr_t data)
14425+{
14426+ struct file *fp;
14427+ struct inode *ip;
14428+ int error;
14429+
14430+ fp = fget(fd);
14431+ if (!fp)
14432+ return (TBADF);
14433+
14434+ ip = fp->f_dentry->d_inode;
14435+ if (MAJOR(ip->i_rdev) == SOCKSYS_MAJOR) {
14436+ error = socksys_fdinit(fd, 0, NULL, NULL);
14437+ if (error < 0)
14438+ return -error;
14439+ fput(fp);
14440+ fp = fget(fd);
14441+ if (!fp)
14442+ return TBADF;
14443+ ip = fp->f_dentry->d_inode;
14444+ }
14445+
14446+ switch (cmd) {
14447+ case 101: { /* SI_GETUDATA */
14448+ struct {
14449+ int tidusize, addrsize, optsize, etsdusize;
14450+ int servtype, so_state, so_options;
14451+ } *it = (void *)data;
14452+
14453+#if defined(CONFIG_ABI_TRACE)
14454+ abi_trace(ABI_TRACE_STREAMS, "%u getudata\n", fd);
14455+#endif
14456+ error = verify_area(VERIFY_WRITE, it, sizeof(*it));
14457+ if (error) {
14458+ fput(fp);
14459+ return (-error << 8) | TSYSERR;
14460+ }
14461+
14462+ __put_user(16384, &it->tidusize);
14463+ __put_user(sizeof(struct sockaddr), &it->addrsize);
14464+ __put_user(-1, &it->optsize);
14465+ __put_user(0, &it->so_state);
14466+ __put_user(0, &it->so_options);
14467+
14468+ switch (SOCKET_I(ip)->type) {
14469+ case SOCK_STREAM:
14470+ __put_user(1, &it->etsdusize);
14471+ __put_user(2, &it->servtype);
14472+ break;
14473+ default:
14474+ __put_user(-2, &it->etsdusize);
14475+ __put_user(3, &it->servtype);
14476+ break;
14477+ }
14478+ fput(fp);
14479+ return 0;
14480+ }
14481+
14482+ case 102: /* SI_SHUTDOWN */
14483+ case 103: /* SI_LISTEN */
14484+ case 104: /* SI_SETMYNAME */
14485+ case 105: /* SI_SETPEERNAME */
14486+ case 106: /* SI_GETINTRANSIT */
14487+ case 107: /* SI_TCL_LINK */
14488+ case 108: /* SI_TCL_UNLINK */
14489+ break;
14490+ }
14491+
14492+#if defined(CONFIG_ABI_TRACE)
14493+ abi_trace(ABI_TRACE_STREAMS,
14494+ "STREAMS sockmod op %d not supported\n", cmd);
14495+#endif
14496+ fput(fp);
14497+ return TNOTSUPPORT;
14498+}
14499+
14500+#if defined(CONFIG_ABI_SYSCALL_MODULES)
14501+EXPORT_SYMBOL(svr4_sockmod_ioctl);
14502+#endif
14503diff -Nru linux-2.6.7/abi/util/Makefile linux-2.6.7-abi/abi/util/Makefile
14504--- linux-2.6.7/abi/util/Makefile 1970-01-01 01:00:00.000000000 +0100
14505+++ linux-2.6.7-abi/abi/util/Makefile 2004-07-22 17:44:21.000000000 +0200
14506@@ -0,0 +1,7 @@
14507+
14508+abi-util-objs := stat.o plist.o
14509+
14510+obj-$(CONFIG_ABI_UTIL) += abi-util.o
14511+
14512+abi-util.o: $(abi-util-objs)
14513+ $(LD) -r -o $@ $(abi-util-objs)
14514diff -Nru linux-2.6.7/abi/util/plist.c linux-2.6.7-abi/abi/util/plist.c
14515--- linux-2.6.7/abi/util/plist.c 1970-01-01 01:00:00.000000000 +0100
14516+++ linux-2.6.7-abi/abi/util/plist.c 2004-07-22 17:44:21.000000000 +0200
14517@@ -0,0 +1,69 @@
14518+#ident "%W% %G%"
14519+
14520+#include <linux/string.h>
14521+#include <linux/fs.h>
14522+#include <linux/slab.h> /* needed by putname macro */
14523+#include <linux/sched.h> /* needed by current-> in __abi_trace() macro */
14524+#include <linux/module.h>
14525+
14526+#include <abi/util/trace.h>
14527+
14528+
14529+#if defined(CONFIG_ABI_TRACE)
14530+static void
14531+print_string(char *buf, char *str)
14532+{
14533+ char *tmp;
14534+
14535+ tmp = getname(str);
14536+ if (!IS_ERR(tmp)) {
14537+ /* we are debugging, we don't need to see it all */
14538+ tmp[80] = '\0';
14539+ sprintf(buf, "\"%s\"", tmp);
14540+ putname(tmp);
14541+ }
14542+}
14543+
14544+void plist(char *name, char *args, int *list)
14545+{
14546+ char buf[512], *p = buf;
14547+
14548+ buf[0] = '\0';
14549+ while (*args) {
14550+ switch (*args++) {
14551+ case 'd':
14552+ sprintf(p, "%d", *list++);
14553+ break;
14554+ case 'o':
14555+ sprintf(p, "0%o", *list++);
14556+ break;
14557+ case 'p':
14558+ sprintf(p, "%p", (void *)(*list++));
14559+ break;
14560+ case '?':
14561+ case 'x':
14562+ sprintf(p, "0x%x", *list++);
14563+ break;
14564+ case 's':
14565+ print_string(p, (char *)(*list++));
14566+ break;
14567+ default:
14568+ sprintf(p, "?%c%c?", '%', args[-1]);
14569+ break;
14570+ }
14571+
14572+ while (*p)
14573+ ++p;
14574+ if (*args) {
14575+ *p++ = ',';
14576+ *p++ = ' ';
14577+ *p = '\0';
14578+ }
14579+ }
14580+ __abi_trace("%s(%s)\n", name, buf);
14581+}
14582+
14583+#if CONFIG_ABI_LCALL7 == m
14584+EXPORT_SYMBOL(plist);
14585+#endif
14586+#endif /* CONFIG_ABI_TRACE */
14587diff -Nru linux-2.6.7/abi/util/stat.c linux-2.6.7-abi/abi/util/stat.c
14588--- linux-2.6.7/abi/util/stat.c 1970-01-01 01:00:00.000000000 +0100
14589+++ linux-2.6.7-abi/abi/util/stat.c 2004-07-22 17:44:21.000000000 +0200
14590@@ -0,0 +1,146 @@
14591+/*
14592+ * Mostly ripped from Al Viro's stat-a-AC9-10 patch, 2001 Christoph Hellwig.
14593+ */
14594+
14595+#ident "%W% %G%"
14596+
14597+#include <linux/module.h> /* needed to shut up modprobe */
14598+#include <linux/fs.h>
14599+#include <linux/stat.h>
14600+#include <linux/sched.h>
14601+#include <linux/file.h>
14602+#include <linux/namei.h>
14603+
14604+#include <abi/util/revalidate.h>
14605+#include <abi/util/stat.h>
14606+
14607+
14608+MODULE_DESCRIPTION("Linux-ABI helper routines");
14609+MODULE_AUTHOR("Christoph Hellwig, ripped from kernel sources/patches");
14610+MODULE_LICENSE("GPL");
14611+
14612+#if 0 /* LINUXABI_OBSOLETE */
14613+int getattr_full(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
14614+{
14615+ struct inode *inode = dentry->d_inode;
14616+ stat->dev = inode->i_rdev;
14617+ stat->ino = inode->i_ino;
14618+ stat->mode = inode->i_mode;
14619+ stat->nlink = inode->i_nlink;
14620+ stat->uid = inode->i_uid;
14621+ stat->gid = inode->i_gid;
14622+ stat->rdev = inode->i_rdev;
14623+ stat->atime = inode->i_atime;
14624+ stat->mtime = inode->i_mtime;
14625+ stat->ctime = inode->i_ctime;
14626+ stat->size = inode->i_size;
14627+ stat->blocks = inode->i_blocks;
14628+ stat->blksize = inode->i_blksize;
14629+ return 0;
14630+}
14631+
14632+/*
14633+ * Use minix fs values for the number of direct and indirect blocks. The
14634+ * count is now exact for the minix fs except that it counts zero blocks.
14635+ * Everything is in units of BLOCK_SIZE until the assignment to
14636+ * stat->blksize.
14637+ */
14638+int getattr_minix(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
14639+{
14640+ struct inode *inode = dentry->d_inode;
14641+ unsigned int blocks, indirect;
14642+
14643+ stat->dev = inode->i_rdev;
14644+ stat->ino = inode->i_ino;
14645+ stat->mode = inode->i_mode;
14646+ stat->nlink = inode->i_nlink;
14647+ stat->uid = inode->i_uid;
14648+ stat->gid = inode->i_gid;
14649+ stat->rdev = inode->i_rdev;
14650+ stat->atime = inode->i_atime;
14651+ stat->mtime = inode->i_mtime;
14652+ stat->ctime = inode->i_ctime;
14653+ stat->size = inode->i_size;
14654+#define D_B 7
14655+#define I_B (BLOCK_SIZE / sizeof(unsigned short))
14656+
14657+ blocks = (stat->size + BLOCK_SIZE - 1) >> BLOCK_SIZE_BITS;
14658+ if (blocks > D_B) {
14659+ indirect = (blocks - D_B + I_B - 1) / I_B;
14660+ blocks += indirect;
14661+ if (indirect > 1) {
14662+ indirect = (indirect - 1 + I_B - 1) / I_B;
14663+ blocks += indirect;
14664+ if (indirect > 1)
14665+ blocks++;
14666+ }
14667+ }
14668+ stat->blocks = (BLOCK_SIZE / 512) * blocks;
14669+ stat->blksize = BLOCK_SIZE;
14670+ return 0;
14671+}
14672+
14673+int vfs_stat(char *filename, struct kstat *stat)
14674+{
14675+ struct nameidata nd;
14676+ int error;
14677+
14678+ error = user_path_walk(filename, &nd);
14679+ if (error)
14680+ return error;
14681+
14682+ error = do_revalidate(nd.dentry);
14683+ if (!error) {
14684+ struct inode *inode = nd.dentry->d_inode;
14685+ if (!inode->i_blksize)
14686+ error = getattr_minix(nd.mnt, nd.dentry, stat);
14687+ else
14688+ error = getattr_full(nd.mnt, nd.dentry, stat);
14689+ path_release(&nd);
14690+ }
14691+
14692+ return error;
14693+}
14694+
14695+int vfs_lstat(char *filename, struct kstat *stat)
14696+{
14697+ struct nameidata nd;
14698+ int error;
14699+
14700+ error = user_path_walk_link(filename, &nd);
14701+ if (error)
14702+ return error;
14703+
14704+ error = do_revalidate(nd.dentry);
14705+ if (!error) {
14706+ struct inode *inode = nd.dentry->d_inode;
14707+ if (!inode->i_blksize)
14708+ error = getattr_minix(nd.mnt, nd.dentry, stat);
14709+ else
14710+ error = getattr_full(nd.mnt, nd.dentry, stat);
14711+ path_release(&nd);
14712+ }
14713+
14714+ return error;
14715+}
14716+
14717+int vfs_fstat(int fd, struct kstat *stat)
14718+{
14719+ struct file *file = fget(fd);
14720+ int error;
14721+
14722+ if (!file)
14723+ return -EBADF;
14724+
14725+ error = do_revalidate(file->f_dentry);
14726+ if (!error) {
14727+ struct inode *inode = file->f_dentry->d_inode;
14728+ if (!inode->i_blksize)
14729+ error = getattr_minix(file->f_vfsmnt, file->f_dentry, stat);
14730+ else
14731+ error = getattr_full(file->f_vfsmnt, file->f_dentry, stat);
14732+ fput(file);
14733+ }
14734+ return error;
14735+}
14736+#endif
14737diff -Nru linux-2.6.7/abi/uw7/access.c linux-2.6.7-abi/abi/uw7/access.c
14738--- linux-2.6.7/abi/uw7/access.c 1970-01-01 01:00:00.000000000 +0100
14739+++ linux-2.6.7-abi/abi/uw7/access.c 2004-07-22 17:44:21.000000000 +0200
14740@@ -0,0 +1,75 @@
14741+/*
14742+ * abi/uw7/access.c - support for UnixWare access(2) system call.
14743+ *
14744+ * We handle the non-POSIX EFF_ONLY_OK/EX_OK flags.
14745+ * This software is under GPL.
14746+ */
14747+
14748+#include <linux/errno.h>
14749+#include <linux/sched.h>
14750+#include <linux/syscalls.h>
14751+#include <linux/dcache.h>
14752+#include <linux/namei.h>
14753+#include <asm/uaccess.h>
14754+
14755+#include <abi/util/revalidate.h>
14756+
14757+
14758+#undef DEBUG
14759+
14760+#ifdef DEBUG
14761+#define DBG(x...) printk(x)
14762+#else
14763+#define DBG(x...)
14764+#endif
14765+
14766+#define UW7_R_OK 004
14767+#define UW7_W_OK 002
14768+#define UW7_X_OK 001
14769+#define UW7_F_OK 000
14770+#define UW7_EFF_ONLY_OK 010
14771+#define UW7_EX_OK 020
14772+
14773+#define UW7_MODE_MSK (UW7_R_OK|UW7_W_OK|UW7_X_OK|UW7_F_OK|UW7_EFF_ONLY_OK|UW7_EX_OK)
14774+
14775+int uw7_access(char * filename, int mode)
14776+{
14777+ struct nameidata nd;
14778+ int error;
14779+
14780+ DBG(KERN_ERR "UW7[%d]: access(%p,%o)\n", current->pid, filename, mode);
14781+
14782+ if (mode & ~UW7_MODE_MSK)
14783+ return -EINVAL;
14784+
14785+ if (mode & UW7_EX_OK) {
14786+ error = user_path_walk(filename, &nd);
14787+ if (!error) {
14788+ error = do_revalidate(nd.dentry);
14789+ if (error) {
14790+ path_release(&nd);
14791+ return -EIO;
14792+ }
14793+ if (!S_ISREG(nd.dentry->d_inode->i_mode)) {
14794+ path_release(&nd);
14795+ return -EACCES;
14796+ }
14797+ path_release(&nd);
14798+ }
14799+ mode &= ~UW7_EX_OK;
14800+ mode |= UW7_X_OK;
14801+ }
14802+ if (mode & UW7_EFF_ONLY_OK) {
14803+ uid_t old_uid = current->uid, old_gid = current->gid;
14804+
14805+ current->uid = current->euid;
14806+ current->gid = current->egid;
14807+ mode &= ~UW7_EFF_ONLY_OK;
14808+ error = sys_access(filename, mode);
14809+ current->uid = old_uid;
14810+ current->gid = old_gid;
14811+ } else
14812+ error = sys_access(filename, mode);
14813+
14814+ return error;
14815+}
14816diff -Nru linux-2.6.7/abi/uw7/context.c linux-2.6.7-abi/abi/uw7/context.c
14817--- linux-2.6.7/abi/uw7/context.c 1970-01-01 01:00:00.000000000 +0100
14818+++ linux-2.6.7-abi/abi/uw7/context.c 2004-07-22 17:44:21.000000000 +0200
14819@@ -0,0 +1,98 @@
14820+/*
14821+ * abi/uw7/context.c
14822+ *
14823+ * This software is under GPL
14824+ */
14825+
14826+
14827+#include <linux/ptrace.h>
14828+#include <linux/errno.h>
14829+#define __KERNEL_SYSCALLS__
14830+#include <linux/unistd.h>
14831+#include <linux/syscalls.h>
14832+#include <asm/uaccess.h>
14833+
14834+#include <asm/abi_machdep.h>
14835+#include <abi/uw7/context.h>
14836+
14837+
14838+int
14839+uw7_sigaltstack(const uw7_stack_t *uw7_ss, uw7_stack_t *uw7_oss)
14840+{
14841+ stack_t ss, oss, *ssp = NULL, *ossp = NULL;
14842+ int error;
14843+ mm_segment_t old_fs;
14844+
14845+ if (uw7_ss) {
14846+ error = verify_area(VERIFY_READ, uw7_ss, sizeof(uw7_stack_t));
14847+ if (error)
14848+ return error;
14849+ __get_user(ss.ss_sp, &uw7_ss->ss_sp);
14850+ __get_user(ss.ss_size, &uw7_ss->ss_size);
14851+ __get_user(ss.ss_flags, &uw7_ss->ss_flags);
14852+ ssp = &ss;
14853+ }
14854+
14855+ if (uw7_oss) {
14856+ error = verify_area(VERIFY_WRITE, uw7_oss, sizeof(uw7_stack_t));
14857+ if (error)
14858+ return error;
14859+ __get_user(oss.ss_sp, &uw7_oss->ss_sp);
14860+ __get_user(oss.ss_size, &uw7_oss->ss_size);
14861+ __get_user(oss.ss_flags, &uw7_oss->ss_flags);
14862+ ossp = &oss;
14863+ }
14864+
14865+ old_fs = get_fs();
14866+ set_fs(get_ds());
14867+ error = sys_sigaltstack(ssp, ossp);
14868+ set_fs(old_fs);
14869+
14870+ if (ossp) {
14871+ __put_user(ossp->ss_sp, &uw7_oss->ss_sp);
14872+ __put_user(ossp->ss_size, &uw7_oss->ss_size);
14873+ __put_user(ossp->ss_flags, &uw7_oss->ss_flags);
14874+ }
14875+ return error;
14876+}
14877+
14878+static int
14879+getcontext(uw7_context_t * uc, struct pt_regs * regs)
14880+{
14881+ uw7_context_t tmp = { 0 };
14882+
14883+ return copy_to_user(uc, &tmp, sizeof(uw7_context_t)) ? -EFAULT : 0;
14884+}
14885+
14886+static int
14887+getxcontext(uw7_context_t * uc, struct pt_regs * regs)
14888+{
14889+ return 0;
14890+}
14891+
14892+static int
14893+setcontext(uw7_context_t * uc, struct pt_regs * regs)
14894+{
14895+ if (!uc) /* SVR4 says setcontext(NULL) => exit(0) */
14896+ sys_exit(0);
14897+ return 0;
14898+}
14899+
14900+int
14901+uw7_context(struct pt_regs * regs)
14902+{
14903+ int fcn = get_syscall_parameter(regs, 0);
14904+ uw7_context_t * uc = (uw7_context_t *) get_syscall_parameter(regs, 1);
14905+
14906+ switch (fcn) {
14907+ case UW7_GETCONTEXT:
14908+ return getcontext(uc, regs);
14909+
14910+ case UW7_GETXCONTEXT:
14911+ return getxcontext(uc, regs);
14912+
14913+ case UW7_SETCONTEXT:
14914+ return setcontext(uc, regs);
14915+ }
14916+ return -EINVAL;
14917+}
14918diff -Nru linux-2.6.7/abi/uw7/ioctl.c linux-2.6.7-abi/abi/uw7/ioctl.c
14919--- linux-2.6.7/abi/uw7/ioctl.c 1970-01-01 01:00:00.000000000 +0100
14920+++ linux-2.6.7-abi/abi/uw7/ioctl.c 2004-07-22 17:44:21.000000000 +0200
14921@@ -0,0 +1,220 @@
14922+/*
14923+ * abi/uw7/ioctl.c - Support for UnixWare 7.x ioctl(2) system call.
14924+ *
14925+ * This module provides a function uw7_ioctl() which is called indirectly
14926+ * via uw7_funcs[] array, see abi/uw7/funcs.c.
14927+ * This software is under GPL
14928+ */
14929+
14930+#include <linux/errno.h>
14931+#include <linux/sched.h>
14932+#include <linux/syscalls.h>
14933+#include <linux/termios.h>
14934+#include <asm/uaccess.h>
14935+
14936+#include <asm/abi_machdep.h>
14937+
14938+#include <abi/uw7/termbits.h>
14939+#include <abi/uw7/termios.h>
14940+#include <abi/svr4/ioctl.h>
14941+
14942+
14943+#undef DEBUG
14944+
14945+#ifdef DEBUG
14946+#define DBG(x...) printk(x)
14947+#else
14948+#define DBG(x...)
14949+#endif
14950+
14951+
14952+static int tioc_tcgets(int fd, struct uw7_termios * tios);
14953+static int tioc_tcsets(int fd, int lnx_cmd, struct uw7_termios * tios);
14954+static int ioctl_T(int fd, unsigned int cmd, void * arg);
14955+
14956+
14957+int uw7_ioctl(struct pt_regs * regs)
14958+{
14959+ int fd;
14960+ unsigned int cmd, class;
14961+ void * arg;
14962+
14963+ fd = (int)get_syscall_parameter(regs, 0);
14964+ cmd = (unsigned int)get_syscall_parameter(regs, 1);
14965+ arg = (void *)get_syscall_parameter(regs, 2);
14966+ class = cmd >> 8;
14967+
14968+ switch (class) {
14969+ case 'T':
14970+ return ioctl_T(fd, cmd, arg);
14971+ default:
14972+ return __svr4_ioctl(regs, fd, cmd, arg);
14973+ }
14974+}
14975+
14976+static int tioc_tcsets(int fd, int lnx_cmd, struct uw7_termios * tios)
14977+{
14978+ struct termios t;
14979+ struct uw7_termios tmp = {0, };
14980+ mm_segment_t old_fs;
14981+ int error;
14982+
14983+ DBG(KERN_ERR "UW7[%d]: tioc_tcsets(%d,%x,%p)\n",
14984+ current->pid, fd, lnx_cmd, tios);
14985+
14986+ error = verify_area(VERIFY_READ, tios, sizeof(struct uw7_termios));
14987+ if (error)
14988+ return error;
14989+
14990+ old_fs = get_fs();
14991+ set_fs(get_ds());
14992+ error = sys_ioctl(fd, TCGETS, (long)&t);
14993+ set_fs(old_fs);
14994+ if (error)
14995+ return error;
14996+
14997+ if (copy_from_user(&tmp, tios, sizeof(struct uw7_termios)))
14998+ return -EFAULT;
14999+ t.c_iflag = tmp.c_iflag & ~UW7_DOSMODE;
15000+ t.c_oflag = tmp.c_oflag;
15001+ t.c_cflag = tmp.c_cflag;
15002+ t.c_lflag = tmp.c_lflag & ~UW7_DEFECHO;
15003+ if (tmp.c_lflag & UW7_FLUSHO)
15004+ t.c_lflag |= FLUSHO;
15005+ else
15006+ t.c_lflag &= ~FLUSHO;
15007+
15008+ DBG(KERN_ERR
15009+ "UW7[%d]: iflag: %lx->%lx, oflag: %lx->%lx, cflag: %lx->%lx, lflag: %lx->%lx\n",
15010+ current->pid, tmp.c_iflag, t.c_iflag, tmp.c_oflag, t.c_oflag,
15011+ tmp.c_cflag, t.c_cflag, tmp.c_lflag, t.c_lflag);
15012+
15013+ t.c_cc[VINTR] = tmp.c_cc[UW7_VINTR];
15014+ t.c_cc[VQUIT] = tmp.c_cc[UW7_VQUIT];
15015+ t.c_cc[VERASE] = tmp.c_cc[UW7_VERASE];
15016+ t.c_cc[VKILL] = tmp.c_cc[UW7_VKILL];
15017+ t.c_cc[VEOL2] = tmp.c_cc[UW7_VEOL2];
15018+ t.c_cc[VSWTC] = tmp.c_cc[UW7_VSWTCH];
15019+ t.c_cc[VSTART] = tmp.c_cc[UW7_VSTART];
15020+ t.c_cc[VSTOP] = tmp.c_cc[UW7_VSTOP];
15021+ t.c_cc[VSUSP] = tmp.c_cc[UW7_VSUSP];
15022+ t.c_cc[VREPRINT] = tmp.c_cc[UW7_VREPRINT];
15023+ t.c_cc[VDISCARD] = tmp.c_cc[UW7_VDISCARD];
15024+ t.c_cc[VWERASE] = tmp.c_cc[UW7_VWERASE];
15025+ t.c_cc[VLNEXT] = tmp.c_cc[UW7_VLNEXT];
15026+ if (t.c_lflag & ICANON) {
15027+ t.c_cc[VEOF] = tmp.c_cc[UW7_VEOF];
15028+ t.c_cc[VEOL] = tmp.c_cc[UW7_VEOL];
15029+ } else {
15030+ t.c_cc[VMIN] = tmp.c_cc[UW7_VMIN];
15031+ t.c_cc[VTIME] = tmp.c_cc[UW7_VTIME];
15032+ t.c_cc[VEOL] = tmp.c_cc[UW7_VEOL2];
15033+ }
15034+
15035+
15036+ DBG(KERN_ERR
15037+ "UW7[%d]: "
15038+ "VINTR: %x->%x, VQUIT: %x->%x, VERASE: %x->%x, VKILL: %x->%x\n"
15039+ "VEOL2: %x->%x\n",
15040+ current->pid, tmp.c_cc[UW7_VINTR], t.c_cc[VINTR],
15041+ tmp.c_cc[UW7_VQUIT], t.c_cc[VQUIT],
15042+ tmp.c_cc[UW7_VERASE], t.c_cc[VERASE],
15043+ tmp.c_cc[UW7_VKILL], t.c_cc[VKILL],
15044+ tmp.c_cc[UW7_VEOL2], t.c_cc[VEOL2]);
15045+
15046+ old_fs = get_fs();
15047+ set_fs(get_ds());
15048+ error = sys_ioctl(fd, lnx_cmd, (long)&t);
15049+ set_fs(old_fs);
15050+ return error;
15051+}
15052+
15053+static int tioc_tcgets(int fd, struct uw7_termios * tios)
15054+{
15055+ struct termios t;
15056+ struct uw7_termios tmp = { 0 };
15057+ mm_segment_t old_fs;
15058+ int error;
15059+
15060+ DBG(KERN_ERR "UW7[%d]: tioc_tcgets(%d,%p)\n", current->pid, fd, tios);
15061+
15062+ old_fs = get_fs();
15063+ set_fs(get_ds());
15064+ error = sys_ioctl(fd, TCGETS, (long)&t);
15065+ set_fs(old_fs);
15066+ if (error)
15067+ return error;
15068+
15069+ tmp.c_iflag = UW7_IFLAG_MSK & (t.c_iflag & ~UW7_DOSMODE);
15070+ tmp.c_oflag = UW7_OFLAG_MSK & t.c_oflag;
15071+ tmp.c_cflag = UW7_CFLAG_MSK & t.c_cflag;
15072+ tmp.c_lflag = UW7_LFLAG_MSK & (t.c_lflag & ~UW7_DEFECHO);
15073+ if (t.c_lflag & FLUSHO)
15074+ tmp.c_lflag |= UW7_FLUSHO;
15075+ else
15076+ tmp.c_lflag &= ~UW7_FLUSHO;
15077+
15078+ DBG(KERN_ERR
15079+ "UW7[%d]: iflag: %lx->%lx, oflag: %lx->%lx, cflag: %lx->%lx, lflag: %lx->%lx\n",
15080+ current->pid, tmp.c_iflag, t.c_iflag, tmp.c_oflag, t.c_oflag,
15081+ tmp.c_cflag, t.c_cflag, tmp.c_lflag, t.c_lflag);
15082+
15083+ if (t.c_lflag & ICANON) {
15084+ tmp.c_cc[UW7_VEOF] = t.c_cc[VEOF];
15085+ tmp.c_cc[UW7_VEOL] = t.c_cc[VEOL];
15086+ } else {
15087+ tmp.c_cc[UW7_VMIN] = t.c_cc[VMIN];
15088+ tmp.c_cc[UW7_VTIME] = t.c_cc[VTIME];
15089+ }
15090+
15091+ tmp.c_cc[UW7_VINTR] = t.c_cc[VINTR];
15092+ tmp.c_cc[UW7_VQUIT] = t.c_cc[VQUIT];
15093+ tmp.c_cc[UW7_VERASE] = t.c_cc[VERASE];
15094+ tmp.c_cc[UW7_VKILL] = t.c_cc[VKILL];
15095+ tmp.c_cc[UW7_VEOL2] = t.c_cc[VEOL2];
15096+ tmp.c_cc[UW7_VSWTCH] = t.c_cc[VSWTC];
15097+ tmp.c_cc[UW7_VSTART] = t.c_cc[VSTART];
15098+ tmp.c_cc[UW7_VSTOP] = t.c_cc[VSTOP];
15099+ tmp.c_cc[UW7_VSUSP] = tmp.c_cc[UW7_VDSUSP] = t.c_cc[VSUSP];
15100+ tmp.c_cc[UW7_VREPRINT] = t.c_cc[VREPRINT];
15101+ tmp.c_cc[UW7_VDISCARD] = t.c_cc[VDISCARD];
15102+ tmp.c_cc[UW7_VWERASE] = t.c_cc[VWERASE];
15103+ tmp.c_cc[UW7_VLNEXT] = t.c_cc[VLNEXT];
15104+
15105+ return copy_to_user(tios, &tmp, sizeof(struct uw7_termios)) ? -EFAULT : 0;
15106+}
15107+
15108+static int ioctl_T(int fd, unsigned int cmd, void * arg)
15109+{
15110+ DBG(KERN_ERR "ioctl_T(%d,%x,%p)\n", fd, cmd, arg);
15111+
15112+ switch (cmd) {
15113+ case UW7_TCSBRK:
15114+ return sys_ioctl(fd, TCSBRK, (long)arg);
15115+
15116+ case UW7_TCXONC:
15117+ return sys_ioctl(fd, TCXONC, (long)arg);
15118+
15119+ case UW7_TCFLSH:
15120+ return sys_ioctl(fd, TCFLSH, (long)arg);
15121+
15122+ case UW7_TIOCSWINSZ:
15123+ return sys_ioctl(fd, TIOCSWINSZ, (long)arg);
15124+
15125+ case UW7_TIOCGWINSZ:
15126+ return sys_ioctl(fd, TIOCGWINSZ, (long)arg);
15127+
15128+ case UW7_TCGETS:
15129+ return tioc_tcgets(fd, arg);
15130+
15131+ case UW7_TCSETS:
15132+ return tioc_tcsets(fd, TCSETS, arg);
15133+
15134+ case UW7_TCSETSW:
15135+ return tioc_tcsets(fd, TCSETSW, arg);
15136+
15137+ case UW7_TCSETSF:
15138+ return tioc_tcsets(fd, TCSETSF, arg);
15139+ }
15140+ return -EINVAL;
15141+}
15142diff -Nru linux-2.6.7/abi/uw7/lfs.c linux-2.6.7-abi/abi/uw7/lfs.c
15143--- linux-2.6.7/abi/uw7/lfs.c 1970-01-01 01:00:00.000000000 +0100
15144+++ linux-2.6.7-abi/abi/uw7/lfs.c 2004-07-22 17:44:21.000000000 +0200
15145@@ -0,0 +1,241 @@
15146+/*
15147+ * Copyright (c) 1999 Tigran Aivazian.
15148+ * Copyright (c) 2001 Christoph Hellwig.
15149+ * All rights reserved.
15150+ *
15151+ * This program is free software; you can redistribute it and/or modify
15152+ * it under the terms of the GNU General Public License as published by
15153+ * the Free Software Foundation; either version 2 of the License, or
15154+ * (at your option) any later version.
15155+ *
15156+ * This program is distributed in the hope that it will be useful,
15157+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15158+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15159+ * GNU General Public License for more details.
15160+ *
15161+ * You should have received a copy of the GNU General Public License
15162+ * along with this program; if not, write to the Free Software
15163+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15164+ */
15165+
15166+#ident "%W% %G%"
15167+
15168+/*
15169+ * Support for the UnixWare 7.x LFS (Large File Summit) syscalls.
15170+ */
15171+#include <linux/sched.h>
15172+#include <linux/file.h>
15173+#include <linux/fs.h>
15174+#include <linux/statfs.h>
15175+#include <linux/kernel.h>
15176+#include <linux/unistd.h>
15177+#include <linux/syscalls.h>
15178+#include <linux/namei.h>
15179+#include <asm/uaccess.h>
15180+
15181+#include <abi/uw7/resource.h>
15182+#include <abi/uw7/statvfs.h>
15183+
15184+
15185+/*
15186+ * The UnixWare 7 truncate64/fruncate64 syscalls are the same as in
15187+ * Linux, but we can't easily handle long long syscall parameters for
15188+ * lcall7, thus we have to fake two 32bit arguments instead.
15189+ *
15190+ * XXX: if do_sys_truncate/do_sys_ftruncate in fs/open.c were exported
15191+ * we could get rid of one function call.
15192+ */
15193+int
15194+uw7_truncate64(const char *filename, u_int len, u_int len_hi)
15195+{
15196+ return sys_truncate64(filename, (len | (loff_t)len_hi << 32));
15197+}
15198+
15199+int
15200+uw7_ftruncate64(int fd, u_int len, u_int len_hi)
15201+{
15202+ return sys_ftruncate64(fd, (len | (loff_t)len_hi << 32));
15203+}
15204+
15205+/*
15206+ * The SVR4 statvfs is basically our statfs, but of course only
15207+ * basically ....
15208+ */
15209+static int
15210+cp_uw7_statvfs64(struct super_block *sbp, struct kstatfs *srcp,
15211+ struct uw7_statvfs64 *dstp)
15212+{
15213+ struct uw7_statvfs64 tmp;
15214+
15215+ memset(&tmp, 0, sizeof(struct uw7_statvfs64));
15216+
15217+ tmp.f_bsize = srcp->f_bsize;
15218+ tmp.f_frsize = srcp->f_bsize;
15219+ tmp.f_blocks = srcp->f_blocks;
15220+ tmp.f_bfree = srcp->f_bfree;
15221+ tmp.f_bavail = srcp->f_bavail;
15222+ tmp.f_files = srcp->f_files;
15223+ tmp.f_ffree = srcp->f_ffree;
15224+ tmp.f_favail = srcp->f_ffree;
15225+ tmp.f_fsid = sbp->s_dev;
15226+
15227+ strcpy(tmp.f_basetype, sbp->s_type->name);
15228+
15229+ tmp.f_namemax = srcp->f_namelen;
15230+
15231+ if (copy_to_user(dstp, &tmp, sizeof(struct uw7_statvfs64)))
15232+ return -EFAULT;
15233+ return 0;
15234+}
15235+
15236+int
15237+uw7_statvfs64(char *filename, struct uw7_statvfs64 *stvfsp)
15238+{
15239+ struct nameidata nd;
15240+ int error;
15241+
15242+ error = user_path_walk(filename, &nd);
15243+ if (!error) {
15244+ struct super_block *sbp = nd.dentry->d_inode->i_sb;
15245+ struct kstatfs tmp;
15246+
15247+ error = vfs_statfs(sbp, &tmp);
15248+ if (!error && cp_uw7_statvfs64(sbp, &tmp, stvfsp))
15249+ error = -EFAULT;
15250+ path_release(&nd);
15251+ }
15252+
15253+ return (error);
15254+}
15255+
15256+
15257+int
15258+uw7_fstatvfs64(int fd, struct uw7_statvfs64 *stvfsp)
15259+{
15260+ struct file *fp;
15261+ int error = -EBADF;
15262+
15263+ fp = fget(fd);
15264+ if (fp) {
15265+ struct super_block *sbp = fp->f_dentry->d_inode->i_sb;
15266+ struct kstatfs tmp;
15267+
15268+ error = vfs_statfs(sbp, &tmp);
15269+ if (!error && cp_uw7_statvfs64(sbp, &tmp, stvfsp))
15270+ error = -EFAULT;
15271+ fput(fp);
15272+ }
15273+
15274+ return (error);
15275+}
15276+
15277+static __inline__ int
15278+uw7_rlim64_to_user(int resource, struct uw7_rlim64 *rlimp)
15279+{
15280+ struct rlimit *lxrlim = current->rlim + resource;
15281+ struct uw7_rlim64 rlim;
15282+
15283+ rlim.rlim_cur = lxrlim->rlim_cur;
15284+ rlim.rlim_max = lxrlim->rlim_max;
15285+
15286+ if (copy_to_user(rlimp, &rlim, sizeof(struct uw7_rlim64)))
15287+ return -EFAULT;
15288+ return 0;
15289+}
15290+
15291+int
15292+uw7_getrlimit64(int resource, struct uw7_rlim64 *rlimp)
15293+{
15294+ if (resource > ARRAY_SIZE(uw7_to_linux_rlimit))
15295+ return -EINVAL;
15296+
15297+ return (uw7_rlim64_to_user(uw7_to_linux_rlimit[resource], rlimp));
15298+}
15299+
15300+static __inline__ int
15301+uw7_check_rlimit64(int resource, const struct uw7_rlim64 *rlimp,
15302+ struct rlimit *lxrlimp)
15303+{
15304+ if ((rlimp->rlim_cur > RLIM_INFINITY) ||
15305+ (rlimp->rlim_max > RLIM_INFINITY))
15306+ return -EPERM; /* XXX: actually this is wrong */
15307+
15308+ if (((rlimp->rlim_cur > lxrlimp->rlim_max) ||
15309+ (rlimp->rlim_max > lxrlimp->rlim_max)) &&
15310+ !capable(CAP_SYS_RESOURCE))
15311+ return -EPERM;
15312+
15313+ if (resource == RLIMIT_NOFILE &&
15314+ (rlimp->rlim_cur > NR_OPEN || rlimp->rlim_max > NR_OPEN))
15315+ return -EPERM;
15316+
15317+ return 0;
15318+}
15319+
15320+int
15321+uw7_setrlimit64(int resource, const struct uw7_rlim64 *rlimp)
15322+{
15323+ struct rlimit *lxrlim = current->rlim + resource;
15324+ struct uw7_rlim64 rlim;
15325+
15326+ if (resource > ARRAY_SIZE(uw7_to_linux_rlimit))
15327+ return -EINVAL;
15328+ if (copy_from_user(&rlim, rlimp, sizeof(struct uw7_rlim64)))
15329+ return -EFAULT;
15330+ if (uw7_check_rlimit64(resource, &rlim, lxrlim))
15331+ return -EPERM;
15332+
15333+ /* XXX: this is non-atomic. */
15334+ lxrlim->rlim_cur = rlim.rlim_cur;
15335+ lxrlim->rlim_max = rlim.rlim_max;
15336+
15337+ return 0;
15338+}
15339+
15340+/*
15341+ * 64bit lseek for UnixWare.
15342+ */
15343+int
15344+uw7_lseek64(int fd, u_int off, u_int off_hi, int orig)
15345+{
15346+ loff_t result;
15347+ int err;
15348+
15349+ if (off_hi == (u_int)-1)
15350+ off_hi = 0;
15351+
15352+ err = sys_llseek(fd, (off_t) off_hi, off, &result, orig);
15353+ if (err)
15354+ return err;
15355+ return (long)result; /* XXX: how does UnixWare return large results? */
15356+}
15357+
15358+/*
15359+ * The UnixWare 7 pread64/pwrite64 syscalls are the same as in Linux,
15360+ * but we can't easily handle long long syscall parameters for lcall7,
15361+ * thus we have to fake two 32bit arguments instead.
15362+ */
15363+ssize_t
15364+uw7_pread64(int fd, char *bufp, int count, u_int pos, u_int pos_hi)
15365+{
15366+ return sys_pread64(fd, bufp, count, (pos | (loff_t)pos_hi << 32));
15367+}
15368+
15369+ssize_t
15370+uw7_pwrite64(int fd, char *bufp, int count, u_int pos, u_int pos_hi)
15371+{
15372+ return sys_pwrite64(fd, bufp, count, (pos | (loff_t)pos_hi << 32));
15373+}
15374+
15375+/*
15376+ * Unlike Linux UnixWare 7 does not simply add O_LARGEFILE to flags in
15377+ * libc, so we have to do it.
15378+ * We call sys_open directly as sys_creat is just yet another wrapper.
15379+ */
15380+#define UW7_CREAT64_FLAGS \
15381+ (O_LARGEFILE | O_CREAT | O_WRONLY | O_TRUNC)
15382+int
15383+uw7_creat64(const char *filename, int mode)
15384+{
15385+ return sys_open(filename, UW7_CREAT64_FLAGS, mode);
15386+}
15387diff -Nru linux-2.6.7/abi/uw7/mac.c linux-2.6.7-abi/abi/uw7/mac.c
15388--- linux-2.6.7/abi/uw7/mac.c 1970-01-01 01:00:00.000000000 +0100
15389+++ linux-2.6.7-abi/abi/uw7/mac.c 2004-07-22 17:44:21.000000000 +0200
15390@@ -0,0 +1,41 @@
15391+/*
15392+ * abi/uw7/mac.c - mldmode(2) and friends.
15393+ *
15394+ * This software is under GPL
15395+ */
15396+
15397+#include <linux/sched.h>
15398+#include <linux/errno.h>
15399+
15400+#undef DEBUG
15401+
15402+#ifdef DEBUG
15403+#define DBG(x...) printk(x)
15404+#else
15405+#define DBG(x...)
15406+#endif
15407+
15408+#define UW7_MLD_REAL 1
15409+#define UW7_MLD_VIRT 0
15410+#define UW7_MLD_QUERY 2
15411+
15412+int uw7_mldmode(int mldmode)
15413+{
15414+ switch (mldmode) {
15415+ case UW7_MLD_REAL:
15416+ DBG(KERN_ERR "UW7[%d]: mldmode(MLD_REAL)\n", current->pid);
15417+ break;
15418+
15419+ case UW7_MLD_VIRT:
15420+ DBG(KERN_ERR "UW7[%d]: mldmode(MLD_VIRT)\n", current->pid);
15421+ break;
15422+
15423+ case UW7_MLD_QUERY:
15424+ DBG(KERN_ERR "UW7[%d]: mldmode(MLD_QUERY)\n", current->pid);
15425+ return UW7_MLD_REAL;
15426+
15427+ default:
15428+ return -EINVAL;
15429+ }
15430+ return 0;
15431+}
15432diff -Nru linux-2.6.7/abi/uw7/Makefile linux-2.6.7-abi/abi/uw7/Makefile
15433--- linux-2.6.7/abi/uw7/Makefile 1970-01-01 01:00:00.000000000 +0100
15434+++ linux-2.6.7-abi/abi/uw7/Makefile 2004-07-22 17:44:21.000000000 +0200
15435@@ -0,0 +1,8 @@
15436+
15437+abi-uw7-objs := access.o context.o ioctl.o lfs.o mac.o \
15438+ misc.o mmap.o stat.o sysent.o
15439+
15440+obj-$(CONFIG_ABI_UW7) += abi-uw7.o
15441+
15442+abi-uw7.o: $(abi-uw7-objs)
15443+ $(LD) -r -o $@ $(abi-uw7-objs)
15444diff -Nru linux-2.6.7/abi/uw7/misc.c linux-2.6.7-abi/abi/uw7/misc.c
15445--- linux-2.6.7/abi/uw7/misc.c 1970-01-01 01:00:00.000000000 +0100
15446+++ linux-2.6.7-abi/abi/uw7/misc.c 2004-07-22 17:44:21.000000000 +0200
15447@@ -0,0 +1,66 @@
15448+/*
15449+ * abi/uw7/misc.c - various UW7 system calls.
15450+ *
15451+ * This software is under GPL
15452+ */
15453+
15454+#include <linux/errno.h>
15455+#include <linux/kernel.h>
15456+#include <linux/sched.h>
15457+#include <linux/file.h>
15458+#include <linux/syscalls.h>
15459+#include <asm/uaccess.h>
15460+
15461+
15462+int uw7_sleep(int seconds)
15463+{
15464+ struct timespec t;
15465+ mm_segment_t old_fs;
15466+ int error;
15467+
15468+ t.tv_sec = seconds;
15469+ t.tv_nsec = 0;
15470+ old_fs = get_fs();
15471+ set_fs(get_ds());
15472+ error = sys_nanosleep(&t, NULL);
15473+ set_fs(old_fs);
15474+ return error;
15475+}
15476+
15477+#define UW7_MAXUID 60002
15478+
15479+int uw7_seteuid(int uid)
15480+{
15481+ if (uid < 0 || uid > UW7_MAXUID)
15482+ return -EINVAL;
15483+ return sys_setreuid16(-1, uid);
15484+}
15485+
15486+int uw7_setegid(int gid)
15487+{
15488+ if (gid < 0 || gid > UW7_MAXUID)
15489+ return -EINVAL;
15490+ return sys_setreuid16(-1, gid);
15491+}
15492+
15493+/* can't call sys_pread64() directly because off is 32bit on UW7 */
15494+int uw7_pread(unsigned int fd, char * buf, int count, long off)
15495+{
15496+ return sys_pread64(fd, buf, count, (loff_t)off);
15497+}
15498+
15499+/* can't call sys_pwrite64() directly because off is 32bit on UW7 */
15500+int uw7_pwrite(unsigned int fd, char * buf, int count, long off)
15501+{
15502+ return sys_pwrite64(fd, buf, count, (loff_t)off);
15503+}
15504+
15505+int uw7_stty(int fd, int cmd)
15506+{
15507+ return -EIO;
15508+}
15509+
15510+int uw7_gtty(int fd, int cmd)
15511+{
15512+ return -EIO;
15513+}
15514diff -Nru linux-2.6.7/abi/uw7/mmap.c linux-2.6.7-abi/abi/uw7/mmap.c
15515--- linux-2.6.7/abi/uw7/mmap.c 1970-01-01 01:00:00.000000000 +0100
15516+++ linux-2.6.7-abi/abi/uw7/mmap.c 2004-07-22 17:44:21.000000000 +0200
15517@@ -0,0 +1,71 @@
15518+/*
15519+ * Copyright (c) 1999 Tigran Aivazian.
15520+ * Copyright (c) 2001 Christoph Hellwig.
15521+ * All rights reserved.
15522+ *
15523+ * This program is free software; you can redistribute it and/or modify
15524+ * it under the terms of the GNU General Public License as published by
15525+ * the Free Software Foundation; either version 2 of the License, or
15526+ * (at your option) any later version.
15527+ *
15528+ * This program is distributed in the hope that it will be useful,
15529+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15530+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15531+ * GNU General Public License for more details.
15532+ *
15533+ * You should have received a copy of the GNU General Public License
15534+ * along with this program; if not, write to the Free Software
15535+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15536+ */
15537+
15538+#ident "%W% %G%"
15539+
15540+/*
15541+ * Support for mmap on UnixWare 7.
15542+ */
15543+#include <linux/mm.h>
15544+#include <linux/errno.h>
15545+#include <linux/file.h>
15546+#include <linux/mman.h>
15547+
15548+#include <asm/uaccess.h>
15549+
15550+
15551+/* the other MAP_XXX values are the same as on Linux/i386 */
15552+#define UW7_MAP_ANONYMOUS 0x100
15553+
15554+int
15555+uw7_mmap64(u_long addr, size_t len, int prot, int flags,
15556+ int fd, u_int off, u_int off_hi)
15557+{
15558+ loff_t off64 = (off | ((loff_t)off_hi << 32));
15559+ u_long pgoff = (off64 >> PAGE_SHIFT);
15560+ int error = -EBADF;
15561+ struct file *fp = NULL;
15562+
15563+ if ((off64 + PAGE_ALIGN(len)) < off64)
15564+ return -EINVAL;
15565+
15566+ if (!(off64 & ~PAGE_MASK))
15567+ return -EINVAL;
15568+
15569+ if (flags & UW7_MAP_ANONYMOUS) {
15570+ flags |= MAP_ANONYMOUS;
15571+ flags &= ~UW7_MAP_ANONYMOUS;
15572+ }
15573+
15574+ flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
15575+ if (!(flags & MAP_ANONYMOUS)) {
15576+ if (!(fp = fget(fd)))
15577+ goto out;
15578+ }
15579+
15580+ down_write(&current->mm->mmap_sem);
15581+ error = do_mmap_pgoff(fp, addr, len, prot, flags, pgoff);
15582+ up_write(&current->mm->mmap_sem);
15583+
15584+ if (fp)
15585+ fput(fp);
15586+out:
15587+ return (error);
15588+}
15589diff -Nru linux-2.6.7/abi/uw7/stat.c linux-2.6.7-abi/abi/uw7/stat.c
15590--- linux-2.6.7/abi/uw7/stat.c 1970-01-01 01:00:00.000000000 +0100
15591+++ linux-2.6.7-abi/abi/uw7/stat.c 2004-07-22 17:44:21.000000000 +0200
15592@@ -0,0 +1,145 @@
15593+/*
15594+ * Copyright (c) 2001 Christoph Hellwig.
15595+ * All rights reserved.
15596+ *
15597+ * This program is free software; you can redistribute it and/or modify
15598+ * it under the terms of the GNU General Public License as published by
15599+ * the Free Software Foundation; either version 2 of the License, or
15600+ * (at your option) any later version.
15601+ *
15602+ * This program is distributed in the hope that it will be useful,
15603+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15604+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15605+ * GNU General Public License for more details.
15606+ *
15607+ * You should have received a copy of the GNU General Public License
15608+ * aint32_t with this program; if not, write to the Free Software
15609+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15610+ */
15611+
15612+#ident "%W% %G%"
15613+
15614+/*
15615+ * UnixWare 7.x xstat support.
15616+ */
15617+#include <linux/kernel.h>
15618+#include <linux/fs.h>
15619+#include <linux/sched.h>
15620+#include <linux/file.h>
15621+#include <linux/string.h>
15622+#include <asm/uaccess.h>
15623+
15624+#include <abi/uw7/types.h>
15625+#include <abi/uw7/stat.h>
15626+#include <abi/svr4/stat.h>
15627+
15628+#include <abi/util/trace.h>
15629+#include <abi/util/stat.h>
15630+
15631+
15632+enum {SVR4_stat = 1, SVR4_xstat = 2, UW7_stat64 = 4};
15633+
15634+int
15635+report_uw7_stat64(struct kstat *stp, struct uw7_stat64 *bufp)
15636+{
15637+ struct uw7_stat64 buf;
15638+
15639+ memset(&buf, 0, sizeof(struct uw7_stat64));
15640+
15641+ buf.st_dev = linux_to_uw7_dev_t(stp->dev);
15642+ buf.st_ino = linux_to_uw7_ino_t(stp->ino);
15643+ buf.st_mode = stp->mode;
15644+ buf.st_nlink = stp->nlink;
15645+ buf.st_uid = linux_to_uw7_uid_t(stp->uid);
15646+ buf.st_gid = linux_to_uw7_gid_t(stp->gid);
15647+ buf.st_rdev = linux_to_uw7_dev_t(stp->rdev);
15648+ buf.st_size = stp->size;
15649+
15650+ buf.st_atime.tv_sec = stp->atime.tv_sec;
15651+ buf.st_mtime.tv_sec = stp->mtime.tv_sec;
15652+ buf.st_ctime.tv_sec = stp->ctime.tv_sec;
15653+
15654+ buf.st_blksize = stp->blksize;
15655+ buf.st_blocks = stp->blocks;
15656+
15657+ strcpy(buf.st_fstype, "ext2");
15658+
15659+ if (copy_to_user(bufp, &buf, sizeof(struct uw7_stat64)))
15660+ return -EFAULT;
15661+ return 0;
15662+}
15663+
15664+int
15665+uw7_xstat(int vers, char *filename, void *bufp)
15666+{
15667+ struct kstat st;
15668+ int error;
15669+
15670+ error = vfs_stat(filename, &st);
15671+ if (error)
15672+ return error;
15673+
15674+ switch (vers) {
15675+ case SVR4_stat:
15676+ return report_svr4_stat(&st, bufp);
15677+ case SVR4_xstat:
15678+ return report_svr4_xstat(&st, bufp);
15679+ case UW7_stat64:
15680+ return report_uw7_stat64(&st, bufp);
15681+ }
15682+
15683+#if defined(CONFIG_ABI_TRACE)
15684+ abi_trace(ABI_TRACE_API, "xstat version %d not supported\n", vers);
15685+#endif
15686+ return -EINVAL;
15687+}
15688+
15689+int
15690+uw7_lxstat(int vers, char *filename, void *bufp)
15691+{
15692+ struct kstat st;
15693+ int error;
15694+
15695+ error = vfs_lstat(filename, &st);
15696+ if (error)
15697+ return error;
15698+
15699+ switch (vers) {
15700+ case SVR4_stat:
15701+ return report_svr4_stat(&st, bufp);
15702+ case SVR4_xstat:
15703+ return report_svr4_xstat(&st, bufp);
15704+ case UW7_stat64:
15705+ return report_uw7_stat64(&st, bufp);
15706+ }
15707+
15708+#if defined(CONFIG_ABI_TRACE)
15709+ abi_trace(ABI_TRACE_API, "lxstat version %d not supported\n", vers);
15710+#endif
15711+ return -EINVAL;
15712+}
15713+
15714+int
15715+uw7_fxstat(int vers, int fd, void *bufp)
15716+{
15717+ struct kstat st;
15718+ int error;
15719+
15720+ error = vfs_fstat(fd, &st);
15721+ if (error)
15722+ return error;
15723+
15724+ switch (vers) {
15725+ case SVR4_stat:
15726+ return report_svr4_stat(&st, bufp);
15727+ case SVR4_xstat:
15728+ return report_svr4_xstat(&st, bufp);
15729+ case UW7_stat64:
15730+ return report_uw7_stat64(&st, bufp);
15731+ }
15732+
15733+#if defined(CONFIG_ABI_TRACE)
15734+ abi_trace(ABI_TRACE_API, "fxstat version %d not supported\n", vers);
15735+#endif
15736+ return -EINVAL;
15737+}
15738diff -Nru linux-2.6.7/abi/uw7/sysent.c linux-2.6.7-abi/abi/uw7/sysent.c
15739--- linux-2.6.7/abi/uw7/sysent.c 1970-01-01 01:00:00.000000000 +0100
15740+++ linux-2.6.7-abi/abi/uw7/sysent.c 2004-07-22 17:44:21.000000000 +0200
15741@@ -0,0 +1,478 @@
15742+/*
15743+ * Copyright (c) 1999 Tigran Aivazian.
15744+ * Copyright (c) 2000, 2001 Christoph Hellwig.
15745+ * All rights reserved.
15746+ *
15747+ * This program is free software; you can redistribute it and/or modify
15748+ * it under the terms of the GNU General Public License as published by
15749+ * the Free Software Foundation; either version 2 of the License, or
15750+ * (at your option) any later version.
15751+ *
15752+ * This program is distributed in the hope that it will be useful,
15753+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15754+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15755+ * GNU General Public License for more details.
15756+ *
15757+ * You should have received a copy of the GNU General Public License
15758+ * along with this program; if not, write to the Free Software
15759+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15760+ */
15761+
15762+#ident "%W% %G%"
15763+
15764+/*
15765+ * UnixWare 7/OpenUnix 8 personality switch.
15766+ */
15767+
15768+#include <linux/config.h>
15769+#include <linux/module.h>
15770+#include <linux/init.h>
15771+#include <linux/kernel.h>
15772+#include <linux/personality.h>
15773+#include <linux/syscalls.h>
15774+#include <linux/socket.h>
15775+#include <linux/net.h>
15776+#include <asm/uaccess.h>
15777+
15778+#include <abi/signal.h>
15779+
15780+#include <abi/svr4/sysent.h>
15781+#include <abi/uw7/sysent.h>
15782+
15783+#include <abi/util/errno.h>
15784+#include <abi/util/sysent.h>
15785+#include <abi/util/socket.h>
15786+
15787+MODULE_DESCRIPTION("UnixWare7/OpenUnix8 personality");
15788+MODULE_AUTHOR("Tigran Aivazian, Christoph Hellwig");
15789+MODULE_LICENSE("GPL");
15790+
15791+
15792+/*
15793+ * We could remove some of the long identity mapped runs but at the
15794+ * expense of extra comparisons for each mapping at run time...
15795+ */
15796+static u_char uw7_err_table[] = {
15797+/* 0 - 9 */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
15798+/* 10 - 19 */ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
15799+/* 20 - 29 */ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
15800+/* 30 - 39 */ 30, 31, 32, 33, 34, 45, 78, 46, 89, 93,
15801+/* 40 - 49 */ 90, 90, 35, 36, 37, 38, 39, 40, 41, 42,
15802+/* 50 - 59 */ 43, 44, 50, 51, 52, 53, 54, 55, 56, 57,
15803+/* 60 - 69 */ 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
15804+/* 70 - 79 */ 70, 71, 74, 76, 77, 79, 80, 81, 82, 83,
15805+/* 80 - 89 */ 84, 85, 86, 87, 88, 91, 92, 94, 95, 96,
15806+/* 90 - 99 */ 97, 98, 99, 120, 121, 122, 123, 124, 125, 126,
15807+/* 100 - 109 */ 127, 128, 129, 130, 131, 132, 133, 134, 143, 144,
15808+/* 110 - 119 */ 145, 146, 147, 148, 149, 150, 22, 135, 137, 138,
15809+/* 120 - 122 */ 139, 140, 28
15810+};
15811+
15812+/*
15813+ * Map Linux RESTART* values (512,513,514) to EINTR
15814+ */
15815+static u_char lnx_err_table[] = {
15816+/* 512 - 514 */ EINTR, EINTR, EINTR
15817+};
15818+
15819+struct map_segment uw7_err_map[] = {
15820+ { 0, 0+sizeof(uw7_err_table)-1, uw7_err_table },
15821+ { 512, 512+sizeof(lnx_err_table)-1, lnx_err_table },
15822+ { -1 }
15823+};
15824+
15825+static long linux_to_uw7_signals[NSIGNALS+1] = {
15826+/* 0 - 3 */ 0, IBCS_SIGHUP, IBCS_SIGINT, IBCS_SIGQUIT,
15827+/* 4 - 7 */ IBCS_SIGILL, IBCS_SIGTRAP, IBCS_SIGABRT, -1,
15828+/* 8 - 11 */ IBCS_SIGFPE, IBCS_SIGKILL, IBCS_SIGUSR1, IBCS_SIGSEGV,
15829+/* 12 - 15 */ IBCS_SIGUSR2, IBCS_SIGPIPE, IBCS_SIGALRM, IBCS_SIGTERM,
15830+/* 16 - 19 */ IBCS_SIGSEGV, IBCS_SIGCHLD, IBCS_SIGCONT, IBCS_SIGSTOP,
15831+/* 20 - 23 */ IBCS_SIGTSTP, IBCS_SIGTTIN, IBCS_SIGTTOU, IBCS_SIGURG,
15832+/* 24 - 27 */ IBCS_SIGGXCPU, IBCS_SIGGXFSZ, IBCS_SIGVTALRM, IBCS_SIGPROF,
15833+/* 28 - 31 */ IBCS_SIGWINCH, IBCS_SIGIO, IBCS_SIGPWR, -1,
15834+/* 32 */ -1
15835+};
15836+
15837+static long uw7_to_linux_signals[NSIGNALS+1] = {
15838+/* 0 - 3 */ 0, SIGHUP, SIGINT, SIGQUIT,
15839+/* 4 - 7 */ SIGILL, SIGTRAP, SIGIOT, SIGUNUSED,
15840+/* 8 - 11 */ SIGFPE, SIGKILL, SIGUNUSED, SIGSEGV,
15841+/* 12 - 15 */ SIGUNUSED, SIGPIPE, SIGALRM, SIGTERM,
15842+/* 16 - 19 */ SIGUSR1, SIGUSR2, SIGCHLD, SIGPWR,
15843+/* 20 - 23 */ SIGWINCH, SIGURG, SIGPOLL, SIGSTOP,
15844+/* 24 - 27 */ SIGTSTP, SIGCONT, SIGTTIN, SIGTTOU,
15845+/* 28 - 31 */ SIGVTALRM, SIGPROF, SIGXCPU, SIGXFSZ,
15846+/* 32 */ -1
15847+};
15848+
15849+static char uw7_socktype[] = {
15850+ SOCK_STREAM,
15851+ SOCK_DGRAM,
15852+ 0,
15853+ SOCK_RAW,
15854+ SOCK_RDM,
15855+ SOCK_SEQPACKET
15856+};
15857+
15858+static struct map_segment uw7_socktype_map[] = {
15859+ { 1, 6, uw7_socktype },
15860+ { -1 }
15861+};
15862+
15863+static struct map_segment uw7_sockopt_map[] = {
15864+ { 0x0001, 0x0001, (char *)SO_DEBUG },
15865+ { 0x0002, 0x0002, (char *)__SO_ACCEPTCON },
15866+ { 0x0004, 0x0004, (char *)SO_REUSEADDR },
15867+ { 0x0008, 0x0008, (char *)SO_KEEPALIVE },
15868+ { 0x0010, 0x0010, (char *)SO_DONTROUTE },
15869+ { 0x0020, 0x0020, (char *)SO_BROADCAST },
15870+ { 0x0040, 0x0040, (char *)SO_USELOOPBACK },
15871+ { 0x0080, 0x0080, (char *)SO_LINGER },
15872+ { 0x0100, 0x0100, (char *)SO_OOBINLINE },
15873+ { 0x0200, 0x0200, (char *)SO_ORDREL },
15874+ { 0x0400, 0x0400, (char *)SO_IMASOCKET },
15875+ { 0x1001, 0x1001, (char *)SO_SNDBUF },
15876+ { 0x1002, 0x1002, (char *)SO_RCVBUF },
15877+ { 0x1003, 0x1003, (char *)SO_SNDLOWAT },
15878+ { 0x1004, 0x1004, (char *)SO_RCVLOWAT },
15879+ { 0x1005, 0x1005, (char *)SO_SNDTIMEO },
15880+ { 0x1006, 0x1006, (char *)SO_RCVTIMEO },
15881+ { 0x1007, 0x1007, (char *)SO_ERROR },
15882+ { 0x1008, 0x1008, (char *)SO_TYPE },
15883+ { 0x1009, 0x1009, (char *)SO_PROTOTYPE },
15884+ { -1 }
15885+};
15886+
15887+static struct map_segment uw7_af_map[] = {
15888+ { 0, 2, NULL },
15889+ { -1 }
15890+};
15891+
15892+
15893+static struct sysent uw7_syscall_table[] = {
15894+/* 0 */ { abi_syscall, Fast, "syscall", "" },
15895+/* 2 */ { sys_exit, 1, "exit", "d" },
15896+/* 3 */ { abi_fork, Spl, "fork", "" },
15897+/* 4 */ { abi_read, 3, "read", "dpd" },
15898+/* 5 */ { sys_write, 3, "write", "dpd" },
15899+/* 6 */ { svr4_open, 3, "open", "soo" },
15900+/* 7 */ { sys_close, 1, "close", "d" },
15901+/* 8 */ { abi_wait, Spl, "wait", "xxx" },
15902+/* 9 */ { sys_creat, 2, "creat", "so" },
15903+/* 10 */ { sys_link, 2, "link", "ss" },
15904+/* 11 */ { sys_unlink, 1, "unlink", "s" },
15905+/* 12 */ { abi_exec, Spl, "exec", "sxx" },
15906+/* 13 */ { sys_chdir, 1, "chdir", "s" },
15907+/* 14 */ { abi_time, 0, "time", "" },
15908+/* 15 */ { svr4_mknod, 3, "mknod", "soo" },
15909+/* 16 */ { sys_chmod, 2, "chmod", "so" },
15910+/* 17 */ { sys_chown, 3, "chown", "sdd" },
15911+/* 18 */ { abi_brk, 1, "brk/break", "x" },
15912+/* 19 */ { svr4_stat, 2, "stat", "sp" },
15913+/* 21 */ { sys_lseek, 3, "seek/lseek", "ddd" },
15914+/* 20 */ { abi_getpid, Spl, "getpid", "" },
15915+/* 21 */ { 0, Ukn, "mount", "" },
15916+/* 22 */ { sys_umount, 1, "umount", "s" },
15917+/* 23 */ { sys_setuid, 1, "setuid", "d" },
15918+/* 24 */ { abi_getuid, Spl, "getuid", "" },
15919+/* 25 */ { sys_stime, 1, "stime", "d" },
15920+/* 26 */ { 0, 4, "ptrace", "" },
15921+/* 27 */ { sys_alarm, 1, "alarm", "d" },
15922+/* 28 */ { svr4_fstat, 2, "fstat", "dp" },
15923+/* 21 */ { sys_pause, 0, "pause", "" },
15924+/* 30 */ { sys_utime, 2, "utime", "xx" },
15925+/* 31 */ { uw7_stty, 2, "stty", "dd" },
15926+/* 32 */ { uw7_gtty, 2, "gtty", "dd" },
15927+/* 33 */ { uw7_access, 2, "access", "so" },
15928+/* 34 */ { sys_nice, 1, "nice", "d" },
15929+/* 35 */ { svr4_statfs, 4, "statfs", "spdd" },
15930+/* 36 */ { sys_sync, 0, "sync", "" },
15931+/* 37 */ { abi_kill, 2, "kill", "dd" },
15932+/* 38 */ { svr4_fstatfs, 4, "fstatfs", "dpdd" },
15933+/* 39 */ { abi_procids, Spl, "procids", "d" },
15934+/* 40 */ { 0, Ukn, "cxenix", "" },
15935+/* 41 */ { sys_dup, 1, "dup", "d" },
15936+/* 42 */ { abi_pipe, Spl, "pipe", "" },
15937+/* 43 */ { sys_times, 1, "times", "p" },
15938+/* 44 */ { 0, 4, "", "" },
15939+/* 45 */ { 0, Ukn, "plock", "" },
15940+/* 46 */ { sys_setgid, 1, "setgid", "d" },
15941+/* 47 */ { abi_getgid, Spl, "getgid", "" },
15942+/* 48 */ { abi_sigfunc, Fast, "sigfunc", "xxx" },
15943+/* 49 */ { svr4_msgsys, Spl, "msgsys", "dxddd" },
15944+/* 50 */ { svr4_sysi86, 3, "sysi86/sys3b", "d" },
15945+/* 51 */ { sys_acct, 1, "acct/sysacct", "x" },
15946+/* 52 */ { svr4_shmsys, Fast, "shmsys", "ddxo" },
15947+/* 53 */ { svr4_semsys, Spl, "semsys", "dddx" },
15948+/* 54 */ { uw7_ioctl, Spl, "ioctl", "dxx" },
15949+/* 55 */ { 0, 3, "uadmin", "xxx" },
15950+/* 56 */ { 0, Ukn, "unimpl/exch", "" },
15951+/* 57 */ { v7_utsname, 1, "utsys", "x" },
15952+/* 58 */ { sys_fsync, 1, "fsync", "d" },
15953+/* 59 */ { abi_exec, Spl, "execv", "spp" },
15954+/* 60 */ { sys_umask, 1, "umask", "o" },
15955+/* 61 */ { sys_chroot, 1, "chroot", "s" },
15956+/* 62 */ { svr4_fcntl, 3, "fcntl", "dxx" },
15957+/* 63 */ { svr4_ulimit, 2, "ulimit", "xx" },
15958+
15959+/*
15960+ * 64-69 were reserved for the UNIX PC, and are now use for NUMA calls.
15961+ */
15962+/* 64 */ { 0, Ukn, "cg_ids", "" },
15963+/* 65 */ { 0, Ukn, "cg_processors","" },
15964+/* 66 */ { 0, Ukn, "cg_info", "" },
15965+/* 67 */ { 0, Ukn, "cg_bind", "" },
15966+/* 68 */ { 0, Ukn, "cg_current", "" },
15967+/* 69 */ { 0, Ukn, "cg_memloc", "" },
15968+/* 70 */ { 0, Ukn, "unimpl/advfs", "" },
15969+/* 71 */ { 0, Ukn, "unimpl/unadvfs","" },
15970+/* 72 */ { 0, Ukn, "unimpl/rmount","" },
15971+/* 73 */ { 0, Ukn, "unimpl/rumount","" },
15972+/* 74 */ { 0, Ukn, "unimpl/rfstart","" },
15973+/* 75 */ { 0, Ukn, "unimpl 75", "" },
15974+/* 76 */ { 0, Ukn, "unimpl/rdebug","" },
15975+/* 77 */ { 0, Ukn, "unimpl/rfstop","" },
15976+/* 78 */ { 0, Ukn, "rfsys", "" },
15977+/* 89 */ { sys_rmdir, 1, "rmdir", "s" },
15978+/* 80 */ { sys_mkdir, 2, "mkdir", "so" },
15979+/* 81 */ { svr4_getdents, 3, "getdents", "dxd" },
15980+/* 82 */ { 0, Ukn, "unimpl/libattach","" },
15981+/* 83 */ { 0, Ukn, "unimpl/libdetach","" },
15982+/* 84 */ { svr4_sysfs, 3, "sysfs", "dxx" },
15983+/* 85 */ { svr4_getmsg, Spl, "getmsg", "dxxx" },
15984+/* 86 */ { svr4_putmsg, Spl, "putmsg", "dxxd" },
15985+/* 87 */ { sys_poll, 3, "poll", "xdd" },
15986+/* 88 */ { svr4_lstat, 2, "lstat", "sp" },
15987+/* 89 */ { sys_symlink, 2, "symlink", "ss" },
15988+/* 90 */ { sys_readlink, 3, "readlink", "spd" },
15989+/* 91 */ { sys_setgroups, 2, "setgroups", "dp" },
15990+/* 92 */ { sys_getgroups, 2, "getgroups", "dp" },
15991+/* 93 */ { sys_fchmod, 2, "fchmod", "do" },
15992+/* 94 */ { sys_fchown, 3, "fchown", "ddd" },
15993+/* 95 */ { abi_sigprocmask, 3, "sigprocmask", "dxx" },
15994+/* 96 */ { abi_sigsuspend, Spl, "sigsuspend", "x" },
15995+/* 97 */ { uw7_sigaltstack, 2, "sigaltstack", "xx" },
15996+/* 98 */ { abi_sigaction, 3, "sigaction", "dxx" },
15997+/* 99 */ { svr4_sigpending, 2, "sigpending", "dp" },
15998+/* 100 */ { uw7_context, Spl, "ucontext", "" },
15999+/* 101 */ { 0, Ukn, "evsys", "" },
16000+/* 102 */ { 0, Ukn, "evtrapret", "" },
16001+/* 103 */ { svr4_statvfs, 2, "statvfs", "sp" },
16002+/* 104 */ { svr4_fstatvfs, 2, "fstatvfs", "dp" },
16003+/* 105 */ { 0, Ukn, "reserved 105", "" },
16004+/* 106 */ { 0, Ukn, "nfssys", "" },
16005+/* 107 */ { svr4_waitid, 4, "waitid", "ddxd" },
16006+/* 108 */ { 0, 3, "sigsendsys", "ddd" },
16007+/* 109 */ { svr4_hrtsys, Spl, "hrtsys", "xxx" },
16008+/* 110 */ { 0, 3, "acancel", "dxd" },
16009+/* 111 */ { 0, Ukn, "async", "" },
16010+/* 112 */ { 0, Ukn, "priocntlsys", "" },
16011+/* 113 */ { svr4_pathconf, 2, "pathconf", "sd" },
16012+/* 114 */ { 0, 3, "mincore", "xdx" },
16013+/* 115 */ { svr4_mmap, 6, "mmap", "xxxxdx"},
16014+/* 116 */ { sys_mprotect, 3, "mprotect", "xdx" },
16015+/* 117 */ { sys_munmap, 2, "munmap", "xd" },
16016+/* 118 */ { svr4_fpathconf, 2, "fpathconf", "dd" },
16017+/* 119 */ { abi_fork, Spl, "vfork", "" },
16018+/* 120 */ { sys_fchdir, 1, "fchdir", "d" },
16019+/* 121 */ { sys_readv, 3, "readv", "dxd" },
16020+/* 122 */ { sys_writev, 3, "writev", "dxd" },
16021+/* 123 */ { uw7_xstat, 3, "xstat", "dsx" },
16022+/* 124 */ { uw7_lxstat, 3, "lxstat", "dsx" },
16023+/* 125 */ { uw7_fxstat, 3, "fxstat", "ddx" },
16024+/* 126 */ { svr4_xmknod, 4, "xmknod", "dsox" },
16025+/* 127 */ { 0, Spl, "syslocal", "d" },
16026+/* 128 */ { svr4_getrlimit, 2, "setrlimit", "dx" },
16027+/* 129 */ { svr4_setrlimit, 2, "getrlimit", "dx" },
16028+/* 130 */ { sys_lchown, 3, "lchown", "sdd" },
16029+/* 131 */ { 0, Ukn, "memcntl", "" },
16030+#if defined(CONFIG_ABI_XTI)
16031+/* 132 */ { svr4_getpmsg, 5, "getpmsg", "dxxxx" },
16032+/* 133 */ { svr4_putpmsg, 5, "putpmsg", "dxxdd" },
16033+#else
16034+/* 132 */ { 0, 5, "getpmsg", "dxxxx" },
16035+/* 133 */ { 0, 5, "putpmsg", "dxxdd" },
16036+#endif
16037+/* 134 */ { sys_rename, 2, "rename", "ss" },
16038+/* 135 */ { abi_utsname, 1, "uname", "x" },
16039+/* 136 */ { uw7_setegid, 1, "setegid", "d" },
16040+/* 137 */ { svr4_sysconfig, 1, "sysconfig", "d" },
16041+/* 138 */ { 0, Ukn, "adjtime", "" },
16042+/* 139 */ { svr4_sysinfo, 3, "systeminfo", "dsd" },
16043+/* 140 */ { socksys_syscall, 1, "socksys_syscall","x" },
16044+/* 141 */ { uw7_seteuid, 1, "seteuid", "d" },
16045+/* 142 */ { 0, Ukn, "unimpl 142", "" },
16046+/* 143 */ { 0, Ukn, "keyctl", "" },
16047+/* 144 */ { 0, 2, "secsys", "dx" },
16048+/* 145 */ { 0, 4, "filepriv", "sdxd" },
16049+/* 146 */ { 0, 3, "procpriv", "dxd" },
16050+/* 147 */ { 0, 3, "devstat", "sdx" },
16051+/* 148 */ { 0, 5, "aclipc", "ddddx" },
16052+/* 149 */ { 0, 3, "fdevstat", "ddx" },
16053+/* 150 */ { 0, 3, "flvlfile", "ddx" },
16054+/* 151 */ { 0, 3, "lvlfile", "sdx" },
16055+/* 152 */ { 0, Ukn, "sendv", "" },
16056+/* 153 */ { 0, 2, "lvlequal", "xx" },
16057+/* 154 */ { 0, 2, "lvlproc", "dx" },
16058+/* 155 */ { 0, Ukn, "unimpl 155", "" },
16059+/* 156 */ { 0, 4, "lvlipc", "dddx" },
16060+/* 157 */ { 0, 4, "acl", "sddx" },
16061+/* 158 */ { 0, Ukn, "auditevt", "" },
16062+/* 159 */ { 0, Ukn, "auditctl", "" },
16063+/* 160 */ { 0, Ukn, "auditdmp", "" },
16064+/* 161 */ { 0, Ukn, "auditlog", "" },
16065+/* 162 */ { 0, Ukn, "auditbuf", "" },
16066+/* 163 */ { 0, 2, "lvldom", "xx" },
16067+/* 164 */ { 0, Ukn, "lvlvfs", "" },
16068+/* 165 */ { 0, 2, "mkmld", "so" },
16069+/* 166 */ { uw7_mldmode, 1, "mldmode", "d" },
16070+/* 167 */ { 0, 2, "secadvise", "xx" },
16071+/* 168 */ { 0, Ukn, "online", "" },
16072+/* 169 */ { sys_setitimer, 3, "setitimer", "dxx" },
16073+/* 170 */ { sys_getitimer, 2, "getitimer", "dx" },
16074+/* 171 */ { sys_gettimeofday, 2, "gettimeofday", "xx" },
16075+/* 172 */ { sys_settimeofday, 2, "settimeofday", "xx" },
16076+/* 173 */ { 0, Ukn, "lwpcreate", "" },
16077+/* 174 */ { 0, Ukn, "lwpexit", "" },
16078+/* 175 */ { 0, Ukn, "lwpwait", "" },
16079+/* 176 */ { 0, Ukn, "lwpself", "" },
16080+/* 177 */ { 0, Ukn, "lwpinfo", "" },
16081+/* 178 */ { 0, Ukn, "lwpprivate", "" },
16082+/* 179 */ { 0, Ukn, "processorbind","" },
16083+/* 180 */ { 0, Ukn, "processorexbind","" },
16084+/* 181 */ { 0, Ukn, "unimpl 181", "" },
16085+/* 182 */ { 0, Ukn, "sendv64", "" },
16086+/* 183 */ { 0, Ukn, "prepblock", "" },
16087+/* 184 */ { 0, Ukn, "block", "" },
16088+/* 185 */ { 0, Ukn, "rdblock", "" },
16089+/* 186 */ { 0, Ukn, "unblock", "" },
16090+/* 187 */ { 0, Ukn, "cancelblock", "" },
16091+/* 188 */ { 0, Ukn, "unimpl 188", "" },
16092+/* 189 */ { uw7_pread, 4, "pread", "dsdd" },
16093+/* 190 */ { uw7_pwrite, 4, "pwrite", "dsdd" },
16094+/* 191 */ { sys_truncate, 2, "truncate", "sd" },
16095+/* 192 */ { sys_ftruncate, 2, "ftruncate", "dd" },
16096+/* 193 */ { 0, Ukn, "lwpkill", "" },
16097+/* 194 */ { 0, Ukn, "sigwait", "" },
16098+/* 195 */ { abi_fork, Spl, "fork1", "" },
16099+/* 196 */ { abi_fork, Spl, "forkall", "" },
16100+
16101+/*
16102+ * 197-202 are for loadable kernel module support.
16103+ */
16104+/* 197 */ { 0, Ukn, "modload", "" },
16105+/* 198 */ { 0, Ukn, "moduload", "" },
16106+/* 199 */ { 0, Ukn, "modpath", "" },
16107+/* 200 */ { 0, Ukn, "modstat", "" },
16108+/* 201 */ { 0, Ukn, "modadm", "" },
16109+/* 202 */ { 0, Ukn, "getksym", "" },
16110+
16111+/* 203 */ { 0, Ukn, "lwpsuspend", "" },
16112+/* 204 */ { 0, Ukn, "lwpcontinue", "" },
16113+/* 205 */ { 0, Ukn, "priocntllst", "" },
16114+/* 206 */ { uw7_sleep, 1, "sleep", "d" },
16115+
16116+/*
16117+ * 207-209 are for post/wait synchronisation.
16118+ */
16119+/* 207 */ { 0, Ukn, "lwp_sema_wait","" },
16120+/* 208 */ { 0, Ukn, "lwp_sema_post","" },
16121+/* 209 */ { 0, Ukn, "lwp_sema_trywait","" },
16122+
16123+/* 210 */ { 0, Ukn, "reserved 210", "" },
16124+/* 211 */ { 0, Ukn, "unused 211", "" },
16125+/* 212 */ { 0, Ukn, "unused 212", "" },
16126+/* 213 */ { 0, Ukn, "unused 213", "" },
16127+/* 214 */ { 0, Ukn, "unused 214", "" },
16128+/* 215 */ { 0, Ukn, "unused 215", "" },
16129+
16130+/*
16131+ * 216-226 are for LFS (Large File Summit) support
16132+ */
16133+/* 216 */ { uw7_fstatvfs64, 2, "fstatvfs64", "dp" },
16134+/* 217 */ { uw7_statvfs64, 2, "statvfs64", "sp" },
16135+/* 218 */ { uw7_ftruncate64, 3, "ftruncate64", "sdd" },
16136+/* 219 */ { uw7_truncate64, 3, "truncate64", "ddd" },
16137+/* 220 */ { uw7_getrlimit64, 2, "getrlimit64", "dp" },
16138+/* 221 */ { uw7_setrlimit64, 2, "setrlimit64", "dp" },
16139+/* 222 */ { uw7_lseek64, 4, "lseek64", "dddd" },
16140+/* 223 */ { uw7_mmap64, 7, "mmap64", "xxxxdxx"},
16141+/* 224 */ { uw7_pread64, 5, "pread64", "dsddd" },
16142+/* 225 */ { uw7_pwrite64, 5, "pwrite64", "dsddd" },
16143+/* 226 */ { uw7_creat64, 2, "creat64", "so" },
16144+
16145+/* 227 */ { 0, Ukn, "dshmsys", "" },
16146+/* 228 */ { 0, Ukn, "invlpg", "" },
16147+
16148+/*
16149+ * 229-234 are used for SSI clustering (Nonstop cluster)
16150+ */
16151+/* 229 */ { 0, Ukn, "rfork1", "" },
16152+/* 230 */ { 0, Ukn, "rforkall", "" },
16153+/* 231 */ { 0, Ukn, "rexecve", "" },
16154+/* 232 */ { 0, Ukn, "migrate", "" },
16155+/* 233 */ { 0, Ukn, "kill3", "" },
16156+/* 234 */ { 0, Ukn, "ssisys", "" },
16157+
16158+/*
16159+ * 235-248 are for kernel-based sockets (Yeah, SVR5 finally got sockets)
16160+ */
16161+/* 235 */ { 0, Ukn, "xaccept", "" },
16162+/* 236 */ { 0, Ukn, "xbind", "" },
16163+/* 237 */ { 0, Ukn, "xbindresvport","" },
16164+/* 238 */ { 0, Ukn, "xconnect", "" },
16165+/* 239 */ { 0, Ukn, "xgetsockaddr", "" },
16166+/* 240 */ { 0, Ukn, "xgetsockopt", "" },
16167+/* 241 */ { 0, Ukn, "xlisten", "" },
16168+/* 242 */ { 0, Ukn, "xrecvmsg", "" },
16169+/* 243 */ { 0, Ukn, "xsendmsg", "" },
16170+/* 244 */ { 0, Ukn, "xsetsockaddr", "" },
16171+/* 245 */ { 0, Ukn, "xsetsockopt", "" },
16172+/* 246 */ { 0, Ukn, "xshutdown", "" },
16173+/* 247 */ { 0, Ukn, "xsocket", "" },
16174+/* 248 */ { 0, Ukn, "xsocketpair", "" },
16175+
16176+/* 249 */ { 0, Ukn, "unused 249", "" },
16177+/* 250 */ { 0, Ukn, "unused 250", "" },
16178+};
16179+
16180+
16181+static void
16182+uw7_lcall7(int segment, struct pt_regs *regs)
16183+{
16184+ int sysno = regs->eax & 0xff;
16185+
16186+ if (sysno >= ARRAY_SIZE(uw7_syscall_table))
16187+ set_error(regs, iABI_errors(-EINVAL));
16188+ else
16189+ lcall7_dispatch(regs, &uw7_syscall_table[sysno], 1);
16190+}
16191+
16192+static struct exec_domain uw7_exec_domain = {
16193+ name: "UnixWare 7",
16194+ handler: uw7_lcall7,
16195+ pers_low: 14 /* PER_UW7 */,
16196+ pers_high: 14 /* PER_UW7 */,
16197+ signal_map: uw7_to_linux_signals,
16198+ signal_invmap: linux_to_uw7_signals,
16199+ err_map: uw7_err_map,
16200+ socktype_map: uw7_socktype_map,
16201+ sockopt_map: uw7_sockopt_map,
16202+ af_map: uw7_af_map,
16203+ module: THIS_MODULE
16204+};
16205+
16206+static int __init
16207+init_uw7(void)
16208+{
16209+ return register_exec_domain(&uw7_exec_domain);
16210+}
16211+
16212+static void __exit
16213+cleanup_uw7(void)
16214+{
16215+ unregister_exec_domain(&uw7_exec_domain);
16216+}
16217+
16218+module_init(init_uw7);
16219+module_exit(cleanup_uw7);
16220diff -Nru linux-2.6.7/abi/wyse/Makefile linux-2.6.7-abi/abi/wyse/Makefile
16221--- linux-2.6.7/abi/wyse/Makefile 1970-01-01 01:00:00.000000000 +0100
16222+++ linux-2.6.7-abi/abi/wyse/Makefile 2004-07-22 17:44:21.000000000 +0200
16223@@ -0,0 +1,7 @@
16224+
16225+abi-wyse-objs := sysent.o ptrace.o socket.o
16226+
16227+obj-$(CONFIG_ABI_WYSE) += abi-wyse.o
16228+
16229+abi-wyse.o: $(abi-wyse-objs)
16230+ $(LD) -r -o $@ $(abi-wyse-objs)
16231diff -Nru linux-2.6.7/abi/wyse/ptrace.c linux-2.6.7-abi/abi/wyse/ptrace.c
16232--- linux-2.6.7/abi/wyse/ptrace.c 1970-01-01 01:00:00.000000000 +0100
16233+++ linux-2.6.7-abi/abi/wyse/ptrace.c 2004-07-22 17:44:21.000000000 +0200
16234@@ -0,0 +1,113 @@
16235+/*
16236+ * ptrace.c - Wyse V/386 ptrace(2) support.
16237+ *
16238+ * Copyright (c) 1995 Mike Jagdis (jaggy@purplet.demon.co.uk)
16239+ */
16240+
16241+#ident "%W% %G%"
16242+
16243+/*
16244+ * This file is nearly identical to abi/sco/ptrace.c, please keep it in sync.
16245+ */
16246+#include <linux/module.h>
16247+#include <linux/errno.h>
16248+#include <linux/sched.h>
16249+#include <linux/ptrace.h>
16250+#include <linux/kernel.h>
16251+#include <linux/mm.h>
16252+#include <linux/personality.h>
16253+#include <linux/user.h>
16254+#define __KERNEL_SYSCALLS__
16255+#include <linux/unistd.h>
16256+
16257+#include <asm/uaccess.h>
16258+
16259+#include <abi/signal.h>
16260+#include <abi/util/trace.h>
16261+
16262+
16263+#define NREGS 19
16264+#define U(X) ((unsigned long)&((struct user *)0)->X)
16265+
16266+
16267+static unsigned long wysev386_to_linux_reg[NREGS] = {
16268+ U(regs.es), U(regs.ds), U(regs.edi), U(regs.esi),
16269+ U(regs.ebp), U(regs.esp),
16270+ U(regs.ebx), U(regs.edx), U(regs.ecx), U(regs.eax),
16271+ U(signal /* Trap */),
16272+ U(reserved /* ERR */),
16273+ U(regs.eip), U(regs.cs),
16274+ U(regs.eflags),
16275+ U(regs.esp /* UESP */),
16276+ U(regs.ss),
16277+ U(regs.fs), U(regs.gs)
16278+};
16279+
16280+static const char *regnam[] = {
16281+ "EBX", "ECX", "EDX", "ESI", "EDI", "EBP", "EAX",
16282+ "DS", "ES", "FS", "GS", "ORIG_EAX", "EIP", "CS",
16283+ "EFL", "UESP", "SS"
16284+};
16285+
16286+
16287+int
16288+wyse_ptrace(int req, int pid, u_long addr, u_long data)
16289+{
16290+ u_long res;
16291+
16292+ /*
16293+ * Slight variations between iBCS and Linux codes.
16294+ */
16295+ if (req == PTRACE_ATTACH)
16296+ req = 10;
16297+ else if (req == PTRACE_DETACH)
16298+ req = 11;
16299+
16300+ if (req == 3 || req == 6) {
16301+ /* get offset of u_ar0 */
16302+ if (addr == 0x1292)
16303+ return 0x4000;
16304+
16305+ /* remap access to the registers. */
16306+ if ((addr & 0xff00) == 0x4000) { /* Registers */
16307+ addr = (addr & 0xff) >> 2;
16308+ if (addr > NREGS)
16309+ return -EIO;
16310+ addr = wysev386_to_linux_reg[addr];
16311+ if (addr == -1)
16312+ return -EIO;
16313+ }
16314+ }
16315+
16316+ if (req == 7 && data > 0) {
16317+ if (data > NSIGNALS)
16318+ return -EIO;
16319+ data = current_thread_info()->exec_domain->signal_map[data];
16320+ }
16321+
16322+ if (req == 1 || req == 2 || req == 3) {
16323+ mm_segment_t old_fs = get_fs();
16324+ int error;
16325+
16326+ set_fs(get_ds());
16327+ error = sys_ptrace(req, pid, addr, (long)&res);
16328+ set_fs(old_fs);
16329+
16330+ if (error)
16331+ return (error);
16332+ }
16333+
16334+#if defined(CONFIG_ABI_TRACE)
16335+ if (req == 3 || req == 6) {
16336+ abi_trace(ABI_TRACE_API, "%ld [%s] = 0x%08lx\n",
16337+ addr >> 2, (addr >> 2) < ARRAY_SIZE(regnam) ?
16338+ regnam[addr >> 2] : "???",
16339+ req == 3 ? res : data);
16340+ }
16341+#endif
16342+
16343+ if (req == 1 || req == 2 || req == 3)
16344+ return (res);
16345+
16346+ return sys_ptrace(req, pid, addr, data);
16347+}
16348diff -Nru linux-2.6.7/abi/wyse/socket.c linux-2.6.7-abi/abi/wyse/socket.c
16349--- linux-2.6.7/abi/wyse/socket.c 1970-01-01 01:00:00.000000000 +0100
16350+++ linux-2.6.7-abi/abi/wyse/socket.c 2004-07-22 17:44:21.000000000 +0200
16351@@ -0,0 +1,307 @@
16352+/*
16353+ * Copyright (c) 1994,1996 Mike Jagdis.
16354+ * Copyright (c) 2001 Christoph Hellwig.
16355+ * All rights reserved.
16356+ *
16357+ * This program is free software; you can redistribute it and/or modify
16358+ * it under the terms of the GNU General Public License as published by
16359+ * the Free Software Foundation; either version 2 of the License, or
16360+ * (at your option) any later version.
16361+ *
16362+ * This program is distributed in the hope that it will be useful,
16363+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16364+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16365+ * GNU General Public License for more details.
16366+ *
16367+ * You should have received a copy of the GNU General Public License
16368+ * along with this program; if not, write to the Free Software
16369+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16370+ *
16371+ */
16372+
16373+#ident "%W% %G%"
16374+
16375+/*
16376+ * BSD-style socket support for Wyse/V386.
16377+ */
16378+#include <linux/net.h>
16379+#include <linux/personality.h>
16380+#include <linux/syscalls.h>
16381+#include <linux/utsname.h>
16382+#include <linux/signal.h>
16383+#include <linux/wait.h>
16384+#include <linux/socket.h>
16385+#include <linux/net.h>
16386+#include <asm/uaccess.h>
16387+
16388+#include <abi/util/map.h>
16389+#include <abi/util/socket.h>
16390+#include <abi/wyse/sysent.h>
16391+
16392+
16393+int wyse_gethostname(char *name, int len)
16394+{
16395+ int error;
16396+ char *p;
16397+
16398+ down_read(&uts_sem);
16399+ error = verify_area(VERIFY_WRITE, name, len);
16400+ if (!error) {
16401+ --len;
16402+ for (p = system_utsname.nodename; *p && len; p++,len--) {
16403+ __put_user(*p, name);
16404+ name++;
16405+ }
16406+ __put_user('\0', name);
16407+ }
16408+ up_read(&uts_sem);
16409+ return error;
16410+}
16411+
16412+int wyse_getdomainname(char *name, int len)
16413+{
16414+ int error;
16415+ char *p;
16416+
16417+ down_read(&uts_sem);
16418+ error = verify_area(VERIFY_WRITE, name, len);
16419+ if (!error) {
16420+ --len;
16421+ for (p = system_utsname.domainname; *p && len; p++,len--) {
16422+ __put_user(*p, name);
16423+ name++;
16424+ }
16425+ __put_user('\0', name);
16426+ }
16427+ up_read(&uts_sem);
16428+ return error;
16429+}
16430+
16431+int wyse_wait3(int *loc)
16432+{
16433+ pid_t pid;
16434+ int res;
16435+
16436+ pid = sys_wait4(-1, loc, WNOHANG, 0);
16437+ if (!loc)
16438+ return pid;
16439+
16440+ get_user(res, (unsigned long *)loc);
16441+
16442+ if ((res & 0xff) == 0x7f) {
16443+ int sig = (res >> 8) & 0xff;
16444+
16445+ sig = current_thread_info()->exec_domain->signal_map[sig];
16446+ res = (res & (~0xff00)) | (sig << 8);
16447+ put_user(res, (unsigned long *)loc);
16448+ } else if (res && res == (res & 0xff)) {
16449+ res = current_thread_info()->exec_domain->signal_map[res & 0x7f];
16450+ put_user(res, (unsigned long *)loc);
16451+ }
16452+
16453+ return pid;
16454+}
16455+
16456+int wyse_socket(int family, int type, int protocol)
16457+{
16458+ family = map_value(current_thread_info()->exec_domain->af_map, family, 0);
16459+ type = map_value(current_thread_info()->exec_domain->socktype_map, family, 0);
16460+
16461+ return sys_socket(family, type, protocol);
16462+}
16463+
16464+int wyse_setsockopt(int fd, int level, int optname, char *optval, int optlen)
16465+{
16466+ switch (level) {
16467+ case 0: /* IPPROTO_IP aka SOL_IP */
16468+ if (--optname == 0)
16469+ optname = 4;
16470+ if (optname > 4) {
16471+ optname += 24;
16472+ if (optname <= 33)
16473+ optname--;
16474+ if (optname < 32 || optname > 36)
16475+ return -EINVAL;
16476+ break;
16477+ }
16478+ case 0xffff:
16479+ level = SOL_SOCKET;
16480+ optname = map_value(current_thread_info()->exec_domain->sockopt_map, optname, 0);
16481+ switch (optname) {
16482+ case SO_LINGER:
16483+ /*
16484+ * SO_LINGER takes a struct linger as the argument
16485+ * but some code uses an int and expects to get
16486+ * away without an error. Sigh...
16487+ */
16488+ if (optlen == sizeof(int))
16489+ return 0;
16490+ break;
16491+ /*
16492+ * The following are not currently implemented under Linux
16493+ * so we must fake them in reasonable ways.
16494+ * (Only SO_PROTOTYPE is documented in SCO's man page).
16495+ */
16496+ case SO_PROTOTYPE:
16497+ case SO_ORDREL:
16498+ case SO_SNDTIMEO:
16499+ case SO_RCVTIMEO:
16500+ return -ENOPROTOOPT;
16501+
16502+ case SO_USELOOPBACK:
16503+ case SO_SNDLOWAT:
16504+ case SO_RCVLOWAT:
16505+ return 0;
16506+
16507+ /*
16508+ * The following are not currenty implemented under Linux
16509+ * and probably aren't settable anyway.
16510+ */
16511+ case SO_IMASOCKET:
16512+ return -ENOPROTOOPT;
16513+ default:
16514+ break;
16515+ }
16516+ default:
16517+ /*
16518+ * XXX We assume everything else uses the same level and
16519+ * XXX option numbers. This is true for IPPROTO_TCP(/SOL_TCP)
16520+ * XXX and TCP_NDELAY but is known to be incorrect for other
16521+ * XXX potential options :-(.
16522+ */
16523+ break;
16524+ }
16525+
16526+ return sys_setsockopt(fd, level, optname, optval, optlen);
16527+}
16528+
16529+int wyse_getsockopt(int fd, int level, int optname, char *optval, int *optlen)
16530+{
16531+ unsigned int len;
16532+ int val;
16533+
16534+ if (get_user(len,optlen))
16535+ return -EFAULT;
16536+ if (len < 0)
16537+ return -EINVAL;
16538+
16539+ switch (level) {
16540+ case 0: /* IPPROTO_IP aka SOL_IP */
16541+ if (--optname == 0)
16542+ optname = 4;
16543+ if (optname > 4) {
16544+ optname += 24;
16545+ if (optname <= 33)
16546+ optname--;
16547+ if (optname < 32 || optname > 36)
16548+ return -EINVAL;
16549+ break;
16550+ }
16551+ case 0xffff:
16552+ level = SOL_SOCKET;
16553+ optname = map_value(current_thread_info()->exec_domain->sockopt_map, optname, 0);
16554+ switch (optname) {
16555+ case SO_LINGER:
16556+ /*
16557+ * SO_LINGER takes a struct linger as the argument
16558+ * but some code uses an int and expects to get
16559+ * away without an error. Sigh...
16560+ */
16561+ if (len != sizeof(int))
16562+ goto native;
16563+
16564+ val = 0;
16565+ break;
16566+ /*
16567+ * The following are not currently implemented under Linux
16568+ * so we must fake them in reasonable ways.
16569+ * (Only SO_PROTOTYPE is documented in SCO's man page).
16570+ */
16571+ case SO_PROTOTYPE:
16572+ val = 0;
16573+ break;
16574+
16575+ case SO_ORDREL:
16576+ case SO_SNDTIMEO:
16577+ case SO_RCVTIMEO:
16578+ return -ENOPROTOOPT;
16579+
16580+ case SO_USELOOPBACK:
16581+ case SO_SNDLOWAT:
16582+ case SO_RCVLOWAT:
16583+ return 0;
16584+
16585+ /*
16586+ * The following are not currenty implemented under Linux
16587+ * and probably aren't settable anyway.
16588+ */
16589+ case SO_IMASOCKET:
16590+ val = 1;
16591+ break;
16592+ default:
16593+ goto native;
16594+ }
16595+
16596+ if (len > sizeof(int))
16597+ len = sizeof(int);
16598+ if (copy_to_user(optval, &val, len))
16599+ return -EFAULT;
16600+ if (put_user(len, optlen))
16601+ return -EFAULT;
16602+ return 0;
16603+
16604+ default:
16605+ /*
16606+ * XXX We assume everything else uses the same level and
16607+ * XXX option numbers. This is true for IPPROTO_TCP(/SOL_TCP)
16608+ * XXX and TCP_NDELAY but is known to be incorrect for other
16609+ * XXX potential options :-(.
16610+ */
16611+ break;
16612+ }
16613+
16614+native:
16615+ return sys_getsockopt(fd, level, optname, optval, optlen);
16616+}
16617+
16618+int wyse_recvfrom(int fd, void *buff, size_t size, unsigned flags,
16619+ struct sockaddr *addr, int *addr_len)
16620+{
16621+ int error;
16622+
16623+ error = sys_recvfrom(fd, buff, size, flags, addr, addr_len);
16624+ if (error == -EAGAIN)
16625+ error = -EWOULDBLOCK;
16626+ return error;
16627+}
16628+
16629+int wyse_recv(int fd, void *buff, size_t size, unsigned flags)
16630+{
16631+ int error;
16632+
16633+ error = sys_recvfrom(fd, buff, size, flags, NULL, NULL);
16634+ if (error == -EAGAIN)
16635+ error = -EWOULDBLOCK;
16636+ return error;
16637+}
16638+
16639+int wyse_sendto(int fd, void *buff, size_t len, unsigned flags,
16640+ struct sockaddr *addr, int addr_len)
16641+{
16642+ int error;
16643+
16644+ error = sys_sendto(fd, buff, len, flags, addr, addr_len);
16645+ if (error == -EAGAIN)
16646+ error = -EWOULDBLOCK;
16647+ return error;
16648+}
16649+
16650+int wyse_send(int fd, void *buff, size_t len, unsigned flags)
16651+{
16652+ int error;
16653+
16654+ error = sys_sendto(fd, buff, len, flags, NULL, 0);
16655+ if (error == -EAGAIN)
16656+ error = -EWOULDBLOCK;
16657+ return error;
16658+}
16659diff -Nru linux-2.6.7/abi/wyse/sysent.c linux-2.6.7-abi/abi/wyse/sysent.c
16660--- linux-2.6.7/abi/wyse/sysent.c 1970-01-01 01:00:00.000000000 +0100
16661+++ linux-2.6.7-abi/abi/wyse/sysent.c 2004-07-22 17:44:21.000000000 +0200
16662@@ -0,0 +1,394 @@
16663+/*
16664+ * Copyright (c) 2001 Christoph Hellwig.
16665+ * All rights reserved.
16666+ *
16667+ * This program is free software; you can redistribute it and/or modify
16668+ * it under the terms of the GNU General Public License as published by
16669+ * the Free Software Foundation; either version 2 of the License, or
16670+ * (at your option) any later version.
16671+ *
16672+ * This program is distributed in the hope that it will be useful,
16673+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16674+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16675+ * GNU General Public License for more details.
16676+ *
16677+ * You should have received a copy of the GNU General Public License
16678+ * along with this program; if not, write to the Free Software
16679+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16680+ *
16681+ */
16682+
16683+#ident "%W% %G%"
16684+
16685+/*
16686+ * Wyse/V386 personality switch.
16687+ */
16688+#include <linux/module.h>
16689+#include <linux/init.h>
16690+#include <linux/kernel.h>
16691+#include <linux/personality.h>
16692+#include <linux/sched.h>
16693+#include <linux/syscalls.h>
16694+#include <linux/socket.h>
16695+#include <linux/net.h>
16696+#include <asm/uaccess.h>
16697+
16698+#include <abi/svr4/sysent.h>
16699+#include <abi/wyse/sysent.h>
16700+
16701+#include <abi/signal.h>
16702+
16703+#include <abi/util/errno.h>
16704+#include <abi/util/sysent.h>
16705+#include <abi/util/socket.h>
16706+
16707+
16708+MODULE_DESCRIPTION("Wyse/V386 personality");
16709+MODULE_AUTHOR("Christoph Hellwig, partially taken from iBCS");
16710+MODULE_LICENSE("GPL");
16711+
16712+
16713+/*
16714+ * local functions
16715+ */
16716+static void wyse_class_nfs(struct pt_regs *);
16717+static void wyse_class_tcp(struct pt_regs *);
16718+
16719+
16720+/*
16721+ * local variables
16722+ */
16723+static u_char wyse_err_table[] = {
16724+ /* 0 - 9 */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
16725+ /* 10 - 19 */ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
16726+ /* 20 - 29 */ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
16727+ /* 30 - 39 */ 30, 31, 32, 33, 34, 45, 78, 46, 228, 46,
16728+ /* 40 - 49 */ 22, 231, 227, 200, 37, 38, 39, 40, 41, 42,
16729+ /* 50 - 59 */ 43, 44, 50, 51, 52, 53, 54, 55, 56, 57,
16730+ /* 60 - 69 */ 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
16731+ /* 70 - 79 */ 70, 71, 74, 76, 77, 22, 80, 81, 82, 83,
16732+ /* 80 - 89 */ 84, 85, 86, 87, 22, 4, 22, 233, 203, 204,
16733+ /* 90 - 99 */ 205, 206, 207, 208, 209, 210, 211, 212, 213, 214,
16734+ /* 100 - 109 */ 215, 216, 217, 218, 219, 220, 221, 222, 223, 224,
16735+ /* 110 - 119 */ 225, 226, 229, 230, 202, 201, 237, 135, 137, 138,
16736+ /* 120 - 122 */ 139, 140, 234
16737+};
16738+
16739+/*
16740+ * Map Linux RESTART* values (512,513,514) to EINTR
16741+ */
16742+static u_char lnx_err_table[] = {
16743+ /* 512 - 514 */ EINTR, EINTR, EINTR
16744+};
16745+
16746+static struct map_segment wyse_err_map[] = {
16747+ { 0, 0 + sizeof(wyse_err_table) - 1, wyse_err_table },
16748+ { 512, 512 + sizeof(lnx_err_table) - 1, lnx_err_table },
16749+ { -1 }
16750+};
16751+
16752+static long linux_to_wyse_signals[NSIGNALS+1] = {
16753+/* 0 - 3 */ 0, IBCS_SIGHUP, IBCS_SIGINT, IBCS_SIGQUIT,
16754+/* 4 - 7 */ IBCS_SIGILL, IBCS_SIGTRAP, IBCS_SIGABRT, -1,
16755+/* 8 - 11 */ IBCS_SIGFPE, IBCS_SIGKILL, IBCS_SIGUSR1, IBCS_SIGSEGV,
16756+/* 12 - 15 */ IBCS_SIGUSR2, IBCS_SIGPIPE, IBCS_SIGALRM, IBCS_SIGTERM,
16757+/* 16 - 19 */ IBCS_SIGSEGV, IBCS_SIGCHLD, IBCS_SIGCONT, IBCS_SIGSTOP,
16758+/* 20 - 23 */ IBCS_SIGTSTP, IBCS_SIGTTIN, IBCS_SIGTTOU, IBCS_SIGURG,
16759+/* 24 - 27 */ IBCS_SIGGXCPU, IBCS_SIGGXFSZ, IBCS_SIGVTALRM, IBCS_SIGPROF,
16760+/* 28 - 31 */ IBCS_SIGWINCH, IBCS_SIGIO, IBCS_SIGPWR, -1,
16761+/* 32 */ -1
16762+};
16763+
16764+static long wyse_to_linux_signals[NSIGNALS+1] = {
16765+/* 0 - 3 */ 0, SIGHUP, SIGINT, SIGQUIT,
16766+/* 4 - 7 */ SIGILL, SIGTRAP, SIGIOT, SIGUNUSED,
16767+/* 8 - 11 */ SIGFPE, SIGKILL, SIGUNUSED, SIGSEGV,
16768+/* 12 - 15 */ SIGUNUSED, SIGPIPE, SIGALRM, SIGTERM,
16769+/* 16 - 19 */ SIGUSR1, SIGUSR2, SIGCHLD, SIGPWR,
16770+/* 20 - 23 */ SIGWINCH, SIGURG, SIGPOLL, SIGSTOP,
16771+/* 24 - 27 */ SIGTSTP, SIGCONT, SIGTTIN, SIGTTOU,
16772+/* 28 - 31 */ SIGVTALRM, SIGPROF, SIGXCPU, SIGXFSZ,
16773+/* 32 */ -1
16774+};
16775+
16776+static char wyse_socktype[] = {
16777+ SOCK_STREAM,
16778+ SOCK_DGRAM,
16779+ 0,
16780+ SOCK_RAW,
16781+ SOCK_RDM,
16782+ SOCK_SEQPACKET
16783+};
16784+
16785+static struct map_segment wyse_socktype_map[] = {
16786+ { 1, 6, wyse_socktype },
16787+ { -1 }
16788+};
16789+
16790+static struct map_segment wyse_sockopt_map[] = {
16791+ { 0x0001, 0x0001, (char *)SO_DEBUG },
16792+ { 0x0002, 0x0002, (char *)__SO_ACCEPTCON },
16793+ { 0x0004, 0x0004, (char *)SO_REUSEADDR },
16794+ { 0x0008, 0x0008, (char *)SO_KEEPALIVE },
16795+ { 0x0010, 0x0010, (char *)SO_DONTROUTE },
16796+ { 0x0020, 0x0020, (char *)SO_BROADCAST },
16797+ { 0x0040, 0x0040, (char *)SO_USELOOPBACK },
16798+ { 0x0080, 0x0080, (char *)SO_LINGER },
16799+ { 0x0100, 0x0100, (char *)SO_OOBINLINE },
16800+ { 0x0200, 0x0200, (char *)SO_ORDREL },
16801+ { 0x0400, 0x0400, (char *)SO_IMASOCKET },
16802+ { 0x1001, 0x1001, (char *)SO_SNDBUF },
16803+ { 0x1002, 0x1002, (char *)SO_RCVBUF },
16804+ { 0x1003, 0x1003, (char *)SO_SNDLOWAT },
16805+ { 0x1004, 0x1004, (char *)SO_RCVLOWAT },
16806+ { 0x1005, 0x1005, (char *)SO_SNDTIMEO },
16807+ { 0x1006, 0x1006, (char *)SO_RCVTIMEO },
16808+ { 0x1007, 0x1007, (char *)SO_ERROR },
16809+ { 0x1008, 0x1008, (char *)SO_TYPE },
16810+ { 0x1009, 0x1009, (char *)SO_PROTOTYPE },
16811+ { -1 }
16812+};
16813+
16814+static struct map_segment wyse_af_map[] = {
16815+ { 0, 2, NULL },
16816+ { -1 }
16817+};
16818+
16819+
16820+static struct sysent wyse_nfscall_table[] = {
16821+/* 0 */ { 0, Ukn, "nfs_svc", "" },
16822+/* 1 */ { 0, Ukn, "async_daemon", "" },
16823+/* 2 */ { 0, Ukn, "nfs_getfh", "" },
16824+/* 3 */ { 0, Ukn, "nfsmount", "" },
16825+};
16826+
16827+static struct sysent wyse_tcpcall_table[] = {
16828+/* 0 */ { sys_select, 5, "select", "dxxxx" },
16829+/* 1 */ { wyse_socket, 3, "socket", "ddd" },
16830+/* 2 */ { sys_connect, 3, "connect", "dxd" },
16831+/* 3 */ { sys_accept, 3, "accept", "dxx" },
16832+/* 4 */ { wyse_send, 4, "send", "dxdd" },
16833+/* 5 */ { wyse_recv, 4, "recv", "dxdd" },
16834+/* 6 */ { sys_bind, 3, "bind", "dxd" },
16835+/* 7 */ { wyse_setsockopt, 5, "setsockopt", "dddxx" },
16836+/* 8 */ { sys_listen, 2, "listen", "dd" },
16837+/* 9 */ { 0, 3, "recvmsg", "dxd" },
16838+/* 10 */ { 0, 3, "sendmsg", "dxd" },
16839+/* 11 */ { wyse_getsockopt, 5, "getsockopt", "dddxx" },
16840+/* 12 */ { wyse_recvfrom, 6, "recvfrom", "dxddxd"},
16841+/* 13 */ { wyse_sendto, 6, "sendto", "dxddxd"},
16842+/* 14 */ { sys_shutdown, 2, "shutdown", "dd" },
16843+/* 15 */ { sys_socketpair, 4, "socketpair", "dddx" },
16844+/* 16 */ { 0, Ukn, "trace", "" },
16845+/* 17 */ { sys_getpeername, 3, "getpeername", "dxx" },
16846+/* 18 */ { sys_getsockname, Spl, "getsockname", "dxx" },
16847+/* 19 */ { wyse_wait3, 1, "wait3", "x" },
16848+};
16849+
16850+
16851+static struct sysent wyse_syscall_table[] = {
16852+/* 0 */ { abi_syscall, Fast, "syscall", "" },
16853+/* 1 */ { sys_exit, 1, "exit", "d" },
16854+/* 2 */ { abi_fork, Spl, "fork", "" },
16855+/* 3 */ { abi_read, 3, "read", "dpd" },
16856+/* 4 */ { sys_write, 3, "write", "dpd" },
16857+/* 5 */ { svr4_open, 3, "open", "soo" },
16858+/* 6 */ { sys_close, 1, "close", "d" },
16859+/* 7 */ { abi_wait, Spl, "wait", "xxx" },
16860+/* 8 */ { sys_creat, 2, "creat", "so" },
16861+/* 9 */ { sys_link, 2, "link", "ss" },
16862+/* 10 */ { sys_unlink, 1, "unlink", "s" },
16863+/* 11 */ { abi_exec, Spl, "exec", "sxx" },
16864+/* 12 */ { sys_chdir, 1, "chdir", "s" },
16865+/* 13 */ { abi_time, 0, "time", "" },
16866+/* 14 */ { svr4_mknod, 3, "mknod", "soo" },
16867+/* 15 */ { sys_chmod, 2, "chmod", "so" },
16868+/* 16 */ { sys_chown, 3, "chown", "sdd" },
16869+/* 17 */ { abi_brk, 1, "brk/break", "x" },
16870+/* 18 */ { svr4_stat, 2, "stat", "sp" },
16871+/* 19 */ { sys_lseek, 3, "seek/lseek", "ddd" },
16872+/* 20 */ { abi_getpid, Spl, "getpid", "" },
16873+/* 21 */ { 0, Ukn, "mount", "" },
16874+/* 22 */ { sys_umount, 1, "umount", "s" },
16875+/* 23 */ { sys_setuid, 1, "setuid", "d" },
16876+/* 24 */ { abi_getuid, Spl, "getuid", "" },
16877+/* 25 */ { sys_stime, 1, "stime", "d" },
16878+/* 26 */ { wyse_ptrace, 4, "ptrace", "xdxx" },
16879+/* 27 */ { sys_alarm, 1, "alarm", "d" },
16880+/* 28 */ { svr4_fstat, 2, "fstat", "dp" },
16881+/* 29 */ { sys_pause, 0, "pause", "" },
16882+/* 30 */ { sys_utime, 2, "utime", "xx" },
16883+/* 31 */ { 0, Ukn, "stty", "" }, /* 31 */
16884+/* 32 */ { 0, Ukn, "gtty", "" },
16885+/* 33 */ { sys_access, 2, "access", "so" },
16886+/* 34 */ { sys_nice, 1, "nice", "d" },
16887+/* 35 */ { svr4_statfs, 4, "statfs", "spdd" },
16888+/* 36 */ { sys_sync, 0, "sync", "" },
16889+/* 37 */ { abi_kill, 2, "kill", "dd" },
16890+/* 38 */ { svr4_fstatfs, 4, "fstatfs", "dpdd" },
16891+/* 39 */ { abi_procids, Spl, "procids", "d" },
16892+/* 40 */ { 0, Ukn, "cxenix", "" },
16893+/* 41 */ { sys_dup, 1, "dup", "d" },
16894+/* 42 */ { abi_pipe, Spl, "pipe", "" },
16895+/* 43 */ { sys_times, 1, "times", "p" },
16896+/* 44 */ { 0, 4, "prof", "xxxx" },
16897+/* 45 */ { 0, Ukn, "lock/plock", "" },
16898+/* 46 */ { sys_setgid, 1, "setgid", "d" },
16899+/* 47 */ { abi_getgid, Spl, "getgid", "" },
16900+/* 48 */ { abi_sigfunc, Fast, "sigfunc", "xxx" },
16901+/* 49 */ { svr4_msgsys, Spl, "msgsys", "dxddd" },
16902+/* 50 */ { svr4_sysi86, 3, "sysi86/sys3b", "d" },
16903+/* 51 */ { sys_acct, 1, "acct/sysacct", "x" },
16904+/* 52 */ { svr4_shmsys, Fast, "shmsys", "ddxo" },
16905+/* 53 */ { svr4_semsys, Spl, "semsys", "dddx" },
16906+/* 54 */ { svr4_ioctl, Spl, "ioctl", "dxx" },
16907+/* 55 */ { 0, 3, "uadmin", "xxx" },
16908+/* 56 */ { 0, Ukn, "?", "" },
16909+/* 57 */ { v7_utsname, 1, "utsys", "x" },
16910+/* 58 */ { sys_fsync, 1, "fsync", "d" },
16911+/* 59 */ { abi_exec, Spl, "execv", "spp" },
16912+/* 60 */ { sys_umask, 1, "umask", "o" },
16913+/* 61 */ { sys_chroot, 1, "chroot", "s" },
16914+/* 62 */ { svr4_fcntl, 3, "fcntl", "dxx" },
16915+/* 63 */ { svr4_ulimit, 2, "ulimit", "xx" },
16916+/* 64 */ { 0, Ukn, "?", "" },
16917+/* 65 */ { 0, Ukn, "?", "" },
16918+/* 66 */ { 0, Ukn, "?", "" },
16919+/* 67 */ { 0, Ukn, "?", "" },
16920+/* 68 */ { 0, Ukn, "?", "" },
16921+/* 69 */ { 0, Ukn, "?", "" },
16922+/* 70 */ { 0, Ukn, "advfs", "" },
16923+/* 71 */ { 0, Ukn, "unadvfs", "" },
16924+/* 72 */ { 0, Ukn, "rmount", "" },
16925+/* 73 */ { 0, Ukn, "rumount", "" },
16926+/* 74 */ { 0, Ukn, "rfstart", "" },
16927+/* 75 */ { 0, Ukn, "?", "" },
16928+/* 76 */ { 0, Ukn, "rdebug", "" },
16929+/* 77 */ { 0, Ukn, "rfstop", "" },
16930+/* 78 */ { 0, Ukn, "rfsys", "" },
16931+/* 79 */ { sys_rmdir, 1, "rmdir", "s" },
16932+/* 80 */ { abi_mkdir, 2, "mkdir", "so" },
16933+/* 81 */ { svr4_getdents, 3, "getdents", "dxd" },
16934+/* 82 */ { 0, Ukn, "libattach", "" },
16935+/* 83 */ { 0, Ukn, "libdetach", "" },
16936+/* 84 */ { svr4_sysfs, 3, "sysfs", "dxx" },
16937+/* 85 */ { svr4_getmsg, Spl, "getmsg", "dxxx" },
16938+/* 86 */ { svr4_putmsg, Spl, "putmsg", "dxxd" },
16939+/* 87 */ { sys_poll, 3, "poll", "xdd" },
16940+/* 88 */ { 0, Ukn, "nosys88", "" },
16941+/* 89 */ { 0, Ukn, "nosys89", "" },
16942+/* 90 */ { 0, Ukn, "nosys90", "" },
16943+/* 91 */ { 0, Ukn, "nosys91", "" },
16944+/* 92 */ { 0, Ukn, "nosys92", "" },
16945+/* 93 */ { 0, Ukn, "nosys93", "" },
16946+/* 94 */ { 0, Ukn, "nosys94", "" },
16947+/* 95 */ { 0, Ukn, "nosys95", "" },
16948+/* 96 */ { 0, Ukn, "nosys96", "" },
16949+/* 97 */ { 0, Ukn, "nosys97", "" },
16950+/* 98 */ { 0, Ukn, "nosys98", "" },
16951+/* 99 */ { 0, Ukn, "nosys99", "" },
16952+/* 100 */ { 0, Ukn, "nosys100", "" },
16953+/* 101 */ { 0, Ukn, "nosys101", "" },
16954+/* 102 */ { 0, Ukn, "nosys102", "" },
16955+/* 103 */ { 0, Ukn, "nosys103", "" },
16956+/* 104 */ { 0, Ukn, "nosys104", "" },
16957+/* 105 */ { 0, Ukn, "nosys105", "" },
16958+/* 106 */ { 0, Ukn, "nosys106", "" },
16959+/* 107 */ { 0, Ukn, "nosys107", "" },
16960+/* 108 */ { 0, Ukn, "nosys108", "" },
16961+/* 109 */ { 0, Ukn, "nosys109", "" },
16962+/* 110 */ { 0, Ukn, "nosys110", "" },
16963+/* 111 */ { 0, Ukn, "nosys111", "" },
16964+/* 112 */ { 0, Ukn, "nosys112", "" },
16965+/* 113 */ { 0, Ukn, "nosys113", "" },
16966+/* 114 */ { 0, Ukn, "nosys114", "" },
16967+/* 115 */ { 0, Ukn, "nosys115", "" },
16968+/* 116 */ { 0, Ukn, "nosys116", "" },
16969+/* 117 */ { 0, Ukn, "nosys117", "" },
16970+/* 118 */ { 0, Ukn, "nosys118", "" },
16971+/* 119 */ { 0, Ukn, "nosys119", "" },
16972+/* 120 */ { 0, Ukn, "nosys120", "" },
16973+/* 121 */ { 0, Ukn, "nosys121", "" },
16974+/* 122 */ { 0, Ukn, "nosys122", "" },
16975+/* 123 */ { 0, Ukn, "nosys123", "" },
16976+/* 124 */ { 0, Ukn, "nosys124", "" },
16977+/* 125 */ { 0, Ukn, "nosys125", "" },
16978+/* 126 */ { 0, Ukn, "nosys126", "" },
16979+/* 127 */ { 0, Ukn, "nosys127", "" },
16980+/* 128 */ { svr4_lstat, 2, "lstat", "sp" },
16981+/* 129 */ { sys_readlink, 3, "readlink", "spd" },
16982+/* 130 */ { sys_symlink, 2, "symlink", "ss" },
16983+/* 131 */ { wyse_class_tcp, Fast, "", "" },
16984+/* 132 */ { wyse_class_nfs, Fast, "", "" },
16985+/* 133 */ { wyse_gethostname, 2, "gethostname", "xd" },
16986+/* 134 */ { sys_sethostname, 2, "sethostname", "sd" },
16987+/* 135 */ { wyse_getdomainname, 2, "getdomainname","xd" },
16988+/* 136 */ { sys_setdomainname, 2, "setdomainname","sd" },
16989+/* 137 */ { 0, Ukn, "?", "" },
16990+/* 138 */ { sys_setreuid, 2, "setreuid", "dd" },
16991+/* 139 */ { sys_setregid, 2, "setregid", "dd" },
16992+};
16993+
16994+static void
16995+wyse_class_nfs(struct pt_regs *regs)
16996+{
16997+
16998+ int sysno = regs->eax >> 8;
16999+
17000+ if (sysno >= ARRAY_SIZE(wyse_nfscall_table))
17001+ set_error(regs, iABI_errors(-EINVAL));
17002+ else
17003+ lcall7_dispatch(regs, &wyse_nfscall_table[sysno], 1);
17004+}
17005+
17006+static void
17007+wyse_class_tcp(struct pt_regs *regs)
17008+{
17009+ int sysno = regs->eax >> 8;
17010+
17011+ if (sysno >= ARRAY_SIZE(wyse_tcpcall_table))
17012+ set_error(regs, iABI_errors(-EINVAL));
17013+ else
17014+ lcall7_dispatch(regs, &wyse_tcpcall_table[sysno], 1);
17015+}
17016+
17017+static void
17018+wyse_lcall7(int segment, struct pt_regs *regs)
17019+{
17020+ int sysno = regs->eax & 0xff;
17021+
17022+ if (sysno >= ARRAY_SIZE(wyse_syscall_table))
17023+ set_error(regs, iABI_errors(-EINVAL));
17024+ else
17025+ lcall7_dispatch(regs, &wyse_syscall_table[sysno], 1);
17026+}
17027+
17028+static struct exec_domain wyse_exec_domain = {
17029+ name: "Wyse/386",
17030+ handler: wyse_lcall7,
17031+ pers_low: 4 /* PER_WYSEV386 */,
17032+ pers_high: 4 /* PER_WYSEV386 */,
17033+ signal_map: wyse_to_linux_signals,
17034+ signal_invmap: linux_to_wyse_signals,
17035+ err_map: wyse_err_map,
17036+ socktype_map: wyse_socktype_map,
17037+ sockopt_map: wyse_sockopt_map,
17038+ af_map: wyse_af_map,
17039+ module: THIS_MODULE
17040+};
17041+
17042+
17043+static int __init
17044+wyse_module_init(void)
17045+{
17046+ return register_exec_domain(&wyse_exec_domain);
17047+}
17048+
17049+static void __exit
17050+wyse_module_exit(void)
17051+{
17052+ unregister_exec_domain(&wyse_exec_domain);
17053+}
17054+
17055+module_init(wyse_module_init);
17056+module_exit(wyse_module_exit);
17057diff -Nru linux-2.6.7/abi/wyse/syslocal.c linux-2.6.7-abi/abi/wyse/syslocal.c
17058--- linux-2.6.7/abi/wyse/syslocal.c 1970-01-01 01:00:00.000000000 +0100
17059+++ linux-2.6.7-abi/abi/wyse/syslocal.c 2004-07-22 17:44:21.000000000 +0200
17060@@ -0,0 +1,55 @@
17061+/*
17062+ * Copyright (C) 1994 Mike Jagdis (jaggy@purplet.demon.co.uk)
17063+ */
17064+
17065+#ident "%W% %G%"
17066+
17067+#include <linux/module.h>
17068+#include <linux/errno.h>
17069+#include <asm/uaccess.h>
17070+
17071+#include <abi/util/trace.h>
17072+
17073+
17074+/*
17075+ * The syslocal() call is used for machine specific functions. For
17076+ * instance on a Wyse 9000 it give information and control of the
17077+ * available processors.
17078+ */
17079+#define SL_ONLINE 0 /* Turn processor online */
17080+#define SL_OFFLINE 1 /* Turn processor offline */
17081+#define SL_QUERY 2 /* Query processor status */
17082+#define SL_NENG 3 /* Return No. of processors configured */
17083+#define SL_AFFINITY 4 /* processor binding */
17084+#define SL_CMC_STAT 7 /* gather CMC performance counters info */
17085+#define SL_KACC 8 /* make kernel data readable by user */
17086+#define SL_MACHTYPE 9 /* return machine type (MP/AT) */
17087+#define SL_BOOTNAME 10 /* return name of booted kernel */
17088+#define SL_BOOTDEV 11 /* return type of booted device */
17089+#define SL_UQUERY 12 /* query user status */
17090+
17091+#define SL_MACH_MP 0
17092+#define SL_MACH_AT 1
17093+#define SL_MACH_EISA 2
17094+#define SL_MACH_EMP 3
17095+
17096+
17097+int
17098+wyse_syslocal(struct pt_regs *regp)
17099+{
17100+ int cmd = get_syscall_parameter(regp, 0);
17101+
17102+ switch (cmd) {
17103+ case SL_QUERY:
17104+ return 0;
17105+ case SL_NENG:
17106+ return 1;
17107+ case SL_MACHTYPE:
17108+ return (EISA_bus ? SL_MACH_EISA : SL_MACH_AT);
17109+ }
17110+
17111+#if defined(CONFIG_ABI_TRACE)
17112+ abi_trace(ABI_TRACE_UNIMPL, "unsupported syslocal call %d\n", cmd);
17113+#endif
17114+ return -EINVAL;
17115+}
17116diff -Nru linux-2.6.7/arch/i386/kernel/i386_ksyms.c linux-2.6.7-abi/arch/i386/kernel/i386_ksyms.c
17117--- linux-2.6.7/arch/i386/kernel/i386_ksyms.c 2004-06-16 07:20:26.000000000 +0200
17118+++ linux-2.6.7-abi/arch/i386/kernel/i386_ksyms.c 2004-07-22 17:44:21.000000000 +0200
17119@@ -16,6 +16,9 @@
17120 #include <linux/tty.h>
17121 #include <linux/highmem.h>
17122 #include <linux/time.h>
17123+#define __KERNEL_SYSCALLS__
17124+#include <linux/unistd.h>
17125+#include <linux/syscalls.h>
17126
17127 #include <asm/semaphore.h>
17128 #include <asm/processor.h>
17129@@ -206,3 +209,8 @@
17130 #endif
17131
17132 EXPORT_SYMBOL(csum_partial);
17133+
17134+EXPORT_SYMBOL(sys_modify_ldt);
17135+EXPORT_SYMBOL(sys_ptrace);
17136+EXPORT_SYMBOL(sys_ipc);
17137+EXPORT_SYMBOL(sys_pause);
17138diff -Nru linux-2.6.7/arch/i386/kernel/lcall7.c linux-2.6.7-abi/arch/i386/kernel/lcall7.c
17139--- linux-2.6.7/arch/i386/kernel/lcall7.c 1970-01-01 01:00:00.000000000 +0100
17140+++ linux-2.6.7-abi/arch/i386/kernel/lcall7.c 2004-07-22 17:44:21.000000000 +0200
17141@@ -0,0 +1,184 @@
17142+/*
17143+ * Copyright (c) 2000,2001 Christoph Hellwig.
17144+ * Copyright (c) 2001 Caldera Deutschland GmbH.
17145+ * All rights resered.
17146+ *
17147+ * This program is free software; you can redistribute it and/or modify
17148+ * it under the terms of the GNU General Public License as published by
17149+ * the Free Software Foundation; either version 2 of the License, or
17150+ * (at your option) any later version.
17151+ *
17152+ * This program is distributed in the hope that it will be useful,
17153+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
17154+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17155+ * GNU General Public License for more details.
17156+ *
17157+ * You should have received a copy of the GNU General Public License
17158+ * along with this program; if not, write to the Free Software
17159+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17160+ */
17161+
17162+#ident "%W% %G%"
17163+
17164+/*
17165+ * Lowlevel handler for lcall7-based syscalls.
17166+ */
17167+#include <linux/module.h>
17168+#include <linux/errno.h>
17169+#include <linux/sched.h>
17170+#include <linux/kernel.h>
17171+#include <linux/mm.h>
17172+#include <linux/ptrace.h>
17173+#include <linux/init.h>
17174+#include <linux/personality.h>
17175+#include <asm/uaccess.h>
17176+
17177+#include <abi/util/errno.h>
17178+#include <abi/util/trace.h>
17179+#include <abi/util/sysent.h>
17180+
17181+MODULE_AUTHOR("Christoph Hellwig");
17182+MODULE_DESCRIPTION("Lowlevel handler for lcall7-based syscalls");
17183+MODULE_LICENSE("GPL");
17184+
17185+
17186+static void get_args(int args[], struct pt_regs *regs, int of, int n)
17187+{
17188+ int i;
17189+
17190+ for (i = 0; i < n; i++)
17191+ get_user(args[i], ((unsigned long *)regs->esp) + (i+of));
17192+}
17193+
17194+/*
17195+ * lcall7_syscall - indirect syscall for the lcall7 entry point
17196+ *
17197+ * @regs: saved user registers
17198+ *
17199+ * This function implements syscall(2) in kernelspace for the lcall7-
17200+ * based personalities.
17201+ */
17202+
17203+int lcall7_syscall(struct pt_regs *regs)
17204+{
17205+ __get_user(regs->eax, ((unsigned long *)regs->esp)+1);
17206+
17207+ ++regs->esp;
17208+ current_thread_info()->exec_domain->handler(-1,regs);
17209+ --regs->esp;
17210+
17211+ return 0;
17212+}
17213+
17214+/**
17215+ * lcall7_dispatch - handle lcall7-based syscall entry
17216+ *
17217+ * @regs: saved user registers
17218+ * @ap: syscall table entry
17219+ * @off: argument offset
17220+ *
17221+ * This function handles lcall7-based syscalls after the personality-
17222+ * specific rountine selected the right syscall table entry.
17223+ */
17224+
17225+void lcall7_dispatch(struct pt_regs *regs, struct sysent *ap, int off)
17226+{
17227+ short nargs = ap->se_nargs;
17228+ int args[8], error;
17229+
17230+ if (!ap->se_syscall) /* XXX kludge XXX */
17231+ nargs = Unimpl;
17232+
17233+ if (nargs <= ARRAY_SIZE(args))
17234+ get_args(args, regs, off, nargs);
17235+
17236+#if defined(CONFIG_ABI_TRACE)
17237+ if (abi_traced(ABI_TRACE_API)) {
17238+ if (nargs == Spl)
17239+ get_args(args, regs, off, strlen(ap->se_args));
17240+ plist(ap->se_name, ap->se_args, args);
17241+ }
17242+#endif
17243+
17244+ switch (nargs) {
17245+ case Fast:
17246+ SYSCALL_PREGS(ap->se_syscall, regs);
17247+ goto show_signals;
17248+ case Spl:
17249+ error = SYSCALL_PREGS(ap->se_syscall, regs);
17250+ break;
17251+ case 0:
17252+ error = SYSCALL_VOID(ap->se_syscall);
17253+ break;
17254+ case 1:
17255+ error = SYSCALL_1ARG(ap->se_syscall, args);
17256+ break;
17257+ case 2:
17258+ error = SYSCALL_2ARG(ap->se_syscall, args);
17259+ break;
17260+ case 3:
17261+ error = SYSCALL_3ARG(ap->se_syscall, args);
17262+ break;
17263+ case 4:
17264+ error = SYSCALL_4ARG(ap->se_syscall, args);
17265+ break;
17266+ case 5:
17267+ error = SYSCALL_5ARG(ap->se_syscall, args);
17268+ break;
17269+ case 6:
17270+ error = SYSCALL_6ARG(ap->se_syscall, args);
17271+ break;
17272+ case 7:
17273+ error = SYSCALL_7ARG(ap->se_syscall, args);
17274+ break;
17275+ default:
17276+#if defined(CONFIG_ABI_TRACE)
17277+ abi_trace(ABI_TRACE_UNIMPL,
17278+ "Unsupported ABI function 0x%lx (%s)\n",
17279+ regs->eax, ap->se_name);
17280+#endif
17281+ error = -ENOSYS;
17282+ }
17283+
17284+ if (error > -ENOIOCTLCMD && error < 0) {
17285+ set_error(regs, iABI_errors(-error));
17286+
17287+#if defined(CONFIG_ABI_TRACE)
17288+ abi_trace(ABI_TRACE_API,
17289+ "%s error return %d/%ld\n",
17290+ ap->se_name, error, regs->eax);
17291+#endif
17292+ } else {
17293+ clear_error(regs);
17294+ set_result(regs, error);
17295+
17296+#if defined(CONFIG_ABI_TRACE)
17297+ abi_trace(ABI_TRACE_API,
17298+ "%s returns %ld (edx:%ld)\n",
17299+ ap->se_name, regs->eax, regs->edx);
17300+#endif
17301+ }
17302+
17303+show_signals:
17304+#if defined(CONFIG_ABI_TRACE)
17305+ if (signal_pending(current) && abi_traced(ABI_TRACE_SIGNAL)) {
17306+ unsigned long signr;
17307+
17308+ signr = current->pending.signal.sig[0] &
17309+ ~current->blocked.sig[0];
17310+
17311+ __asm__("bsf %1,%0\n\t"
17312+ :"=r" (signr)
17313+ :"0" (signr));
17314+
17315+ __abi_trace("SIGNAL %lu, queued 0x%08lx\n",
17316+ signr+1, current->pending.signal.sig[0]);
17317+ }
17318+#endif
17319+ return;
17320+}
17321+
17322+#if defined(CONFIG_ABI_SYSCALL_MODULES)
17323+EXPORT_SYMBOL(lcall7_syscall);
17324+EXPORT_SYMBOL(lcall7_dispatch);
17325+#endif
17326diff -Nru linux-2.6.7/arch/i386/kernel/Makefile linux-2.6.7-abi/arch/i386/kernel/Makefile
17327--- linux-2.6.7/arch/i386/kernel/Makefile 2004-06-16 07:19:01.000000000 +0200
17328+++ linux-2.6.7-abi/arch/i386/kernel/Makefile 2004-07-22 17:44:21.000000000 +0200
17329@@ -25,6 +25,7 @@
17330 obj-$(CONFIG_X86_IO_APIC) += io_apic.o
17331 obj-$(CONFIG_X86_NUMAQ) += numaq.o
17332 obj-$(CONFIG_X86_SUMMIT_NUMA) += summit.o
17333+obj-$(CONFIG_ABI_LCALL7) += lcall7.o
17334 obj-$(CONFIG_MODULES) += module.o
17335 obj-y += sysenter.o vsyscall.o
17336 obj-$(CONFIG_ACPI_SRAT) += srat.o
17337diff -Nru linux-2.6.7/arch/i386/kernel/traps.c linux-2.6.7-abi/arch/i386/kernel/traps.c
17338--- linux-2.6.7/arch/i386/kernel/traps.c 2004-06-16 07:19:01.000000000 +0200
17339+++ linux-2.6.7-abi/arch/i386/kernel/traps.c 2004-07-22 17:44:21.000000000 +0200
17340@@ -588,6 +588,26 @@
17341
17342 __asm__ __volatile__("movl %%db6,%0" : "=r" (condition));
17343
17344+ /*
17345+ * Entering the kernel via lcall7 or lcall27 does not clear the TF bit.
17346+ * Leaving it set in kernel code will stop the machine. The first
17347+ * instructions of lcall7 and lcall27 in entry.S save the CPU flags.
17348+ * The saved flags should have the TF bit set, so we ignore this trap.
17349+ */
17350+ if (regs->eip == (unsigned long) &lcall7 ||
17351+ regs->eip == (unsigned long) &lcall27)
17352+ return;
17353+
17354+ /*
17355+ * After having saved the flags, TF will fire the single step trap
17356+ * again. This time TF should be cleared. It will be restored by the
17357+ * iret instruction returning to user mode. This way, the very next
17358+ * instruction after lcall in the user programm will not be stopped at.
17359+ */
17360+ if (regs->eip - 1 == (unsigned long) &lcall7 || /* pushfl is a one-byte op */
17361+ regs->eip - 1 == (unsigned long) &lcall27)
17362+ goto clear_TF;
17363+
17364 /* It's safe to allow irq's after DR6 has been saved */
17365 if (regs->eflags & X86_EFLAGS_IF)
17366 local_irq_enable();
17367diff -Nru linux-2.6.7/arch/ia64/ia32/ia32priv.h linux-2.6.7-abi/arch/ia64/ia32/ia32priv.h
17368--- linux-2.6.7/arch/ia64/ia32/ia32priv.h 2004-06-16 07:20:19.000000000 +0200
17369+++ linux-2.6.7-abi/arch/ia64/ia32/ia32priv.h 2004-07-22 17:44:21.000000000 +0200
17370@@ -332,7 +332,7 @@
17371
17372 #ifdef __KERNEL__
17373 # define SET_PERSONALITY(EX,IBCS2) \
17374- (current->personality = (IBCS2) ? PER_SVR4 : PER_LINUX)
17375+ (is_cur_personality((IBCS2)) ? PER_SVR4 : PER_LINUX)
17376 #endif
17377
17378 #define IA32_EFLAG 0x200
17379diff -Nru linux-2.6.7/arch/parisc/kernel/signal.c linux-2.6.7-abi/arch/parisc/kernel/signal.c
17380--- linux-2.6.7/arch/parisc/kernel/signal.c 2004-06-16 07:20:19.000000000 +0200
17381+++ linux-2.6.7-abi/arch/parisc/kernel/signal.c 2004-07-22 17:44:21.000000000 +0200
17382@@ -75,7 +75,7 @@
17383 #ifdef __LP64__
17384 compat_sigset_t newset32;
17385
17386- if(personality(current->personality) == PER_LINUX32){
17387+ if(is_cur_personality_id(PERID_LINUX32)){
17388 /* XXX: Don't preclude handling different sized sigset_t's. */
17389 if (sigsetsize != sizeof(compat_sigset_t))
17390 return -EINVAL;
17391@@ -152,7 +152,7 @@
17392 compat_sigset_t compat_set;
17393 struct compat_rt_sigframe * compat_frame;
17394
17395- if(personality(current->personality) == PER_LINUX32)
17396+ if(is_cur_personality_id(PERID_LINUX32))
17397 sigframe_size = PARISC_RT_SIGFRAME_SIZE32;
17398 #endif
17399
17400@@ -165,7 +165,7 @@
17401 #ifdef __LP64__
17402 compat_frame = (struct compat_rt_sigframe *)frame;
17403
17404- if(personality(current->personality) == PER_LINUX32){
17405+ if(is_cur_personality_id(PERID_LINUX32)){
17406 DBG(2,"sys_rt_sigreturn: ELF32 process.\n");
17407 if (__copy_from_user(&compat_set, &compat_frame->uc.uc_sigmask, sizeof(compat_set)))
17408 goto give_sigsegv;
17409@@ -185,7 +185,7 @@
17410
17411 /* Good thing we saved the old gr[30], eh? */
17412 #ifdef __LP64__
17413- if(personality(current->personality) == PER_LINUX32){
17414+ if(is_cur_personality_id(PERID_LINUX32)){
17415 DBG(1,"sys_rt_sigreturn: compat_frame->uc.uc_mcontext 0x%p\n",
17416 &compat_frame->uc.uc_mcontext);
17417 // FIXME: Load upper half from register file
17418@@ -315,7 +315,7 @@
17419
17420 compat_frame = (struct compat_rt_sigframe *)frame;
17421
17422- if(personality(current->personality) == PER_LINUX32) {
17423+ if(is_personality_id(PERID_LINUX32)) {
17424 DBG(1,"setup_rt_frame: frame->info = 0x%p\n", &compat_frame->info);
17425 err |= compat_copy_siginfo_to_user(&compat_frame->info, info);
17426 DBG(1,"SETUP_RT_FRAME: 1\n");
17427@@ -392,7 +392,7 @@
17428 haddr = A(ka->sa.sa_handler);
17429 /* The sa_handler may be a pointer to a function descriptor */
17430 #ifdef __LP64__
17431- if(personality(current->personality) == PER_LINUX32) {
17432+ if(is_cur_personality_id(PERID_LINUX32)) {
17433 #endif
17434 if (haddr & PA_PLABEL_FDESC) {
17435 Elf32_Fdesc fdesc;
17436@@ -427,19 +427,19 @@
17437 */
17438 sigframe_size = PARISC_RT_SIGFRAME_SIZE;
17439 #ifdef __LP64__
17440- if(personality(current->personality) == PER_LINUX32)
17441+ if(is_cur_personality_id(PERID_LINUX32))
17442 sigframe_size = PARISC_RT_SIGFRAME_SIZE32;
17443 #endif
17444 if (in_syscall) {
17445 regs->gr[31] = haddr;
17446 #ifdef __LP64__
17447- if(personality(current->personality) == PER_LINUX)
17448+ if(is_cur_personality_id(PERID_LINUX))
17449 sigframe_size |= 1;
17450 #endif
17451 } else {
17452 unsigned long psw = USER_PSW;
17453 #ifdef __LP64__
17454- if(personality(current->personality) == PER_LINUX)
17455+ if(is_cur_personality_id(PERID_LINUX))
17456 psw |= PSW_W;
17457 #endif
17458
17459@@ -452,7 +452,7 @@
17460 regs->gr[26] = sig; /* signal number */
17461
17462 #ifdef __LP64__
17463- if(personality(current->personality) == PER_LINUX32){
17464+ if(is_cur_personality_id(PERID_LINUX32)){
17465 regs->gr[25] = A(&compat_frame->info); /* siginfo pointer */
17466 regs->gr[24] = A(&compat_frame->uc); /* ucontext pointer */
17467 } else
17468diff -Nru linux-2.6.7/arch/x86_64/ia32/sys_ia32.c linux-2.6.7-abi/arch/x86_64/ia32/sys_ia32.c
17469--- linux-2.6.7/arch/x86_64/ia32/sys_ia32.c 2004-06-16 07:19:22.000000000 +0200
17470+++ linux-2.6.7-abi/arch/x86_64/ia32/sys_ia32.c 2004-07-22 17:44:21.000000000 +0200
17471@@ -924,12 +924,15 @@
17472 sys32_personality(unsigned long personality)
17473 {
17474 int ret;
17475- if (personality(current->personality) == PER_LINUX32 &&
17476+
17477+ if (is_personality_id(PERID_LINUX32) &&
17478 personality == PER_LINUX)
17479 personality = PER_LINUX32;
17480 ret = sys_personality(personality);
17481+
17482 if (ret == PER_LINUX32)
17483 ret = PER_LINUX;
17484+
17485 return ret;
17486 }
17487
17488@@ -1077,7 +1080,7 @@
17489 __put_user(0,name->version+__OLD_UTS_LEN);
17490 {
17491 char *arch = "x86_64";
17492- if (personality(current->personality) == PER_LINUX32)
17493+ if (is_cur_personality_id(PERID_LINUX32))
17494 arch = "i686";
17495
17496 __copy_to_user(&name->machine,arch,strlen(arch)+1);
17497@@ -1098,7 +1101,7 @@
17498 down_read(&uts_sem);
17499 err=copy_to_user(name, &system_utsname, sizeof (*name));
17500 up_read(&uts_sem);
17501- if (personality(current->personality) == PER_LINUX32)
17502+ if (is_cur_personality_id(PERID_LINUX32))
17503 err |= copy_to_user(&name->machine, "i686", 5);
17504 return err?-EFAULT:0;
17505 }
17506diff -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
17507--- linux-2.6.7/arch/x86_64/kernel/sys_x86_64.c 2004-06-16 07:19:37.000000000 +0200
17508+++ linux-2.6.7-abi/arch/x86_64/kernel/sys_x86_64.c 2004-07-22 17:44:21.000000000 +0200
17509@@ -148,7 +148,7 @@
17510 down_read(&uts_sem);
17511 err = copy_to_user(name, &system_utsname, sizeof (*name));
17512 up_read(&uts_sem);
17513- if (personality(current->personality) == PER_LINUX32)
17514+ if (is_cur_personality_id(PERID_LINUX32))
17515 err |= copy_to_user(&name->machine, "i686", 5);
17516 return err ? -EFAULT : 0;
17517 }
17518diff -Nru linux-2.6.7/Documentation/abi/00-INDEX linux-2.6.7-abi/Documentation/abi/00-INDEX
17519--- linux-2.6.7/Documentation/abi/00-INDEX 1970-01-01 01:00:00.000000000 +0100
17520+++ linux-2.6.7-abi/Documentation/abi/00-INDEX 2004-07-22 17:44:20.000000000 +0200
17521@@ -0,0 +1,30 @@
17522+00-INDEX
17523+ - this file
17524+COMPAT
17525+ - a list of software that has run succesfull under iBCS
17526+CREDITS
17527+ - a list of people that have contributed to linux-abi or iBCS
17528+ChangeLog
17529+ - changelog of linux-abi
17530+ChangeLog.ibcs
17531+ - changelog of the iBCS project (up to 1998)
17532+Error.map
17533+ - mapping of error codes from Linux to various personalities
17534+HINTS
17535+ - FAQ-style Q&A
17536+Local-X
17537+ - help on local X interfaces
17538+Notes.Signal
17539+ - some notes on signal handling
17540+Personality
17541+ - an introduction into Linux personality support
17542+README.first
17543+ - read this first!
17544+Syscall.map
17545+ - the syscall mapping for certain personalities
17546+TODO.ibcs
17547+ - things to be done, leftovers from iBCS
17548+autoload.txt
17549+ - autoloading personality modules under Linux-ABI
17550+modules.txt
17551+ - a brief overview of the Linux-ABI modules
17552diff -Nru linux-2.6.7/Documentation/abi/autoload.txt linux-2.6.7-abi/Documentation/abi/autoload.txt
17553--- linux-2.6.7/Documentation/abi/autoload.txt 1970-01-01 01:00:00.000000000 +0100
17554+++ linux-2.6.7-abi/Documentation/abi/autoload.txt 2004-07-22 17:44:20.000000000 +0200
17555@@ -0,0 +1,49 @@
17556+Autoloading personality modules under Linux-ABI
17557+2001-July-19
17558+Christoph Hellwig, <hch@caldera.de>
17559+
17560+Linux-ABI can automatically load binary format modules (see modules.txt
17561+for information on what binary format modules are). This file explains
17562+how to setup a system to automatically load the binary format modules
17563+on demand.
17564+
17565+Automatic module loading is done in Linux using a facility called 'kmod'
17566+which is - unlike the name suggests - _not_ a system daemon, but a kernel-
17567+facility to make userspace upcalls to te module loading program 'modprobe'.
17568+
17569+Linux-ABI uses the function request_module that is exported by kmod to
17570+request modules for personalities that are currently not available but
17571+requested by one of the binary fomrat detection heuristics. For a missing
17572+personality, request_module is called for the module-string
17573+
17574+ personality-<personality-number>
17575+
17576+To get the right modules loaded you have to alias these string to the
17577+actually wanted modules in /etc/modules.conf. To do that you have to know
17578+which personality number maps to what module. Here is a table for the
17579+personalities supported by Linux-ABI:
17580+
17581+
17582+ personalities module
17583+ -----------------------------------
17584+ 1,2,5,7 abi-ibcs
17585+ 3 abi-sco
17586+ 4 abi-wyse
17587+ 13 abi-solaris
17588+ 14 abi-uw7
17589+
17590+Below is an example snipplet from modules.conf for such a setup:
17591+
17592+------------------- snip --------------------
17593+
17594+alias personality-1 abi-ibcs
17595+alias personality-2 abi-ibcs
17596+alias personality-3 abi-sco
17597+alias personality-4 abi-wyse
17598+alias personality-5 abi-ibcs
17599+alias personality-7 abi-ibcs
17600+alias personality-13 abi-solaris
17601+alias personality-14 abi-uw7
17602+
17603+------------------- snip --------------------
17604+
17605diff -Nru linux-2.6.7/Documentation/abi/ChangeLog linux-2.6.7-abi/Documentation/abi/ChangeLog
17606--- linux-2.6.7/Documentation/abi/ChangeLog 1970-01-01 01:00:00.000000000 +0100
17607+++ linux-2.6.7-abi/Documentation/abi/ChangeLog 2004-07-22 17:44:20.000000000 +0200
17608@@ -0,0 +1,135 @@
17609+2002-01-03 Christoph Hellwig <hch@caldera.de>
17610+
17611