change gdium conf to print message out both on uart and lcd
[pmon-gdium.git] / sys / kern / kern_syscall.c
blob1096bd8074b11f902820e0ba06ddd6edcba747dc
1 /* $Id: kern_syscall.c,v 1.1.1.1 2006/09/14 01:59:08 root Exp $ */
3 /*
4 * Copyright (c) 2000 Opsycon AB (www.opsycon.se)
5 * Copyright (c) 2000 Rtmx, Inc (www.rtmx.com)
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
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
32 * SUCH DAMAGE.
36 #include <sys/param.h>
37 #include <sys/proc.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 */
56 return -1;
58 *set |= (1 << ((signo)-1)); /* sigmask(signo) */
59 return (0);
61 static __inline int sigdelset(sigset_t *set, int signo) {
62 extern int errno;
64 if (signo <= 0 || signo >= _NSIG) {
65 errno = 22; /* EINVAL */
66 return -1;
68 *set &= ~(1 << ((signo)-1)); /* sigmask(signo) */
69 return (0);
72 static __inline int sigismember(const sigset_t *set, int signo) {
73 extern int errno;
75 if (signo <= 0 || signo >= _NSIG) {
76 errno = 22; /* EINVAL */
77 return -1;
79 return ((*set & (1 << ((signo)-1))) != 0);
82 #define sigemptyset(set) (*(set) = 0, 0)
85 #define MAXARGS 6
88 static int gensyscall __P((int (*) __P((struct proc *, void *, register_t *)), int, int, va_list));
90 static int
91 gensyscall (int (*func) __P((struct proc *, void *, register_t *)), int nargs, int a1, va_list ap)
93 extern int errno;
94 struct args {register_t a[MAXARGS];} ua;
95 struct proc *p = curproc;
96 register_t rval[2];
97 int error, sig, i;
99 if (p->p_stat != SNOTKERN)
100 panic ("nested syscall");
102 if (nargs > 0) {
103 ua.a[0] = a1;
105 for (i = 1; i < nargs; i++) {
106 ua.a[i] = va_arg (ap, register_t);
109 while (1) {
110 p->p_stat = SRUN;
111 rval[0] = 0;
112 error = (*func) (p, &ua, rval);
113 while ((sig = CURSIG (p)) != 0) /* handle signals here */
114 psig (sig);
115 p->p_stat = SNOTKERN;
116 if (error != ERESTART) {
117 if (error) {
118 errno = error;
119 return -1;
121 return rval[0];
126 #define syscall(pub, pri, nargs) \
127 int pub __P((int, ...)); \
128 int pub (int a1, ...) \
130 int res; \
131 va_list ap; \
132 va_start (ap, a1); \
133 res = gensyscall (SYSCALL(pri), nargs, a1, ap); \
134 va_end (ap); \
135 return(res); \
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)
149 #if 0
150 syscall(getdtablesize, getdtablesize, 0)
151 #endif
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)
173 #ifdef notyet
175 * TBD: user callable socket system call
178 soc_syscall ()
180 extern int errno;
181 errno = EINVAL;
182 return -1;
185 #endif
188 * user callable exit (distinct from prom's exit routine)
190 void soc_exit __P((int));
191 void
192 soc_exit (rv)
194 exit1 (curproc, rv & 0xff);
198 * Dummy system calls
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));
211 int getpid()
213 return curproc->p_pid;
216 int getpgrp __P((int));
217 int getpgrp(pid)
219 /* for us pgid == pid */
220 return curproc->p_pid;
223 int gethostid __P((void));
224 int gethostid()
226 extern char *getenv __P((char *));
227 extern in_addr_t inet_addr __P((const char *));
228 char *netaddr;
229 int id;
231 netaddr = getenv ("netaddr");
232 if (netaddr && (id = inet_addr (netaddr)) != -1)
233 return id;
234 return 0;
238 int gethostname __P((char *buf, int n));
240 gethostname (char *buf, int n)
242 extern char *getenv __P((char *));
243 char *hostname;
244 extern int errno;
246 hostname = getenv ("hostname");
247 if (!hostname)
248 hostname = "pmon";
250 if (n < strlen (hostname) + 1) {
251 errno = EINVAL;
252 return -1;
254 strcpy (buf, hostname);
255 return 0;
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)
264 int signo;
265 struct sigvec *sv, *osv;
267 int ret;
269 if (sv)
270 sv->sv_flags ^= SV_INTERRUPT; /* !SA_INTERRUPT */
271 ret = sigaction(signo, (struct sigaction *)sv, (struct sigaction *)osv);
272 if (ret == 0 && osv)
273 osv->sv_flags ^= SV_INTERRUPT; /* !SA_INTERRUPT */
274 return (ret);
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)
285 sigset_t new, old;
286 int oerrno;
288 if (!set) {
289 how = SIG_BLOCK;
290 new = 0;
291 } else {
292 new = *set;
295 oerrno = errno; errno = 0;
296 old = kernsigprocmask (how, new);
297 if (old == (sigset_t)-1 && errno)
298 return -1;
299 errno = oerrno;
301 if (oset)
302 *oset = old;
303 return 0;
306 int sigsetmask __P((int));
308 sigsetmask(mask)
309 int mask;
311 int omask, n;
313 n = sigprocmask(SIG_SETMASK, (sigset_t *) &mask, (sigset_t *) &omask);
314 if (n)
315 return (n);
316 return (omask);
319 int sigblock __P((int));
321 sigblock(mask)
322 int mask;
324 int omask, n;
326 n = sigprocmask(SIG_BLOCK, (sigset_t *) &mask, (sigset_t *) &omask);
327 if (n)
328 return (n);
329 return (omask);
332 int sigpause __P((int));
334 sigpause(mask)
335 int mask;
337 return (sigsuspend((int)&mask));
340 sigset_t _sigintr; /* shared with siginterrupt */
342 sig_t
343 signal(s, a)
344 int s;
345 sig_t a;
347 struct sigaction sa, osa;
349 sa.sa_handler = a;
350 sigemptyset(&sa.sa_mask);
351 sa.sa_flags = 0;
352 if (!sigismember(&_sigintr, s))
353 sa.sa_flags |= SA_RESTART;
354 if (sigaction(s, &sa, &osa) < 0)
355 return (BADSIG);
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)
366 int sig, flag;
368 extern sigset_t _sigintr;
369 struct sigaction sa;
370 int ret;
372 if ((ret = sigaction(sig, (struct sigaction *)0, &sa)) < 0)
373 return (ret);
374 if (flag) {
375 sigaddset(&_sigintr, sig);
376 sa.sa_flags &= ~SA_RESTART;
377 } else {
378 sigdelset(&_sigintr, sig);
379 sa.sa_flags |= SA_RESTART;
381 return (sigaction(sig, &sa, (struct sigaction *)0));