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