1 /* $Id: kern_syscall.c,v 1.1.1.1 2006/09/14 01:59:08 root Exp $ */
4 * Copyright (c) 2000 Opsycon AB (www.opsycon.se)
5 * Copyright (c) 2000 Rtmx, Inc (www.rtmx.com)
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed for Rtmx, Inc by
18 * Opsycon Open System Consulting AB, Sweden.
19 * 4. The name of the author may not be used to endorse or promote products
20 * derived from this software without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
23 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
26 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 #include <sys/param.h>
38 #include <sys/kernel.h>
39 #include <sys/systm.h>
40 #include <sys/signal.h>
41 #include <sys/signalvar.h>
42 #include <sys/errno.h>
43 #include <sys/syslog.h>
44 #include <sys/syscallargs.h>
46 #include <machine/stdarg.h>
48 int errno
; /* has to be declared somewhere */
50 * Some stuff taken from signal.h.
52 static __inline
int sigaddset(sigset_t
*set
, int signo
) {
54 if (signo
<= 0 || signo
>= _NSIG
) {
55 errno
= 22; /* EINVAL */
58 *set
|= (1 << ((signo
)-1)); /* sigmask(signo) */
61 static __inline
int sigdelset(sigset_t
*set
, int signo
) {
64 if (signo
<= 0 || signo
>= _NSIG
) {
65 errno
= 22; /* EINVAL */
68 *set
&= ~(1 << ((signo
)-1)); /* sigmask(signo) */
72 static __inline
int sigismember(const sigset_t
*set
, int signo
) {
75 if (signo
<= 0 || signo
>= _NSIG
) {
76 errno
= 22; /* EINVAL */
79 return ((*set
& (1 << ((signo
)-1))) != 0);
82 #define sigemptyset(set) (*(set) = 0, 0)
88 static int gensyscall
__P((int (*) __P((struct proc
*, void *, register_t
*)), int, int, va_list));
91 gensyscall (int (*func
) __P((struct proc
*, void *, register_t
*)), int nargs
, int a1
, va_list ap
)
94 struct args
{register_t a
[MAXARGS
];} ua
;
95 struct proc
*p
= curproc
;
99 if (p
->p_stat
!= SNOTKERN
)
100 panic ("nested syscall");
105 for (i
= 1; i
< nargs
; i
++) {
106 ua
.a
[i
] = va_arg (ap
, register_t
);
112 error
= (*func
) (p
, &ua
, rval
);
113 while ((sig
= CURSIG (p
)) != 0) /* handle signals here */
115 p
->p_stat
= SNOTKERN
;
116 if (error
!= ERESTART
) {
126 #define syscall(pub, pri, nargs) \
127 int pub __P((int, ...)); \
128 int pub (int a1, ...) \
133 res = gensyscall (SYSCALL(pri), nargs, a1, ap); \
138 syscall(soc_read
, read
, 3)
139 syscall(soc_write
, write
, 3)
140 syscall(soc_close
, close
, 1)
141 syscall(recvmsg
, recvmsg
, 3)
142 syscall(sendmsg
, sendmsg
, 3)
143 syscall(recvfrom
, recvfrom
, 6)
144 syscall(accept
, accept
, 3)
145 syscall(getpeername
, getpeername
, 3)
146 syscall(getsockname
, getsockname
, 3)
147 syscall(soc_dup
, dup
, 2)
148 syscall(soc_ioctl
, ioctl
, 3)
150 syscall(getdtablesize
, getdtablesize
, 0)
152 syscall(soc_dup2
, dup2
, 2)
153 syscall(soc_fcntl
, fcntl
, 3)
154 syscall(select
, select
, 5)
155 syscall(socket
, socket
, 3)
156 syscall(connect
, connect
, 3)
157 syscall(bind
, bind
, 3)
158 syscall(setsockopt
, setsockopt
, 5)
159 syscall(listen
, listen
, 2)
160 syscall(getsockopt
, getsockopt
, 5)
161 syscall(readv
, readv
, 3)
162 syscall(writev
, writev
, 3)
163 syscall(sendto
, sendto
, 6)
164 syscall(shutdown
, shutdown
, 2)
165 syscall(sigaction
, sigaction
, 3)
166 syscall(kernsigprocmask
, sigprocmask
, 2)
167 syscall(sigpending
, sigpending
, 0)
168 syscall(sigsuspend
, sigsuspend
, 1)
169 syscall(gettimeofday
, gettimeofday
, 2)
170 syscall(getitimer
, getitimer
, 2)
171 syscall(setitimer
, setitimer
, 3)
175 * TBD: user callable socket system call
188 * user callable exit (distinct from prom's exit routine)
190 void soc_exit
__P((int));
194 exit1 (curproc
, rv
& 0xff);
201 int getuid
__P((void));
202 int getuid() {return 0;}
203 int geteuid
__P((void));
204 int geteuid() {return 0;}
205 int getegid
__P((void));
206 int getegid() {return 0;}
207 int getgid
__P((void));
208 int getgid() {return 0;}
210 int getpid
__P((void));
213 return curproc
->p_pid
;
216 int getpgrp
__P((int));
219 /* for us pgid == pid */
220 return curproc
->p_pid
;
223 int gethostid
__P((void));
226 extern char *getenv
__P((char *));
227 extern in_addr_t inet_addr
__P((const char *));
231 netaddr
= getenv ("netaddr");
232 if (netaddr
&& (id
= inet_addr (netaddr
)) != -1)
238 int gethostname
__P((char *buf
, int n
));
240 gethostname (char *buf
, int n
)
242 extern char *getenv
__P((char *));
246 hostname
= getenv ("hostname");
250 if (n
< strlen (hostname
) + 1) {
254 strcpy (buf
, hostname
);
259 * User-level signal handling (4.3bsd emulation on top of POSIX)
261 int sigvec
__P((int, struct sigvec
*, struct sigvec
*));
263 sigvec(signo
, sv
, osv
)
265 struct sigvec
*sv
, *osv
;
270 sv
->sv_flags
^= SV_INTERRUPT
; /* !SA_INTERRUPT */
271 ret
= sigaction(signo
, (struct sigaction
*)sv
, (struct sigaction
*)osv
);
273 osv
->sv_flags
^= SV_INTERRUPT
; /* !SA_INTERRUPT */
278 * The real sigprocmask system call takes only two args, and returns
279 * the old mask. This cover function munges the arguments appropriately.
281 int sigprocmask
__P((int how
, const sigset_t
*set
, sigset_t
*oset
));
283 sigprocmask (int how
, const sigset_t
*set
, sigset_t
*oset
)
295 oerrno
= errno
; errno
= 0;
296 old
= kernsigprocmask (how
, new);
297 if (old
== (sigset_t
)-1 && errno
)
306 int sigsetmask
__P((int));
313 n
= sigprocmask(SIG_SETMASK
, (sigset_t
*) &mask
, (sigset_t
*) &omask
);
319 int sigblock
__P((int));
326 n
= sigprocmask(SIG_BLOCK
, (sigset_t
*) &mask
, (sigset_t
*) &omask
);
332 int sigpause
__P((int));
337 return (sigsuspend((int)&mask
));
340 sigset_t _sigintr
; /* shared with siginterrupt */
347 struct sigaction sa
, osa
;
350 sigemptyset(&sa
.sa_mask
);
352 if (!sigismember(&_sigintr
, s
))
353 sa
.sa_flags
|= SA_RESTART
;
354 if (sigaction(s
, &sa
, &osa
) < 0)
356 return (osa
.sa_handler
);
360 * Set signal state to prevent restart of system calls
361 * after an instance of the indicated signal.
363 int siginterrupt
__P((int, int));
365 siginterrupt(sig
, flag
)
368 extern sigset_t _sigintr
;
372 if ((ret
= sigaction(sig
, (struct sigaction
*)0, &sa
)) < 0)
375 sigaddset(&_sigintr
, sig
);
376 sa
.sa_flags
&= ~SA_RESTART
;
378 sigdelset(&_sigintr
, sig
);
379 sa
.sa_flags
|= SA_RESTART
;
381 return (sigaction(sig
, &sa
, (struct sigaction
*)0));