1 /*
2  *    Implements HPUX syscalls.
3  *
4  *    Copyright (C) 1999 Matthew Wilcox <willy with parisc-linux.org>
5  *    Copyright (C) 2000 Philipp Rumpf
6  *    Copyright (C) 2000 John Marvin <jsm with parisc-linux.org>
7  *    Copyright (C) 2000 Michael Ang <mang with subcarrier.org>
8  *    Copyright (C) 2001 Nathan Neulinger <nneul at umr.edu>
9  *
10  *    This program is free software; you can redistribute it and/or modify
11  *    it under the terms of the GNU General Public License as published by
12  *    the Free Software Foundation; either version 2 of the License, or
13  *    (at your option) any later version.
14  *
15  *    This program is distributed in the hope that it will be useful,
16  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *    GNU General Public License for more details.
19  *
20  *    You should have received a copy of the GNU General Public License
21  *    along with this program; if not, write to the Free Software
22  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23  */
24 
25 #include <linux/capability.h>
26 #include <linux/file.h>
27 #include <linux/fs.h>
28 #include <linux/namei.h>
29 #include <linux/sched.h>
30 #include <linux/slab.h>
31 #include <linux/syscalls.h>
32 #include <linux/utsname.h>
33 #include <linux/vfs.h>
34 #include <linux/vmalloc.h>
35 
36 #include <asm/errno.h>
37 #include <asm/pgalloc.h>
38 #include <asm/uaccess.h>
39 
hpux_brk(unsigned long addr)40 unsigned long hpux_brk(unsigned long addr)
41 {
42 	/* Sigh.  Looks like HP/UX libc relies on kernel bugs. */
43 	return sys_brk(addr + PAGE_SIZE);
44 }
45 
hpux_sbrk(void)46 int hpux_sbrk(void)
47 {
48 	return -ENOSYS;
49 }
50 
51 /* Random other syscalls */
52 
hpux_nice(int priority_change)53 int hpux_nice(int priority_change)
54 {
55 	return -ENOSYS;
56 }
57 
hpux_ptrace(void)58 int hpux_ptrace(void)
59 {
60 	return -ENOSYS;
61 }
62 
hpux_wait(int __user * stat_loc)63 int hpux_wait(int __user *stat_loc)
64 {
65 	return sys_waitpid(-1, stat_loc, 0);
66 }
67 
hpux_setpgrp(void)68 int hpux_setpgrp(void)
69 {
70 	return sys_setpgid(0,0);
71 }
72 
hpux_setpgrp3(void)73 int hpux_setpgrp3(void)
74 {
75 	return hpux_setpgrp();
76 }
77 
78 #define _SC_CPU_VERSION	10001
79 #define _SC_OPEN_MAX	4
80 #define CPU_PA_RISC1_1	0x210
81 
hpux_sysconf(int which)82 int hpux_sysconf(int which)
83 {
84 	switch (which) {
85 	case _SC_CPU_VERSION:
86 		return CPU_PA_RISC1_1;
87 	case _SC_OPEN_MAX:
88 		return INT_MAX;
89 	default:
90 		return -EINVAL;
91 	}
92 }
93 
94 /*****************************************************************************/
95 
96 #define HPUX_UTSLEN 9
97 #define HPUX_SNLEN 15
98 
99 struct hpux_utsname {
100 	char sysname[HPUX_UTSLEN];
101 	char nodename[HPUX_UTSLEN];
102 	char release[HPUX_UTSLEN];
103 	char version[HPUX_UTSLEN];
104 	char machine[HPUX_UTSLEN];
105 	char idnumber[HPUX_SNLEN];
106 } ;
107 
108 struct hpux_ustat {
109 	int32_t		f_tfree;	/* total free (daddr_t)  */
110 	u_int32_t	f_tinode;	/* total inodes free (ino_t)  */
111 	char		f_fname[6];	/* filsys name */
112 	char		f_fpack[6];	/* filsys pack name */
113 	u_int32_t	f_blksize;	/* filsys block size (int) */
114 };
115 
116 /*
117  * HPUX's utssys() call.  It's a collection of miscellaneous functions,
118  * alas, so there's no nice way of splitting them up.
119  */
120 
121 /*  This function is called from hpux_utssys(); HP-UX implements
122  *  ustat() as an option to utssys().
123  *
124  *  Now, struct ustat on HP-UX is exactly the same as on Linux, except
125  *  that it contains one addition field on the end, int32_t f_blksize.
126  *  So, we could have written this function to just call the Linux
127  *  sys_ustat(), (defined in linux/fs/super.c), and then just
128  *  added this additional field to the user's structure.  But I figure
129  *  if we're gonna be digging through filesystem structures to get
130  *  this, we might as well just do the whole enchilada all in one go.
131  *
132  *  So, most of this function is almost identical to sys_ustat().
133  *  I have placed comments at the few lines changed or added, to
134  *  aid in porting forward if and when sys_ustat() is changed from
135  *  its form in kernel 2.2.5.
136  */
hpux_ustat(dev_t dev,struct hpux_ustat __user * ubuf)137 static int hpux_ustat(dev_t dev, struct hpux_ustat __user *ubuf)
138 {
139 	struct super_block *s;
140 	struct hpux_ustat tmp;  /* Changed to hpux_ustat */
141 	struct kstatfs sbuf;
142 	int err = -EINVAL;
143 
144 	s = user_get_super(dev);
145 	if (s == NULL)
146 		goto out;
147 	err = statfs_by_dentry(s->s_root, &sbuf);
148 	drop_super(s);
149 	if (err)
150 		goto out;
151 
152 	memset(&tmp,0,sizeof(tmp));
153 
154 	tmp.f_tfree = (int32_t)sbuf.f_bfree;
155 	tmp.f_tinode = (u_int32_t)sbuf.f_ffree;
156 	tmp.f_blksize = (u_int32_t)sbuf.f_bsize;  /*  Added this line  */
157 
158 	err = copy_to_user(ubuf, &tmp, sizeof(tmp)) ? -EFAULT : 0;
159 out:
160 	return err;
161 }
162 
163 /*
164  * Wrapper for hpux statfs call. At the moment, just calls the linux native one
165  * and ignores the extra fields at the end of the hpux statfs struct.
166  *
167  */
168 
169 typedef int32_t hpux_fsid_t[2];              /* file system ID type */
170 typedef uint16_t hpux_site_t;
171 
172 struct hpux_statfs {
173      int32_t f_type;                    /* type of info, zero for now */
174      int32_t f_bsize;                   /* fundamental file system block size */
175      int32_t f_blocks;                  /* total blocks in file system */
176      int32_t f_bfree;                   /* free block in fs */
177      int32_t f_bavail;                  /* free blocks avail to non-superuser */
178      int32_t f_files;                   /* total file nodes in file system */
179      int32_t f_ffree;                   /* free file nodes in fs */
180      hpux_fsid_t  f_fsid;                    /* file system ID */
181      int32_t f_magic;                   /* file system magic number */
182      int32_t f_featurebits;             /* file system features */
183      int32_t f_spare[4];                /* spare for later */
184      hpux_site_t  f_cnode;                   /* cluster node where mounted */
185      int16_t f_pad;
186 };
187 
do_statfs_hpux(struct kstatfs * st,struct hpux_statfs __user * p)188 static int do_statfs_hpux(struct kstatfs *st, struct hpux_statfs __user *p)
189 {
190 	struct hpux_statfs buf;
191 	memset(&buf, 0, sizeof(buf));
192 	buf.f_type = st->f_type;
193 	buf.f_bsize = st->f_bsize;
194 	buf.f_blocks = st->f_blocks;
195 	buf.f_bfree = st->f_bfree;
196 	buf.f_bavail = st->f_bavail;
197 	buf.f_files = st->f_files;
198 	buf.f_ffree = st->f_ffree;
199 	buf.f_fsid[0] = st->f_fsid.val[0];
200 	buf.f_fsid[1] = st->f_fsid.val[1];
201 	if (copy_to_user(p, &buf, sizeof(buf)))
202 		return -EFAULT;
203 	return 0;
204 }
205 
206 /* hpux statfs */
hpux_statfs(const char __user * pathname,struct hpux_statfs __user * buf)207 asmlinkage long hpux_statfs(const char __user *pathname,
208 						struct hpux_statfs __user *buf)
209 {
210 	struct kstatfs st;
211 	int error = user_statfs(pathname, &st);
212 	if (!error)
213 		error = do_statfs_hpux(&st, buf);
214 	return error;
215 }
216 
hpux_fstatfs(unsigned int fd,struct hpux_statfs __user * buf)217 asmlinkage long hpux_fstatfs(unsigned int fd, struct hpux_statfs __user * buf)
218 {
219 	struct kstatfs st;
220 	int error = fd_statfs(fd, &st);
221 	if (!error)
222 		error = do_statfs_hpux(&st, buf);
223 	return error;
224 }
225 
226 
227 /*  This function is called from hpux_utssys(); HP-UX implements
228  *  uname() as an option to utssys().
229  *
230  *  The form of this function is pretty much copied from sys_olduname(),
231  *  defined in linux/arch/i386/kernel/sys_i386.c.
232  */
233 /*  TODO: Are these put_user calls OK?  Should they pass an int?
234  *        (I copied it from sys_i386.c like this.)
235  */
hpux_uname(struct hpux_utsname __user * name)236 static int hpux_uname(struct hpux_utsname __user *name)
237 {
238 	int error;
239 
240 	if (!name)
241 		return -EFAULT;
242 	if (!access_ok(VERIFY_WRITE,name,sizeof(struct hpux_utsname)))
243 		return -EFAULT;
244 
245 	down_read(&uts_sem);
246 
247 	error = __copy_to_user(&name->sysname, &utsname()->sysname,
248 			       HPUX_UTSLEN - 1);
249 	error |= __put_user(0, name->sysname + HPUX_UTSLEN - 1);
250 	error |= __copy_to_user(&name->nodename, &utsname()->nodename,
251 				HPUX_UTSLEN - 1);
252 	error |= __put_user(0, name->nodename + HPUX_UTSLEN - 1);
253 	error |= __copy_to_user(&name->release, &utsname()->release,
254 				HPUX_UTSLEN - 1);
255 	error |= __put_user(0, name->release + HPUX_UTSLEN - 1);
256 	error |= __copy_to_user(&name->version, &utsname()->version,
257 				HPUX_UTSLEN - 1);
258 	error |= __put_user(0, name->version + HPUX_UTSLEN - 1);
259 	error |= __copy_to_user(&name->machine, &utsname()->machine,
260 				HPUX_UTSLEN - 1);
261 	error |= __put_user(0, name->machine + HPUX_UTSLEN - 1);
262 
263 	up_read(&uts_sem);
264 
265 	/*  HP-UX  utsname has no domainname field.  */
266 
267 	/*  TODO:  Implement idnumber!!!  */
268 #if 0
269 	error |= __put_user(0,name->idnumber);
270 	error |= __put_user(0,name->idnumber+HPUX_SNLEN-1);
271 #endif
272 
273 	error = error ? -EFAULT : 0;
274 
275 	return error;
276 }
277 
278 /*  Note: HP-UX just uses the old suser() function to check perms
279  *  in this system call.  We'll use capable(CAP_SYS_ADMIN).
280  */
hpux_utssys(char __user * ubuf,int n,int type)281 int hpux_utssys(char __user *ubuf, int n, int type)
282 {
283 	int len;
284 	int error;
285 	switch( type ) {
286 	case 0:
287 		/*  uname():  */
288 		return hpux_uname((struct hpux_utsname __user *)ubuf);
289 		break ;
290 	case 1:
291 		/*  Obsolete (used to be umask().)  */
292 		return -EFAULT ;
293 		break ;
294 	case 2:
295 		/*  ustat():  */
296 		return hpux_ustat(new_decode_dev(n),
297 				  (struct hpux_ustat __user *)ubuf);
298 		break;
299 	case 3:
300 		/*  setuname():
301 		 *
302 		 *  On linux (unlike HP-UX), utsname.nodename
303 		 *  is the same as the hostname.
304 		 *
305 		 *  sys_sethostname() is defined in linux/kernel/sys.c.
306 		 */
307 		if (!capable(CAP_SYS_ADMIN))
308 			return -EPERM;
309 		/*  Unlike Linux, HP-UX returns an error if n==0:  */
310 		if ( n <= 0 )
311 			return -EINVAL ;
312 		/*  Unlike Linux, HP-UX truncates it if n is too big:  */
313 		len = (n <= __NEW_UTS_LEN) ? n : __NEW_UTS_LEN ;
314 		return sys_sethostname(ubuf, len);
315 		break ;
316 	case 4:
317 		/*  sethostname():
318 		 *
319 		 *  sys_sethostname() is defined in linux/kernel/sys.c.
320 		 */
321 		if (!capable(CAP_SYS_ADMIN))
322 			return -EPERM;
323 		/*  Unlike Linux, HP-UX returns an error if n==0:  */
324 		if ( n <= 0 )
325 			return -EINVAL ;
326 		/*  Unlike Linux, HP-UX truncates it if n is too big:  */
327 		len = (n <= __NEW_UTS_LEN) ? n : __NEW_UTS_LEN ;
328 		return sys_sethostname(ubuf, len);
329 		break ;
330 	case 5:
331 		/*  gethostname():
332 		 *
333 		 *  sys_gethostname() is defined in linux/kernel/sys.c.
334 		 */
335 		/*  Unlike Linux, HP-UX returns an error if n==0:  */
336 		if ( n <= 0 )
337 			return -EINVAL ;
338 		return sys_gethostname(ubuf, n);
339 		break ;
340 	case 6:
341 		/*  Supposedly called from setuname() in libc.
342 		 *  TODO: When and why is this called?
343 		 *        Is it ever even called?
344 		 *
345 		 *  This code should look a lot like sys_sethostname(),
346 		 *  defined in linux/kernel/sys.c.  If that gets updated,
347 		 *  update this code similarly.
348 		 */
349 		if (!capable(CAP_SYS_ADMIN))
350 			return -EPERM;
351 		/*  Unlike Linux, HP-UX returns an error if n==0:  */
352 		if ( n <= 0 )
353 			return -EINVAL ;
354 		/*  Unlike Linux, HP-UX truncates it if n is too big:  */
355 		len = (n <= __NEW_UTS_LEN) ? n : __NEW_UTS_LEN ;
356 		/**/
357 		/*  TODO:  print a warning about using this?  */
358 		down_write(&uts_sem);
359 		error = -EFAULT;
360 		if (!copy_from_user(utsname()->sysname, ubuf, len)) {
361 			utsname()->sysname[len] = 0;
362 			error = 0;
363 		}
364 		up_write(&uts_sem);
365 		return error;
366 		break ;
367 	case 7:
368 		/*  Sets utsname.release, if you're allowed.
369 		 *  Undocumented.  Used by swinstall to change the
370 		 *  OS version, during OS updates.  Yuck!!!
371 		 *
372 		 *  This code should look a lot like sys_sethostname()
373 		 *  in linux/kernel/sys.c.  If that gets updated, update
374 		 *  this code similarly.
375 		 */
376 		if (!capable(CAP_SYS_ADMIN))
377 			return -EPERM;
378 		/*  Unlike Linux, HP-UX returns an error if n==0:  */
379 		if ( n <= 0 )
380 			return -EINVAL ;
381 		/*  Unlike Linux, HP-UX truncates it if n is too big:  */
382 		len = (n <= __NEW_UTS_LEN) ? n : __NEW_UTS_LEN ;
383 		/**/
384 		/*  TODO:  print a warning about this?  */
385 		down_write(&uts_sem);
386 		error = -EFAULT;
387 		if (!copy_from_user(utsname()->release, ubuf, len)) {
388 			utsname()->release[len] = 0;
389 			error = 0;
390 		}
391 		up_write(&uts_sem);
392 		return error;
393 		break ;
394 	default:
395 		/*  This system call returns -EFAULT if given an unknown type.
396 	 	 *  Why not -EINVAL?  I don't know, it's just not what they did.
397 	 	 */
398 		return -EFAULT ;
399 	}
400 }
401 
hpux_getdomainname(char __user * name,int len)402 int hpux_getdomainname(char __user *name, int len)
403 {
404  	int nlen;
405  	int err = -EFAULT;
406 
407  	down_read(&uts_sem);
408 
409 	nlen = strlen(utsname()->domainname) + 1;
410 
411 	if (nlen < len)
412 		len = nlen;
413 	if(len > __NEW_UTS_LEN)
414 		goto done;
415 	if(copy_to_user(name, utsname()->domainname, len))
416 		goto done;
417 	err = 0;
418 done:
419 	up_read(&uts_sem);
420 	return err;
421 
422 }
423 
hpux_pipe(int * kstack_fildes)424 int hpux_pipe(int *kstack_fildes)
425 {
426 	return do_pipe_flags(kstack_fildes, 0);
427 }
428 
429 /* lies - says it works, but it really didn't lock anything */
hpux_lockf(int fildes,int function,off_t size)430 int hpux_lockf(int fildes, int function, off_t size)
431 {
432 	return 0;
433 }
434 
hpux_sysfs(int opcode,unsigned long arg1,unsigned long arg2)435 int hpux_sysfs(int opcode, unsigned long arg1, unsigned long arg2)
436 {
437 	char *fsname = NULL;
438 	int len = 0;
439 	int fstype;
440 
441 /*Unimplemented HP-UX syscall emulation. Syscall #334 (sysfs)
442   Args: 1 80057bf4 0 400179f0 0 0 0 */
443 	printk(KERN_DEBUG "in hpux_sysfs\n");
444 	printk(KERN_DEBUG "hpux_sysfs called with opcode = %d\n", opcode);
445 	printk(KERN_DEBUG "hpux_sysfs called with arg1='%lx'\n", arg1);
446 
447 	if ( opcode == 1 ) { /* GETFSIND */
448 		char __user *user_fsname = (char __user *)arg1;
449 		len = strlen_user(user_fsname);
450 		printk(KERN_DEBUG "len of arg1 = %d\n", len);
451 		if (len == 0)
452 			return 0;
453 		fsname = kmalloc(len, GFP_KERNEL);
454 		if (!fsname) {
455 			printk(KERN_DEBUG "failed to kmalloc fsname\n");
456 			return 0;
457 		}
458 
459 		if (copy_from_user(fsname, user_fsname, len)) {
460 			printk(KERN_DEBUG "failed to copy_from_user fsname\n");
461 			kfree(fsname);
462 			return 0;
463 		}
464 
465 		/* String could be altered by userspace after strlen_user() */
466 		fsname[len] = '\0';
467 
468 		printk(KERN_DEBUG "that is '%s' as (char *)\n", fsname);
469 		if ( !strcmp(fsname, "hfs") ) {
470 			fstype = 0;
471 		} else {
472 			fstype = 0;
473 		}
474 
475 		kfree(fsname);
476 
477 		printk(KERN_DEBUG "returning fstype=%d\n", fstype);
478 		return fstype; /* something other than default */
479 	}
480 
481 
482 	return 0;
483 }
484 
485 
486 /* Table of syscall names and handle for unimplemented routines */
487 static const char * const syscall_names[] = {
488 	"nosys",                  /* 0 */
489 	"exit",
490 	"fork",
491 	"read",
492 	"write",
493 	"open",                   /* 5 */
494 	"close",
495 	"wait",
496 	"creat",
497 	"link",
498 	"unlink",                 /* 10 */
499 	"execv",
500 	"chdir",
501 	"time",
502 	"mknod",
503 	"chmod",                  /* 15 */
504 	"chown",
505 	"brk",
506 	"lchmod",
507 	"lseek",
508 	"getpid",                 /* 20 */
509 	"mount",
510 	"umount",
511 	"setuid",
512 	"getuid",
513 	"stime",                  /* 25 */
514 	"ptrace",
515 	"alarm",
516 	NULL,
517 	"pause",
518 	"utime",                  /* 30 */
519 	"stty",
520 	"gtty",
521 	"access",
522 	"nice",
523 	"ftime",                  /* 35 */
524 	"sync",
525 	"kill",
526 	"stat",
527 	"setpgrp3",
528 	"lstat",                  /* 40 */
529 	"dup",
530 	"pipe",
531 	"times",
532 	"profil",
533 	"ki_call",                /* 45 */
534 	"setgid",
535 	"getgid",
536 	NULL,
537 	NULL,
538 	NULL,                     /* 50 */
539 	"acct",
540 	"set_userthreadid",
541 	NULL,
542 	"ioctl",
543 	"reboot",                 /* 55 */
544 	"symlink",
545 	"utssys",
546 	"readlink",
547 	"execve",
548 	"umask",                  /* 60 */
549 	"chroot",
550 	"fcntl",
551 	"ulimit",
552 	NULL,
553 	NULL,                     /* 65 */
554 	"vfork",
555 	NULL,
556 	NULL,
557 	NULL,
558 	NULL,                     /* 70 */
559 	"mmap",
560 	NULL,
561 	"munmap",
562 	"mprotect",
563 	"madvise",                /* 75 */
564 	"vhangup",
565 	"swapoff",
566 	NULL,
567 	"getgroups",
568 	"setgroups",              /* 80 */
569 	"getpgrp2",
570 	"setpgid/setpgrp2",
571 	"setitimer",
572 	"wait3",
573 	"swapon",                 /* 85 */
574 	"getitimer",
575 	NULL,
576 	NULL,
577 	NULL,
578 	"dup2",                   /* 90 */
579 	NULL,
580 	"fstat",
581 	"select",
582 	NULL,
583 	"fsync",                  /* 95 */
584 	"setpriority",
585 	NULL,
586 	NULL,
587 	NULL,
588 	"getpriority",            /* 100 */
589 	NULL,
590 	NULL,
591 	NULL,
592 	NULL,
593 	NULL,                     /* 105 */
594 	NULL,
595 	NULL,
596 	"sigvector",
597 	"sigblock",
598 	"sigsetmask",             /* 110 */
599 	"sigpause",
600 	"sigstack",
601 	NULL,
602 	NULL,
603 	NULL,                     /* 115 */
604 	"gettimeofday",
605 	"getrusage",
606 	NULL,
607 	NULL,
608 	"readv",                  /* 120 */
609 	"writev",
610 	"settimeofday",
611 	"fchown",
612 	"fchmod",
613 	NULL,                     /* 125 */
614 	"setresuid",
615 	"setresgid",
616 	"rename",
617 	"truncate",
618 	"ftruncate",              /* 130 */
619 	NULL,
620 	"sysconf",
621 	NULL,
622 	NULL,
623 	NULL,                     /* 135 */
624 	"mkdir",
625 	"rmdir",
626 	NULL,
627 	"sigcleanup",
628 	"setcore",                /* 140 */
629 	NULL,
630 	"gethostid",
631 	"sethostid",
632 	"getrlimit",
633 	"setrlimit",              /* 145 */
634 	NULL,
635 	NULL,
636 	"quotactl",
637 	"get_sysinfo",
638 	NULL,                     /* 150 */
639 	"privgrp",
640 	"rtprio",
641 	"plock",
642 	NULL,
643 	"lockf",                  /* 155 */
644 	"semget",
645 	NULL,
646 	"semop",
647 	"msgget",
648 	NULL,                     /* 160 */
649 	"msgsnd",
650 	"msgrcv",
651 	"shmget",
652 	NULL,
653 	"shmat",                  /* 165 */
654 	"shmdt",
655 	NULL,
656 	"csp/nsp_init",
657 	"cluster",
658 	"mkrnod",                 /* 170 */
659 	"test",
660 	"unsp_open",
661 	NULL,
662 	"getcontext",
663 	"osetcontext",            /* 175 */
664 	"bigio",
665 	"pipenode",
666 	"lsync",
667 	"getmachineid",
668 	"cnodeid/mysite",         /* 180 */
669 	"cnodes/sitels",
670 	"swapclients",
671 	"rmtprocess",
672 	"dskless_stats",
673 	"sigprocmask",            /* 185 */
674 	"sigpending",
675 	"sigsuspend",
676 	"sigaction",
677 	NULL,
678 	"nfssvc",                 /* 190 */
679 	"getfh",
680 	"getdomainname",
681 	"setdomainname",
682 	"async_daemon",
683 	"getdirentries",          /* 195 */
684 	NULL,
685 	NULL,
686 	"vfsmount",
687 	NULL,
688 	"waitpid",                /* 200 */
689 	NULL,
690 	NULL,
691 	NULL,
692 	NULL,
693 	NULL,                     /* 205 */
694 	NULL,
695 	NULL,
696 	NULL,
697 	NULL,
698 	NULL,                     /* 210 */
699 	NULL,
700 	NULL,
701 	NULL,
702 	NULL,
703 	NULL,                     /* 215 */
704 	NULL,
705 	NULL,
706 	NULL,
707 	NULL,
708 	NULL,                     /* 220 */
709 	NULL,
710 	NULL,
711 	NULL,
712 	"sigsetreturn",
713 	"sigsetstatemask",        /* 225 */
714 	"bfactl",
715 	"cs",
716 	"cds",
717 	NULL,
718 	"pathconf",               /* 230 */
719 	"fpathconf",
720 	NULL,
721 	NULL,
722 	"nfs_fcntl",
723 	"ogetacl",                /* 235 */
724 	"ofgetacl",
725 	"osetacl",
726 	"ofsetacl",
727 	"pstat",
728 	"getaudid",               /* 240 */
729 	"setaudid",
730 	"getaudproc",
731 	"setaudproc",
732 	"getevent",
733 	"setevent",               /* 245 */
734 	"audwrite",
735 	"audswitch",
736 	"audctl",
737 	"ogetaccess",
738 	"fsctl",                  /* 250 */
739 	"ulconnect",
740 	"ulcontrol",
741 	"ulcreate",
742 	"uldest",
743 	"ulrecv",                 /* 255 */
744 	"ulrecvcn",
745 	"ulsend",
746 	"ulshutdown",
747 	"swapfs",
748 	"fss",                    /* 260 */
749 	NULL,
750 	NULL,
751 	NULL,
752 	NULL,
753 	NULL,                     /* 265 */
754 	NULL,
755 	"tsync",
756 	"getnumfds",
757 	"poll",
758 	"getmsg",                 /* 270 */
759 	"putmsg",
760 	"fchdir",
761 	"getmount_cnt",
762 	"getmount_entry",
763 	"accept",                 /* 275 */
764 	"bind",
765 	"connect",
766 	"getpeername",
767 	"getsockname",
768 	"getsockopt",             /* 280 */
769 	"listen",
770 	"recv",
771 	"recvfrom",
772 	"recvmsg",
773 	"send",                   /* 285 */
774 	"sendmsg",
775 	"sendto",
776 	"setsockopt",
777 	"shutdown",
778 	"socket",                 /* 290 */
779 	"socketpair",
780 	"proc_open",
781 	"proc_close",
782 	"proc_send",
783 	"proc_recv",              /* 295 */
784 	"proc_sendrecv",
785 	"proc_syscall",
786 	"ipccreate",
787 	"ipcname",
788 	"ipcnamerase",            /* 300 */
789 	"ipclookup",
790 	"ipcselect",
791 	"ipcconnect",
792 	"ipcrecvcn",
793 	"ipcsend",                /* 305 */
794 	"ipcrecv",
795 	"ipcgetnodename",
796 	"ipcsetnodename",
797 	"ipccontrol",
798 	"ipcshutdown",            /* 310 */
799 	"ipcdest",
800 	"semctl",
801 	"msgctl",
802 	"shmctl",
803 	"mpctl",                  /* 315 */
804 	"exportfs",
805 	"getpmsg",
806 	"putpmsg",
807 	"strioctl",
808 	"msync",                  /* 320 */
809 	"msleep",
810 	"mwakeup",
811 	"msem_init",
812 	"msem_remove",
813 	"adjtime",                /* 325 */
814 	"kload",
815 	"fattach",
816 	"fdetach",
817 	"serialize",
818 	"statvfs",                /* 330 */
819 	"fstatvfs",
820 	"lchown",
821 	"getsid",
822 	"sysfs",
823 	NULL,                     /* 335 */
824 	NULL,
825 	"sched_setparam",
826 	"sched_getparam",
827 	"sched_setscheduler",
828 	"sched_getscheduler",     /* 340 */
829 	"sched_yield",
830 	"sched_get_priority_max",
831 	"sched_get_priority_min",
832 	"sched_rr_get_interval",
833 	"clock_settime",          /* 345 */
834 	"clock_gettime",
835 	"clock_getres",
836 	"timer_create",
837 	"timer_delete",
838 	"timer_settime",          /* 350 */
839 	"timer_gettime",
840 	"timer_getoverrun",
841 	"nanosleep",
842 	"toolbox",
843 	NULL,                     /* 355 */
844 	"getdents",
845 	"getcontext",
846 	"sysinfo",
847 	"fcntl64",
848 	"ftruncate64",            /* 360 */
849 	"fstat64",
850 	"getdirentries64",
851 	"getrlimit64",
852 	"lockf64",
853 	"lseek64",                /* 365 */
854 	"lstat64",
855 	"mmap64",
856 	"setrlimit64",
857 	"stat64",
858 	"truncate64",             /* 370 */
859 	"ulimit64",
860 	NULL,
861 	NULL,
862 	NULL,
863 	NULL,                     /* 375 */
864 	NULL,
865 	NULL,
866 	NULL,
867 	NULL,
868 	"setcontext",             /* 380 */
869 	"sigaltstack",
870 	"waitid",
871 	"setpgrp",
872 	"recvmsg2",
873 	"sendmsg2",               /* 385 */
874 	"socket2",
875 	"socketpair2",
876 	"setregid",
877 	"lwp_create",
878 	"lwp_terminate",          /* 390 */
879 	"lwp_wait",
880 	"lwp_suspend",
881 	"lwp_resume",
882 	"lwp_self",
883 	"lwp_abort_syscall",      /* 395 */
884 	"lwp_info",
885 	"lwp_kill",
886 	"ksleep",
887 	"kwakeup",
888 	"ksleep_abort",           /* 400 */
889 	"lwp_proc_info",
890 	"lwp_exit",
891 	"lwp_continue",
892 	"getacl",
893 	"fgetacl",                /* 405 */
894 	"setacl",
895 	"fsetacl",
896 	"getaccess",
897 	"lwp_mutex_init",
898 	"lwp_mutex_lock_sys",     /* 410 */
899 	"lwp_mutex_unlock",
900 	"lwp_cond_init",
901 	"lwp_cond_signal",
902 	"lwp_cond_broadcast",
903 	"lwp_cond_wait_sys",      /* 415 */
904 	"lwp_getscheduler",
905 	"lwp_setscheduler",
906 	"lwp_getprivate",
907 	"lwp_setprivate",
908 	"lwp_detach",             /* 420 */
909 	"mlock",
910 	"munlock",
911 	"mlockall",
912 	"munlockall",
913 	"shm_open",               /* 425 */
914 	"shm_unlink",
915 	"sigqueue",
916 	"sigwaitinfo",
917 	"sigtimedwait",
918 	"sigwait",                /* 430 */
919 	"aio_read",
920 	"aio_write",
921 	"lio_listio",
922 	"aio_error",
923 	"aio_return",             /* 435 */
924 	"aio_cancel",
925 	"aio_suspend",
926 	"aio_fsync",
927 	"mq_open",
928 	"mq_unlink",              /* 440 */
929 	"mq_send",
930 	"mq_receive",
931 	"mq_notify",
932 	"mq_setattr",
933 	"mq_getattr",             /* 445 */
934 	"ksem_open",
935 	"ksem_unlink",
936 	"ksem_close",
937 	"ksem_destroy",
938 	"lw_sem_incr",            /* 450 */
939 	"lw_sem_decr",
940 	"lw_sem_read",
941 	"mq_close",
942 };
943 static const int syscall_names_max = 453;
944 
945 int
hpux_unimplemented(unsigned long arg1,unsigned long arg2,unsigned long arg3,unsigned long arg4,unsigned long arg5,unsigned long arg6,unsigned long arg7,unsigned long sc_num)946 hpux_unimplemented(unsigned long arg1,unsigned long arg2,unsigned long arg3,
947 		   unsigned long arg4,unsigned long arg5,unsigned long arg6,
948 		   unsigned long arg7,unsigned long sc_num)
949 {
950 	/* NOTE: sc_num trashes arg8 for the few syscalls that actually
951 	 * have a valid 8th argument.
952 	 */
953 	const char *name = NULL;
954 	if ( sc_num <= syscall_names_max && sc_num >= 0 ) {
955 		name = syscall_names[sc_num];
956 	}
957 
958 	if ( name ) {
959 		printk(KERN_DEBUG "Unimplemented HP-UX syscall emulation. Syscall #%lu (%s)\n",
960 		sc_num, name);
961 	} else {
962 		printk(KERN_DEBUG "Unimplemented unknown HP-UX syscall emulation. Syscall #%lu\n",
963 		sc_num);
964 	}
965 
966 	printk(KERN_DEBUG "  Args: %lx %lx %lx %lx %lx %lx %lx\n",
967 		arg1, arg2, arg3, arg4, arg5, arg6, arg7);
968 
969 	return -ENOSYS;
970 }
971