xref: /csrg-svn/sys/hp/hpux/hpux_compat.c (revision 41486)
1*41486Smckusick /*
2*41486Smckusick  * Copyright (c) 1988 University of Utah.
3*41486Smckusick  * Copyright (c) 1990 The Regents of the University of California.
4*41486Smckusick  * All rights reserved.
5*41486Smckusick  *
6*41486Smckusick  * This code is derived from software contributed to Berkeley by
7*41486Smckusick  * the Systems Programming Group of the University of Utah Computer
8*41486Smckusick  * Science Department.
9*41486Smckusick  *
10*41486Smckusick  * %sccs.include.redist.c%
11*41486Smckusick  *
12*41486Smckusick  * from: Utah $Hdr: hpux_compat.c 1.33 89/08/23$
13*41486Smckusick  *
14*41486Smckusick  *	@(#)hpux_compat.c	7.1 (Berkeley) 05/08/90
15*41486Smckusick  */
16*41486Smckusick 
17*41486Smckusick /*
18*41486Smckusick  * Various HPUX compatibility routines
19*41486Smckusick  */
20*41486Smckusick 
21*41486Smckusick #ifdef HPUXCOMPAT
22*41486Smckusick 
23*41486Smckusick #include "param.h"
24*41486Smckusick #include "systm.h"
25*41486Smckusick #include "syscontext.h"
26*41486Smckusick #include "kernel.h"
27*41486Smckusick #include "proc.h"
28*41486Smckusick #include "buf.h"
29*41486Smckusick #include "wait.h"
30*41486Smckusick #include "file.h"
31*41486Smckusick #include "vnode.h"
32*41486Smckusick #include "ioctl.h"
33*41486Smckusick #include "uio.h"
34*41486Smckusick #include "ptrace.h"
35*41486Smckusick #include "stat.h"
36*41486Smckusick #include "syslog.h"
37*41486Smckusick #include "malloc.h"
38*41486Smckusick #include "mount.h"
39*41486Smckusick #include "ipc.h"
40*41486Smckusick 
41*41486Smckusick #include "machine/cpu.h"
42*41486Smckusick #include "machine/reg.h"
43*41486Smckusick #include "machine/psl.h"
44*41486Smckusick #include "machine/vmparam.h"
45*41486Smckusick #include "hpux.h"
46*41486Smckusick #include "hpux_termio.h"
47*41486Smckusick 
48*41486Smckusick #ifdef DEBUG
49*41486Smckusick int unimpresponse = 0;
50*41486Smckusick #endif
51*41486Smckusick 
52*41486Smckusick /* "tick" value for HZ==50 */
53*41486Smckusick int hpuxtick = 1000000 / 50;
54*41486Smckusick 
55*41486Smckusick /* SYS5 style UTSNAME info */
56*41486Smckusick struct hpuxutsname protoutsname = {
57*41486Smckusick 	"4.4bsd", "", "2.0", "B", "9000/3?0", ""
58*41486Smckusick };
59*41486Smckusick 
60*41486Smckusick /* 6.0 and later style context */
61*41486Smckusick #ifdef FPCOPROC
62*41486Smckusick char hpuxcontext[] =
63*41486Smckusick 	"standalone HP-MC68881 HP-MC68020 HP-MC68010 localroot default";
64*41486Smckusick #else
65*41486Smckusick char hpuxcontext[] =
66*41486Smckusick 	"standalone HP-MC68020 HP-MC68010 localroot default";
67*41486Smckusick #endif
68*41486Smckusick 
69*41486Smckusick /* YP domainname */
70*41486Smckusick char	domainname[MAXHOSTNAMELEN] = "unknown";
71*41486Smckusick int	domainnamelen = 7;
72*41486Smckusick 
73*41486Smckusick #define NERR	79
74*41486Smckusick #define BERR	1000
75*41486Smckusick 
76*41486Smckusick /* indexed by BSD errno */
77*41486Smckusick short bsdtohpuxerrnomap[NERR] = {
78*41486Smckusick /*00*/	  0,   1,   2,   3,   4,   5,   6,   7,   8,   9,
79*41486Smckusick /*10*/	 10,  45,  12,  13,  14,  15,  16,  17,  18,  19,
80*41486Smckusick /*20*/	 20,  21,  22,  23,  24,  25,  26,  27,  28,  29,
81*41486Smckusick /*30*/	 30,  31,  32,  33,  34, 246, 245, 244, 216, 217,
82*41486Smckusick /*40*/	218, 219, 220, 221, 222, 223, 224, 225, 226, 227,
83*41486Smckusick /*50*/	228, 229, 230, 231, 232, 233, 234, 235, 236, 237,
84*41486Smckusick /*60*/	238, 239, 249, 248, 241, 242, 247,BERR,BERR,BERR,
85*41486Smckusick /*70*/   70,  71,BERR,BERR,BERR,BERR,BERR,  46,BERR
86*41486Smckusick };
87*41486Smckusick 
88*41486Smckusick notimp(code, nargs)
89*41486Smckusick {
90*41486Smckusick #ifdef DEBUG
91*41486Smckusick 	int *argp = u.u_ap;
92*41486Smckusick 	extern char *hpuxsyscallnames[];
93*41486Smckusick 
94*41486Smckusick 	printf("HPUX %s(", hpuxsyscallnames[code]);
95*41486Smckusick 	if (nargs)
96*41486Smckusick 		while (nargs--)
97*41486Smckusick 			printf("%x%c", *argp++, nargs? ',' : ')');
98*41486Smckusick 	else
99*41486Smckusick 		printf(")");
100*41486Smckusick 	printf("\n");
101*41486Smckusick 	switch (unimpresponse) {
102*41486Smckusick 	case 0:
103*41486Smckusick 		nosys();
104*41486Smckusick 		break;
105*41486Smckusick 	case 1:
106*41486Smckusick 		u.u_error = EINVAL;
107*41486Smckusick 		break;
108*41486Smckusick 	}
109*41486Smckusick #else
110*41486Smckusick 	nosys();
111*41486Smckusick #endif
112*41486Smckusick 	uprintf("HPUX system call %d not implemented\n", code);
113*41486Smckusick }
114*41486Smckusick 
115*41486Smckusick /*
116*41486Smckusick  * HPUX versions of wait and wait3 actually pass the parameters
117*41486Smckusick  * (status pointer, options, rusage) into the kernel rather than
118*41486Smckusick  * handling it in the C library stub.  We also need to map any
119*41486Smckusick  * termination signal from BSD to HPUX.
120*41486Smckusick  */
121*41486Smckusick hpuxwait3()
122*41486Smckusick {
123*41486Smckusick 	struct a {
124*41486Smckusick 		int	*status;
125*41486Smckusick 		int	options;
126*41486Smckusick 		int	rusage;
127*41486Smckusick 	} *uap = (struct a *)u.u_ap;
128*41486Smckusick 
129*41486Smckusick 	/* rusage pointer must be zero */
130*41486Smckusick 	if (uap->rusage) {
131*41486Smckusick 		u.u_error = EINVAL;
132*41486Smckusick 		return;
133*41486Smckusick 	}
134*41486Smckusick 	u.u_ar0[PS] = PSL_ALLCC;
135*41486Smckusick 	u.u_ar0[R0] = uap->options;
136*41486Smckusick 	u.u_ar0[R1] = uap->rusage;
137*41486Smckusick 	hpuxwait();
138*41486Smckusick }
139*41486Smckusick 
140*41486Smckusick hpuxwait()
141*41486Smckusick {
142*41486Smckusick 	int sig, *statp;
143*41486Smckusick 	struct a {
144*41486Smckusick 		int	*status;
145*41486Smckusick 	} *uap = (struct a *)u.u_ap;
146*41486Smckusick 
147*41486Smckusick 	statp = uap->status;	/* owait clobbers first arg */
148*41486Smckusick 	owait();
149*41486Smckusick 	/*
150*41486Smckusick 	 * HP-UX wait always returns EINTR when interrupted by a signal
151*41486Smckusick 	 * (well, unless its emulating a BSD process, but we don't bother...)
152*41486Smckusick 	 */
153*41486Smckusick 	if (u.u_eosys == RESTARTSYS) {
154*41486Smckusick 		u.u_eosys = NORMALRETURN;
155*41486Smckusick 		u.u_error = EINTR;
156*41486Smckusick 	}
157*41486Smckusick 	if (u.u_error)
158*41486Smckusick 		return;
159*41486Smckusick 	sig = u.u_r.r_val2 & 0xFF;
160*41486Smckusick 	if (sig == WSTOPPED) {
161*41486Smckusick 		sig = (u.u_r.r_val2 >> 8) & 0xFF;
162*41486Smckusick 		u.u_r.r_val2 = (bsdtohpuxsig(sig) << 8) | WSTOPPED;
163*41486Smckusick 	} else if (sig)
164*41486Smckusick 		u.u_r.r_val2 = (u.u_r.r_val2 & 0xFF00) |
165*41486Smckusick 			bsdtohpuxsig(sig & 0x7F) | (sig & 0x80);
166*41486Smckusick 	if (statp)
167*41486Smckusick 		if (suword((caddr_t)statp, u.u_r.r_val2))
168*41486Smckusick 			u.u_error = EFAULT;
169*41486Smckusick }
170*41486Smckusick 
171*41486Smckusick /*
172*41486Smckusick  * Must remap some bits in the mode mask.
173*41486Smckusick  * O_CREAT, O_TRUNC, and O_EXCL must be remapped,
174*41486Smckusick  * O_SYNCIO (0100000) is removed entirely.
175*41486Smckusick  */
176*41486Smckusick hpuxopen(scp)
177*41486Smckusick 	register struct syscontext *scp;
178*41486Smckusick {
179*41486Smckusick 	struct a {
180*41486Smckusick 		char	*fname;
181*41486Smckusick 		int	mode;
182*41486Smckusick 		int	crtmode;
183*41486Smckusick 	} *uap = (struct a *) scp->sc_ap;
184*41486Smckusick 	struct nameidata *ndp = &scp->sc_nd;
185*41486Smckusick 	int mode;
186*41486Smckusick 
187*41486Smckusick 	mode = uap->mode;
188*41486Smckusick 	uap->mode &= ~(HPUXFSYNCIO|HPUXFEXCL|HPUXFTRUNC|HPUXFCREAT);
189*41486Smckusick 	if (mode & HPUXFCREAT) {
190*41486Smckusick 		/*
191*41486Smckusick 		 * simulate the pre-NFS behavior that opening a
192*41486Smckusick 		 * file for READ+CREATE ignores the CREATE (unless
193*41486Smckusick 		 * EXCL is set in which case we will return the
194*41486Smckusick 		 * proper error).
195*41486Smckusick 		 */
196*41486Smckusick 		if ((mode & HPUXFEXCL) || ((mode-FOPEN) & FWRITE))
197*41486Smckusick 			uap->mode |= FCREAT;
198*41486Smckusick 	}
199*41486Smckusick 	if (mode & HPUXFTRUNC)
200*41486Smckusick 		uap->mode |= FTRUNC;
201*41486Smckusick 	if (mode & HPUXFEXCL)
202*41486Smckusick 		uap->mode |= FEXCL;
203*41486Smckusick 	ndp->ni_segflg = UIO_USERSPACE;
204*41486Smckusick 	ndp->ni_dirp = uap->fname;
205*41486Smckusick 	RETURN (copen(scp, uap->mode-FOPEN, uap->crtmode &~ scp->sc_cmask, ndp,
206*41486Smckusick 		&scp->sc_retval1));
207*41486Smckusick }
208*41486Smckusick 
209*41486Smckusick hpuxfcntl()
210*41486Smckusick {
211*41486Smckusick 	register struct a {
212*41486Smckusick 		int	fdes;
213*41486Smckusick 		int	cmd;
214*41486Smckusick 		int	arg;
215*41486Smckusick 	} *uap = (struct a *)u.u_ap;
216*41486Smckusick 	int mode;
217*41486Smckusick 
218*41486Smckusick 	switch (uap->cmd) {
219*41486Smckusick 	case F_SETFL:
220*41486Smckusick 		uap->arg &= ~(HPUXFSYNCIO|HPUXFREMOTE|FUSECACHE);
221*41486Smckusick 		break;
222*41486Smckusick 	case F_GETFL:
223*41486Smckusick 	case F_DUPFD:
224*41486Smckusick 	case F_GETFD:
225*41486Smckusick 	case F_SETFD:
226*41486Smckusick 		break;
227*41486Smckusick 	default:
228*41486Smckusick 		u.u_error = EINVAL;
229*41486Smckusick 		return;
230*41486Smckusick 	}
231*41486Smckusick 	fcntl();
232*41486Smckusick 	if (u.u_error == 0 && uap->arg == F_GETFL) {
233*41486Smckusick 		mode = u.u_r.r_val1;
234*41486Smckusick 		u.u_r.r_val1 &= ~(FCREAT|FTRUNC|FEXCL|FUSECACHE);
235*41486Smckusick 		if (mode & FCREAT)
236*41486Smckusick 			u.u_r.r_val1 |= HPUXFCREAT;
237*41486Smckusick 		if (mode & FTRUNC)
238*41486Smckusick 			u.u_r.r_val1 |= HPUXFTRUNC;
239*41486Smckusick 		if (mode & FEXCL)
240*41486Smckusick 			u.u_r.r_val1 |= HPUXFEXCL;
241*41486Smckusick 	}
242*41486Smckusick }
243*41486Smckusick 
244*41486Smckusick /*
245*41486Smckusick  * Read and write should return a 0 count when an operation
246*41486Smckusick  * on a VNODE would block, not an error.  Sockets appear to
247*41486Smckusick  * return EWOULDBLOCK (at least in 6.2).  This is probably
248*41486Smckusick  * not entirely correct, since the behavior is only defined
249*41486Smckusick  * for pipes and tty type devices.
250*41486Smckusick  */
251*41486Smckusick hpuxread()
252*41486Smckusick {
253*41486Smckusick 	struct a {
254*41486Smckusick 		int	fd;
255*41486Smckusick 	} *uap = (struct a *)u.u_ap;
256*41486Smckusick 
257*41486Smckusick 	read();
258*41486Smckusick 	if (u.u_error == EWOULDBLOCK &&
259*41486Smckusick 	    u.u_ofile[uap->fd]->f_type == DTYPE_VNODE) {
260*41486Smckusick 		u.u_error = 0;
261*41486Smckusick 		u.u_r.r_val1 = 0;
262*41486Smckusick 	}
263*41486Smckusick }
264*41486Smckusick 
265*41486Smckusick hpuxwrite()
266*41486Smckusick {
267*41486Smckusick 	struct a {
268*41486Smckusick 		int	fd;
269*41486Smckusick 	} *uap = (struct a *)u.u_ap;
270*41486Smckusick 
271*41486Smckusick 	write();
272*41486Smckusick 	if (u.u_error == EWOULDBLOCK &&
273*41486Smckusick 	    u.u_ofile[uap->fd]->f_type == DTYPE_VNODE) {
274*41486Smckusick 		u.u_error = 0;
275*41486Smckusick 		u.u_r.r_val1 = 0;
276*41486Smckusick 	}
277*41486Smckusick }
278*41486Smckusick 
279*41486Smckusick hpuxreadv()
280*41486Smckusick {
281*41486Smckusick 	struct a {
282*41486Smckusick 		int	fd;
283*41486Smckusick 	} *uap = (struct a *)u.u_ap;
284*41486Smckusick 
285*41486Smckusick 	readv();
286*41486Smckusick 	if (u.u_error == EWOULDBLOCK &&
287*41486Smckusick 	    u.u_ofile[uap->fd]->f_type == DTYPE_VNODE) {
288*41486Smckusick 		u.u_error = 0;
289*41486Smckusick 		u.u_r.r_val1 = 0;
290*41486Smckusick 	}
291*41486Smckusick }
292*41486Smckusick 
293*41486Smckusick hpuxwritev()
294*41486Smckusick {
295*41486Smckusick 	struct a {
296*41486Smckusick 		int	fd;
297*41486Smckusick 	} *uap = (struct a *)u.u_ap;
298*41486Smckusick 
299*41486Smckusick 	writev();
300*41486Smckusick 	if (u.u_error == EWOULDBLOCK &&
301*41486Smckusick 	    u.u_ofile[uap->fd]->f_type == DTYPE_VNODE) {
302*41486Smckusick 		u.u_error = 0;
303*41486Smckusick 		u.u_r.r_val1 = 0;
304*41486Smckusick 	}
305*41486Smckusick }
306*41486Smckusick 
307*41486Smckusick /*
308*41486Smckusick  * 4.3bsd dup allows dup2 to come in on the same syscall entry
309*41486Smckusick  * and hence allows two arguments.  HPUX dup has only one arg.
310*41486Smckusick  */
311*41486Smckusick hpuxdup()
312*41486Smckusick {
313*41486Smckusick 	register struct a {
314*41486Smckusick 		int	i;
315*41486Smckusick 	} *uap = (struct a *)u.u_ap;
316*41486Smckusick 	struct file *fp;
317*41486Smckusick 	int j;
318*41486Smckusick 
319*41486Smckusick 	if ((unsigned)uap->i >= NOFILE || (fp = u.u_ofile[uap->i]) == NULL) {
320*41486Smckusick 		u.u_error = EBADF;
321*41486Smckusick 		return;
322*41486Smckusick 	}
323*41486Smckusick 	u.u_error = ufalloc(0, &j);
324*41486Smckusick 	if (u.u_error)
325*41486Smckusick 		return;
326*41486Smckusick 	u.u_r.r_val1 = j;
327*41486Smckusick 	dupit(j, fp, u.u_pofile[uap->i] &~ UF_EXCLOSE);
328*41486Smckusick }
329*41486Smckusick 
330*41486Smckusick hpuxuname()
331*41486Smckusick {
332*41486Smckusick 	register struct a {
333*41486Smckusick 		struct hpuxutsname *uts;
334*41486Smckusick 		int dev;
335*41486Smckusick 		int request;
336*41486Smckusick 	} *uap = (struct a *)u.u_ap;
337*41486Smckusick 	register int i;
338*41486Smckusick 
339*41486Smckusick 	switch (uap->request) {
340*41486Smckusick 	/* uname */
341*41486Smckusick 	case 0:
342*41486Smckusick 		/* fill in machine type */
343*41486Smckusick 		switch (machineid) {
344*41486Smckusick 		case HP_320:
345*41486Smckusick 			protoutsname.machine[6] = '2';
346*41486Smckusick 			break;
347*41486Smckusick 		/* includes 318 and 319 */
348*41486Smckusick 		case HP_330:
349*41486Smckusick 			protoutsname.machine[6] = '3';
350*41486Smckusick 			break;
351*41486Smckusick 		case HP_340:
352*41486Smckusick 			protoutsname.machine[6] = '4';
353*41486Smckusick 			break;
354*41486Smckusick 		case HP_350:
355*41486Smckusick 			protoutsname.machine[6] = '5';
356*41486Smckusick 			break;
357*41486Smckusick 		case HP_360:
358*41486Smckusick 			protoutsname.machine[6] = '6';
359*41486Smckusick 			break;
360*41486Smckusick 		case HP_370:
361*41486Smckusick 			protoutsname.machine[6] = '7';
362*41486Smckusick 			break;
363*41486Smckusick 		}
364*41486Smckusick 		/* copy hostname (sans domain) to nodename */
365*41486Smckusick 		for (i = 0; i < 9 && hostname[i] != '.'; i++)
366*41486Smckusick 			protoutsname.nodename[i] = hostname[i];
367*41486Smckusick 		u.u_error = copyout((caddr_t)&protoutsname, (caddr_t)uap->uts,
368*41486Smckusick 				    sizeof(struct hpuxutsname));
369*41486Smckusick 		break;
370*41486Smckusick 	/* ustat - who cares? */
371*41486Smckusick 	case 2:
372*41486Smckusick 	default:
373*41486Smckusick 		u.u_error = EINVAL;
374*41486Smckusick 		break;
375*41486Smckusick 	}
376*41486Smckusick }
377*41486Smckusick 
378*41486Smckusick hpuxstat()
379*41486Smckusick {
380*41486Smckusick 	struct a {
381*41486Smckusick 		char	*fname;
382*41486Smckusick 		struct hpuxstat *hsb;
383*41486Smckusick 	} *uap = (struct a *)u.u_ap;
384*41486Smckusick 
385*41486Smckusick 	u.u_error = hpuxstat1(uap->fname, uap->hsb, FOLLOW);
386*41486Smckusick }
387*41486Smckusick 
388*41486Smckusick hpuxlstat()
389*41486Smckusick {
390*41486Smckusick 	struct a {
391*41486Smckusick 		char	*fname;
392*41486Smckusick 		struct	hpuxstat *hsb;
393*41486Smckusick 	} *uap = (struct a *) u.u_ap;
394*41486Smckusick 
395*41486Smckusick 	u.u_error = hpuxstat1(uap->fname, uap->hsb, NOFOLLOW);
396*41486Smckusick }
397*41486Smckusick 
398*41486Smckusick hpuxfstat()
399*41486Smckusick {
400*41486Smckusick 	register struct file *fp;
401*41486Smckusick 	register struct a {
402*41486Smckusick 		int	fdes;
403*41486Smckusick 		struct	hpuxstat *hsb;
404*41486Smckusick 	} *uap = (struct a *)u.u_ap;
405*41486Smckusick 	struct stat sb;
406*41486Smckusick 
407*41486Smckusick 	if ((unsigned)uap->fdes >= NOFILE ||
408*41486Smckusick 	    (fp = u.u_ofile[uap->fdes]) == NULL) {
409*41486Smckusick 		u.u_error = EBADF;
410*41486Smckusick 		return;
411*41486Smckusick 	}
412*41486Smckusick 	switch (fp->f_type) {
413*41486Smckusick 
414*41486Smckusick 	case DTYPE_VNODE:
415*41486Smckusick 		u.u_error = vn_stat((struct vnode *)fp->f_data, &sb);
416*41486Smckusick 		break;
417*41486Smckusick 
418*41486Smckusick 	case DTYPE_SOCKET:
419*41486Smckusick 		u.u_error = soo_stat((struct socket *)fp->f_data, &sb);
420*41486Smckusick 		break;
421*41486Smckusick 
422*41486Smckusick 	default:
423*41486Smckusick 		panic("fstat");
424*41486Smckusick 		/*NOTREACHED*/
425*41486Smckusick 	}
426*41486Smckusick 	/* is this right for sockets?? */
427*41486Smckusick 	if (u.u_error == 0)
428*41486Smckusick 		u.u_error = bsdtohpuxstat(&sb, uap->hsb);
429*41486Smckusick }
430*41486Smckusick 
431*41486Smckusick hpuxulimit()
432*41486Smckusick {
433*41486Smckusick 	struct a {
434*41486Smckusick 		int	cmd;
435*41486Smckusick 		long	newlimit;
436*41486Smckusick 	} *uap = (struct a *)u.u_ap;
437*41486Smckusick 	struct rlimit *limp;
438*41486Smckusick 
439*41486Smckusick 	limp = &u.u_rlimit[RLIMIT_FSIZE];
440*41486Smckusick 	switch (uap->cmd) {
441*41486Smckusick 	case 2:
442*41486Smckusick 		uap->newlimit *= 512;
443*41486Smckusick 		if (uap->newlimit > limp->rlim_max &&
444*41486Smckusick 		    (u.u_error = suser(u.u_cred, &u.u_acflag)))
445*41486Smckusick 			break;
446*41486Smckusick 		limp->rlim_cur = limp->rlim_max = uap->newlimit;
447*41486Smckusick 		/* else fall into... */
448*41486Smckusick 
449*41486Smckusick 	case 1:
450*41486Smckusick 		u.u_r.r_off = limp->rlim_max / 512;
451*41486Smckusick 		break;
452*41486Smckusick 
453*41486Smckusick 	case 3:
454*41486Smckusick 		limp = &u.u_rlimit[RLIMIT_DATA];
455*41486Smckusick 		u.u_r.r_off = ctob(u.u_tsize) + limp->rlim_max;
456*41486Smckusick 		break;
457*41486Smckusick 
458*41486Smckusick 	default:
459*41486Smckusick 		u.u_error = EINVAL;
460*41486Smckusick 		break;
461*41486Smckusick 	}
462*41486Smckusick }
463*41486Smckusick 
464*41486Smckusick /*
465*41486Smckusick  * Map "real time" priorities 0 (high) thru 127 (low) into nice
466*41486Smckusick  * values -16 (high) thru -1 (low).
467*41486Smckusick  */
468*41486Smckusick hpuxrtprio()
469*41486Smckusick {
470*41486Smckusick 	register struct a {
471*41486Smckusick 		int pid;
472*41486Smckusick 		int prio;
473*41486Smckusick 	} *uap = (struct a *)u.u_ap;
474*41486Smckusick 	struct proc *p;
475*41486Smckusick 	int nice;
476*41486Smckusick 
477*41486Smckusick 	if (uap->prio < RTPRIO_MIN && uap->prio > RTPRIO_MAX &&
478*41486Smckusick 	    uap->prio != RTPRIO_NOCHG && uap->prio != RTPRIO_RTOFF) {
479*41486Smckusick 		u.u_error = EINVAL;
480*41486Smckusick 		return;
481*41486Smckusick 	}
482*41486Smckusick 	if (uap->pid == 0)
483*41486Smckusick 		p = u.u_procp;
484*41486Smckusick 	else if ((p = pfind(uap->pid)) == 0) {
485*41486Smckusick 		u.u_error = ESRCH;
486*41486Smckusick 		return;
487*41486Smckusick 	}
488*41486Smckusick 	nice = p->p_nice;
489*41486Smckusick 	if (nice < NZERO)
490*41486Smckusick 		u.u_r.r_val1 = (nice + 16) << 3;
491*41486Smckusick 	else
492*41486Smckusick 		u.u_r.r_val1 = RTPRIO_RTOFF;
493*41486Smckusick 	switch (uap->prio) {
494*41486Smckusick 
495*41486Smckusick 	case RTPRIO_NOCHG:
496*41486Smckusick 		return;
497*41486Smckusick 
498*41486Smckusick 	case RTPRIO_RTOFF:
499*41486Smckusick 		if (nice >= NZERO)
500*41486Smckusick 			return;
501*41486Smckusick 		nice = NZERO;
502*41486Smckusick 		break;
503*41486Smckusick 
504*41486Smckusick 	default:
505*41486Smckusick 		nice = (uap->prio >> 3) - 16;
506*41486Smckusick 		break;
507*41486Smckusick 	}
508*41486Smckusick 	donice(p, nice);
509*41486Smckusick 	if (u.u_error == EACCES)
510*41486Smckusick 		u.u_error = EPERM;
511*41486Smckusick }
512*41486Smckusick 
513*41486Smckusick /*
514*41486Smckusick  * Kudos to HP folks for using such mnemonic names so I could figure
515*41486Smckusick  * out what this guy does.
516*41486Smckusick  */
517*41486Smckusick hpuxadvise()
518*41486Smckusick {
519*41486Smckusick 	struct a {
520*41486Smckusick 		int	arg;
521*41486Smckusick 	} *uap = (struct a *) u.u_ap;
522*41486Smckusick 
523*41486Smckusick 	switch (uap->arg) {
524*41486Smckusick 	case 0:
525*41486Smckusick 		u.u_pcb.pcb_flags |= PCB_HPUXMMAP;
526*41486Smckusick 		break;
527*41486Smckusick 	case 1:
528*41486Smckusick 		ICIA();
529*41486Smckusick 		break;
530*41486Smckusick 	case 2:
531*41486Smckusick 		DCIA();
532*41486Smckusick 		break;
533*41486Smckusick 	default:
534*41486Smckusick 		u.u_error = EINVAL;
535*41486Smckusick 		break;
536*41486Smckusick 	}
537*41486Smckusick }
538*41486Smckusick 
539*41486Smckusick hpuxptrace()
540*41486Smckusick {
541*41486Smckusick 	struct a {
542*41486Smckusick 		int	req;
543*41486Smckusick 		int	pid;
544*41486Smckusick 		int	*addr;
545*41486Smckusick 		int	data;
546*41486Smckusick 	} *uap = (struct a *)u.u_ap;
547*41486Smckusick 
548*41486Smckusick 	if (uap->req == PT_STEP || uap->req == PT_CONTINUE) {
549*41486Smckusick 		if (uap->data) {
550*41486Smckusick 			uap->data = hpuxtobsdsig(uap->data);
551*41486Smckusick 			if (uap->data == 0)
552*41486Smckusick 				uap->data = NSIG;
553*41486Smckusick 		}
554*41486Smckusick 	}
555*41486Smckusick 	ptrace();
556*41486Smckusick }
557*41486Smckusick 
558*41486Smckusick hpuxgetdomainname()
559*41486Smckusick {
560*41486Smckusick 	register struct a {
561*41486Smckusick 		char	*domainname;
562*41486Smckusick 		u_int	len;
563*41486Smckusick 	} *uap = (struct a *)u.u_ap;
564*41486Smckusick 
565*41486Smckusick 	if (uap->len > domainnamelen + 1)
566*41486Smckusick 		uap->len = domainnamelen + 1;
567*41486Smckusick 	u.u_error = copyout(domainname, uap->domainname, uap->len);
568*41486Smckusick }
569*41486Smckusick 
570*41486Smckusick hpuxsetdomainname()
571*41486Smckusick {
572*41486Smckusick 	register struct a {
573*41486Smckusick 		char	*domainname;
574*41486Smckusick 		u_int	len;
575*41486Smckusick 	} *uap = (struct a *)u.u_ap;
576*41486Smckusick 
577*41486Smckusick 	if (u.u_error = suser(u.u_cred, &u.u_acflag))
578*41486Smckusick 		return;
579*41486Smckusick 	if (uap->len > sizeof (domainname) - 1) {
580*41486Smckusick 		u.u_error = EINVAL;
581*41486Smckusick 		return;
582*41486Smckusick 	}
583*41486Smckusick 	domainnamelen = uap->len;
584*41486Smckusick 	u.u_error = copyin(uap->domainname, domainname, uap->len);
585*41486Smckusick 	domainname[domainnamelen] = 0;
586*41486Smckusick }
587*41486Smckusick 
588*41486Smckusick #ifdef SYSVSHM
589*41486Smckusick hpuxshmat()
590*41486Smckusick {
591*41486Smckusick 	shmat(u.u_ap);
592*41486Smckusick }
593*41486Smckusick 
594*41486Smckusick hpuxshmctl()
595*41486Smckusick {
596*41486Smckusick 	shmctl(u.u_ap);
597*41486Smckusick }
598*41486Smckusick 
599*41486Smckusick hpuxshmdt()
600*41486Smckusick {
601*41486Smckusick 	shmdt(u.u_ap);
602*41486Smckusick }
603*41486Smckusick 
604*41486Smckusick hpuxshmget()
605*41486Smckusick {
606*41486Smckusick 	shmget(u.u_ap);
607*41486Smckusick }
608*41486Smckusick #endif
609*41486Smckusick 
610*41486Smckusick /*
611*41486Smckusick  * Fake semaphore routines, just don't return an error.
612*41486Smckusick  * Should be adequate for starbase to run.
613*41486Smckusick  */
614*41486Smckusick hpuxsemctl()
615*41486Smckusick {
616*41486Smckusick 	struct a {
617*41486Smckusick 		int semid;
618*41486Smckusick 		u_int semnum;
619*41486Smckusick 		int cmd;
620*41486Smckusick 		int arg;
621*41486Smckusick 	} *uap = (struct a *)u.u_ap;
622*41486Smckusick 
623*41486Smckusick 	/* XXX: should do something here */
624*41486Smckusick }
625*41486Smckusick 
626*41486Smckusick hpuxsemget()
627*41486Smckusick {
628*41486Smckusick 	struct a {
629*41486Smckusick 		key_t key;
630*41486Smckusick 		int nsems;
631*41486Smckusick 		int semflg;
632*41486Smckusick 	} *uap = (struct a *)u.u_ap;
633*41486Smckusick 
634*41486Smckusick 	/* XXX: should do something here */
635*41486Smckusick }
636*41486Smckusick 
637*41486Smckusick hpuxsemop()
638*41486Smckusick {
639*41486Smckusick 	struct a {
640*41486Smckusick 		int semid;
641*41486Smckusick 		struct sembuf *sops;
642*41486Smckusick 		u_int nsops;
643*41486Smckusick 	} *uap = (struct a *)u.u_ap;
644*41486Smckusick 
645*41486Smckusick 	/* XXX: should do something here */
646*41486Smckusick }
647*41486Smckusick 
648*41486Smckusick /* convert from BSD to HPUX errno */
649*41486Smckusick bsdtohpuxerrno(err)
650*41486Smckusick 	int err;
651*41486Smckusick {
652*41486Smckusick 	if (err < 0 || err >= NERR)
653*41486Smckusick 		return(BERR);
654*41486Smckusick 	return((int)bsdtohpuxerrnomap[err]);
655*41486Smckusick }
656*41486Smckusick 
657*41486Smckusick hpuxstat1(fname, hsb, follow)
658*41486Smckusick 	char *fname;
659*41486Smckusick 	struct hpuxstat *hsb;
660*41486Smckusick 	int follow;
661*41486Smckusick {
662*41486Smckusick 	register struct nameidata *ndp = &u.u_nd;
663*41486Smckusick 	struct stat sb;
664*41486Smckusick 	int error;
665*41486Smckusick 
666*41486Smckusick 	ndp->ni_nameiop = LOOKUP | LOCKLEAF | follow;
667*41486Smckusick 	ndp->ni_segflg = UIO_USERSPACE;
668*41486Smckusick 	ndp->ni_dirp = fname;
669*41486Smckusick 	if (error = namei(ndp))
670*41486Smckusick 		return (error);
671*41486Smckusick 	error = vn_stat(ndp->ni_vp, &sb);
672*41486Smckusick 	vput(ndp->ni_vp);
673*41486Smckusick 	if (error == 0)
674*41486Smckusick 		error = bsdtohpuxstat(&sb, hsb);
675*41486Smckusick 	return (error);
676*41486Smckusick }
677*41486Smckusick 
678*41486Smckusick #include "grf.h"
679*41486Smckusick 
680*41486Smckusick bsdtohpuxstat(sb, hsb)
681*41486Smckusick 	struct stat *sb;
682*41486Smckusick 	struct hpuxstat *hsb;
683*41486Smckusick {
684*41486Smckusick 	struct hpuxstat ds;
685*41486Smckusick 
686*41486Smckusick 	bzero((caddr_t)&ds, sizeof(ds));
687*41486Smckusick 	ds.hst_dev = sb->st_dev;
688*41486Smckusick 	ds.hst_ino = (u_long)sb->st_ino;
689*41486Smckusick 	ds.hst_mode = sb->st_mode;
690*41486Smckusick 	ds.hst_nlink = sb->st_nlink;
691*41486Smckusick 	ds.hst_uid = (u_short)sb->st_uid;
692*41486Smckusick 	ds.hst_gid = (u_short)sb->st_gid;
693*41486Smckusick #if NGRF > 0
694*41486Smckusick 	/* XXX: I don't want to talk about it... */
695*41486Smckusick 	if ((sb->st_mode & S_IFMT) == S_IFCHR && major(sb->st_rdev) == 10)
696*41486Smckusick 		ds.hst_rdev = grfdevno(sb->st_rdev);
697*41486Smckusick 	else
698*41486Smckusick #endif
699*41486Smckusick 		ds.hst_rdev = bsdtohpuxdev(sb->st_rdev);
700*41486Smckusick 	ds.hst_size = sb->st_size;
701*41486Smckusick 	ds.hst_atime = sb->st_atime;
702*41486Smckusick 	ds.hst_mtime = sb->st_mtime;
703*41486Smckusick 	ds.hst_ctime = sb->st_ctime;
704*41486Smckusick 	ds.hst_blksize = sb->st_blksize;
705*41486Smckusick 	ds.hst_blocks = sb->st_blocks;
706*41486Smckusick 	return(copyout((caddr_t)&ds, (caddr_t)hsb, sizeof(ds)));
707*41486Smckusick }
708*41486Smckusick 
709*41486Smckusick hpuxtobsdioctl(com)
710*41486Smckusick 	int com;
711*41486Smckusick {
712*41486Smckusick 	switch (com) {
713*41486Smckusick 	case HPUXTIOCSLTC:
714*41486Smckusick 		com = TIOCSLTC; break;
715*41486Smckusick 	case HPUXTIOCGLTC:
716*41486Smckusick 		com = TIOCGLTC; break;
717*41486Smckusick 	case HPUXTIOCSPGRP:
718*41486Smckusick 		com = TIOCSPGRP; break;
719*41486Smckusick 	case HPUXTIOCGPGRP:
720*41486Smckusick 		com = TIOCGPGRP; break;
721*41486Smckusick 	case HPUXTIOCLBIS:
722*41486Smckusick 		com = TIOCLBIS; break;
723*41486Smckusick 	case HPUXTIOCLBIC:
724*41486Smckusick 		com = TIOCLBIC; break;
725*41486Smckusick 	case HPUXTIOCLSET:
726*41486Smckusick 		com = TIOCLSET; break;
727*41486Smckusick 	case HPUXTIOCLGET:
728*41486Smckusick 		com = TIOCLGET; break;
729*41486Smckusick 	}
730*41486Smckusick 	return(com);
731*41486Smckusick }
732*41486Smckusick 
733*41486Smckusick /*
734*41486Smckusick  * HPUX ioctl system call.  The differences here are:
735*41486Smckusick  *	IOC_IN also means IOC_VOID if the size portion is zero.
736*41486Smckusick  *	no FIOCLEX/FIONCLEX/FIONBIO/FIOASYNC/FIOGETOWN/FIOSETOWN
737*41486Smckusick  *	the sgttyb struct is 2 bytes longer
738*41486Smckusick  */
739*41486Smckusick hpuxioctl()
740*41486Smckusick {
741*41486Smckusick 	register struct file *fp;
742*41486Smckusick 	struct a {
743*41486Smckusick 		int	fdes;
744*41486Smckusick 		int	cmd;
745*41486Smckusick 		caddr_t	cmarg;
746*41486Smckusick 	} *uap = (struct a *)u.u_ap;
747*41486Smckusick 	register int com;
748*41486Smckusick 	register u_int size;
749*41486Smckusick 	caddr_t memp = 0;
750*41486Smckusick #define STK_PARAMS	128
751*41486Smckusick 	char stkbuf[STK_PARAMS];
752*41486Smckusick 	caddr_t data = stkbuf;
753*41486Smckusick 
754*41486Smckusick 	com = uap->cmd;
755*41486Smckusick 
756*41486Smckusick 	/* XXX */
757*41486Smckusick 	if (com == HPUXTIOCGETP || com == HPUXTIOCSETP) {
758*41486Smckusick 		getsettty(uap->fdes, com, uap->cmarg);
759*41486Smckusick 		return;
760*41486Smckusick 	}
761*41486Smckusick 
762*41486Smckusick 	if ((unsigned)uap->fdes >= NOFILE ||
763*41486Smckusick 	    (fp = u.u_ofile[uap->fdes]) == NULL) {
764*41486Smckusick 		u.u_error = EBADF;
765*41486Smckusick 		return;
766*41486Smckusick 	}
767*41486Smckusick 	if ((fp->f_flag & (FREAD|FWRITE)) == 0) {
768*41486Smckusick 		u.u_error = EBADF;
769*41486Smckusick 		return;
770*41486Smckusick 	}
771*41486Smckusick 
772*41486Smckusick 	/*
773*41486Smckusick 	 * Interpret high order word to find
774*41486Smckusick 	 * amount of data to be copied to/from the
775*41486Smckusick 	 * user's address space.
776*41486Smckusick 	 */
777*41486Smckusick 	size = IOCPARM_LEN(com);
778*41486Smckusick 	if (size > IOCPARM_MAX) {
779*41486Smckusick 		u.u_error = EFAULT;
780*41486Smckusick 		return;
781*41486Smckusick 	}
782*41486Smckusick 	if (size > sizeof (stkbuf)) {
783*41486Smckusick 		memp = (caddr_t)malloc((u_long)IOCPARM_MAX, M_IOCTLOPS,
784*41486Smckusick 		    M_WAITOK);
785*41486Smckusick 		data = memp;
786*41486Smckusick 	}
787*41486Smckusick 	if (com&IOC_IN) {
788*41486Smckusick 		if (size) {
789*41486Smckusick 			u.u_error = copyin(uap->cmarg, data, (u_int)size);
790*41486Smckusick 			if (u.u_error) {
791*41486Smckusick 				if (memp)
792*41486Smckusick 					free(memp, M_IOCTLOPS);
793*41486Smckusick 				return;
794*41486Smckusick 			}
795*41486Smckusick 		} else
796*41486Smckusick 			*(caddr_t *)data = uap->cmarg;
797*41486Smckusick 	} else if ((com&IOC_OUT) && size)
798*41486Smckusick 		/*
799*41486Smckusick 		 * Zero the buffer on the stack so the user
800*41486Smckusick 		 * always gets back something deterministic.
801*41486Smckusick 		 */
802*41486Smckusick 		bzero(data, size);
803*41486Smckusick 	else if (com&IOC_VOID)
804*41486Smckusick 		*(caddr_t *)data = uap->cmarg;
805*41486Smckusick 
806*41486Smckusick 	switch (com) {
807*41486Smckusick 
808*41486Smckusick 	case HPUXTIOCCONS:
809*41486Smckusick 		*(int *)data = 1;
810*41486Smckusick 		u.u_error = (*fp->f_ops->fo_ioctl)(fp, TIOCCONS, data);
811*41486Smckusick 		break;
812*41486Smckusick 
813*41486Smckusick 	/* BSD-style job control ioctls */
814*41486Smckusick 	case HPUXTIOCLBIS:
815*41486Smckusick 	case HPUXTIOCLBIC:
816*41486Smckusick 	case HPUXTIOCLSET:
817*41486Smckusick 		*(int *)data &= HPUXLTOSTOP;
818*41486Smckusick 		if (*(int *)data & HPUXLTOSTOP)
819*41486Smckusick 			*(int *)data = LTOSTOP;
820*41486Smckusick 		/* fall into */
821*41486Smckusick 	case HPUXTIOCLGET:
822*41486Smckusick 	case HPUXTIOCSLTC:
823*41486Smckusick 	case HPUXTIOCGLTC:
824*41486Smckusick 	case HPUXTIOCSPGRP:
825*41486Smckusick 	case HPUXTIOCGPGRP:
826*41486Smckusick 		u.u_error = (*fp->f_ops->fo_ioctl)(fp, hpuxtobsdioctl(com), data);
827*41486Smckusick 		if (u.u_error == 0 && com == HPUXTIOCLGET) {
828*41486Smckusick 			*(int *)data &= LTOSTOP;
829*41486Smckusick 			if (*(int *)data & LTOSTOP)
830*41486Smckusick 				*(int *)data = HPUXLTOSTOP;
831*41486Smckusick 		}
832*41486Smckusick 		break;
833*41486Smckusick 
834*41486Smckusick 	/* SYS 5 termio */
835*41486Smckusick 	case HPUXTCGETA:
836*41486Smckusick 	case HPUXTCSETA:
837*41486Smckusick 	case HPUXTCSETAW:
838*41486Smckusick 	case HPUXTCSETAF:
839*41486Smckusick 		u.u_error = hpuxtermio(fp, com, data);
840*41486Smckusick 		break;
841*41486Smckusick 
842*41486Smckusick 	default:
843*41486Smckusick 		u.u_error = (*fp->f_ops->fo_ioctl)(fp, com, data);
844*41486Smckusick 		break;
845*41486Smckusick 	}
846*41486Smckusick 	/*
847*41486Smckusick 	 * Copy any data to user, size was
848*41486Smckusick 	 * already set and checked above.
849*41486Smckusick 	 */
850*41486Smckusick 	if (u.u_error == 0 && (com&IOC_OUT) && size)
851*41486Smckusick 		u.u_error = copyout(data, uap->cmarg, (u_int)size);
852*41486Smckusick 	if (memp)
853*41486Smckusick 		free(memp, M_IOCTLOPS);
854*41486Smckusick }
855*41486Smckusick 
856*41486Smckusick /*
857*41486Smckusick  * Man page lies, behaviour here is based on observed behaviour.
858*41486Smckusick  */
859*41486Smckusick hpuxgetcontext()
860*41486Smckusick {
861*41486Smckusick 	struct a {
862*41486Smckusick 		char *buf;
863*41486Smckusick 		int len;
864*41486Smckusick 	} *uap = (struct a *)u.u_ap;
865*41486Smckusick 	int error = 0;
866*41486Smckusick 	register int len;
867*41486Smckusick 
868*41486Smckusick 	len = MIN(uap->len, sizeof(hpuxcontext));
869*41486Smckusick 	if (len)
870*41486Smckusick 		error = copyout(hpuxcontext, uap->buf, (u_int)len);
871*41486Smckusick 	if (!error)
872*41486Smckusick 		u.u_r.r_val1 = sizeof(hpuxcontext);
873*41486Smckusick 	return(error);
874*41486Smckusick }
875*41486Smckusick 
876*41486Smckusick /*
877*41486Smckusick  * XXX: simple recognition hack to see if we can make grmd work.
878*41486Smckusick  */
879*41486Smckusick hpuxlockf()
880*41486Smckusick {
881*41486Smckusick 	struct a {
882*41486Smckusick 		int fd;
883*41486Smckusick 		int func;
884*41486Smckusick 		long size;
885*41486Smckusick 	} *uap = (struct a *)u.u_ap;
886*41486Smckusick #ifdef DEBUG
887*41486Smckusick 	log(LOG_DEBUG, "%d: lockf(%d, %d, %d)\n",
888*41486Smckusick 	    u.u_procp->p_pid, uap->fd, uap->func, uap->size);
889*41486Smckusick #endif
890*41486Smckusick 	return(0);
891*41486Smckusick }
892*41486Smckusick 
893*41486Smckusick /*
894*41486Smckusick  * This is the equivalent of BSD getpgrp but with more restrictions.
895*41486Smckusick  * Note we do not check the real uid or "saved" uid.
896*41486Smckusick  */
897*41486Smckusick hpuxgetpgrp2()
898*41486Smckusick {
899*41486Smckusick 	register struct proc *p;
900*41486Smckusick 	register struct a {
901*41486Smckusick 		int pid;
902*41486Smckusick 	} *uap = (struct a *)u.u_ap;
903*41486Smckusick 
904*41486Smckusick 	if (uap->pid == 0)
905*41486Smckusick 		uap->pid = u.u_procp->p_pid;
906*41486Smckusick 	p = pfind(uap->pid);
907*41486Smckusick 	if (p == 0) {
908*41486Smckusick 		u.u_error = ESRCH;
909*41486Smckusick 		return;
910*41486Smckusick 	}
911*41486Smckusick 	if (u.u_uid && p->p_uid != u.u_uid && !inferior(p)) {
912*41486Smckusick 		u.u_error = EPERM;
913*41486Smckusick 		return;
914*41486Smckusick 	}
915*41486Smckusick 	u.u_r.r_val1 = p->p_pgid;
916*41486Smckusick }
917*41486Smckusick 
918*41486Smckusick /*
919*41486Smckusick  * This is the equivalent of BSD setpgrp but with more restrictions.
920*41486Smckusick  * Note we do not check the real uid or "saved" uid or pgrp.
921*41486Smckusick  */
922*41486Smckusick hpuxsetpgrp2()
923*41486Smckusick {
924*41486Smckusick 	struct a {
925*41486Smckusick 		int	pid;
926*41486Smckusick 		int	pgrp;
927*41486Smckusick 	} *uap = (struct a *)u.u_ap;
928*41486Smckusick 
929*41486Smckusick 	/* empirically determined */
930*41486Smckusick 	if (uap->pgrp < 0 || uap->pgrp >= 30000) {
931*41486Smckusick 		u.u_error = EINVAL;
932*41486Smckusick 		return;
933*41486Smckusick 	}
934*41486Smckusick 	setpgrp();
935*41486Smckusick }
936*41486Smckusick 
937*41486Smckusick /*
938*41486Smckusick  * Brutal hack!  Map HPUX u-area offsets into BSD u offsets.
939*41486Smckusick  * No apologies offered, if you don't like it, rewrite it!
940*41486Smckusick  */
941*41486Smckusick 
942*41486Smckusick #define UOFF(f)		((int)&((struct user *)0)->f)
943*41486Smckusick #define HPUOFF(f)	((int)&((struct hpuxuser *)0)->f)
944*41486Smckusick 
945*41486Smckusick /* simplified FP structure */
946*41486Smckusick struct bsdfp {
947*41486Smckusick 	int save[54];
948*41486Smckusick 	int reg[24];
949*41486Smckusick 	int ctrl[3];
950*41486Smckusick };
951*41486Smckusick 
952*41486Smckusick hpuxtobsduoff(off)
953*41486Smckusick 	int *off;
954*41486Smckusick {
955*41486Smckusick 	struct hpuxfp *hp;
956*41486Smckusick 	struct bsdfp *bp;
957*41486Smckusick 	register u_int raddr;
958*41486Smckusick 
959*41486Smckusick 	/* u_ar0 field */
960*41486Smckusick 	if ((int)off == HPUOFF(hpuxu_ar0))
961*41486Smckusick 		return(UOFF(u_ar0));
962*41486Smckusick 
963*41486Smckusick #ifdef FPCOPROC
964*41486Smckusick 	/* 68881 registers from PCB */
965*41486Smckusick 	hp = (struct hpuxfp *)HPUOFF(hpuxu_fp);
966*41486Smckusick 	bp = (struct bsdfp *)UOFF(u_pcb.pcb_fpregs);
967*41486Smckusick 	if (off >= hp->hpfp_ctrl && off < &hp->hpfp_ctrl[3])
968*41486Smckusick 		return((int)&bp->ctrl[off - hp->hpfp_ctrl]);
969*41486Smckusick 	if (off >= hp->hpfp_reg && off < &hp->hpfp_reg[24])
970*41486Smckusick 		return((int)&bp->reg[off - hp->hpfp_reg]);
971*41486Smckusick #endif
972*41486Smckusick 
973*41486Smckusick 	/*
974*41486Smckusick 	 * Everything else we recognize comes from the kernel stack,
975*41486Smckusick 	 * so we convert off to an absolute address (if not already)
976*41486Smckusick 	 * for simplicity.
977*41486Smckusick 	 */
978*41486Smckusick 	if (off < (int *)ctob(UPAGES))
979*41486Smckusick 		off = (int *)((u_int)off + (u_int)&u);
980*41486Smckusick 
981*41486Smckusick 	/*
982*41486Smckusick 	 * 68020 registers.
983*41486Smckusick 	 * We know that the HPUX registers are in the same order as ours.
984*41486Smckusick 	 * The only difference is that their PS is 2 bytes instead of a
985*41486Smckusick 	 * padded 4 like ours throwing the alignment off.
986*41486Smckusick 	 */
987*41486Smckusick 	if (off >= u.u_ar0 && off < &u.u_ar0[18]) {
988*41486Smckusick 		/*
989*41486Smckusick 		 * PS: return low word and high word of PC as HP-UX would
990*41486Smckusick 		 * (e.g. &u.u_ar0[16.5]).
991*41486Smckusick 		 */
992*41486Smckusick 		if (off == &u.u_ar0[PS])
993*41486Smckusick 			raddr = (u_int) &((short *)u.u_ar0)[PS*2+1];
994*41486Smckusick 		/*
995*41486Smckusick 		 * PC: off will be &u.u_ar0[16.5]
996*41486Smckusick 		 */
997*41486Smckusick 		else if (off == (int *)&(((short *)u.u_ar0)[PS*2+1]))
998*41486Smckusick 			raddr = (u_int) &u.u_ar0[PC];
999*41486Smckusick 		/*
1000*41486Smckusick 		 * D0-D7, A0-A7: easy
1001*41486Smckusick 		 */
1002*41486Smckusick 		else
1003*41486Smckusick 			raddr = (u_int) &u.u_ar0[(int)(off - u.u_ar0)];
1004*41486Smckusick 		return((int)(raddr - (u_int)&u));
1005*41486Smckusick 	}
1006*41486Smckusick 
1007*41486Smckusick 	/* everything else */
1008*41486Smckusick 	return(-1);
1009*41486Smckusick }
1010*41486Smckusick 
1011*41486Smckusick /*
1012*41486Smckusick  * Kludge up a uarea dump so that HPUX debuggers can find out
1013*41486Smckusick  * what they need.  IMPORTANT NOTE: we do not EVEN attempt to
1014*41486Smckusick  * convert the entire user struct.
1015*41486Smckusick  */
1016*41486Smckusick hpuxdumpu(vp, cred)
1017*41486Smckusick 	struct vnode *vp;
1018*41486Smckusick 	struct ucred *cred;
1019*41486Smckusick {
1020*41486Smckusick 	int error;
1021*41486Smckusick 	struct hpuxuser *faku;
1022*41486Smckusick 	struct bsdfp *bp;
1023*41486Smckusick 	short *foop;
1024*41486Smckusick 
1025*41486Smckusick 	faku = (struct hpuxuser *)malloc((u_long)ctob(1), M_TEMP, M_WAITOK);
1026*41486Smckusick 	/*
1027*41486Smckusick 	 * Make sure there is no mistake about this
1028*41486Smckusick 	 * being a real user structure.
1029*41486Smckusick 	 */
1030*41486Smckusick 	bzero((caddr_t)faku, ctob(1));
1031*41486Smckusick 	/*
1032*41486Smckusick 	 * Fill in the process sizes.
1033*41486Smckusick 	 */
1034*41486Smckusick 	faku->hpuxu_tsize = u.u_tsize;
1035*41486Smckusick 	faku->hpuxu_dsize = u.u_dsize;
1036*41486Smckusick 	faku->hpuxu_ssize = u.u_ssize;
1037*41486Smckusick 	/*
1038*41486Smckusick 	 * Fill in the exec header for CDB.
1039*41486Smckusick 	 * This was saved back in exec().  As far as I can tell CDB
1040*41486Smckusick 	 * only uses this information to verify that a particular
1041*41486Smckusick 	 * core file goes with a particular binary.
1042*41486Smckusick 	 */
1043*41486Smckusick 	bcopy((caddr_t)u.u_pcb.pcb_exec,
1044*41486Smckusick 	      (caddr_t)&faku->hpuxu_exdata, sizeof (struct hpux_exec));
1045*41486Smckusick 	/*
1046*41486Smckusick 	 * Adjust user's saved registers (on kernel stack) to reflect
1047*41486Smckusick 	 * HPUX order.  Note that HPUX saves the SR as 2 bytes not 4
1048*41486Smckusick 	 * so we have to move it up.
1049*41486Smckusick 	 */
1050*41486Smckusick 	faku->hpuxu_ar0 = u.u_ar0;
1051*41486Smckusick 	foop = (short *) u.u_ar0;
1052*41486Smckusick 	foop[32] = foop[33];
1053*41486Smckusick 	foop[33] = foop[34];
1054*41486Smckusick 	foop[34] = foop[35];
1055*41486Smckusick #ifdef FPCOPROC
1056*41486Smckusick 	/*
1057*41486Smckusick 	 * Copy 68881 registers from our PCB format to HPUX format
1058*41486Smckusick 	 */
1059*41486Smckusick 	bp = (struct bsdfp *) &u.u_pcb.pcb_fpregs;
1060*41486Smckusick 	bcopy((caddr_t)bp->save, (caddr_t)faku->hpuxu_fp.hpfp_save,
1061*41486Smckusick 	      sizeof(bp->save));
1062*41486Smckusick 	bcopy((caddr_t)bp->ctrl, (caddr_t)faku->hpuxu_fp.hpfp_ctrl,
1063*41486Smckusick 	      sizeof(bp->ctrl));
1064*41486Smckusick 	bcopy((caddr_t)bp->reg, (caddr_t)faku->hpuxu_fp.hpfp_reg,
1065*41486Smckusick 	      sizeof(bp->reg));
1066*41486Smckusick #endif
1067*41486Smckusick 	/*
1068*41486Smckusick 	 * Slay the dragon
1069*41486Smckusick 	 */
1070*41486Smckusick 	faku->hpuxu_dragon = -1;
1071*41486Smckusick 	/*
1072*41486Smckusick 	 * Dump this artfully constructed page in place of the
1073*41486Smckusick 	 * user struct page.
1074*41486Smckusick 	 */
1075*41486Smckusick 	error = vn_rdwr(UIO_WRITE, vp,
1076*41486Smckusick 			(caddr_t)faku, ctob(1), (off_t)0,
1077*41486Smckusick 			UIO_SYSSPACE, IO_NODELOCKED|IO_UNIT, cred, (int *)0);
1078*41486Smckusick 	/*
1079*41486Smckusick 	 * Dump the remaining UPAGES-1 pages normally
1080*41486Smckusick 	 */
1081*41486Smckusick 	if (!error)
1082*41486Smckusick 		error = vn_rdwr(UIO_WRITE, vp, ((caddr_t)&u)+ctob(1),
1083*41486Smckusick 				ctob(UPAGES-1), (off_t)ctob(1), UIO_SYSSPACE,
1084*41486Smckusick 				IO_NODELOCKED|IO_UNIT, cred, (int *)0);
1085*41486Smckusick 	free((caddr_t)faku, M_TEMP);
1086*41486Smckusick 	return(error);
1087*41486Smckusick }
1088*41486Smckusick 
1089*41486Smckusick /*
1090*41486Smckusick  * The remaining routines are essentially the same as those in kern_xxx.c
1091*41486Smckusick  * and vfs_xxx.c as defined under "#ifdef COMPAT".  We replicate them here
1092*41486Smckusick  * to avoid HPUXCOMPAT dependencies in those files and to make sure that
1093*41486Smckusick  * HP-UX compatibility still works even when COMPAT is not defined.
1094*41486Smckusick  */
1095*41486Smckusick /* #ifdef COMPAT */
1096*41486Smckusick 
1097*41486Smckusick #include "../h/times.h"
1098*41486Smckusick 
1099*41486Smckusick /* from old timeb.h */
1100*41486Smckusick struct hpuxtimeb {
1101*41486Smckusick 	time_t	time;
1102*41486Smckusick 	u_short	millitm;
1103*41486Smckusick 	short	timezone;
1104*41486Smckusick 	short	dstflag;
1105*41486Smckusick };
1106*41486Smckusick 
1107*41486Smckusick /* ye ole stat structure */
1108*41486Smckusick struct	ohpuxstat {
1109*41486Smckusick 	dev_t	ohst_dev;
1110*41486Smckusick 	u_short	ohst_ino;
1111*41486Smckusick 	u_short ohst_mode;
1112*41486Smckusick 	short  	ohst_nlink;
1113*41486Smckusick 	short  	ohst_uid;
1114*41486Smckusick 	short  	ohst_gid;
1115*41486Smckusick 	dev_t	ohst_rdev;
1116*41486Smckusick 	int	ohst_size;
1117*41486Smckusick 	int	ohst_atime;
1118*41486Smckusick 	int	ohst_mtime;
1119*41486Smckusick 	int	ohst_ctime;
1120*41486Smckusick };
1121*41486Smckusick 
1122*41486Smckusick /*
1123*41486Smckusick  * Right now the following two routines are the same as the 4.3
1124*41486Smckusick  * osetuid/osetgid calls.  Eventually they need to be changed to
1125*41486Smckusick  * implement the notion of "saved" ids (whatever that means).
1126*41486Smckusick  */
1127*41486Smckusick ohpuxsetuid()
1128*41486Smckusick {
1129*41486Smckusick 	register uid;
1130*41486Smckusick 	register struct a {
1131*41486Smckusick 		int	uid;
1132*41486Smckusick 	} *uap = (struct a *)u.u_ap;
1133*41486Smckusick 
1134*41486Smckusick 	uid = uap->uid;
1135*41486Smckusick 	if (uid != u.u_procp->p_ruid && uid != u.u_cred->cr_uid &&
1136*41486Smckusick 	    (u.u_error = suser(u.u_cred, &u.u_acflag)))
1137*41486Smckusick 		return;
1138*41486Smckusick 	if (u.u_cred->cr_ref > 1)
1139*41486Smckusick 		u.u_cred = crcopy(u.u_cred);
1140*41486Smckusick 	u.u_cred->cr_uid = uid;
1141*41486Smckusick 	u.u_procp->p_uid = uid;
1142*41486Smckusick 	u.u_procp->p_ruid = uid;
1143*41486Smckusick }
1144*41486Smckusick 
1145*41486Smckusick ohpuxsetgid()
1146*41486Smckusick {
1147*41486Smckusick 	register gid;
1148*41486Smckusick 	register struct a {
1149*41486Smckusick 		int	gid;
1150*41486Smckusick 	} *uap = (struct a *)u.u_ap;
1151*41486Smckusick 
1152*41486Smckusick 	gid = uap->gid;
1153*41486Smckusick 	if (u.u_procp->p_rgid != gid && u.u_cred->cr_groups[0] != gid &&
1154*41486Smckusick 	    (u.u_error = suser(u.u_cred, &u.u_acflag)))
1155*41486Smckusick 		return;
1156*41486Smckusick 	if (u.u_cred->cr_ref > 1)
1157*41486Smckusick 		u.u_cred = crcopy(u.u_cred);
1158*41486Smckusick 	u.u_procp->p_rgid = gid;
1159*41486Smckusick 	u.u_cred->cr_groups[0] = gid;
1160*41486Smckusick }
1161*41486Smckusick 
1162*41486Smckusick /*
1163*41486Smckusick  * SYS V style setpgrp()
1164*41486Smckusick  */
1165*41486Smckusick ohpuxsetpgrp()
1166*41486Smckusick {
1167*41486Smckusick 	register struct proc *p = u.u_procp;
1168*41486Smckusick 
1169*41486Smckusick 	if (p->p_pid != p->p_pgid)
1170*41486Smckusick 		pgmv(p, p->p_pid, 0);
1171*41486Smckusick 	u.u_r.r_val1 = p->p_pgid;
1172*41486Smckusick }
1173*41486Smckusick 
1174*41486Smckusick ohpuxtime()
1175*41486Smckusick {
1176*41486Smckusick 	register struct a {
1177*41486Smckusick 		long	*tp;
1178*41486Smckusick 	} *uap = (struct a *)u.u_ap;
1179*41486Smckusick 
1180*41486Smckusick 	if (uap->tp)
1181*41486Smckusick 		u.u_error = copyout((caddr_t)&time.tv_sec, (caddr_t)uap->tp,
1182*41486Smckusick 				    sizeof (long));
1183*41486Smckusick 	u.u_r.r_time = time.tv_sec;
1184*41486Smckusick }
1185*41486Smckusick 
1186*41486Smckusick ohpuxstime()
1187*41486Smckusick {
1188*41486Smckusick 	register struct a {
1189*41486Smckusick 		int	time;
1190*41486Smckusick 	} *uap = (struct a *)u.u_ap;
1191*41486Smckusick 	struct timeval tv;
1192*41486Smckusick 	int s;
1193*41486Smckusick 
1194*41486Smckusick 	tv.tv_sec = uap->time;
1195*41486Smckusick 	tv.tv_usec = 0;
1196*41486Smckusick 	u.u_error = suser(u.u_cred, &u.u_acflag);
1197*41486Smckusick 	if (u.u_error)
1198*41486Smckusick 		return;
1199*41486Smckusick 
1200*41486Smckusick 	/* WHAT DO WE DO ABOUT PENDING REAL-TIME TIMEOUTS??? */
1201*41486Smckusick 	boottime.tv_sec += tv.tv_sec - time.tv_sec;
1202*41486Smckusick 	s = splhigh(); time = tv; splx(s);
1203*41486Smckusick 	resettodr();
1204*41486Smckusick }
1205*41486Smckusick 
1206*41486Smckusick ohpuxftime()
1207*41486Smckusick {
1208*41486Smckusick 	register struct a {
1209*41486Smckusick 		struct	hpuxtimeb *tp;
1210*41486Smckusick 	} *uap;
1211*41486Smckusick 	struct hpuxtimeb tb;
1212*41486Smckusick 	int s;
1213*41486Smckusick 
1214*41486Smckusick 	uap = (struct a *)u.u_ap;
1215*41486Smckusick 	s = splhigh();
1216*41486Smckusick 	tb.time = time.tv_sec;
1217*41486Smckusick 	tb.millitm = time.tv_usec / 1000;
1218*41486Smckusick 	splx(s);
1219*41486Smckusick 	tb.timezone = tz.tz_minuteswest;
1220*41486Smckusick 	tb.dstflag = tz.tz_dsttime;
1221*41486Smckusick 	u.u_error = copyout((caddr_t)&tb, (caddr_t)uap->tp, sizeof (tb));
1222*41486Smckusick }
1223*41486Smckusick 
1224*41486Smckusick ohpuxalarm()
1225*41486Smckusick {
1226*41486Smckusick 	register struct a {
1227*41486Smckusick 		int	deltat;
1228*41486Smckusick 	} *uap = (struct a *)u.u_ap;
1229*41486Smckusick 	register struct proc *p = u.u_procp;
1230*41486Smckusick 	int s = splhigh();
1231*41486Smckusick 
1232*41486Smckusick 	untimeout(realitexpire, (caddr_t)p);
1233*41486Smckusick 	timerclear(&p->p_realtimer.it_interval);
1234*41486Smckusick 	u.u_r.r_val1 = 0;
1235*41486Smckusick 	if (timerisset(&p->p_realtimer.it_value) &&
1236*41486Smckusick 	    timercmp(&p->p_realtimer.it_value, &time, >))
1237*41486Smckusick 		u.u_r.r_val1 = p->p_realtimer.it_value.tv_sec - time.tv_sec;
1238*41486Smckusick 	if (uap->deltat == 0) {
1239*41486Smckusick 		timerclear(&p->p_realtimer.it_value);
1240*41486Smckusick 		splx(s);
1241*41486Smckusick 		return;
1242*41486Smckusick 	}
1243*41486Smckusick 	p->p_realtimer.it_value = time;
1244*41486Smckusick 	p->p_realtimer.it_value.tv_sec += uap->deltat;
1245*41486Smckusick 	timeout(realitexpire, (caddr_t)p, hzto(&p->p_realtimer.it_value));
1246*41486Smckusick 	splx(s);
1247*41486Smckusick }
1248*41486Smckusick 
1249*41486Smckusick ohpuxnice()
1250*41486Smckusick {
1251*41486Smckusick 	register struct a {
1252*41486Smckusick 		int	niceness;
1253*41486Smckusick 	} *uap = (struct a *)u.u_ap;
1254*41486Smckusick 	register struct proc *p = u.u_procp;
1255*41486Smckusick 
1256*41486Smckusick 	donice(p, (p->p_nice-NZERO)+uap->niceness);
1257*41486Smckusick 	u.u_r.r_val1 = p->p_nice - NZERO;
1258*41486Smckusick }
1259*41486Smckusick 
1260*41486Smckusick ohpuxtimes()
1261*41486Smckusick {
1262*41486Smckusick 	register struct a {
1263*41486Smckusick 		struct	tms *tmsb;
1264*41486Smckusick 	} *uap = (struct a *)u.u_ap;
1265*41486Smckusick 	struct tms atms;
1266*41486Smckusick 
1267*41486Smckusick 	atms.tms_utime = scale50(&u.u_ru.ru_utime);
1268*41486Smckusick 	atms.tms_stime = scale50(&u.u_ru.ru_stime);
1269*41486Smckusick 	atms.tms_cutime = scale50(&u.u_cru.ru_utime);
1270*41486Smckusick 	atms.tms_cstime = scale50(&u.u_cru.ru_stime);
1271*41486Smckusick 	u.u_error = copyout((caddr_t)&atms, (caddr_t)uap->tmsb, sizeof (atms));
1272*41486Smckusick 	if (u.u_error == 0)
1273*41486Smckusick 		u.u_r.r_time = scale50(&time) - scale50(&boottime);
1274*41486Smckusick }
1275*41486Smckusick 
1276*41486Smckusick scale50(tvp)
1277*41486Smckusick 	register struct timeval *tvp;
1278*41486Smckusick {
1279*41486Smckusick 	extern int hpuxtick;
1280*41486Smckusick 
1281*41486Smckusick 	/*
1282*41486Smckusick 	 * Doesn't exactly do what the documentation says.
1283*41486Smckusick 	 * What we really do is return 50th of a second since that
1284*41486Smckusick 	 * is what HZ is on all bobcats I know of.
1285*41486Smckusick 	 */
1286*41486Smckusick 	return ((tvp->tv_sec * 50 + tvp->tv_usec / hpuxtick));
1287*41486Smckusick }
1288*41486Smckusick 
1289*41486Smckusick /*
1290*41486Smckusick  * Set IUPD and IACC times on file.
1291*41486Smckusick  * Can't set ICHG.
1292*41486Smckusick  */
1293*41486Smckusick ohpuxutime()
1294*41486Smckusick {
1295*41486Smckusick 	register struct a {
1296*41486Smckusick 		char	*fname;
1297*41486Smckusick 		time_t	*tptr;
1298*41486Smckusick 	} *uap = (struct a *)u.u_ap;
1299*41486Smckusick 	struct vattr vattr;
1300*41486Smckusick 	time_t tv[2];
1301*41486Smckusick 	register struct vnode *vp;
1302*41486Smckusick 	register struct nameidata *ndp = &u.u_nd;
1303*41486Smckusick 
1304*41486Smckusick 	if (uap->tptr) {
1305*41486Smckusick 		u.u_error =
1306*41486Smckusick 			copyin((caddr_t)uap->tptr, (caddr_t)tv, sizeof (tv));
1307*41486Smckusick 		if (u.u_error)
1308*41486Smckusick 			return;
1309*41486Smckusick 	} else
1310*41486Smckusick 		tv[0] = tv[1] = time.tv_sec;
1311*41486Smckusick 	ndp->ni_nameiop = LOOKUP | FOLLOW | LOCKLEAF;
1312*41486Smckusick 	ndp->ni_segflg = UIO_USERSPACE;
1313*41486Smckusick 	ndp->ni_dirp = uap->fname;
1314*41486Smckusick 	vattr_null(&vattr);
1315*41486Smckusick 	vattr.va_atime.tv_sec = tv[0];
1316*41486Smckusick 	vattr.va_atime.tv_usec = 0;
1317*41486Smckusick 	vattr.va_mtime.tv_sec = tv[1];
1318*41486Smckusick 	vattr.va_mtime.tv_usec = 0;
1319*41486Smckusick 	if (u.u_error = namei(ndp))
1320*41486Smckusick 		return;
1321*41486Smckusick 	vp = ndp->ni_vp;
1322*41486Smckusick 	if (vp->v_mount->m_flag & M_RDONLY)
1323*41486Smckusick 		u.u_error = EROFS;
1324*41486Smckusick 	else
1325*41486Smckusick 		u.u_error = VOP_SETATTR(vp, &vattr, ndp->ni_cred);
1326*41486Smckusick 	vput(vp);
1327*41486Smckusick }
1328*41486Smckusick 
1329*41486Smckusick ohpuxpause()
1330*41486Smckusick {
1331*41486Smckusick 
1332*41486Smckusick 	for (;;)
1333*41486Smckusick 		sleep((caddr_t)&u, PSLEP);
1334*41486Smckusick }
1335*41486Smckusick 
1336*41486Smckusick /*
1337*41486Smckusick  * The old fstat system call.
1338*41486Smckusick  */
1339*41486Smckusick ohpuxfstat()
1340*41486Smckusick {
1341*41486Smckusick 	register struct a {
1342*41486Smckusick 		int	fd;
1343*41486Smckusick 		struct ohpuxstat *sb;
1344*41486Smckusick 	} *uap = (struct a *)u.u_ap;
1345*41486Smckusick 	struct file *fp;
1346*41486Smckusick 	extern struct file *getinode();
1347*41486Smckusick 
1348*41486Smckusick 	if ((unsigned)uap->fd >= NOFILE || (fp = u.u_ofile[uap->fd]) == NULL) {
1349*41486Smckusick 		u.u_error = EBADF;
1350*41486Smckusick 		return;
1351*41486Smckusick 	}
1352*41486Smckusick 	if (fp->f_type != DTYPE_VNODE) {
1353*41486Smckusick 		u.u_error = EINVAL;
1354*41486Smckusick 		return;
1355*41486Smckusick 	}
1356*41486Smckusick 	u.u_error = ohpuxstat1((struct vnode *)fp->f_data, uap->sb);
1357*41486Smckusick }
1358*41486Smckusick 
1359*41486Smckusick /*
1360*41486Smckusick  * Old stat system call.  This version follows links.
1361*41486Smckusick  */
1362*41486Smckusick ohpuxstat()
1363*41486Smckusick {
1364*41486Smckusick 	register struct a {
1365*41486Smckusick 		char	*fname;
1366*41486Smckusick 		struct ohpuxstat *sb;
1367*41486Smckusick 	} *uap = (struct a *)u.u_ap;
1368*41486Smckusick 	register struct nameidata *ndp = &u.u_nd;
1369*41486Smckusick 
1370*41486Smckusick 	ndp->ni_nameiop = LOOKUP | LOCKLEAF | FOLLOW;
1371*41486Smckusick 	ndp->ni_segflg = UIO_USERSPACE;
1372*41486Smckusick 	ndp->ni_dirp = uap->fname;
1373*41486Smckusick 	if (u.u_error = namei(ndp))
1374*41486Smckusick 		return;
1375*41486Smckusick 	u.u_error = ohpuxstat1(ndp->ni_vp, uap->sb);
1376*41486Smckusick 	vput(ndp->ni_vp);
1377*41486Smckusick }
1378*41486Smckusick 
1379*41486Smckusick int
1380*41486Smckusick ohpuxstat1(vp, ub)
1381*41486Smckusick 	register struct vnode *vp;
1382*41486Smckusick 	struct ohpuxstat *ub;
1383*41486Smckusick {
1384*41486Smckusick 	struct ohpuxstat ds;
1385*41486Smckusick 	struct vattr vattr;
1386*41486Smckusick 	register int error;
1387*41486Smckusick 
1388*41486Smckusick 	error = VOP_GETATTR(vp, &vattr, u.u_cred);
1389*41486Smckusick 	if (error)
1390*41486Smckusick 		return(error);
1391*41486Smckusick 	/*
1392*41486Smckusick 	 * Copy from inode table
1393*41486Smckusick 	 */
1394*41486Smckusick 	ds.ohst_dev = vattr.va_fsid;
1395*41486Smckusick 	ds.ohst_ino = (short)vattr.va_fileid;
1396*41486Smckusick 	ds.ohst_mode = (u_short)vattr.va_mode;
1397*41486Smckusick 	ds.ohst_nlink = vattr.va_nlink;
1398*41486Smckusick 	ds.ohst_uid = (short)vattr.va_uid;
1399*41486Smckusick 	ds.ohst_gid = (short)vattr.va_gid;
1400*41486Smckusick 	ds.ohst_rdev = (dev_t)vattr.va_rdev;
1401*41486Smckusick 	ds.ohst_size = (int)vattr.va_size;
1402*41486Smckusick 	ds.ohst_atime = (int)vattr.va_atime.tv_sec;
1403*41486Smckusick 	ds.ohst_mtime = (int)vattr.va_mtime.tv_sec;
1404*41486Smckusick 	ds.ohst_ctime = (int)vattr.va_ctime.tv_sec;
1405*41486Smckusick 	return (copyout((caddr_t)&ds, (caddr_t)ub, sizeof(ds)));
1406*41486Smckusick }
1407*41486Smckusick /* #endif */
1408*41486Smckusick 
1409*41486Smckusick #endif
1410