1 /*
2  * Copyright (c) 1988 University of Utah.
3  * Copyright (c) 1990 The Regents of the University of California.
4  * All rights reserved.
5  *
6  * This code is derived from software contributed to Berkeley by
7  * the Systems Programming Group of the University of Utah Computer
8  * Science Department and Ralph Campbell.
9  *
10  * %sccs.include.redist.c%
11  *
12  * from: Utah $Hdr: hpux_compat.c 1.41 91/04/06$
13  *
14  *	@(#)ultrix_compat.c	7.2 (Berkeley) 03/28/92
15  */
16 
17 /*
18  * Various ULTRIX compatibility routines
19  */
20 
21 #ifdef ULTRIXCOMPAT
22 
23 #include "param.h"
24 #include "systm.h"
25 #include "signalvar.h"
26 #include "kernel.h"
27 #include "filedesc.h"
28 #include "proc.h"
29 #include "buf.h"
30 #include "wait.h"
31 #include "file.h"
32 #include "namei.h"
33 #include "vnode.h"
34 #include "ioctl.h"
35 #include "ptrace.h"
36 #include "stat.h"
37 #include "syslog.h"
38 #include "malloc.h"
39 #include "mount.h"
40 #include "ipc.h"
41 #include "user.h"
42 
43 #include "machine/cpu.h"
44 #include "machine/reg.h"
45 #include "machine/psl.h"
46 #include "machine/vmparam.h"
47 
48 #ifdef DEBUG
49 int unimpresponse = 0;
50 #endif
51 
52 /* YP domainname */
53 char	domainname[MAXHOSTNAMELEN] = "unknown";
54 int	domainnamelen = 7;
55 
56 notimp(p, uap, retval)
57 	struct proc *p;
58 	void *uap;
59 	int *retval;
60 {
61 	int error = 0;
62 #ifdef notdef
63 	register int *argp = uap;
64 	extern char *ultrixsyscallnames[];
65 
66 	printf("ULTRIX %s(", ultrixsyscallnames[code]);
67 	if (nargs)
68 		while (nargs--)
69 			printf("%x%c", *argp++, nargs? ',' : ')');
70 	else
71 		printf(")");
72 	printf("\n");
73 	switch (unimpresponse) {
74 	case 0:
75 		error = nosys(p, uap, retval);
76 		break;
77 	case 1:
78 		error = EINVAL;
79 		break;
80 	}
81 #else
82 	uprintf("ULTRIX system call %d not implemented\n", p->p_md.md_regs[V0]);
83 	error = nosys(p, uap, retval);
84 #endif
85 	return (error);
86 }
87 
88 ultrixwait3(p, uap, retval)
89 	struct proc *p;
90 	struct args {
91 		int	*status;
92 		int	options;
93 		int	rusage;
94 	} *uap;
95 	int *retval;
96 {
97 	struct {
98 		int	pid;
99 		int	*status;
100 		int	options;
101 		struct	rusage *rusage;
102 		int	compat;
103 	} bsd_uap;
104 
105 	/* rusage pointer must be zero */
106 	if (uap->rusage)
107 		return (EINVAL);
108 	bsd_uap.pid = WAIT_ANY;
109 	bsd_uap.status = uap->status;
110 	bsd_uap.options = 0;
111 	bsd_uap.rusage = 0;
112 	bsd_uap.compat = 0;
113 	return (wait1(p, &bsd_uap, retval));
114 }
115 
116 ultrixgetdomainname(p, uap, retval)
117 	struct proc *p;
118 	register struct args {
119 		char	*domainname;
120 		u_int	len;
121 	} *uap;
122 	int *retval;
123 {
124 	if (uap->len > domainnamelen + 1)
125 		uap->len = domainnamelen + 1;
126 	return (copyout(domainname, uap->domainname, uap->len));
127 }
128 
129 ultrixsetdomainname(p, uap, retval)
130 	struct proc *p;
131 	register struct args {
132 		char	*domainname;
133 		u_int	len;
134 	} *uap;
135 	int *retval;
136 {
137 	int error;
138 
139 	if (error = suser(p->p_ucred, &p->p_acflag))
140 		return (error);
141 	if (uap->len > sizeof (domainname) - 1)
142 		return (EINVAL);
143 	domainnamelen = uap->len;
144 	error = copyin(uap->domainname, domainname, uap->len);
145 	domainname[domainnamelen] = 0;
146 	return (error);
147 }
148 
149 /*
150  * This is the equivalent of BSD getpgrp but with more restrictions.
151  * Note we do not check the real uid or "saved" uid.
152  */
153 ultrixgetpgrp(cp, uap, retval)
154 	struct proc *cp;
155 	register struct args {
156 		int pid;
157 	} *uap;
158 	int *retval;
159 {
160 	register struct proc *p;
161 
162 	if (uap->pid == 0)
163 		uap->pid = cp->p_pid;
164 	p = pfind(uap->pid);
165 	if (p == 0)
166 		return (ESRCH);
167 	if (cp->p_ucred->cr_uid && p->p_ucred->cr_uid != cp->p_ucred->cr_uid &&
168 	    !inferior(p))
169 		return (EPERM);
170 	*retval = p->p_pgid;
171 	return (0);
172 }
173 
174 /*
175  * This is the equivalent of BSD setpgrp but with more restrictions.
176  * Note we do not check the real uid or "saved" uid or pgrp.
177  */
178 ultrixsetpgrp(p, uap, retval)
179 	struct proc *p;
180 	struct args {
181 		int	pid;
182 		int	pgrp;
183 	} *uap;
184 	int *retval;
185 {
186 	/* empirically determined */
187 	if (uap->pgrp < 0 || uap->pgrp >= 30000)
188 		return (EINVAL);
189 	return (setpgid(p, uap, retval));
190 }
191 
192 ultrixsigvec(p, uap, retval)
193 	struct proc *p;
194 	register struct args {
195 		int	signo;
196 		struct	sigvec *nsv;
197 		struct	sigvec *osv;
198 		caddr_t	sigcode;	/* handler return address */
199 	} *uap;
200 	int *retval;
201 {
202 	return (osigvec(p, uap, retval));
203 }
204 
205 ultrixsigcleanup(p, uap, retval)
206 	struct proc *p;
207 	void *uap;
208 	int *retval;
209 {
210 	printf("ultrixsigcleanup %s %d\n", p->p_comm, p->p_pid); /* XXX */
211 	return (ENOSYS);
212 }
213 
214 ultrixsigreturn(p, uap, retval)
215 	struct proc *p;
216 	void *uap;
217 	int *retval;
218 {
219 	printf("ultrixsigreturn %s %d\n", p->p_comm, p->p_pid); /* XXX */
220 	return (ENOSYS);
221 }
222 
223 /*
224  * Switch process from ULTRIX emulation to BSD.
225  */
226 ultrixtobsd(p, uap, retval)
227 	struct proc *p;
228 	void *uap;
229 	int *retval;
230 {
231 
232 	p->p_md.md_flags &= ~MDP_ULTRIX;
233 	return (0);
234 }
235 
236 ultrixgetsysinfo(p, uap, retval)
237 	struct proc *p;
238 	void *uap;
239 	int *retval;
240 {
241 
242 	/*
243 	 * Just return a 0.  This says that the requested information is
244 	 * not available which is certainly true for the most part.
245 	 */
246 	retval[0] = 0;
247 	return (0);
248 }
249 
250 #endif
251