📄 kern_syscall.c
字号:
/* $Id: kern_syscall.c,v 1.1.1.1 2001/10/01 18:47:34 patrik Exp $ *//* * Copyright (c) 2000 Opsycon AB (www.opsycon.se) * Copyright (c) 2000 Rtmx, Inc (www.rtmx.com) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed for Rtmx, Inc by * Opsycon Open System Consulting AB, Sweden. * 4. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */#include <sys/param.h>#include <sys/proc.h>#include <sys/kernel.h>#include <sys/systm.h>#include <sys/signal.h>#include <sys/signalvar.h>#include <sys/errno.h>#include <sys/syslog.h>#include <sys/syscallargs.h>#include <machine/stdarg.h>int errno; /* has to be declared somewhere *//* * Some stuff taken from signal.h. */static __inline int sigaddset(sigset_t *set, int signo) { if (signo <= 0 || signo >= _NSIG) { errno = 22; /* EINVAL */ return -1; } *set |= (1 << ((signo)-1)); /* sigmask(signo) */ return (0);}static __inline int sigdelset(sigset_t *set, int signo) { extern int errno; if (signo <= 0 || signo >= _NSIG) { errno = 22; /* EINVAL */ return -1; } *set &= ~(1 << ((signo)-1)); /* sigmask(signo) */ return (0);}static __inline int sigismember(const sigset_t *set, int signo) { extern int errno; if (signo <= 0 || signo >= _NSIG) { errno = 22; /* EINVAL */ return -1; } return ((*set & (1 << ((signo)-1))) != 0);}#define sigemptyset(set) (*(set) = 0, 0)#define MAXARGS 6static int gensyscall __P((int (*) __P((struct proc *, void *, register_t *)), int, int, va_list));static intgensyscall (int (*func) __P((struct proc *, void *, register_t *)), int nargs, int a1, va_list ap){ extern int errno; struct args {register_t a[MAXARGS];} ua; struct proc *p = curproc; register_t rval[2]; int error, sig, i; if (p->p_stat != SNOTKERN) panic ("nested syscall"); if (nargs > 0) { ua.a[0] = a1; } for (i = 1; i < nargs; i++) { ua.a[i] = va_arg (ap, register_t); } while (1) { p->p_stat = SRUN; rval[0] = 0; error = (*func) (p, &ua, rval); while ((sig = CURSIG (p)) != 0) /* handle signals here */ psig (sig); p->p_stat = SNOTKERN; if (error != ERESTART) { if (error) { errno = error; return -1; } return rval[0]; } }}#define syscall(pub, pri, nargs) \int pub __P((int, ...)); \int pub (int a1, ...) \{ \ int res; \ va_list ap; \ va_start (ap, a1); \ res = gensyscall (SYSCALL(pri), nargs, a1, ap); \ va_end (ap); \ return(res); \}syscall(soc_read, read, 3)syscall(soc_write, write, 3)syscall(soc_close, close, 1)syscall(recvmsg, recvmsg, 3)syscall(sendmsg, sendmsg, 3)syscall(recvfrom, recvfrom, 6)syscall(accept, accept, 3)syscall(getpeername, getpeername, 3)syscall(getsockname, getsockname, 3)syscall(soc_dup, dup, 2)syscall(soc_ioctl, ioctl, 3)#if 0syscall(getdtablesize, getdtablesize, 0)#endifsyscall(soc_dup2, dup2, 2)syscall(soc_fcntl, fcntl, 3)syscall(select, select, 5)syscall(socket, socket, 3)syscall(connect, connect, 3)syscall(bind, bind, 3)syscall(setsockopt, setsockopt, 5)syscall(listen, listen, 2)syscall(getsockopt, getsockopt, 5)syscall(readv, readv, 3)syscall(writev, writev, 3)syscall(sendto, sendto, 6)syscall(shutdown, shutdown, 2)syscall(sigaction, sigaction, 3)syscall(kernsigprocmask, sigprocmask, 2)syscall(sigpending, sigpending, 0)syscall(sigsuspend, sigsuspend, 1)syscall(gettimeofday, gettimeofday, 2)syscall(getitimer, getitimer, 2)syscall(setitimer, setitimer, 3)#ifdef notyet/* * TBD: user callable socket system call */intsoc_syscall (){ extern int errno; errno = EINVAL; return -1;}#endif/* * user callable exit (distinct from prom's exit routine) */void soc_exit __P((int));voidsoc_exit (rv){ exit1 (curproc, rv & 0xff);}/* * Dummy system calls */int getuid __P((void));int getuid() {return 0;}int geteuid __P((void));int geteuid() {return 0;}int getegid __P((void));int getegid() {return 0;}int getgid __P((void));int getgid() {return 0;}int getpid __P((void));int getpid() { return curproc->p_pid;}int getpgrp __P((int));int getpgrp(pid){ /* for us pgid == pid */ return curproc->p_pid;}int gethostid __P((void));int gethostid(){extern char *getenv __P((char *));extern in_addr_t inet_addr __P((const char *)); char *netaddr; int id; netaddr = getenv ("netaddr"); if (netaddr && (id = inet_addr (netaddr)) != -1) return id; return 0;}int gethostname __P((char *buf, int n));intgethostname (char *buf, int n){extern char *getenv __P((char *)); char *hostname; extern int errno; hostname = getenv ("hostname"); if (!hostname) hostname = "pmon"; if (n < strlen (hostname) + 1) { errno = EINVAL; return -1; } strcpy (buf, hostname); return 0;}/* * User-level signal handling (4.3bsd emulation on top of POSIX) */int sigvec __P((int, struct sigvec *, struct sigvec *));intsigvec(signo, sv, osv) int signo; struct sigvec *sv, *osv;{ int ret; if (sv) sv->sv_flags ^= SV_INTERRUPT; /* !SA_INTERRUPT */ ret = sigaction(signo, (struct sigaction *)sv, (struct sigaction *)osv); if (ret == 0 && osv) osv->sv_flags ^= SV_INTERRUPT; /* !SA_INTERRUPT */ return (ret);}/* * The real sigprocmask system call takes only two args, and returns * the old mask. This cover function munges the arguments appropriately. */int sigprocmask __P((int how, const sigset_t *set, sigset_t *oset));intsigprocmask (int how, const sigset_t *set, sigset_t *oset){ sigset_t new, old; int oerrno; if (!set) { how = SIG_BLOCK; new = 0; } else { new = *set; } oerrno = errno; errno = 0; old = kernsigprocmask (how, new); if (old == (sigset_t)-1 && errno) return -1; errno = oerrno; if (oset) *oset = old; return 0;}int sigsetmask __P((int));intsigsetmask(mask) int mask;{ int omask, n; n = sigprocmask(SIG_SETMASK, (sigset_t *) &mask, (sigset_t *) &omask); if (n) return (n); return (omask);}int sigblock __P((int));intsigblock(mask) int mask;{ int omask, n; n = sigprocmask(SIG_BLOCK, (sigset_t *) &mask, (sigset_t *) &omask); if (n) return (n); return (omask);}int sigpause __P((int));intsigpause(mask) int mask;{ return (sigsuspend((int)&mask));}sigset_t _sigintr; /* shared with siginterrupt */sig_tsignal(s, a) int s; sig_t a;{ struct sigaction sa, osa; sa.sa_handler = a; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; if (!sigismember(&_sigintr, s)) sa.sa_flags |= SA_RESTART; if (sigaction(s, &sa, &osa) < 0) return (BADSIG); return (osa.sa_handler);}/* * Set signal state to prevent restart of system calls * after an instance of the indicated signal. */int siginterrupt __P((int, int));intsiginterrupt(sig, flag) int sig, flag;{ extern sigset_t _sigintr; struct sigaction sa; int ret; if ((ret = sigaction(sig, (struct sigaction *)0, &sa)) < 0) return (ret); if (flag) { sigaddset(&_sigintr, sig); sa.sa_flags &= ~SA_RESTART; } else { sigdelset(&_sigintr, sig); sa.sa_flags |= SA_RESTART; } return (sigaction(sig, &sa, (struct sigaction *)0));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -