From 945d746288b9effacb793b662a28049a01b2f4f7 Mon Sep 17 00:00:00 2001 From: manu Date: Wed, 26 Dec 2001 11:04:20 +0000 Subject: [PATCH] integrated a copy of svr4_waitsys(), which should be merged later. This has not been fully tested, but it makes IRIX's /bin/sh able to survive running an external command such as ls. --- sys/compat/irix/irix_signal.c | 245 ++++++++++++++++++++++++++++- sys/compat/irix/irix_signal.h | 52 +++++- sys/compat/irix/irix_syscall.h | 7 +- sys/compat/irix/irix_syscallargs.h | 13 +- sys/compat/irix/irix_syscalls.c | 8 +- sys/compat/irix/irix_sysent.c | 10 +- sys/compat/irix/irix_types.h | 7 +- sys/compat/irix/syscalls.master | 6 +- 8 files changed, 327 insertions(+), 21 deletions(-) diff --git a/sys/compat/irix/irix_signal.c b/sys/compat/irix/irix_signal.c index 9204a0f16956..e2c89fda33ee 100644 --- a/sys/compat/irix/irix_signal.c +++ b/sys/compat/irix/irix_signal.c @@ -1,11 +1,11 @@ -/* $NetBSD: irix_signal.c,v 1.2 2001/12/25 19:04:18 manu Exp $ */ +/* $NetBSD: irix_signal.c,v 1.3 2001/12/26 11:04:20 manu Exp $ */ /*- - * Copyright (c) 2001 The NetBSD Foundation, Inc. + * Copyright (c) 1994, 2001 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation - * by Emmanuel Dreyfus. + * by Christos Zoulas and Emmanuel Dreyfus. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -37,18 +37,24 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: irix_signal.c,v 1.2 2001/12/25 19:04:18 manu Exp $"); +__KERNEL_RCSID(0, "$NetBSD: irix_signal.c,v 1.3 2001/12/26 11:04:20 manu Exp $"); #include #include #include #include +#include +#include #include +#include #include +#include +#include #include #include +#include #include #include @@ -56,12 +62,70 @@ __KERNEL_RCSID(0, "$NetBSD: irix_signal.c,v 1.2 2001/12/25 19:04:18 manu Exp $") extern const int native_to_svr4_sig[]; extern const int svr4_to_native_sig[]; +static int irix_setinfo __P((struct proc *, int, irix_irix5_siginfo_t *)); + #define irix_sigmask(n) (1 << (((n) - 1) & 31)) #define irix_sigword(n) (((n) - 1) >> 5) #define irix_sigemptyset(s) memset((s), 0, sizeof(*(s))) #define irix_sigismember(s, n) ((s)->bits[irix_sigword(n)] & irix_sigmask(n)) #define irix_sigaddset(s, n) ((s)->bits[irix_sigword(n)] |= irix_sigmask(n)) +/* + * This is ripped from svr4_setinfo. See irix_sys_waitsys... + */ +int +irix_setinfo(p, st, s) + struct proc *p; + int st; + irix_irix5_siginfo_t *s; +{ + irix_irix5_siginfo_t i; + int sig; + + memset(&i, 0, sizeof(i)); + + i.isi_signo = SVR4_SIGCHLD; + i.isi_errno = 0; /* XXX? */ + + if (p) { + i.isi_pid = p->p_pid; + if (p->p_stat == SZOMB) { + i.isi_stime = p->p_ru->ru_stime.tv_sec; + i.isi_utime = p->p_ru->ru_utime.tv_sec; + } + else { + i.isi_stime = p->p_stats->p_ru.ru_stime.tv_sec; + i.isi_utime = p->p_stats->p_ru.ru_utime.tv_sec; + } + } + + if (WIFEXITED(st)) { + i.isi_status = WEXITSTATUS(st); + i.isi_code = SVR4_CLD_EXITED; + } else if (WIFSTOPPED(st)) { + sig = WSTOPSIG(st); + if (sig >= 0 && sig < NSIG) + i.isi_status = native_to_svr4_sig[sig]; + + if (i.isi_status == SVR4_SIGCONT) + i.isi_code = SVR4_CLD_CONTINUED; + else + i.isi_code = SVR4_CLD_STOPPED; + } else { + sig = WTERMSIG(st); + if (sig >= 0 && sig < NSIG) + i.isi_status = native_to_svr4_sig[sig]; + + if (WCOREDUMP(st)) + i.isi_code = SVR4_CLD_DUMPED; + else + i.isi_code = SVR4_CLD_KILLED; + } + + return copyout(&i, s, sizeof(i)); +} + + void native_to_irix_sigset(bss, sss) const sigset_t *bss; @@ -376,3 +440,176 @@ irix_sys_setcontext(p, v, retval) out: return error; } + + +/* + * The following code is from svr4_sys_waitsys(), with a few lines added + * for supporting the rusage argument which is present in the IRIX version + * and not in the SVR4 version. + * Both version could be merged by creating a svr4_sys_waitsys1() with the + * rusage argument, and by calling it with NULL from svr4_sys_waitsys(). + * irix_setinfo is here because 1) svr4_setinfo is static and cannot be + * used here and 2) because struct irix_irix5_siginfo is quite different + * from svr4_siginfo. In order to merge, we need to include irix_signal.h + * from svr4_misc.c, or push the irix_irix5_siginfo into svr4_siginfo.h + */ +int +irix_sys_waitsys(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + struct irix_sys_waitsys_args /* { + syscallarg(int) type; + syscallarg(int) pid; + syscallarg(struct irix_irix5_siginfo *) info; + syscallarg(int) options; + syscallarg(struct rusage *) ru; + } */ *uap = v; + int nfound, error, s; + struct proc *q, *t; + + switch (SCARG(uap, type)) { + case SVR4_P_PID: + break; + + case SVR4_P_PGID: + SCARG(uap, pid) = -p->p_pgid; + break; + + case SVR4_P_ALL: + SCARG(uap, pid) = WAIT_ANY; + break; + + default: + return EINVAL; + } + +#ifdef DEBUG_IRIX + printf("waitsys(%d, %d, %p, %x)\n", + SCARG(uap, type), SCARG(uap, pid), + SCARG(uap, info), SCARG(uap, options)); +#endif + +loop: + nfound = 0; + for (q = p->p_children.lh_first; q != 0; q = q->p_sibling.le_next) { + if (SCARG(uap, pid) != WAIT_ANY && + q->p_pid != SCARG(uap, pid) && + q->p_pgid != -SCARG(uap, pid)) { +#ifdef DEBUG_IRIX + printf("pid %d pgid %d != %d\n", q->p_pid, + q->p_pgid, SCARG(uap, pid)); +#endif + continue; + } + nfound++; + if (q->p_stat == SZOMB && + ((SCARG(uap, options) & (SVR4_WEXITED|SVR4_WTRAPPED)))) { + *retval = 0; +#ifdef DEBUG_IRIX + printf("found %d\n", q->p_pid); +#endif + if ((error = irix_setinfo(q, q->p_xstat, + SCARG(uap, info))) != 0) + return error; + + + if ((SCARG(uap, options) & SVR4_WNOWAIT)) { +#ifdef DEBUG_IRIX + printf(("Don't wait\n")); +#endif + return 0; + } + if (SCARG(uap, ru) && + (error = copyout((caddr_t)p->p_ru, + (caddr_t)SCARG(uap, ru), + sizeof(struct rusage)))) + return (error); + + /* + * If we got the child via ptrace(2) or procfs, and + * the parent is different (meaning the process was + * attached, rather than run as a child), then we need + * to give it back to the old parent, and send the + * parent a SIGCHLD. The rest of the cleanup will be + * done when the old parent waits on the child. + */ + if ((q->p_flag & P_TRACED) && + q->p_oppid != q->p_pptr->p_pid) { + t = pfind(q->p_oppid); + proc_reparent(q, t ? t : initproc); + q->p_oppid = 0; + q->p_flag &= ~(P_TRACED|P_WAITED|P_FSTRACE); + psignal(q->p_pptr, SIGCHLD); + wakeup((caddr_t)q->p_pptr); + return (0); + } + q->p_xstat = 0; + ruadd(&p->p_stats->p_cru, q->p_ru); + pool_put(&rusage_pool, q->p_ru); + + /* + * Finally finished with old proc entry. + * Unlink it from its process group and free it. + */ + leavepgrp(q); + + s = proclist_lock_write(); + LIST_REMOVE(q, p_list); /* off zombproc */ + proclist_unlock_write(s); + + LIST_REMOVE(q, p_sibling); + + /* + * Decrement the count of procs running with this uid. + */ + (void)chgproccnt(q->p_cred->p_ruid, -1); + + /* + * Free up credentials. + */ + if (--q->p_cred->p_refcnt == 0) { + crfree(q->p_cred->pc_ucred); + pool_put(&pcred_pool, q->p_cred); + } + + /* + * Release reference to text vnode + */ + if (q->p_textvp) + vrele(q->p_textvp); + + pool_put(&proc_pool, q); + nprocs--; + return 0; + } + if (q->p_stat == SSTOP && (q->p_flag & P_WAITED) == 0 && + (q->p_flag & P_TRACED || + (SCARG(uap, options) & (SVR4_WSTOPPED|SVR4_WCONTINUED)))) { +#ifdef DEBUG_IRIX + printf("jobcontrol %d\n", q->p_pid); +#endif + if (((SCARG(uap, options) & SVR4_WNOWAIT)) == 0) + q->p_flag |= P_WAITED; + *retval = 0; + return irix_setinfo(q, W_STOPCODE(q->p_xstat), + SCARG(uap, info)); + } + } + + if (nfound == 0) + return ECHILD; + + if (SCARG(uap, options) & SVR4_WNOHANG) { + *retval = 0; + if ((error = irix_setinfo(NULL, 0, SCARG(uap, info))) != 0) + return error; + return 0; + } + + if ((error = tsleep((caddr_t)p, PWAIT | PCATCH, "svr4_wait", 0)) != 0) + return error; + goto loop; + +} diff --git a/sys/compat/irix/irix_signal.h b/sys/compat/irix/irix_signal.h index 5198728b7c44..0248f8eeac3a 100644 --- a/sys/compat/irix/irix_signal.h +++ b/sys/compat/irix/irix_signal.h @@ -1,4 +1,4 @@ -/* $NetBSD: irix_signal.h,v 1.2 2001/12/25 19:04:18 manu Exp $ */ +/* $NetBSD: irix_signal.h,v 1.3 2001/12/26 11:04:20 manu Exp $ */ /*- * Copyright (c) 2001 The NetBSD Foundation, Inc. @@ -108,10 +108,60 @@ typedef struct irix_ucontext { int iuc_triggersave; } irix_ucontext_t; +/* From IRIX's */ +#define IRIX_SI_MAXSZ 128 +#define IRIX_SI_PAD ((IRIX_SI_MAXSZ / sizeof(__int32_t)) - 3) + +/* From IRIX's */ +typedef union irix_irix5_sigval { + irix_app32_int_t sigbval_int; + irix_app32_ptr_t sival_ptr; +} irix_irix5_sigval_t; + +typedef struct irix_irix5_siginfo { + irix_app32_int_t isi_signo; + irix_app32_int_t isi_code; + irix_app32_int_t isi_errno; + union { + irix_app32_int_t si_pad[IRIX_SI_PAD]; + struct { + irix_irix5_pid_t __pid; + union { + struct { + irix_irix5_uid_t __uid; + } __kill; + struct { + irix_irix5_clock_t __utime; + irix_app32_int_t __status; + irix_irix5_clock_t __stime; + irix_app32_int_t __swap; + } __cld; + } __pdata; + } __proc; + struct { + irix_app32_ptr_t __addr; + } __fault; + struct { + irix_app32_int_t __fd; + irix_app32_long_t __band; + } __file; + union irix_irix5_sigval __value; + } __data; +} irix_irix5_siginfo_t; +#define isi_pid __data.__proc.__pid +#define isi_stime __data.__proc.__pdata.__cld.__stime +#define isi_utime __data.__proc.__pdata.__cld.__utime +#define isi_status __data.__proc.__pdata.__cld.__status +#define isi_addr __data.__fault.__addr; +#define isi_trap + + #ifdef _KERNEL __BEGIN_DECLS void native_to_irix_sigset __P((const sigset_t *, irix_sigset_t *)); void irix_to_native_sigset __P((const irix_sigset_t *, sigset_t *)); + + void irix_sendsig __P((sig_t, int, sigset_t *, u_long)); __END_DECLS #endif /* _KERNEL */ diff --git a/sys/compat/irix/irix_syscall.h b/sys/compat/irix/irix_syscall.h index cd7b7d13ed6b..968a5dee4cd2 100644 --- a/sys/compat/irix/irix_syscall.h +++ b/sys/compat/irix/irix_syscall.h @@ -1,10 +1,10 @@ -/* $NetBSD: irix_syscall.h,v 1.16 2001/12/25 21:32:30 manu Exp $ */ +/* $NetBSD: irix_syscall.h,v 1.17 2001/12/26 11:04:20 manu Exp $ */ /* * System call numbers. * * DO NOT EDIT-- this file is automatically generated. - * created from NetBSD: syscalls.master,v 1.14 2001/12/25 19:04:19 manu Exp + * created from NetBSD: syscalls.master,v 1.15 2001/12/25 21:32:31 manu Exp */ /* syscall: "syscall" ret: "int" args: */ @@ -266,6 +266,9 @@ /* syscall: "setcontext" ret: "int" args: "const irix_ucontext_t *" */ #define IRIX_SYS_setcontext 169 +/* syscall: "waitsys" ret: "int" args: "int" "int" "struct irix_irix5_siginfo *" "int" "struct rusage *" */ +#define IRIX_SYS_waitsys 170 + /* syscall: "readv" ret: "ssize_t" args: "int" "const struct iovec *" "int" */ #define IRIX_SYS_readv 181 diff --git a/sys/compat/irix/irix_syscallargs.h b/sys/compat/irix/irix_syscallargs.h index e75ce1259807..1566580d94f9 100644 --- a/sys/compat/irix/irix_syscallargs.h +++ b/sys/compat/irix/irix_syscallargs.h @@ -1,10 +1,10 @@ -/* $NetBSD: irix_syscallargs.h,v 1.16 2001/12/25 21:32:30 manu Exp $ */ +/* $NetBSD: irix_syscallargs.h,v 1.17 2001/12/26 11:04:20 manu Exp $ */ /* * System call argument lists. * * DO NOT EDIT-- this file is automatically generated. - * created from NetBSD: syscalls.master,v 1.14 2001/12/25 19:04:19 manu Exp + * created from NetBSD: syscalls.master,v 1.15 2001/12/25 21:32:31 manu Exp */ #ifndef _IRIX_SYS__SYSCALLARGS_H_ @@ -260,6 +260,14 @@ struct irix_sys_setcontext_args { syscallarg(const irix_ucontext_t *) ucp; }; +struct irix_sys_waitsys_args { + syscallarg(int) type; + syscallarg(int) pid; + syscallarg(struct irix_irix5_siginfo *) info; + syscallarg(int) options; + syscallarg(struct rusage *) ru; +}; + struct irix_sys_getmountid_args { syscallarg(const char *) path; syscallarg(irix_mountid_t *) buf; @@ -367,6 +375,7 @@ int svr4_sys_sigprocmask(struct proc *, void *, register_t *); int svr4_sys_sigsuspend(struct proc *, void *, register_t *); int irix_sys_getcontext(struct proc *, void *, register_t *); int irix_sys_setcontext(struct proc *, void *, register_t *); +int irix_sys_waitsys(struct proc *, void *, register_t *); int sys_readv(struct proc *, void *, register_t *); int sys_writev(struct proc *, void *, register_t *); int irix_sys_getmountid(struct proc *, void *, register_t *); diff --git a/sys/compat/irix/irix_syscalls.c b/sys/compat/irix/irix_syscalls.c index 24eccfa1f673..947784a8272d 100644 --- a/sys/compat/irix/irix_syscalls.c +++ b/sys/compat/irix/irix_syscalls.c @@ -1,14 +1,14 @@ -/* $NetBSD: irix_syscalls.c,v 1.16 2001/12/25 21:32:30 manu Exp $ */ +/* $NetBSD: irix_syscalls.c,v 1.17 2001/12/26 11:04:20 manu Exp $ */ /* * System call names. * * DO NOT EDIT-- this file is automatically generated. - * created from NetBSD: syscalls.master,v 1.14 2001/12/25 19:04:19 manu Exp + * created from NetBSD: syscalls.master,v 1.15 2001/12/25 21:32:31 manu Exp */ #include -__KERNEL_RCSID(0, "$NetBSD: irix_syscalls.c,v 1.16 2001/12/25 21:32:30 manu Exp $"); +__KERNEL_RCSID(0, "$NetBSD: irix_syscalls.c,v 1.17 2001/12/26 11:04:20 manu Exp $"); #if defined(_KERNEL_OPT) #if defined(_KERNEL_OPT) @@ -211,7 +211,7 @@ const char *const irix_syscallnames[] = { "#167 (unimplemented swapctl)", /* 167 = unimplemented swapctl */ "getcontext", /* 168 = getcontext */ "setcontext", /* 169 = setcontext */ - "#170 (unimplemented waitsys)", /* 170 = unimplemented waitsys */ + "waitsys", /* 170 = waitsys */ "#171 (unimplemented sigstack)", /* 171 = unimplemented sigstack */ "#172 (unimplemented sigaltstack)", /* 172 = unimplemented sigaltstack */ "#173 (unimplemented sigsendset)", /* 173 = unimplemented sigsendset */ diff --git a/sys/compat/irix/irix_sysent.c b/sys/compat/irix/irix_sysent.c index 69dc66269941..3e638558ea5b 100644 --- a/sys/compat/irix/irix_sysent.c +++ b/sys/compat/irix/irix_sysent.c @@ -1,14 +1,14 @@ -/* $NetBSD: irix_sysent.c,v 1.16 2001/12/25 21:32:31 manu Exp $ */ +/* $NetBSD: irix_sysent.c,v 1.17 2001/12/26 11:04:20 manu Exp $ */ /* * System call switch table. * * DO NOT EDIT-- this file is automatically generated. - * created from NetBSD: syscalls.master,v 1.14 2001/12/25 19:04:19 manu Exp + * created from NetBSD: syscalls.master,v 1.15 2001/12/25 21:32:31 manu Exp */ #include -__KERNEL_RCSID(0, "$NetBSD: irix_sysent.c,v 1.16 2001/12/25 21:32:31 manu Exp $"); +__KERNEL_RCSID(0, "$NetBSD: irix_sysent.c,v 1.17 2001/12/26 11:04:20 manu Exp $"); #if defined(_KERNEL_OPT) #include "opt_ntp.h" @@ -384,8 +384,8 @@ struct sysent irix_sysent[] = { irix_sys_getcontext }, /* 168 = getcontext */ { 1, s(struct irix_sys_setcontext_args), 0, irix_sys_setcontext }, /* 169 = setcontext */ - { 0, 0, 0, - sys_nosys }, /* 170 = unimplemented waitsys */ + { 5, s(struct irix_sys_waitsys_args), 0, + irix_sys_waitsys }, /* 170 = waitsys */ { 0, 0, 0, sys_nosys }, /* 171 = unimplemented sigstack */ { 0, 0, 0, diff --git a/sys/compat/irix/irix_types.h b/sys/compat/irix/irix_types.h index ecafc12ba731..5d9a9b0b8963 100644 --- a/sys/compat/irix/irix_types.h +++ b/sys/compat/irix/irix_types.h @@ -1,4 +1,4 @@ -/* $NetBSD: irix_types.h,v 1.8 2001/12/25 19:04:19 manu Exp $ */ +/* $NetBSD: irix_types.h,v 1.9 2001/12/26 11:04:20 manu Exp $ */ /*- * Copyright (c) 2001 The NetBSD Foundation, Inc. @@ -50,12 +50,14 @@ typedef struct { } irix_sigset_t; /* From IRIX's */ +typedef __int32_t irix_app32_int_t; typedef __uint32_t irix_app32_ulong_t; typedef __int32_t irix_app32_long_t; typedef __uint64_t irix_app32_ulong_long_t; typedef __int64_t irix_app32_long_long_t; typedef __uint32_t irix_ino_t; typedef __int32_t irix_off_t; +typedef __uint32_t irix_app32_ptr_t; #if 1 /* _MIPS_SZLONG == 32 */ typedef unsigned long irix_mode_t; @@ -84,6 +86,9 @@ typedef __int64_t irix_blkcnt64_t; /* From IRIX's */ typedef irix_app32_long_long_t irix_irix5_n32_off_t; +typedef irix_app32_long_t irix_irix5_uid_t; +typedef irix_app32_long_t irix_irix5_clock_t; +typedef irix_app32_long_t irix_irix5_pid_t; /* From IRIX's */ typedef irix_app32_long_t irix_irix5_time_t; diff --git a/sys/compat/irix/syscalls.master b/sys/compat/irix/syscalls.master index 901535eaba16..ede49c701aba 100644 --- a/sys/compat/irix/syscalls.master +++ b/sys/compat/irix/syscalls.master @@ -1,4 +1,4 @@ - $NetBSD: syscalls.master,v 1.15 2001/12/25 21:32:31 manu Exp $ + $NetBSD: syscalls.master,v 1.16 2001/12/26 11:04:20 manu Exp $ ; @(#)syscalls.master 8.1 (Berkeley) 7/19/93 @@ -280,7 +280,9 @@ 167 UNIMPL swapctl 168 STD { int irix_sys_getcontext(irix_ucontext_t *ucp); } 169 STD { int irix_sys_setcontext(const irix_ucontext_t *ucp); } -170 UNIMPL waitsys +170 STD { int irix_sys_waitsys(int type, int pid, \ + struct irix_irix5_siginfo *info, int options, \ + struct rusage *ru); } 171 UNIMPL sigstack 172 UNIMPL sigaltstack 173 UNIMPL sigsendset