--- /dev/null
+# rts sources
+.PATH: ${.CURDIR}/arch/${ARCH}/sys-minix
+
+SRCS+= \
+ __sigreturn.S \
+ _ipc.S \
+ _senda.S \
+ brksize.S \
+ ucontext.S
--- /dev/null
+/* This routine is the low-level code for returning from signals. */
+/* It calls _sigreturn, which is the normal "system call" routine. */
+/* Both __sigreturn and _sigreturn are needed. */
+#include <machine/asm.h>
+
+IMPORT(_sigreturn)
+ENTRY(__sigreturn)
+ addl $16, %esp
+ jmp _C_LABEL(_sigreturn)
--- /dev/null
+#include <minix/ipcconst.h>
+#include <machine/asm.h>
+
+ IPCVEC = 33 /* ipc trap to kernel */
+ KERVEC = 32 /* syscall trap to kernel */
+
+ SRC_DST = 8 /* source/ destination process */
+ MESSAGE = 12 /* message pointer */
+ STATUS = 16 /* status pointer */
+
+/**========================================================================* */
+/* IPC assembly routines * */
+/**========================================================================* */
+/* all message passing routines save ebx, but destroy eax and ecx. */
+ENTRY(_send)
+ push %ebp
+ movl %esp, %ebp
+ push %ebx
+ movl SRC_DST(%ebp), %eax /* eax = dest-src */
+ movl MESSAGE(%ebp), %ebx /* ebx = message pointer */
+ movl $SEND, %ecx /* _send(dest, ptr) */
+ int $IPCVEC /* trap to the kernel */
+ pop %ebx
+ pop %ebp
+ ret
+
+ENTRY(_receive)
+ push %ebp
+ movl %esp, %ebp
+ push %ebx
+ movl SRC_DST(%ebp), %eax /* eax = dest-src */
+ movl MESSAGE(%ebp), %ebx /* ebx = message pointer */
+ movl $RECEIVE, %ecx /* _receive(src, ptr) */
+ int $IPCVEC /* trap to the kernel */
+ movl STATUS(%ebp), %ecx /* ecx = status pointer */
+ movl %ebx, (%ecx)
+ pop %ebx
+ pop %ebp
+ ret
+
+ENTRY(_sendrec)
+ push %ebp
+ movl %esp, %ebp
+ push %ebx
+ movl SRC_DST(%ebp), %eax /* eax = dest-src */
+ movl MESSAGE(%ebp), %ebx /* ebx = message pointer */
+ movl $SENDREC, %ecx /* _sendrec(srcdest, ptr) */
+ int $IPCVEC /* trap to the kernel */
+ pop %ebx
+ pop %ebp
+ ret
+
+ENTRY(_notify)
+ push %ebp
+ movl %esp, %ebp
+ push %ebx
+ movl SRC_DST(%ebp), %eax /* eax = destination */
+ movl $NOTIFY, %ecx /* _notify(srcdst) */
+ int $IPCVEC /* trap to the kernel */
+ pop %ebx
+ pop %ebp
+ ret
+
+ENTRY(_sendnb)
+ push %ebp
+ movl %esp, %ebp
+ push %ebx
+ movl SRC_DST(%ebp), %eax /* eax = dest-src */
+ movl MESSAGE(%ebp), %ebx /* ebx = message pointer */
+ movl $SENDNB, %ecx /* _sendnb(dest, ptr) */
+ int $IPCVEC /* trap to the kernel */
+ pop %ebx
+ pop %ebp
+ ret
+
+ENTRY(_do_kernel_call)
+ /* pass the message pointer to kernel in the %eax register */
+ movl 4(%esp), %eax
+ int $KERVEC
+ ret
--- /dev/null
+#include <minix/ipcconst.h>
+#include <machine/asm.h>
+
+ SYSVEC = 33
+
+ MSGTAB = 8 /* message table */
+ TABCOUNT = 12 /* number of entries in message table */
+
+ENTRY(_senda)
+ push %ebp
+ movl %esp, %ebp
+ push %ebx
+ movl TABCOUNT(%ebp), %eax /* eax = count */
+ movl MSGTAB(%ebp), %ebx /* ebx = table */
+ movl $SENDA, %ecx /* _senda(table, count) */
+ int $SYSVEC /* trap to the kernel */
+ pop %ebx
+ pop %ebp
+ ret
--- /dev/null
+#if defined(__ELF__)
+.globl _end
+.globl _brksize
+
+.data
+_brksize: .long _end
+#else
+.globl __brksize
+.data
+.extern endbss, __brksize
+__brksize:
+.long endbss
+#endif
--- /dev/null
+#include <machine/asm.h>
+
+#ifdef __ACK__
+.text
+begtext:
+#ifdef __ACK__
+.rom
+#else
+.data
+#endif
+begrom:
+.data
+begdata:
+.bss
+begbss:
+#endif
+
+
+IMPORT(getuctx)
+IMPORT(setuctx)
+IMPORT(resumecontext)
+
+
+/* Offsets into ucontext_t structure. Keep in sync with <sys/ucontext.h>! */
+#define UC_FLAGS 0
+#define UC_LINK UC_FLAGS + 4
+#define MCTX UC_LINK + 4
+#define MAGIC MCTX
+#define GS MAGIC+4
+#define FS GS+2
+#define ES FS+2
+#define DS ES+2
+#define DI DS+2
+#define SI DI+4
+#define BP SI+4
+#define ST BP+4 /* Hole for another SP */
+#define BX ST+4
+#define DX BX+4
+#define CX DX+4
+#define AX CX+4
+#define RETADR AX+4
+#define PC RETADR+4
+#define CS PC+4
+#define PSW CS+4
+#define SP PSW+4
+#define SS SP+4
+
+
+/* MCF_MAGIC value from <mcontext.h> */
+#define MCF_MAGIC 0xc0ffee
+
+/* Values from <sys/ucontext.h> */
+#define UCF_IGNFPU 0x002
+#define UCF_IGNSIGM 0x004
+
+
+/* EINVAL from errno.h */
+#define EFAULT 14
+#define EINVAL 22
+
+
+/* int getcontext(ucontext_t *ucp)
+ * Initialise the structure pointed to by ucp to the current user context
+ * of the calling thread. */
+ENTRY(getcontext)
+ /* In case a process does not use the FPU and is neither interested in
+ * saving its signal mask, then we can skip the context switch to
+ * PM and kernel altogether and only save general-purpose registers. */
+
+ mov (%esp), %ecx /* Save return address:
+ * When setcontext or swapcontext is called,
+ * we jump to this address and continue
+ * running. */
+
+ mov 4(%esp), %edx /* edx = ucp */
+ /* Check null pointer */
+ cmp $0, %edx /* edx == NULL? */
+ jne 3f /* Not null, continue */
+ movl $EFAULT, (_C_LABEL(errno))
+ xor %eax, %eax
+ dec %eax /* return -1 */
+ ret
+
+3: /* Check flags */
+ push %ecx /* save ecx */
+ push %ebx /* save ebx */
+ lea UC_FLAGS(%edx), %ebx /* ebx = &(ucp->uc_flags) */
+ mov (%ebx), %ecx /* ecx = ucp->uc_flags */
+ mov $UCF_IGNFPU, %eax
+ or $UCF_IGNSIGM, %eax
+ cmp %eax, %ecx /* is UCF_IGNFPU or UCF_IGNSIGM set? */
+ pop %ebx /* restore ebx */
+ pop %ecx /* restore ecx */
+ jz 1f /* Both are set, skip getuctx */
+
+0:
+ push %ecx /* Save ecx */
+ push %edx
+ call _C_LABEL(getuctx) /* getuctx(ucp) */
+ pop %edx /* clean up stack and restore edx */
+ pop %ecx /* Restore ecx */
+
+1:
+ /* Save the context */
+ mov 4(%esp), %edx /* edx = ucp */
+ pop %eax /* retaddr */
+ mov %eax, PC(%edx) /* Save real RTA in mcp struct */
+ mov %esp, SP(%edx) /* Save stack pointer (now pointing to ucp) */
+ /* Save GP registers */
+ mov %ebp, BP(%edx) /* Save EBP */
+ mov %esi, SI(%edx) /* Save ESI */
+ mov %edi, DI(%edx) /* Save EDI */
+ mov %ebx, BX(%edx) /* Save EBX */
+ mov %ecx, CX(%edx) /* Save ECX */
+ movl $MCF_MAGIC, MAGIC(%edx) /* Set magic value */
+ push %eax /* Restore retaddr */
+
+ xor %eax, %eax /* Return 0 */
+
+2:
+ add $4, %esp /* Remove stale (setcontext) RTA */
+ jmp *%ecx /* Restore return address */
+
+
+/* int setcontext(const ucontext_t *ucp)
+ * Restore the user context pointed to by ucp. A successful call to
+ * setcontext does not return; program execution resumes at the point
+ * specified by the ucp argument. If ucp was created with getcontext(),
+ * program execution continues as if the corresponding call of getcontext()
+ * had just returned. If ucp was created with makecontext(), program
+ * execution continues with the function passed to makecontext(). */
+ENTRY(setcontext)
+ /* In case a process does not use the FPU and is neither interested in
+ * restoring its signal mask, then we can skip the context switch to
+ * PM and kernel altogether and restore state here. */
+
+ mov 4(%esp), %edx /* edx = ucp */
+
+ /* Check null pointer */
+ cmp $0, %edx /* edx == NULL? */
+ jnz 3f /* Not null, continue */
+ movl $EFAULT, (_C_LABEL(errno))
+ xor %eax, %eax
+ dec %eax /* return -1 */
+ ret
+
+3: /* Check flags */
+ push %ebx /* save ebx */
+ lea MAGIC(%edx), %ebx /* ebx = &(ucp->mc_context.mc_magic) */
+ mov (%ebx), %ecx /* ecx = ucp->mc_context.mc_magic */
+ pop %ebx /* restore ebx */
+ cmp $MCF_MAGIC, %ecx /* is the magic value set (is context valid)?*/
+ jz 4f /* is set, proceed */
+ movl $EINVAL, (_C_LABEL(errno)) /* not set, return error code */
+ xor %eax, %eax
+ dec %eax /* return -1 */
+ ret
+
+
+4: push %ebx /* save ebx */
+ lea UC_FLAGS(%edx), %ebx /* ebx = &(ucp->uc_flags) */
+ mov (%ebx), %ecx /* ecx = ucp->uc_flags */
+ pop %ebx /* restore ebx */
+ mov $UCF_IGNFPU, %eax
+ or $UCF_IGNSIGM, %eax
+ cmp %eax, %ecx /* Are UCF_IGNFPU and UCF_IGNSIGM flags set? */
+ jz 1f /* Both are set, so don't bother restoring FPU
+ * state and signal mask */
+
+0: push %ecx /* Save ecx */
+ push %edx
+ call _C_LABEL(setuctx) /* setuctx(ucp) */
+ pop %edx /* Clean up stack and restore edx */
+ pop %ecx /* Restore ecx */
+
+1: /* Restore the registers */
+ mov 4(%esp), %edx /* edx = ucp */
+ mov CX(%edx), %ecx /* Restore ECX */
+ mov BX(%edx), %ebx /* Restore EBX */
+ mov DI(%edx), %edi /* Restore EDI */
+ mov SI(%edx), %esi /* Restore ESI */
+ mov BP(%edx), %ebp /* Restore EBP */
+ mov SP(%edx), %esp /* Restore stack pointer */
+
+2:
+ jmp *PC(%edx) /* Push RTA onto stack so we can return to it */
+
+
+/* void ctx_start((void *func)(int arg1, ..., argn), arg1, ..., argn,
+ * ucontext_t *ucp)
+ * A wrapper to start function `func'. ESI register will contain a pointer
+ * to ucp on the stack. By setting ESP to ESI, we effectively 'remove' all
+ * arguments to `func' from the stack. Finally, a call to resumecontext
+ * will start the next context in the linked list (or exit the program if
+ * there is no context). */
+ENTRY(ctx_start)
+ /* 0(esp) -> func
+ * 4(esp) -> arg1
+ * ...
+ * 4*n(esp) -> argn
+ * 4*(n+1)(esp) -> ucp */
+
+ pop %eax /* eax = func */
+ call *%eax /* func(arg1, ..., argn) */
+ mov %esi, %esp /* Clean up stack */
+ /* ucp is now at the top of the stack again */
+ call _C_LABEL(resumecontext) /* resumecontext(ucp) */
+ ret /* never reached */
+
+
--- /dev/null
+/*
+ * clock - determine the processor time used
+ */
+#include <sys/cdefs.h>
+#include "namespace.h"
+
+#include <time.h>
+#include <sys/times.h>
+
+clock_t clock(void)
+{
+ struct tms tms;
+
+ times(&tms);
+ return tms.tms_utime;
+}
--- /dev/null
+/* getdomainname() Author: Kees J. Bot
+ * 2 Dec 1994
+ */
+#define nil 0
+#include <sys/types.h>
+#include <unistd.h>
+#include <string.h>
+
+int getdomainname(char *domain, size_t size)
+{
+ char nodename[256];
+ char *dot;
+
+ if (gethostname(nodename, sizeof(nodename)) < 0)
+ return -1;
+ nodename[sizeof(nodename)-1]= 0;
+ if ((dot= strchr(nodename, '.')) == nil) dot= ".";
+
+ strncpy(domain, dot+1, size);
+ if (size > 0) domain[size-1]= 0;
+ return 0;
+}
--- /dev/null
+/* gethostname(2) system call emulation */
+#include <sys/cdefs.h>
+#include "namespace.h"
+
+#include <sys/types.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <net/gen/netdb.h>
+
+#ifdef __weak_alias
+__weak_alias(gethostname, _gethostname)
+#endif
+
+#define HOSTNAME_FILE "/etc/hostname.file"
+
+int gethostname(char *buf, size_t len)
+{
+ int fd;
+ int r;
+ char *nl;
+
+ if ((fd= open(HOSTNAME_FILE, O_RDONLY)) < 0) return -1;
+
+ r= read(fd, buf, len);
+ close(fd);
+ if (r == -1) return -1;
+
+ buf[len-1]= '\0';
+ if ((nl= strchr(buf, '\n')) != NULL) *nl= '\0';
+ return 0;
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+
+#include <sys/types.h>
+#include <paths.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <lib.h>
+
+#ifdef __weak_alias
+__weak_alias(getloadavg, _getloadavg)
+#endif
+
+/* Retrieve system load average information. */
+int getloadavg(double *loadavg, int nelem)
+{
+ FILE *fp;
+ int i;
+
+ if(nelem < 1) {
+ errno = ENOSPC;
+ return -1;
+ }
+
+ if((fp = fopen(_PATH_PROC "loadavg", "r")) == NULL)
+ return -1;
+
+ for(i = 0; i < nelem; i++)
+ if(fscanf(fp, "%lf", &loadavg[i]) != 1)
+ break;
+
+ fclose(fp);
+
+ if (i == 0) {
+ errno = ENOENT;
+ return -1;
+ }
+
+ return i;
+}
--- /dev/null
+/*
+getpagesize.c
+*/
+#include <sys/cdefs.h>
+#include "namespace.h"
+
+#include <machine/vmparam.h>
+#include <unistd.h>
+
+#ifdef __weak_alias
+__weak_alias(getpagesize, _getpagesize)
+#endif
+
+int getpagesize(void)
+{
+ return PAGE_SIZE;
+}
--- /dev/null
+/* getpass() - read a password Author: Kees J. Bot
+ * Feb 16 1993
+ */
+#include <sys/cdefs.h>
+#include "namespace.h"
+
+#define _MINIX
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <signal.h>
+#include <termios.h>
+#include <string.h>
+
+#ifdef __weak_alias
+__weak_alias(getpass, _getpass)
+#endif
+
+static int intr;
+
+static void catch(int sig)
+{
+ intr= 1;
+}
+
+char *getpass(const char *prompt)
+{
+ struct sigaction osa, sa;
+ struct termios cooked, raw;
+ static char password[32+1];
+ int fd, n= 0;
+
+ /* Try to open the controlling terminal. */
+ if ((fd= open("/dev/tty", O_RDONLY)) < 0) return NULL;
+
+ /* Trap interrupts unless ignored. */
+ intr= 0;
+ sigaction(SIGINT, NULL, &osa);
+ if (osa.sa_handler != SIG_IGN) {
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags= 0;
+ sa.sa_handler= catch;
+ sigaction(SIGINT, &sa, &osa);
+ }
+
+ /* Set the terminal to non-echo mode. */
+ tcgetattr(fd, &cooked);
+ raw= cooked;
+ raw.c_iflag|= ICRNL;
+ raw.c_lflag&= ~ECHO;
+ raw.c_lflag|= ECHONL;
+ raw.c_oflag|= OPOST | ONLCR;
+ tcsetattr(fd, TCSANOW, &raw);
+
+ /* Print the prompt. (After setting non-echo!) */
+ write(2, prompt, strlen(prompt));
+
+ /* Read the password, 32 characters max. */
+ while (read(fd, password+n, 1) > 0) {
+ if (password[n] == '\n') break;
+ if (n < 32) n++;
+ }
+ password[n]= 0;
+
+ /* Terminal back to cooked mode. */
+ tcsetattr(fd, TCSANOW, &cooked);
+
+ close(fd);
+
+ /* Interrupt? */
+ sigaction(SIGINT, &osa, NULL);
+ if (intr) raise(SIGINT);
+
+ return password;
+}
--- /dev/null
+/* $NetBSD: getprogname.c,v 1.3 2003/07/26 19:24:42 salo Exp $ */
+
+/*
+ * Copyright (c) 2001 Christopher G. Demetriou
+ * All rights reserved.
+ *
+ * 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 the
+ * NetBSD Project. See http://www.NetBSD.org/ for
+ * information about NetBSD.
+ * 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.
+ *
+ * <<Id: LICENSE,v 1.2 2000/06/14 15:57:33 cgd Exp>>
+ */
+
+#include <sys/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: getprogname.c,v 1.3 2003/07/26 19:24:42 salo Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+#include "namespace.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef __weak_alias
+__weak_alias(getprogname, _getprogname)
+__weak_alias(setprogname, _setprogname)
+#endif
+
+#if defined(__ELF__)
+extern const char *__progname;
+
+const char *
+getprogname(void)
+{
+
+ return (__progname);
+}
+
+void
+setprogname(const char *progname)
+{
+ const char *p;
+
+ p = strrchr(progname, '/');
+ if (p != NULL)
+ __progname = p + 1;
+ else
+ __progname = progname;
+}
+#else
+static const char *theprogname = NULL;
+extern const char **__prognamep; /* Copy of argv[]. */
+extern int __argc; /* Copy of argc. */
+
+const char *
+getprogname(void)
+{
+ const char *pn = NULL, *component;
+ if(theprogname)
+ return theprogname;
+ if(__argc > 0 && __prognamep)
+ pn = __prognamep[0];
+ else
+ return NULL;
+
+ if((component=strrchr(pn, '/')))
+ return component+1;
+ return pn;
+}
+
+void
+setprogname(const char *newprogname)
+{
+ theprogname = newprogname;
+}
+#endif
--- /dev/null
+/*
+ * popen - open a pipe
+ */
+/* $Header$ */
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <minix/ansi.h>
+
+#ifdef __weak_alias
+__weak_alias(popen, _popen)
+__weak_alias(pclose, _pclose)
+#endif
+
+#include <sys/types.h>
+#include <limits.h>
+#include <errno.h>
+#include <signal.h>
+#include <stdio.h>
+
+#if defined(__BSD4_2)
+union wait {
+ int w_status;
+};
+typedef union wait wait_arg;
+#else
+typedef int wait_arg;
+#endif /* __BSD4_2 */
+
+#ifdef _ANSI
+int _close(int d);
+int _dup2(int oldd, int newd); /* not present in System 5 */
+int _execl(const char *name, const char *_arg, ... );
+pid_t _fork(void);
+int _pipe(int fildes[2]);
+pid_t _wait(wait_arg *status);
+void _exit(int status);
+#endif
+
+static int pids[OPEN_MAX];
+
+FILE *
+popen(command, type)
+_CONST char *command;
+_CONST char *type;
+{
+ int piped[2];
+ int Xtype = *type == 'r' ? 0 : *type == 'w' ? 1 : 2;
+ int pid;
+
+ if (Xtype == 2 ||
+ _pipe(piped) < 0 ||
+ (pid = _fork()) < 0) return 0;
+
+ if (pid == 0) {
+ /* child */
+ register int *p;
+
+ for (p = pids; p < &pids[OPEN_MAX]; p++) {
+ if (*p) _close((int)(p - pids));
+ }
+ _close(piped[Xtype]);
+ _dup2(piped[!Xtype], !Xtype);
+ _close(piped[!Xtype]);
+ _execl("/bin/sh", "sh", "-c", command, (char *) 0);
+ _exit(127); /* like system() ??? */
+ }
+
+ pids[piped[Xtype]] = pid;
+ _close(piped[!Xtype]);
+ return fdopen(piped[Xtype], type);
+}
+
+#if defined(__BSD4_2)
+#define ret_val status.w_status
+#else
+#define ret_val status
+#endif
+
+int
+pclose(stream)
+FILE *stream;
+{
+ int fd = fileno(stream);
+ wait_arg status;
+ int wret;
+
+#ifdef _ANSI
+ void (*intsave)(int) = signal(SIGINT, SIG_IGN);
+ void (*quitsave)(int) = signal(SIGQUIT, SIG_IGN);
+#else
+ void (*intsave)() = signal(SIGINT, SIG_IGN);
+ void (*quitsave)() = signal(SIGQUIT, SIG_IGN);
+#endif
+ fclose(stream);
+ while ((wret = _wait(&status)) != -1) {
+ if (wret == pids[fd]) break;
+ }
+ if (wret == -1) ret_val = -1;
+ signal(SIGINT, intsave);
+ signal(SIGQUIT, quitsave);
+ pids[fd] = 0;
+ return ret_val;
+}
+
+#if defined(__USG)
+int _dup(int fildes);
+
+static int
+_dup2(oldd, newd)
+int oldd, newd;
+{
+ int i = 0, fd, tmp;
+ int fdbuf[_NFILES];
+
+ /* ignore the error on the close() */
+ tmp = errno; (void) _close(newd); errno = tmp;
+ while ((fd = _dup(oldd)) != newd) {
+ if (fd == -1) break;
+ fdbuf[i++] = fd;
+ }
+ tmp = errno;
+ while (--i >= 0) {
+ _close(fdbuf[i]);
+ }
+ errno = tmp;
+ return -(fd == -1);
+}
+#endif /* __USG */
--- /dev/null
+/*
+ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ * See the copyright notice in the ACK home directory, in the file "Copyright".
+ */
+/* $Header$ */
+
+#if defined(_POSIX_SOURCE)
+#include <sys/types.h>
+#endif
+#include <signal.h>
+
+int _kill(int pid, int sig);
+pid_t _getpid(void);
+
+int
+raise(int sig)
+{
+ if (sig < 0 || sig >= _NSIG)
+ return -1;
+ return _kill(_getpid(), sig);
+}
--- /dev/null
+/* sysconf.c POSIX 4.8.1
+ * long int sysconf(int name);
+ *
+ * POSIX allows some of the values in <limits.h> to be increased at
+ * run time. The sysconf() function allows such values to be checked
+ * at run time. MINIX does not use this facility - the run time
+ * limits are those given in <limits.h>.
+ */
+#include <sys/cdefs.h>
+#include "namespace.h"
+
+#include <lib.h>
+#include <unistd.h>
+#include <time.h>
+#include <stdio.h>
+#include <paths.h>
+
+#ifdef __weak_alias
+__weak_alias(sysconf, __sysconf)
+#endif
+
+PRIVATE u32_t get_hz(void)
+{
+ FILE *fp;
+ u32_t hz;
+ int r;
+
+ if ((fp = fopen(_PATH_PROC "hz", "r")) != NULL)
+ {
+ r = fscanf(fp, "%lu", &hz);
+
+ fclose(fp);
+
+ if (r == 1)
+ return hz;
+ }
+
+ return DEFAULT_HZ;
+}
+
+PUBLIC long int sysconf(name)
+int name; /* property being inspected */
+{
+ switch(name) {
+ case _SC_ARG_MAX:
+ return (long) ARG_MAX;
+
+ case _SC_CHILD_MAX:
+ return (long) CHILD_MAX;
+
+ case _SC_CLK_TCK:
+ return (long) get_hz();
+
+ case _SC_NGROUPS_MAX:
+ return (long) NGROUPS_MAX;
+
+ case _SC_OPEN_MAX:
+ return (long) OPEN_MAX;
+
+ case _SC_JOB_CONTROL:
+ return -1L; /* no job control */
+
+ case _SC_SAVED_IDS:
+ return -1L; /* no saved uid/gid */
+
+ case _SC_VERSION:
+ return (long) _POSIX_VERSION;
+
+ case _SC_STREAM_MAX:
+ return (long) STREAM_MAX;
+
+ case _SC_TZNAME_MAX:
+ return (long) TZNAME_MAX;
+
+ case _SC_PAGESIZE:
+ return getpagesize();
+
+ default:
+ errno = EINVAL;
+ return -1L;
+ }
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+
+#include <lib.h>
+#include <sys/times.h>
+
+#ifdef __weak_alias
+__weak_alias(times, _times)
+#endif
+
+PUBLIC clock_t times(buf)
+struct tms *buf;
+{
+ message m;
+
+ m.m4_l5 = 0; /* return this if system is pre-1.6 */
+ if (_syscall(PM_PROC_NR, TIMES, &m) < 0) return( (clock_t) -1);
+ buf->tms_utime = m.m4_l1;
+ buf->tms_stime = m.m4_l2;
+ buf->tms_cutime = m.m4_l3;
+ buf->tms_cstime = m.m4_l4;
+ return(m.m4_l5);
+}
--- /dev/null
+/* uname(3) - describe the machine. Author: Kees J. Bot
+ * 5 Dec 1992
+ */
+#include <sys/cdefs.h>
+#include "namespace.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/utsname.h>
+
+#ifdef __weak_alias
+__weak_alias(uname, _uname)
+#endif
+
+#define uts_get(field, string) \
+ if (sysuname(_UTS_GET, field, name->string, sizeof(name->string)) < 0) \
+ return -1; \
+ name->string[sizeof(name->string)-1]= 0;
+
+int uname(name)
+struct utsname *name;
+{
+ int hf, n, err;
+ char *nl;
+
+ /* Get each of the strings with a sysuname call. Null terminate them,
+ * because the buffers in the kernel may grow before this and the
+ * programs are recompiled.
+ */
+ uts_get(_UTS_SYSNAME, sysname);
+ uts_get(_UTS_NODENAME, nodename);
+ uts_get(_UTS_RELEASE, release);
+ uts_get(_UTS_VERSION, version);
+ uts_get(_UTS_MACHINE, machine);
+ uts_get(_UTS_ARCH, arch);
+#if 0
+ uts_get(_UTS_KERNEL, kernel);
+ uts_get(_UTS_HOSTNAME, hostname);
+ uts_get(_UTS_BUS, bus);
+#endif
+
+ /* Try to read the node name from /etc/hostname.file. This information
+ * should be stored in the kernel.
+ */
+ if ((hf = open("/etc/hostname.file", O_RDONLY)) < 0) {
+ if (errno != ENOENT) return(-1);
+ } else {
+ n = read(hf, name->nodename, sizeof(name->nodename) - 1);
+ err = errno;
+ close(hf);
+ errno = err;
+ if (n < 0) return(-1);
+ name->nodename[n] = 0;
+ if ((nl = strchr(name->nodename, '\n')) != NULL) {
+ memset(nl, 0, (name->nodename +
+ sizeof(name->nodename)) - nl);
+ }
+ }
+ return 0;
+}
+
+/*
+ * $PchId: _uname.c,v 1.4 1995/11/27 20:09:08 philip Exp $
+ */
--- /dev/null
+/* utime(2) for POSIX Authors: Terrence W. Holm & Edwin L. Froese */
+
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+#include <string.h>
+#include <utime.h>
+
+PUBLIC int utime(name, timp)
+_CONST char *name;
+_CONST struct utimbuf *timp;
+{
+ message m;
+
+ if (timp == NULL) {
+ m.m2_i1 = 0; /* name size 0 means NULL `timp' */
+ m.m2_i2 = strlen(name) + 1; /* actual size here */
+ } else {
+ m.m2_l1 = timp->actime;
+ m.m2_l2 = timp->modtime;
+ m.m2_i1 = strlen(name) + 1;
+ }
+ m.m2_p1 = (char *) name;
+ return(_syscall(VFS_PROC_NR, UTIME, &m));
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include <lib.h>
+#include "namespace.h"
+
+#include <sys/wait.h>
+
+#ifdef __weak_alias
+__weak_alias(wait, _wait)
+#endif
+
+pid_t wait(status)
+int * status;
+{
+ message m;
+
+ if (_syscall(PM_PROC_NR, WAIT, &m) < 0) return(-1);
+ if (status != 0) *status = m.m2_i1;
+ return(m.m_type);
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include <lib.h>
+#include "namespace.h"
+
+#include <sys/wait.h>
+
+#ifdef __weak_alias
+__weak_alias(waitpid, _waitpid)
+#endif
+
+pid_t waitpid(pid, status, options)
+pid_t pid;
+int *status;
+int options;
+{
+ message m;
+
+ m.m1_i1 = pid;
+ m.m1_i2 = options;
+ if (_syscall(PM_PROC_NR, WAITPID, &m) < 0) return(-1);
+ if (status != 0) *status = m.m2_i1;
+ return m.m_type;
+}
--- /dev/null
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <net/if.h>
+#include <ifaddrs.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+
+#include <net/gen/in.h>
+#include <net/gen/ip_io.h>
+#include <net/gen/tcp.h>
+#include <net/gen/udp.h>
+
+int
+getifaddrs(struct ifaddrs **ifap)
+{
+ static int fd = -1;
+ nwio_ipconf_t ipconf;
+ int flags;
+ static struct ifaddrs ifa;
+ static struct sockaddr_in addr, netmask;
+
+ memset(&ifa, 0, sizeof(ifa));
+ memset(&addr, 0, sizeof(addr));
+ memset(&netmask, 0, sizeof(netmask));
+ ifa.ifa_next = NULL;
+ ifa.ifa_name = "ip";
+ addr.sin_family = netmask.sin_family = AF_INET;
+ ifa.ifa_addr = (struct sockaddr *) &addr;
+ ifa.ifa_netmask = (struct sockaddr *) &netmask;
+ addr.sin_addr.s_addr = 0;
+ netmask.sin_addr.s_addr = 0;
+
+ if(fd < 0) {
+ char *ipd;
+ if(!(ipd=getenv("IP_DEVICE")))
+ ipd="/dev/ip";
+ if((fd = open(ipd, O_RDWR)) < 0)
+ return -1;
+ }
+
+ /* Code taken from commands/simple/ifconfig.c. */
+
+ if((flags = fcntl(fd, F_GETFL)) < 0 ||
+ fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0 ||
+ ioctl(fd, NWIOGIPCONF, &ipconf))
+ return 0; /* Report interface as down. */
+
+ addr.sin_addr.s_addr = ipconf.nwic_ipaddr;
+ netmask.sin_addr.s_addr = ipconf.nwic_netmask;
+ if(addr.sin_addr.s_addr) ifa.ifa_flags = IFF_UP;
+
+ /* Just report on this interface. */
+
+ *ifap = &ifa;
+
+ return 0;
+}
+
+void
+freeifaddrs(struct ifaddrs *ifp)
+{
+ /* getifaddrs points to static data, so no need to free. */
+ ;
+}
+
--- /dev/null
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/socket.h>
+
+/*
+ * get the effective user ID and effective group ID of a peer
+ * connected through a Unix domain socket.
+ */
+int getpeereid(int sd, uid_t *euid, gid_t *egid) {
+ int rc;
+ struct ucred cred;
+ socklen_t ucred_length;
+
+ /* Initialize Data Structures */
+ ucred_length = sizeof(struct ucred);
+ memset(&cred, '\0', ucred_length);
+
+ /* Validate Input Parameters */
+ if (euid == NULL || egid == NULL) {
+ errno = EFAULT;
+ return -1;
+ } /* getsockopt will handle validating 'sd' */
+
+ /* Get the credentials of the peer at the other end of 'sd' */
+ rc = getsockopt(sd, SOL_SOCKET, SO_PEERCRED, &cred, &ucred_length);
+ if (rc == 0) {
+ /* Success - return the results */
+ *euid = cred.uid;
+ *egid = cred.gid;
+ return 0;
+ } else {
+ /* Failure - getsockopt takes care of setting errno */
+ return -1;
+ }
+}
--- /dev/null
+_lwp_*
+acct
+adjtime
+lchmod
+lchown
+clone
+clock_getres
+clock_gettime
+clock_settime
+extattr_*
+fhopen
+fhstat
+fhstatvfs
+fsync_range
+getfh
+__setlogin
+getpgid
+setrlimit
+getrusage
+getsid
+getvfsstat
+issetugid /* WARNING: Always returns 0 in this impl. */
+kevent
+kqueue
+ktrace
+lfs_*
+madvise
+mincore
+minherit
+mlock
+mlockall
+munlock
+munlockall
+modctl
+mprotect
+mremap
+msgctl
+msgget
+msgrcv
+msgsnd
+msync
+nfs_svc
+pmc_*
+pollts
+posix_fadvise
+posix_madvise
+pselect /* Implementable as select wrapper */
+preadv
+pwritev
+quotactl
+rasctl
+sa_*
+_sched_*
+semconfig
+setpgid
+setpgrp
+setregid
+setreuid
+sigaltstack
+sigqueue
+sigqueueinfo
+sigstack
+sigtimedwait
+sigwait
+sigwaitinfo
+swapctl
+swapon
+sysarch
+timer_create
+timer_delete
+timer_settime
+undelete
+utimes
+lutimes
+futimes
+utrace
+uuidgen
+vadvise
+vfork
--- /dev/null
+.PATH: ${.CURDIR}/sys-minix
+
+SRCS+= accept.c access.c bind.c brk.c sbrk.c \
+ chdir.c chmod.c fchmod.c chown.c fchown.c chroot.c close.c \
+ connect.c dup.c dup2.c execve.c fcntl.c flock.c fpathconf.c fork.c \
+ fstatvfs.c fsync.c ftruncate.c getdents.c getegid.c getgid.c \
+ getgroups.c getitimer.c setitimer.c __getlogin.c getpeername.c \
+ getpgrp.c getpid.c getppid.c priority.c getrlimit.c getsockname.c \
+ getsockopt.c setsockopt.c gettimeofday.c geteuid.c getuid.c \
+ ioctl.c issetugid.c kill.c link.c listen.c loadname.c lseek.c \
+ minix_rs.c mkdir.c mkfifo.c mknod.c mmap.c mount.c nanosleep.c \
+ open.c pathconf.c pipe.c poll.c pread.c ptrace.c pwrite.c \
+ read.c readlink.c reboot.c recvfrom.c recvmsg.c rename.c\
+ rmdir.c select.c sem.c sendmsg.c sendto.c setgroups.c setsid.c \
+ setgid.c settimeofday.c setuid.c shmat.c shmctl.c shmget.c stime.c \
+ vectorio.c shutdown.c sigaction.c sigpending.c sigreturn.c sigsuspend.c\
+ sigprocmask.c socket.c socketpair.c stat.c statvfs.c symlink.c \
+ sync.c syscall.c sysuname.c truncate.c umask.c unlink.c write.c \
+ _exit.c _ucontext.c environ.c __getcwd.c
+
+# Minix specific syscalls.
+SRCS+= cprofile.c lseek64.c sprofile.c _mcontext.c
+
+.include "${ARCHDIR}/sys-minix/Makefile.inc"
--- /dev/null
+/* getcwd() - get the name of the current working directory.
+ * Author: Kees J. Bot
+ * 30 Apr 1989
+ */
+
+#define chdir _chdir
+#include <sys/cdefs.h>
+#include "namespace.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <limits.h>
+#include <string.h>
+
+static int addpath(const char *path, char **ap, const char *entry)
+/* Add the name of a directory entry at the front of the path being built.
+ * Note that the result always starts with a slash.
+ */
+{
+ const char *e= entry;
+ char *p= *ap;
+
+ while (*e != 0) e++;
+
+ while (e > entry && p > path) *--p = *--e;
+
+ if (p == path) return -1;
+ *--p = '/';
+ *ap= p;
+ return 0;
+}
+
+static int recover(char *p)
+/* Undo all those chdir("..")'s that have been recorded by addpath. This
+ * has to be done entry by entry, because the whole pathname may be too long.
+ */
+{
+ int e= errno, slash;
+ char *p0;
+
+ while (*p != 0) {
+ p0= ++p;
+
+ do p++; while (*p != 0 && *p != '/');
+ slash= *p; *p= 0;
+
+ if (chdir(p0) < 0) return -1;
+ *p= slash;
+ }
+ errno= e;
+ return 0;
+}
+
+int __getcwd(char *path, size_t size)
+{
+ struct stat above, current, tmp;
+ struct dirent *entry;
+ DIR *d;
+ char *p, *up, *dotdot;
+ int cycle;
+
+ if (path == NULL || size <= 1) { errno= EINVAL; return -1; }
+
+ p= path + size;
+ *--p = 0;
+
+ if (stat(".", ¤t) < 0) return -1;
+
+ while (1) {
+ dotdot= "..";
+ if (stat(dotdot, &above) < 0) { recover(p); return -1; }
+
+ if (above.st_dev == current.st_dev
+ && above.st_ino == current.st_ino)
+ break; /* Root dir found */
+
+ if ((d= opendir(dotdot)) == NULL) { recover(p); return -1; }
+
+ /* Cycle is 0 for a simple inode nr search, or 1 for a search
+ * for inode *and* device nr.
+ */
+ cycle= above.st_dev == current.st_dev ? 0 : 1;
+
+ do {
+ char name[3 + NAME_MAX + 1];
+
+ tmp.st_ino= 0;
+ if ((entry= readdir(d)) == NULL) {
+ switch (++cycle) {
+ case 1:
+ rewinddir(d);
+ continue;
+ case 2:
+ closedir(d);
+ errno= ENOENT;
+ recover(p);
+ return -1;
+ }
+ }
+ if (strcmp(entry->d_name, ".") == 0) continue;
+ if (strcmp(entry->d_name, "..") == 0) continue;
+
+ switch (cycle) {
+ case 0:
+ /* Simple test on inode nr. */
+ if (entry->d_ino != current.st_ino) continue;
+ /*FALL THROUGH*/
+
+ case 1:
+ /* Current is mounted. */
+ strcpy(name, "../");
+ strcpy(name+3, entry->d_name);
+ if (stat(name, &tmp) < 0) continue;
+ break;
+ }
+ } while (tmp.st_ino != current.st_ino
+ || tmp.st_dev != current.st_dev);
+
+ up= p;
+ if (addpath(path, &up, entry->d_name) < 0) {
+ closedir(d);
+ errno = ERANGE;
+ recover(p);
+ return -1;
+ }
+ closedir(d);
+
+ if (chdir(dotdot) < 0) { recover(p); return -1; }
+ p= up;
+
+ current= above;
+ }
+ if (recover(p) < 0) return -1; /* Undo all those chdir("..")'s. */
+ if (*p == 0) *--p = '/'; /* Cwd is "/" if nothing added */
+ if (p > path) strcpy(path, p); /* Move string to start of path. */
+ return 0;
+}
--- /dev/null
+/* getlogin(3)
+ *
+ * Author: Terrence W. Holm Aug. 1988
+ */
+
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+#include <pwd.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+#include "extern.h"
+
+
+
+int __getlogin(char *logname, size_t sz)
+{
+ struct passwd *pw_entry;
+
+ pw_entry = getpwuid(getuid());
+
+ if (pw_entry == (struct passwd *)NULL)
+ return 0;
+
+ strncpy(logname, pw_entry->pw_name, sz);
+ return sz;
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+#include <unistd.h>
+
+#ifdef __weak_alias
+__weak_alias(_exit, __exit)
+#endif
+
+__dead void _exit(status)
+int status;
+{
+ void (*suicide)(void);
+ message m;
+
+ m.m1_i1 = status;
+ _syscall(PM_PROC_NR, EXIT, &m);
+
+ /* If exiting nicely through PM fails for some reason, try to
+ * commit suicide. E.g., message to PM might fail due to deadlock.
+ */
+ suicide = (void (*)(void)) -1;
+ suicide();
+
+ /* If committing suicide fails for some reason, hang. */
+ for(;;) { }
+}
+
--- /dev/null
+/*
+ * mcontext.c
+*/
+#include <sys/cdefs.h>
+#include <lib.h>
+#include <namespace.h>
+
+#include <ucontext.h>
+#include <unistd.h>
+
+PUBLIC int setmcontext(const mcontext_t *mcp)
+{
+ message m;
+
+ m.m1_p1 = (char *) mcp;
+
+ return(_syscall(PM_PROC_NR, SETMCONTEXT, &m));
+}
+
+
+PUBLIC int getmcontext(mcontext_t *mcp)
+{
+ message m;
+
+ m.m1_p1 = (char *) mcp;
+
+ return(_syscall(PM_PROC_NR, GETMCONTEXT, &m));
+}
+
--- /dev/null
+#include <sys/cdefs.h>
+#include <namespace.h>
+#include <lib.h>
+#include <machine/stackframe.h>
+#include <ucontext.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <stdio.h>
+
+_PROTOTYPE( void ctx_start, (void (*)(void), int, ...) );
+
+/*===========================================================================*
+ * setuctx *
+ *===========================================================================*/
+PUBLIC int setuctx(const ucontext_t *ucp)
+{
+ int r;
+
+ if (ucp == NULL) {
+ errno = EFAULT;
+ return(-1);
+ }
+
+ if (!(ucp->uc_flags & UCF_IGNSIGM)) {
+ /* Set signal mask */
+ if ((r = sigprocmask(SIG_SETMASK, &ucp->uc_sigmask, NULL)) == -1)
+ return(r);
+ }
+
+ if (!(ucp->uc_flags & UCF_IGNFPU)) {
+ if ((r = setmcontext(&(ucp->uc_mcontext))) == -1)
+ return(r);
+ }
+
+ return(0);
+}
+
+
+/*===========================================================================*
+ * getuctx *
+ *===========================================================================*/
+PUBLIC int getuctx(ucontext_t *ucp)
+{
+ int r;
+
+ if (ucp == NULL) {
+ errno = EFAULT;
+ return(-1);
+ }
+
+ if (!(ucp->uc_flags & UCF_IGNSIGM)) {
+ /* Get signal mask */
+ if ((r = sigprocmask(0, NULL, &ucp->uc_sigmask)) == -1)
+ return(r);
+ }
+
+ if (!(ucp->uc_flags & UCF_IGNFPU)) {
+ if ((r = getmcontext(&(ucp->uc_mcontext))) != 0)
+ return(r);
+ }
+
+ return(0);
+}
+
+
+/*===========================================================================*
+ * makecontext *
+ *===========================================================================*/
+PUBLIC void makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...)
+{
+ va_list ap;
+ unsigned int *stack_top;
+
+ /* There are a number of situations that are erroneous, but we can't actually
+ tell the caller something is wrong, because this is a void function.
+ Instead, mcontext_t contains a magic field that has to be set
+ properly before it can be used. */
+ if (ucp == NULL) {
+ return;
+ } else if ((ucp->uc_stack.ss_sp == NULL) ||
+ (ucp->uc_stack.ss_size < MINSIGSTKSZ)) {
+ ucp->uc_mcontext.mc_magic = 0;
+ ucp->uc_mcontext.mc_p_reg.sp = 0;
+ return;
+ }
+
+ if (ucp->uc_mcontext.mc_magic == MCF_MAGIC) {
+#if (_MINIX_CHIP == _CHIP_INTEL)
+ /* The caller provides a pointer to a stack that we can use to run our
+ context on. When the context starts, control is given to a wrapped
+ start routine, which calls a function and cleans up the stack
+ afterwards. The wrapper needs the address of that function on the
+ stack.
+ The stack will be prepared as follows:
+ func() - start routine
+ arg1 - first argument
+ ...
+ argn - last argument
+ ucp - context, esp points here when `func' returns
+ _ctx_start pops the address of `func' from the stack and calls it.
+ The stack will then be setup with all arguments for `func'. When
+ `func' returns, _ctx_start cleans up the stack such that ucp is at
+ the top of the stack, ready to be used by resumecontext.
+ Resumecontext, in turn, checks whether another context is ready to
+ be executed (i.e., uc_link != NULL) or exit(2)s the process. */
+
+ /* Find the top of the stack from which we grow downwards. */
+ stack_top = (unsigned int *) ((uintptr_t ) ucp->uc_stack.ss_sp +
+ ucp->uc_stack.ss_size);
+
+ /* Align the arguments to 16 bytes (we might lose a few bytes of stack
+ space here).*/
+ stack_top = (unsigned int *) ((uintptr_t) stack_top & ~0xf);
+
+ /* Make room for 'func', the `func' routine arguments, and ucp. */
+ stack_top -= (1 + argc + 1);
+
+ /* Adjust the machine context to point to the top of this stack and the
+ program counter to the context start wrapper. */
+ ucp->uc_mcontext.mc_p_reg.fp = 0; /* Clear frame pointer */
+ ucp->uc_mcontext.mc_p_reg.sp = (reg_t) stack_top;
+ ucp->uc_mcontext.mc_p_reg.pc = (reg_t) ctx_start;
+
+ *stack_top++ = (uintptr_t) func;
+
+ /* Copy arguments to the stack. */
+ va_start(ap, argc);
+ while (argc-- > 0) {
+ *stack_top++ = va_arg(ap, uintptr_t);
+ }
+ va_end(ap);
+
+ /* Store ucp on the stack */
+ *stack_top = (uintptr_t) ucp;
+
+ /* Set ESI to point to the base of the stack where ucp is stored, so
+ that the wrapper function knows how to clean up the stack after
+ calling `func' (i.e., how to adjust ESP). */
+ ucp->uc_mcontext.mc_p_reg.si = (reg_t) stack_top;
+
+
+ /* If we ran out of stack space, invalidate stack pointer. Eventually,
+ swapcontext will choke on this and return ENOMEM. */
+ if (stack_top == ucp->uc_stack.ss_sp)
+ ucp->uc_mcontext.mc_p_reg.sp = 0;
+
+#else
+# error "Unsupported platform"
+#endif
+ }
+}
+
+
+/*===========================================================================*
+ * swapcontext *
+ *===========================================================================*/
+PUBLIC int swapcontext(ucontext_t *oucp, const ucontext_t *ucp)
+{
+ int r;
+
+ if ((oucp == NULL) || (ucp == NULL)) {
+ errno = EFAULT;
+ return(-1);
+ }
+
+ if (ucp->uc_mcontext.mc_p_reg.sp == 0) {
+ /* No stack space. Bail out. */
+ errno = ENOMEM;
+ return(-1);
+ }
+
+ oucp->uc_flags &= ~UCF_SWAPPED;
+ r = getcontext(oucp);
+ if ((r == 0) && !(oucp->uc_flags & UCF_SWAPPED)) {
+ oucp->uc_flags |= UCF_SWAPPED;
+ r = setcontext(ucp);
+ }
+
+ return(r);
+}
+
+
+/*===========================================================================*
+ * resumecontext *
+ *===========================================================================*/
+PUBLIC void resumecontext(ucontext_t *ucp)
+{
+ if (ucp->uc_link == NULL) exit(0);
+
+ /* Error handling? Where should the error go to? */
+ (void) setcontext((const ucontext_t *) ucp->uc_link);
+
+ exit(1); /* Never reached */
+}
+
--- /dev/null
+#include <sys/cdefs.h>
+#include <minix/ansi.h>
+#include "namespace.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#include <net/netlib.h>
+#include <net/gen/in.h>
+#include <net/gen/tcp.h>
+#include <net/gen/tcp_io.h>
+#include <net/gen/udp.h>
+#include <net/gen/udp_io.h>
+
+#define DEBUG 0
+
+static int _tcp_accept(int sock, struct sockaddr *_RESTRICT address,
+ socklen_t *_RESTRICT address_len);
+
+static int _uds_accept(int sock, struct sockaddr *_RESTRICT address,
+ socklen_t *_RESTRICT address_len);
+
+int accept(int sock, struct sockaddr *_RESTRICT address,
+ socklen_t *_RESTRICT address_len)
+{
+ int r;
+ nwio_udpopt_t udpopt;
+
+ r= _tcp_accept(sock, address, address_len);
+ if (r != -1 || (errno != ENOTTY && errno != EBADIOCTL))
+ return r;
+
+ r= _uds_accept(sock, address, address_len);
+ if (r != -1 || (errno != ENOTTY && errno != EBADIOCTL))
+ return r;
+
+ /* Unfortunately, we have to return EOPNOTSUPP for a socket that
+ * does not support accept (such as a UDP socket) and ENOTSOCK for
+ * filedescriptors that do not refer to a socket.
+ */
+ r= ioctl(sock, NWIOGUDPOPT, &udpopt);
+ if (r == 0)
+ {
+ /* UDP socket */
+ errno= EOPNOTSUPP;
+ return -1;
+ }
+ if ((errno == ENOTTY || errno == EBADIOCTL))
+ {
+ errno= ENOTSOCK;
+ return -1;
+ }
+
+ return r;
+}
+
+static int _tcp_accept(int sock, struct sockaddr *_RESTRICT address,
+ socklen_t *_RESTRICT address_len)
+{
+ int r, s1, t_errno;
+ tcp_cookie_t cookie;
+
+ s1= open(TCP_DEVICE, O_RDWR);
+ if (s1 == -1)
+ return s1;
+ r= ioctl(s1, NWIOGTCPCOOKIE, &cookie);
+ if (r == -1)
+ {
+ t_errno= errno;
+ close(s1);
+ errno= t_errno;
+ return -1;
+ }
+ r= ioctl(sock, NWIOTCPACCEPTTO, &cookie);
+ if (r == -1)
+ {
+ t_errno= errno;
+ close(s1);
+ errno= t_errno;
+ return -1;
+ }
+ if (address != NULL)
+ getpeername(s1, address, address_len);
+ return s1;
+}
+
+static int _uds_accept(int sock, struct sockaddr *_RESTRICT address,
+ socklen_t *_RESTRICT address_len)
+{
+ int s1;
+ int r;
+ struct sockaddr_un uds_addr;
+ socklen_t len;
+
+ memset(&uds_addr, '\0', sizeof(struct sockaddr_un));
+
+ r= ioctl(sock, NWIOGUDSADDR, &uds_addr);
+ if (r == -1) {
+ return r;
+ }
+
+ if (uds_addr.sun_family != AF_UNIX) {
+ errno= EINVAL;
+ return -1;
+ }
+
+ len= *address_len;
+ if (len > sizeof(struct sockaddr_un))
+ len = sizeof(struct sockaddr_un);
+
+ memcpy(address, &uds_addr, len);
+ *address_len= len;
+
+ s1= open(UDS_DEVICE, O_RDWR);
+ if (s1 == -1)
+ return s1;
+
+ r= ioctl(s1, NWIOSUDSACCEPT, address);
+ if (r == -1) {
+ int ioctl_errno = errno;
+ close(s1);
+ errno = ioctl_errno;
+ return r;
+ }
+
+ return s1;
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+#include <unistd.h>
+
+#ifdef __weak_alias
+__weak_alias(access, _access)
+#endif
+
+PUBLIC int access(name, mode)
+_CONST char *name;
+int mode;
+{
+ message m;
+
+ m.m3_i2 = mode;
+ _loadname(name, &m);
+ return(_syscall(VFS_PROC_NR, ACCESS, &m));
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+
+#include <unistd.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <netinet/in.h>
+
+#include <net/gen/in.h>
+#include <net/gen/tcp.h>
+#include <net/gen/tcp_io.h>
+#include <net/gen/udp.h>
+#include <net/gen/udp_io.h>
+#include <sys/un.h>
+
+#include <minix/config.h>
+#include <minix/const.h>
+
+#define DEBUG 0
+
+static int _tcp_bind(int sock, const struct sockaddr *address,
+ socklen_t address_len, nwio_tcpconf_t *tcpconfp);
+static int _udp_bind(int sock, const struct sockaddr *address,
+ socklen_t address_len, nwio_udpopt_t *udpoptp);
+static int _uds_bind(int sock, const struct sockaddr *address,
+ socklen_t address_len, struct sockaddr_un *uds_addr);
+
+int bind(int sock, const struct sockaddr *address, socklen_t address_len)
+{
+ int r;
+ nwio_tcpconf_t tcpconf;
+ nwio_udpopt_t udpopt;
+ struct sockaddr_un uds_addr;
+
+ r= ioctl(sock, NWIOGTCPCONF, &tcpconf);
+ if (r != -1 || (errno != ENOTTY && errno != EBADIOCTL))
+ {
+ if (r == -1)
+ return r;
+ r= _tcp_bind(sock, address, address_len, &tcpconf);
+#if DEBUG
+ if (r == -1)
+ {
+ int t_errno= errno;
+ fprintf(stderr, "bind(tcp) failed: %s\n",
+ strerror(errno));
+ errno= t_errno;
+ }
+#endif
+ return r;
+ }
+
+ r= ioctl(sock, NWIOGUDPOPT, &udpopt);
+ if (r != -1 || (errno != ENOTTY && errno != EBADIOCTL))
+ {
+ if (r == -1)
+ return r;
+ return _udp_bind(sock, address, address_len, &udpopt);
+ }
+
+ r= ioctl(sock, NWIOGUDSADDR, &uds_addr);
+ if (r != -1 || (errno != ENOTTY && errno != EBADIOCTL))
+ {
+ if (r == -1)
+ return r;
+ return _uds_bind(sock, address, address_len, &uds_addr);
+ }
+
+#if DEBUG
+ fprintf(stderr, "bind: not implemented for fd %d\n", sock);
+#endif
+ errno= ENOSYS;
+ return -1;
+}
+
+static int _tcp_bind(int sock, const struct sockaddr *address,
+ socklen_t address_len, nwio_tcpconf_t *tcpconfp)
+{
+ int r;
+ nwio_tcpconf_t tcpconf;
+ struct sockaddr_in *sinp;
+
+ sinp= (struct sockaddr_in *)address;
+ if (sinp->sin_family != AF_INET || address_len != sizeof(*sinp))
+ {
+#if DEBUG
+ fprintf(stderr, "bind(tcp): sin_family = %d, len = %d\n",
+ sinp->sin_family, address_len);
+#endif
+ errno= EAFNOSUPPORT;
+ return -1;
+ }
+
+ if (sinp->sin_addr.s_addr != INADDR_ANY &&
+ sinp->sin_addr.s_addr != tcpconfp->nwtc_locaddr)
+ {
+ errno= EADDRNOTAVAIL;
+ return -1;
+ }
+
+ tcpconf.nwtc_flags= 0;
+
+ if (sinp->sin_port == 0)
+ tcpconf.nwtc_flags |= NWTC_LP_SEL;
+ else
+ {
+ tcpconf.nwtc_flags |= NWTC_LP_SET;
+ tcpconf.nwtc_locport= sinp->sin_port;
+ }
+
+ r= ioctl(sock, NWIOSTCPCONF, &tcpconf);
+ return r;
+}
+
+static int _udp_bind(int sock, const struct sockaddr *address,
+ socklen_t address_len, nwio_udpopt_t *udpoptp)
+{
+ int r;
+ unsigned long curr_flags;
+ nwio_udpopt_t udpopt;
+ struct sockaddr_in *sinp;
+
+ sinp= (struct sockaddr_in *)address;
+ if (sinp->sin_family != AF_INET || address_len != sizeof(*sinp))
+ {
+#if DEBUG
+ fprintf(stderr, "bind(udp): sin_family = %d, len = %d\n",
+ sinp->sin_family, address_len);
+#endif
+ errno= EAFNOSUPPORT;
+ return -1;
+ }
+
+ if (sinp->sin_addr.s_addr != INADDR_ANY &&
+ sinp->sin_addr.s_addr != udpoptp->nwuo_locaddr)
+ {
+ errno= EADDRNOTAVAIL;
+ return -1;
+ }
+
+ udpopt.nwuo_flags= 0;
+
+ if (sinp->sin_port == 0)
+ udpopt.nwuo_flags |= NWUO_LP_SEL;
+ else
+ {
+ udpopt.nwuo_flags |= NWUO_LP_SET;
+ udpopt.nwuo_locport= sinp->sin_port;
+ }
+
+ curr_flags= udpoptp->nwuo_flags;
+ if (!(curr_flags & NWUO_ACC_MASK))
+ udpopt.nwuo_flags |= NWUO_EXCL;
+ if (!(curr_flags & (NWUO_EN_LOC|NWUO_DI_LOC)))
+ udpopt.nwuo_flags |= NWUO_EN_LOC;
+ if (!(curr_flags & (NWUO_EN_BROAD|NWUO_DI_BROAD)))
+ udpopt.nwuo_flags |= NWUO_EN_BROAD;
+ if (!(curr_flags & (NWUO_RP_SET|NWUO_RP_ANY)))
+ udpopt.nwuo_flags |= NWUO_RP_ANY;
+ if (!(curr_flags & (NWUO_RA_SET|NWUO_RA_ANY)))
+ udpopt.nwuo_flags |= NWUO_RA_ANY;
+ if (!(curr_flags & (NWUO_RWDATONLY|NWUO_RWDATALL)))
+ udpopt.nwuo_flags |= NWUO_RWDATALL;
+ if (!(curr_flags & (NWUO_EN_IPOPT|NWUO_DI_IPOPT)))
+ udpopt.nwuo_flags |= NWUO_DI_IPOPT;
+
+ r= ioctl(sock, NWIOSUDPOPT, &udpopt);
+ return r;
+}
+
+static int in_group(uid_t uid, gid_t gid)
+{
+ int r, i;
+ int size;
+ gid_t *list;
+
+ size = sysconf(_SC_NGROUPS_MAX);
+ list = malloc(size * sizeof(gid_t));
+
+ if (list == NULL) {
+ return 0;
+ }
+
+ r= getgroups(size, list);
+ if (r == -1) {
+ free(list);
+ return 0;
+ }
+
+ for (i = 0; i < r; i++) {
+ if (gid == list[i]) {
+ free(list);
+ return 1;
+ }
+ }
+
+ free(list);
+ return 0;
+}
+
+
+static int _uds_bind(int sock, const struct sockaddr *address,
+ socklen_t address_len, struct sockaddr_un *uds_addr)
+{
+ int r;
+ int did_mknod;
+
+ if (address == NULL) {
+ errno = EFAULT;
+ return -1;
+ }
+
+ did_mknod = 0;
+
+ r = mknod(((struct sockaddr_un *) address)->sun_path,
+ S_IFSOCK|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH, 0);
+
+ if (r == -1 && errno != EEXIST) {
+ return -1;
+ } else if (r == 0) {
+ did_mknod = 1;
+ }
+
+ /* perform the bind */
+ r= ioctl(sock, NWIOSUDSADDR, (void *) address);
+
+ if (r == -1 && did_mknod) {
+
+ /* bind() failed in pfs, so we roll back the
+ * file system change
+ */
+ unlink(((struct sockaddr_un *) address)->sun_path);
+ }
+
+ return r;
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+#include <unistd.h>
+
+#ifdef __weak_alias
+__weak_alias(brk, _brk)
+#endif
+
+extern char *_brksize;
+
+/* Both OSF/1 and SYSVR4 man pages specify that brk(2) returns int.
+ * However, BSD4.3 specifies that brk() returns char*. POSIX omits
+ * brk() on the grounds that it imposes a memory model on an architecture.
+ * For this reason, brk() and sbrk() are not in the lib/posix directory.
+ * On the other hand, they are so crucial to correct operation of so many
+ * parts of the system, that we have chosen to hide the name brk using _brk,
+ * as with system calls. In this way, if a user inadvertently defines a
+ * procedure brk, MINIX may continue to work because the true call is _brk.
+ */
+PUBLIC int brk(addr)
+void *addr;
+{
+ message m;
+
+ if (addr != _brksize) {
+ m.PMBRK_ADDR = addr;
+ if (_syscall(PM_PROC_NR, BRK, &m) < 0) return(-1);
+ _brksize = m.m2_p1;
+ }
+ return(0);
+}
+
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+#include <unistd.h>
+
+#ifdef __weak_alias
+__weak_alias(chdir, _chdir)
+__weak_alias(fchdir, _fchdir)
+#endif
+
+PUBLIC int chdir(name)
+_CONST char *name;
+{
+ message m;
+
+ _loadname(name, &m);
+ return(_syscall(VFS_PROC_NR, CHDIR, &m));
+}
+
+PUBLIC int fchdir(fd)
+int fd;
+{
+ message m;
+
+ m.m1_i1 = fd;
+ return(_syscall(VFS_PROC_NR, FCHDIR, &m));
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+#include <sys/stat.h>
+
+#ifdef __weak_alias
+__weak_alias(chmod, _chmod)
+#endif
+
+PUBLIC int chmod(const char *name, mode_t mode)
+{
+ message m;
+
+ m.m3_i2 = mode;
+ _loadname(name, &m);
+ return(_syscall(VFS_PROC_NR, CHMOD, &m));
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+#include <string.h>
+#include <unistd.h>
+
+PUBLIC int chown(const char *name, uid_t owner, gid_t grp)
+{
+ message m;
+
+ m.m1_i1 = strlen(name) + 1;
+ m.m1_i2 = owner;
+ m.m1_i3 = grp;
+ m.m1_p1 = (char *) name;
+ return(_syscall(VFS_PROC_NR, CHOWN, &m));
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+#include <unistd.h>
+
+#ifdef __weak_alias
+__weak_alias(chroot, _chroot)
+#endif
+
+PUBLIC int chroot(name)
+_CONST char *name;
+{
+ message m;
+
+ _loadname(name, &m);
+ return(_syscall(VFS_PROC_NR, CHROOT, &m));
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+#include <unistd.h>
+
+#ifdef __weak_alias
+__weak_alias(close, _close)
+#endif
+
+PUBLIC int close(fd)
+int fd;
+{
+ message m;
+
+ m.m1_i1 = fd;
+ return(_syscall(VFS_PROC_NR, CLOSE, &m));
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <minix/config.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <netinet/in.h>
+
+#include <net/gen/in.h>
+#include <net/gen/tcp.h>
+#include <net/gen/tcp_io.h>
+#include <net/gen/udp.h>
+#include <net/gen/udp_io.h>
+
+#include <minix/const.h>
+
+#define DEBUG 0
+
+static int _tcp_connect(int sock, const struct sockaddr *address,
+ socklen_t address_len, nwio_tcpconf_t *tcpconfp);
+static int _udp_connect(int sock, const struct sockaddr *address,
+ socklen_t address_len, nwio_udpopt_t *udpoptp);
+static int _uds_connect(int sock, const struct sockaddr *address,
+ socklen_t address_len);
+
+int connect(int sock, const struct sockaddr *address,
+ socklen_t address_len)
+{
+ int r;
+ nwio_tcpconf_t tcpconf;
+ nwio_udpopt_t udpopt;
+
+ r= ioctl(sock, NWIOGTCPCONF, &tcpconf);
+ if (r != -1 || (errno != ENOTTY && errno != EBADIOCTL))
+ {
+ if (r == -1)
+ {
+ /* Bad file descriptor */
+ return -1;
+ }
+ return _tcp_connect(sock, address, address_len, &tcpconf);
+ }
+
+ r= ioctl(sock, NWIOGUDPOPT, &udpopt);
+ if (r != -1 || (errno != ENOTTY && errno != EBADIOCTL))
+ {
+ if (r == -1)
+ {
+ /* Bad file descriptor */
+ return -1;
+ }
+ return _udp_connect(sock, address, address_len, &udpopt);
+ }
+
+ r= _uds_connect(sock, address, address_len);
+ if (r != -1 ||
+ (errno != ENOTTY && errno != EBADIOCTL &&
+ errno != EAFNOSUPPORT))
+ {
+ if (r == -1)
+ {
+ /* Bad file descriptor */
+ return -1;
+ }
+
+ return r;
+ }
+
+#if DEBUG
+ fprintf(stderr, "connect: not implemented for fd %d\n", sock);
+#endif
+ errno= ENOSYS;
+ return -1;
+}
+
+static int _tcp_connect(int sock, const struct sockaddr *address,
+ socklen_t address_len, nwio_tcpconf_t *tcpconfp)
+{
+ int r;
+ struct sockaddr_in *sinp;
+ nwio_tcpconf_t tcpconf;
+ nwio_tcpcl_t tcpcl;
+
+ if (address_len != sizeof(*sinp))
+ {
+ errno= EINVAL;
+ return -1;
+ }
+ sinp= (struct sockaddr_in *)address;
+ if (sinp->sin_family != AF_INET)
+ {
+ errno= EINVAL;
+ return -1;
+ }
+ tcpconf.nwtc_flags= NWTC_SET_RA | NWTC_SET_RP;
+ if ((tcpconfp->nwtc_flags & NWTC_LOCPORT_MASK) == NWTC_LP_UNSET)
+ tcpconf.nwtc_flags |= NWTC_LP_SEL;
+ tcpconf.nwtc_remaddr= sinp->sin_addr.s_addr;
+ tcpconf.nwtc_remport= sinp->sin_port;
+
+ if (ioctl(sock, NWIOSTCPCONF, &tcpconf) == -1)
+ {
+ /* Ignore EISCONN error. The NWIOTCPCONN ioctl will get the
+ * right error.
+ */
+ if (errno != EISCONN)
+ return -1;
+ }
+
+ tcpcl.nwtcl_flags= TCF_DEFAULT;
+
+ r= fcntl(sock, F_GETFL);
+ if (r == 1)
+ return -1;
+ if (r & O_NONBLOCK)
+ tcpcl.nwtcl_flags |= TCF_ASYNCH;
+
+ r= ioctl(sock, NWIOTCPCONN, &tcpcl);
+ return r;
+}
+
+static int _udp_connect(int sock, const struct sockaddr *address,
+ socklen_t address_len, nwio_udpopt_t *udpoptp)
+{
+ int r;
+ struct sockaddr_in *sinp;
+ nwio_udpopt_t udpopt;
+
+ if (address == NULL)
+ {
+ /* Unset remote address */
+ udpopt.nwuo_flags= NWUO_RP_ANY | NWUO_RA_ANY | NWUO_RWDATALL;
+
+ r= ioctl(sock, NWIOSUDPOPT, &udpopt);
+ return r;
+ }
+
+ if (address_len != sizeof(*sinp))
+ {
+ errno= EINVAL;
+ return -1;
+ }
+ sinp= (struct sockaddr_in *)address;
+ if (sinp->sin_family != AF_INET)
+ {
+ errno= EINVAL;
+ return -1;
+ }
+ udpopt.nwuo_flags= NWUO_RP_SET | NWUO_RA_SET | NWUO_RWDATONLY;
+ if ((udpoptp->nwuo_flags & NWUO_LOCPORT_MASK) == NWUO_LP_ANY)
+ udpopt.nwuo_flags |= NWUO_LP_SEL;
+ udpopt.nwuo_remaddr= sinp->sin_addr.s_addr;
+ udpopt.nwuo_remport= sinp->sin_port;
+
+ r= ioctl(sock, NWIOSUDPOPT, &udpopt);
+ return r;
+}
+
+static int _uds_connect(int sock, const struct sockaddr *address,
+ socklen_t address_len)
+{
+
+ if (address == NULL) {
+ errno = EFAULT;
+ return -1;
+ }
+
+ /* perform the connect */
+ return ioctl(sock, NWIOSUDSCONN, (void *) address);
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+
+#ifdef __weak_alias
+#define cprofile _cprofile
+__weak_alias(cprofile, _cprofile)
+#endif
+
+#include <lib.h>
+#include <minix/profile.h>
+
+int cprofile(int action, int size, void *ctl_ptr, void *mem_ptr)
+{
+ message m;
+
+ m.PROF_ACTION = action;
+ m.PROF_MEM_SIZE = size;
+ m.PROF_CTL_PTR = (void *) ctl_ptr;
+ m.PROF_MEM_PTR = (void *) mem_ptr;
+
+ return _syscall(PM_PROC_NR, CPROF, &m);
+}
+
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+#include <fcntl.h>
+#include <unistd.h>
+
+#ifdef __weak_alias
+__weak_alias(dup, _dup)
+#endif
+
+PUBLIC int dup(fd)
+int fd;
+{
+ return(fcntl(fd, F_DUPFD, 0));
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+#include <fcntl.h>
+#include <unistd.h>
+
+#ifdef __weak_alias
+__weak_alias(dup2, _dup2)
+#endif
+
+PUBLIC int dup2(fd, fd2)
+int fd, fd2;
+{
+/* The behavior of dup2 is defined by POSIX in 6.2.1.2 as almost, but not
+ * quite the same as fcntl.
+ */
+
+ if (fd2 < 0 || fd2 > OPEN_MAX) {
+ errno = EBADF;
+ return(-1);
+ }
+
+ /* Check to see if fildes is valid. */
+ if (fcntl(fd, F_GETFL) < 0) {
+ /* 'fd' is not valid. */
+ return(-1);
+ } else {
+ /* 'fd' is valid. */
+ if (fd == fd2) return(fd2);
+ close(fd2);
+ return(fcntl(fd, F_DUPFD, fd2));
+ }
+}
--- /dev/null
+/*
+ * environ.c - define the variable environ
+ */
+/* $Header$ */
+/*
+ * This file defines the variable environ and initializes it with a magic
+ * value. The C run-time start-off routine tests whether the variable
+ * environ is initialized with this value. If it is not, it is assumed
+ * that it is defined by the user. Only two bytes are tested, since we
+ * don't know the endian-ness and alignment restrictions of the machine.
+ * This means that the low-order two-bytes should be equal to the
+ * high-order two-bytes on machines with four-byte pointers. In fact, all
+ * the bytes in the pointer are the same, just in case.
+ */
+
+#if _EM_PSIZE==2
+char **environ = (char **) 0x5353;
+#else
+char **environ = (char **) 0x53535353;
+#endif
--- /dev/null
+/* execve() - basic program execution call Author: Kees J. Bot
+ * 21 Jan 1994
+ */
+#define _MINIX_SOURCE
+
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+#include <unistd.h>
+#include <string.h>
+#include <stddef.h>
+
+#ifdef __weak_alias
+__weak_alias(execve, _execve)
+#endif
+
+int execve(const char *path, char * const *argv, char * const *envp)
+{
+ char * const *ap;
+ char * const *ep;
+ char *frame;
+ char **vp;
+ char *sp;
+ size_t argc;
+ size_t frame_size;
+ size_t string_off;
+ size_t n;
+ int ov;
+ message m;
+
+ /* Assumptions: size_t and char *, it's all the same thing. */
+
+ /* Create a stack image that only needs to be patched up slightly
+ * by the kernel to be used for the process to be executed.
+ */
+
+ ov= 0; /* No overflow yet. */
+ frame_size= 0; /* Size of the new initial stack. */
+ string_off= 0; /* Offset to start of the strings. */
+ argc= 0; /* Argument count. */
+
+ for (ap= argv; *ap != NULL; ap++) {
+ n = sizeof(*ap) + strlen(*ap) + 1;
+ frame_size+= n;
+ if (frame_size < n) ov= 1;
+ string_off+= sizeof(*ap);
+ argc++;
+ }
+
+ for (ep= envp; *ep != NULL; ep++) {
+ n = sizeof(*ep) + strlen(*ep) + 1;
+ frame_size+= n;
+ if (frame_size < n) ov= 1;
+ string_off+= sizeof(*ap);
+ }
+
+ /* Add an argument count and two terminating nulls. */
+ frame_size+= sizeof(argc) + sizeof(*ap) + sizeof(*ep);
+ string_off+= sizeof(argc) + sizeof(*ap) + sizeof(*ep);
+
+ /* Align. */
+ frame_size= (frame_size + sizeof(char *) - 1) & ~(sizeof(char *) - 1);
+
+ /* The party is off if there is an overflow. */
+ if (ov || frame_size < 3 * sizeof(char *)) {
+ errno= E2BIG;
+ return -1;
+ }
+
+ /* Allocate space for the stack frame. */
+ if ((frame = (char *) sbrk(frame_size)) == (char *) -1) {
+ errno = E2BIG;
+ return -1;
+ }
+
+ /* Set arg count, init pointers to vector and string tables. */
+ * (size_t *) frame = argc;
+ vp = (char **) (frame + sizeof(argc));
+ sp = frame + string_off;
+
+ /* Load the argument vector and strings. */
+ for (ap= argv; *ap != NULL; ap++) {
+ *vp++= (char *) (sp - frame);
+ n= strlen(*ap) + 1;
+ memcpy(sp, *ap, n);
+ sp+= n;
+ }
+ *vp++= NULL;
+
+ /* Load the environment vector and strings. */
+ for (ep= envp; *ep != NULL; ep++) {
+ *vp++= (char *) (sp - frame);
+ n= strlen(*ep) + 1;
+ memcpy(sp, *ep, n);
+ sp+= n;
+ }
+ *vp++= NULL;
+
+ /* Padding. */
+ while (sp < frame + frame_size) *sp++= 0;
+
+ /* We can finally make the system call. */
+ m.m1_i1 = strlen(path) + 1;
+ m.m1_i2 = frame_size;
+ m.m1_p1 = (char *) path;
+ m.m1_p2 = frame;
+
+ /* Clear unused fields */
+ m.m1_i3 = 0;
+ m.m1_p3 = NULL;
+
+ (void) _syscall(PM_PROC_NR, EXEC, &m);
+
+ /* Failure, return the memory used for the frame and exit. */
+ (void) sbrk(-frame_size);
+ return -1;
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+#include <sys/stat.h>
+
+#ifdef __weak_alias
+__weak_alias(fchmod, _fchmod)
+#endif
+
+PUBLIC int fchmod(int fd, mode_t mode)
+{
+ message m;
+
+ m.m1_i1 = fd;
+ m.m1_i2 = mode;
+ return(_syscall(VFS_PROC_NR, FCHMOD, &m));
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+#include <string.h>
+#include <unistd.h>
+
+#ifdef __weak_alias
+__weak_alias(fchown, _fchown)
+#endif
+
+PUBLIC int fchown(int fd, uid_t owner, gid_t grp)
+{
+ message m;
+
+ m.m1_i1 = fd;
+ m.m1_i2 = owner;
+ m.m1_i3 = grp;
+ return(_syscall(VFS_PROC_NR, FCHOWN, &m));
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+#include <fcntl.h>
+#include <stdarg.h>
+
+#ifdef __weak_alias
+__weak_alias(fcntl, _fcntl)
+#endif
+
+#if _ANSI
+PUBLIC int fcntl(int fd, int cmd, ...)
+#else
+PUBLIC int fcntl(fd, cmd)
+int fd;
+int cmd;
+#endif
+{
+ va_list argp;
+ message m;
+
+ va_start(argp, cmd);
+
+ /* Set up for the sensible case where there is no variable parameter. This
+ * covers F_GETFD, F_GETFL and invalid commands.
+ */
+ m.m1_i3 = 0;
+ m.m1_p1 = NULL;
+
+ /* Adjust for the stupid cases. */
+ switch(cmd) {
+ case F_DUPFD:
+ case F_SETFD:
+ case F_SETFL:
+ m.m1_i3 = va_arg(argp, int);
+ break;
+ case F_GETLK:
+ case F_SETLK:
+ case F_SETLKW:
+ case F_FREESP:
+ m.m1_p1 = (char *) va_arg(argp, struct flock *);
+ break;
+ }
+
+ /* Clean up and make the system call. */
+ va_end(argp);
+ m.m1_i1 = fd;
+ m.m1_i2 = cmd;
+ return(_syscall(VFS_PROC_NR, FCNTL, &m));
+}
--- /dev/null
+/* Library routines
+ *
+ * Porting to Minix 2.0.0
+ * Author: Giovanni Falzoni <gfalzoni@pointest.com>
+ */
+
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+#include <sys/types.h>
+#include <fcntl.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+
+#ifdef __weak_alias
+__weak_alias(flock, _flock)
+#endif
+
+/*
+ * Name: int flock(int fd, int mode);
+ * Function: Implements the flock function in Minix.
+ */
+int flock(int fd, int mode)
+{
+ struct flock lck;
+ register int retcode;
+
+ memset((void *) &lck, 0, sizeof(struct flock));
+ lck.l_type = mode & ~LOCK_NB;
+ lck.l_pid = getpid();
+ if ((retcode = fcntl(fd, mode & LOCK_NB ? F_SETLK : F_SETLKW, &lck)) < 0 && errno == EAGAIN)
+ errno = EWOULDBLOCK;
+ return retcode;
+}
+
+/** flock.c **/
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+#include <unistd.h>
+
+#ifdef __weak_alias
+__weak_alias(fork, _fork)
+#endif
+
+PUBLIC pid_t fork()
+{
+ message m;
+
+ return(_syscall(PM_PROC_NR, FORK, &m));
+}
--- /dev/null
+/* POSIX fpathconf (Sec. 5.7.1) Author: Andy Tanenbaum */
+
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+#include <sys/stat.h>
+#include <errno.h>
+#include <limits.h>
+#include <unistd.h>
+#include <termios.h>
+
+#ifdef __weak_alias
+__weak_alias(fpathconf, _fpathconf)
+#endif
+
+PUBLIC long fpathconf(fd, name)
+int fd; /* file descriptor being interrogated */
+int name; /* property being inspected */
+{
+/* POSIX allows some of the values in <limits.h> to be increased at
+ * run time. The pathconf and fpathconf functions allow these values
+ * to be checked at run time. MINIX does not use this facility.
+ * The run-time limits are those given in <limits.h>.
+ */
+
+ struct stat stbuf;
+
+ switch(name) {
+ case _PC_LINK_MAX:
+ /* Fstat the file. If that fails, return -1. */
+ if (fstat(fd, &stbuf) != 0) return(-1);
+ if (S_ISDIR(stbuf.st_mode))
+ return(1L); /* no links to directories */
+ else
+ return( (long) LINK_MAX);
+
+ case _PC_MAX_CANON:
+ return( (long) MAX_CANON);
+
+ case _PC_MAX_INPUT:
+ return( (long) MAX_INPUT);
+
+ case _PC_NAME_MAX:
+ return( (long) NAME_MAX);
+
+ case _PC_PATH_MAX:
+ return( (long) PATH_MAX);
+
+ case _PC_PIPE_BUF:
+ return( (long) PIPE_BUF);
+
+ case _PC_CHOWN_RESTRICTED:
+ return( (long) _POSIX_CHOWN_RESTRICTED);
+
+ case _PC_NO_TRUNC:
+ return( (long) _POSIX_NO_TRUNC);
+
+ case _PC_VDISABLE:
+ return( (long) _POSIX_VDISABLE);
+
+ default:
+ errno = EINVAL;
+ return(-1);
+ }
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+#include <sys/statvfs.h>
+
+#ifdef __weak_alias
+__weak_alias(fstatvfs, _fstatvfs)
+#endif
+
+int fstatvfs(int fd, struct statvfs *buffer)
+{
+ message m;
+
+ m.FSTATVFS_FD = fd;
+ m.FSTATVFS_BUF = (char *) buffer;
+ return(_syscall(VFS_PROC_NR, FSTATVFS, &m));
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+#include <unistd.h>
+
+#ifdef __weak_alias
+__weak_alias(fsync, _fsync)
+#endif
+
+PUBLIC int fsync(int fd)
+{
+ message m;
+
+ m.m1_i1 = fd;
+
+ return(_syscall(VFS_PROC_NR, FSYNC, &m));
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+#include <string.h>
+#include <unistd.h>
+
+#ifdef __weak_alias
+__weak_alias(ftruncate, _ftruncate)
+#endif
+
+int ftruncate(int _fd, off_t _length)
+{
+ message m;
+ m.m2_l1 = _length;
+ m.m2_i1 = _fd;
+
+ return(_syscall(VFS_PROC_NR, FTRUNCATE, &m));
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+#include <dirent.h>
+
+PUBLIC ssize_t getdents(fd, buffer, nbytes)
+int fd;
+char *buffer;
+size_t nbytes;
+{
+ message m;
+
+ m.m1_i1 = fd;
+ m.m1_i2 = nbytes;
+ m.m1_p1 = (char *) buffer;
+ return _syscall(VFS_PROC_NR, GETDENTS, &m);
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+#include <unistd.h>
+
+#ifdef __weak_alias
+__weak_alias(getegid, _getegid)
+#endif
+
+PUBLIC gid_t getegid()
+{
+ message m;
+
+ /* POSIX says that this function is always successful and that no
+ * return value is reserved to indicate an error. Minix syscalls
+ * are not always successful and Minix returns the unreserved value
+ * (gid_t) -1 when there is an error.
+ */
+ if (_syscall(PM_PROC_NR, GETGID, &m) < 0) return ( (gid_t) -1);
+ return( (gid_t) m.m2_i1);
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+#include <unistd.h>
+
+#ifdef __weak_alias
+__weak_alias(geteuid, _geteuid)
+#endif
+
+PUBLIC uid_t geteuid()
+{
+ message m;
+
+ /* POSIX says that this function is always successful and that no
+ * return value is reserved to indicate an error. Minix syscalls
+ * are not always successful and Minix returns the unreserved value
+ * (uid_t) -1 when there is an error.
+ */
+ if (_syscall(PM_PROC_NR, GETUID, &m) < 0) return ( (uid_t) -1);
+ return( (uid_t) m.m2_i1);
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+#include <unistd.h>
+
+#ifdef __weak_alias
+__weak_alias(getgid, _getgid)
+#endif
+
+PUBLIC gid_t getgid()
+{
+ message m;
+
+ return( (gid_t) _syscall(PM_PROC_NR, GETGID, &m));
+}
--- /dev/null
+/*
+getgroups.c
+*/
+
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+#include <unistd.h>
+
+#ifdef __weak_alias
+__weak_alias(getgroups, _getgroups)
+#endif
+
+
+PUBLIC int getgroups(int ngroups, gid_t *arr)
+{
+ message m;
+ m.m1_i1 = ngroups;
+ m.m1_p1 = arr;
+
+ return(_syscall(PM_PROC_NR, GETGROUPS, &m));
+}
+
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+#include <sys/time.h>
+
+/*
+ * This is the implementation for the function to
+ * invoke the interval timer retrieval system call.
+ */
+int getitimer(int which, struct itimerval *value)
+{
+ message m;
+
+ m.m1_i1 = which;
+ m.m1_p1 = NULL; /* only retrieve the timer */
+ m.m1_p2 = (char *) value;
+
+ return _syscall(PM_PROC_NR, ITIMER, &m);
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <minix/ansi.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+#include <net/gen/in.h>
+#include <net/gen/tcp.h>
+#include <net/gen/tcp_io.h>
+#include <net/gen/udp.h>
+#include <sys/un.h>
+
+#define DEBUG 0
+
+static int _tcp_getpeername(int sock, struct sockaddr *_RESTRICT address,
+ socklen_t *_RESTRICT address_len, nwio_tcpconf_t *tcpconfp);
+
+static int _uds_getpeername(int sock, struct sockaddr *_RESTRICT address,
+ socklen_t *_RESTRICT address_len, struct sockaddr_un *uds_addr);
+
+int getpeername(int sock, struct sockaddr *_RESTRICT address,
+ socklen_t *_RESTRICT address_len)
+{
+ int r;
+ nwio_tcpconf_t tcpconf;
+ struct sockaddr_un uds_addr;
+
+ r= ioctl(sock, NWIOGTCPCONF, &tcpconf);
+ if (r != -1 || (errno != ENOTTY && errno != EBADIOCTL))
+ {
+ if (r == -1)
+ {
+ /* Bad file descriptor */
+ return -1;
+ }
+ return _tcp_getpeername(sock, address, address_len,
+ &tcpconf);
+ }
+
+ r= ioctl(sock, NWIOGUDSPADDR, &uds_addr);
+ if (r != -1 || (errno != ENOTTY && errno != EBADIOCTL))
+ {
+ if (r == -1)
+ {
+ /* Bad file descriptor */
+ return -1;
+ }
+ return _uds_getpeername(sock, address, address_len,
+ &uds_addr);
+ }
+
+
+#if DEBUG
+ fprintf(stderr, "getpeername: not implemented for fd %d\n", sock);
+#endif
+ errno= ENOSYS;
+ return -1;
+}
+
+static int _tcp_getpeername(int sock, struct sockaddr *_RESTRICT address,
+ socklen_t *_RESTRICT address_len, nwio_tcpconf_t *tcpconfp)
+{
+ socklen_t len;
+ struct sockaddr_in sin;
+
+ if (tcpconfp->nwtc_remaddr == 0 ||
+ tcpconfp->nwtc_remport == 0)
+ {
+ errno= ENOTCONN;
+ return -1;
+ }
+
+ memset(&sin, '\0', sizeof(sin));
+ sin.sin_family= AF_INET;
+ sin.sin_addr.s_addr= tcpconfp->nwtc_remaddr;
+ sin.sin_port= tcpconfp->nwtc_remport;
+
+ len= *address_len;
+ if (len > sizeof(sin))
+ len= sizeof(sin);
+ memcpy(address, &sin, len);
+ *address_len= len;
+
+ return 0;
+}
+
+static int _uds_getpeername(int sock, struct sockaddr *_RESTRICT address,
+ socklen_t *_RESTRICT address_len, struct sockaddr_un *uds_addr)
+{
+ socklen_t len;
+
+ if (uds_addr->sun_family != AF_UNIX)
+ {
+ errno= ENOTCONN;
+ return -1;
+ }
+
+ len= *address_len;
+ if (len > sizeof(struct sockaddr_un))
+ len = sizeof(struct sockaddr_un);
+
+ memcpy(address, uds_addr, len);
+ *address_len= len;
+
+ return 0;
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+#include <unistd.h>
+
+#ifdef __weak_alias
+__weak_alias(getpgrp, _getpgrp)
+#endif
+
+PUBLIC pid_t getpgrp()
+{
+ message m;
+
+ return(_syscall(PM_PROC_NR, GETPGRP, &m));
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+#include <unistd.h>
+
+#ifdef __weak_alias
+__weak_alias(getpid, _getpid)
+#endif
+
+PUBLIC pid_t getpid()
+{
+ message m;
+
+ return(_syscall(PM_PROC_NR, MINIX_GETPID, &m));
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+#include <unistd.h>
+
+#ifdef __weak_alias
+__weak_alias(getppid, _getppid)
+#endif
+
+PUBLIC pid_t getppid()
+{
+ message m;
+
+ /* POSIX says that this function is always successful and that no
+ * return value is reserved to indicate an error. Minix syscalls
+ * are not always successful and Minix returns the reserved value
+ * (pid_t) -1 when there is an error.
+ */
+ if (_syscall(PM_PROC_NR, MINIX_GETPID, &m) < 0) return ( (pid_t) -1);
+ return( (pid_t) m.m2_i1);
+}
--- /dev/null
+/* getrlimit Author: Erik van der Kouwe
+ * query resource consumtion limits 4 December 2009
+ *
+ * Based on these specifications:
+ * http://www.opengroup.org/onlinepubs/007908775/xsh/getdtablesize.html
+ * http://www.opengroup.org/onlinepubs/007908775/xsh/getrlimit.html
+ */
+
+#include <sys/cdefs.h>
+#include "namespace.h"
+
+#include <errno.h>
+#include <limits.h>
+#include <sys/resource.h>
+#include <unistd.h>
+
+int getrlimit(int resource, struct rlimit *rlp)
+{
+ rlim_t limit;
+
+ switch (resource)
+ {
+ case RLIMIT_CORE:
+ /* no core currently produced */
+ limit = 0;
+ break;
+
+ case RLIMIT_CPU:
+ case RLIMIT_DATA:
+ case RLIMIT_FSIZE:
+ case RLIMIT_STACK:
+ case RLIMIT_AS:
+ /* no limit enforced (however architectural limits
+ * may apply)
+ */
+ limit = RLIM_INFINITY;
+ break;
+
+ case RLIMIT_NOFILE:
+ limit = OPEN_MAX;
+ break;
+
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+
+ /* return limit */
+ rlp->rlim_cur = limit;
+ rlp->rlim_max = limit;
+ return 0;
+}
+
--- /dev/null
+/*
+
+ getsockname()
+
+ from socket emulation library for Minix 2.0.x
+
+*/
+
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <minix/ansi.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+#include <net/gen/in.h>
+#include <net/gen/tcp.h>
+#include <net/gen/tcp_io.h>
+#include <net/gen/udp.h>
+#include <sys/un.h>
+
+/*
+#define DEBUG 0
+*/
+
+static int _tcp_getsockname(int fd, struct sockaddr *_RESTRICT address,
+ socklen_t *_RESTRICT address_len, nwio_tcpconf_t *tcpconfp);
+
+static int _uds_getsockname(int fd, struct sockaddr *_RESTRICT address,
+ socklen_t *_RESTRICT address_len, struct sockaddr_un *uds_addr);
+
+int getsockname(int fd, struct sockaddr *_RESTRICT address,
+ socklen_t *_RESTRICT address_len)
+{
+ int r;
+ nwio_tcpconf_t tcpconf;
+ struct sockaddr_un uds_addr;
+
+#ifdef DEBUG
+ fprintf(stderr,"mnx_getsockname: ioctl fd %d.\n", fd);
+#endif
+
+ r= ioctl(fd, NWIOGTCPCONF, &tcpconf);
+ if (r != -1 || (errno != ENOTTY && errno != EBADIOCTL))
+ {
+ if (r == -1)
+ {
+ /* Bad file descriptor */
+ return -1;
+ }
+
+ return _tcp_getsockname(fd, address, address_len, &tcpconf);
+ }
+
+ r= ioctl(fd, NWIOGUDSADDR, &uds_addr);
+ if (r != -1 || (errno != ENOTTY && errno != EBADIOCTL))
+ {
+ if (r == -1)
+ {
+ /* Bad file descriptor */
+ return -1;
+ }
+
+ return _uds_getsockname(fd, address, address_len, &uds_addr);
+ }
+
+#if DEBUG
+ fprintf(stderr, "getsockname: not implemented for fd %d\n", socket);
+#endif
+
+ errno= ENOSYS;
+ return -1;
+}
+
+
+static int _tcp_getsockname(int fd, struct sockaddr *_RESTRICT address,
+ socklen_t *_RESTRICT address_len, nwio_tcpconf_t *tcpconf)
+{
+ socklen_t len;
+ struct sockaddr_in sin;
+
+#ifdef DEBUG1
+ fprintf(stderr, "mnx_getsockname: from %s, %u",
+ inet_ntoa(tcpconf.nwtc_remaddr),
+ ntohs(tcpconf.nwtc_remport));
+ fprintf(stderr," for %s, %u\n",
+ inet_ntoa(tcpconf.nwtc_locaddr),
+ ntohs(tcpconf.nwtc_locport));
+#endif
+
+ memset(&sin, '\0', sizeof(sin));
+ sin.sin_family= AF_INET;
+ sin.sin_addr.s_addr= tcpconf->nwtc_locaddr ;
+ sin.sin_port= tcpconf->nwtc_locport;
+
+ len= *address_len;
+ if (len > sizeof(sin))
+ len= sizeof(sin);
+ memcpy(address, &sin, len);
+ *address_len= len;
+
+ return 0;
+}
+
+static int _uds_getsockname(int fd, struct sockaddr *_RESTRICT address,
+ socklen_t *_RESTRICT address_len, struct sockaddr_un *uds_addr)
+{
+ socklen_t len;
+
+ if (uds_addr->sun_family != AF_UNIX)
+ {
+ errno= EINVAL;
+ return -1;
+ }
+
+ len= *address_len;
+ if (len > sizeof(struct sockaddr_un))
+ len = sizeof(struct sockaddr_un);
+
+ memcpy(address, uds_addr, len);
+ *address_len= len;
+
+ return 0;
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include <minix/ansi.h>
+#include "namespace.h"
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/ucred.h>
+#include <netinet/tcp.h>
+
+#include <net/gen/in.h>
+#include <net/gen/tcp.h>
+#include <net/gen/tcp_io.h>
+#include <net/gen/udp.h>
+#include <net/gen/udp_io.h>
+
+#include <minix/type.h>
+
+#define DEBUG 0
+
+static int _tcp_getsockopt(int sock, int level, int option_name,
+ void *_RESTRICT option_value, socklen_t *_RESTRICT option_len);
+static int _udp_getsockopt(int sock, int level, int option_name,
+ void *_RESTRICT option_value, socklen_t *_RESTRICT option_len);
+static int _uds_getsockopt(int sock, int level, int option_name,
+ void *_RESTRICT option_value, socklen_t *_RESTRICT option_len);
+static void getsockopt_copy(void *return_value, size_t return_len,
+ void *_RESTRICT option_value, socklen_t *_RESTRICT option_len);
+
+int getsockopt(int sock, int level, int option_name,
+ void *_RESTRICT option_value, socklen_t *_RESTRICT option_len)
+{
+ int r;
+ nwio_tcpopt_t tcpopt;
+ nwio_udpopt_t udpopt;
+ struct sockaddr_un uds_addr;
+
+ r= ioctl(sock, NWIOGTCPOPT, &tcpopt);
+ if (r != -1 || (errno != ENOTTY && errno != EBADIOCTL))
+ {
+ if (r == -1)
+ {
+ /* Bad file descriptor */
+ return -1;
+ }
+ return _tcp_getsockopt(sock, level, option_name,
+ option_value, option_len);
+ }
+
+ r= ioctl(sock, NWIOGUDPOPT, &udpopt);
+ if (r != -1 || (errno != ENOTTY && errno != EBADIOCTL))
+ {
+ if (r == -1)
+ {
+ /* Bad file descriptor */
+ return -1;
+ }
+ return _udp_getsockopt(sock, level, option_name,
+ option_value, option_len);
+ }
+
+ r= ioctl(sock, NWIOGUDSADDR, &uds_addr);
+ if (r != -1 || (errno != ENOTTY && errno != EBADIOCTL))
+ {
+ if (r == -1)
+ {
+ /* Bad file descriptor */
+ return -1;
+ }
+ return _uds_getsockopt(sock, level, option_name,
+ option_value, option_len);
+ }
+
+
+#if DEBUG
+ fprintf(stderr, "getsockopt: not implemented for fd %d\n", sock);
+#endif
+ errno= ENOTSOCK;
+ return -1;
+}
+
+static void getsockopt_copy(void *return_value, size_t return_len,
+ void *_RESTRICT option_value, socklen_t *_RESTRICT option_len)
+{
+ /* copy as much data as possible */
+ if (*option_len < return_len)
+ memcpy(option_value, return_value, *option_len);
+ else
+ memcpy(option_value, return_value, return_len);
+
+ /* return length */
+ *option_len = return_len;
+}
+
+static int _tcp_getsockopt(int sock, int level, int option_name,
+ void *_RESTRICT option_value, socklen_t *_RESTRICT option_len)
+{
+ int i, r, err;
+
+ if (level == SOL_SOCKET && option_name == SO_REUSEADDR)
+ {
+ i = 1; /* Binds to TIME_WAIT sockets never cause errors */
+ getsockopt_copy(&i, sizeof(i), option_value, option_len);
+ return 0;
+ }
+ if (level == SOL_SOCKET && option_name == SO_KEEPALIVE)
+ {
+ i = 1; /* Keepalive is always on */
+ getsockopt_copy(&i, sizeof(i), option_value, option_len);
+ return 0;
+ }
+ if (level == SOL_SOCKET && option_name == SO_ERROR)
+ {
+ r = ioctl(sock, NWIOTCPGERROR, &err);
+ if (r != 0)
+ return r;
+
+ getsockopt_copy(&err, sizeof(err), option_value, option_len);
+ return 0;
+ }
+ if (level == SOL_SOCKET && option_name == SO_RCVBUF)
+ {
+ i = 32 * 1024; /* Receive buffer in the current
+ * implementation
+ */
+ getsockopt_copy(&i, sizeof(i), option_value, option_len);
+ return 0;
+ }
+ if (level == SOL_SOCKET && option_name == SO_SNDBUF)
+ {
+ i = 32 * 1024; /* Send buffer in the current implementation */
+ getsockopt_copy(&i, sizeof(i), option_value, option_len);
+ return 0;
+ }
+ if (level == SOL_SOCKET && option_name == SO_TYPE)
+ {
+ i = SOCK_STREAM; /* this is a TCP socket */
+ getsockopt_copy(&i, sizeof(i), option_value, option_len);
+ return 0;
+ }
+ if (level == IPPROTO_TCP && option_name == TCP_NODELAY)
+ {
+ i = 0; /* nodelay is always off */
+ getsockopt_copy(&i, sizeof(i), option_value, option_len);
+ return 0;
+ }
+#if DEBUG
+ fprintf(stderr, "_tcp_getsocketopt: level %d, name %d\n",
+ level, option_name);
+#endif
+
+ errno= ENOPROTOOPT;
+ return -1;
+}
+
+static int _udp_getsockopt(int sock, int level, int option_name,
+ void *_RESTRICT option_value, socklen_t *_RESTRICT option_len)
+{
+ int i;
+
+ if (level == SOL_SOCKET && option_name == SO_TYPE)
+ {
+ i = SOCK_DGRAM; /* this is a UDP socket */
+ getsockopt_copy(&i, sizeof(i), option_value, option_len);
+ return 0;
+ }
+#if DEBUG
+ fprintf(stderr, "_udp_getsocketopt: level %d, name %d\n",
+ level, option_name);
+#endif
+
+ errno= ENOSYS;
+ return -1;
+}
+
+static int _uds_getsockopt(int sock, int level, int option_name,
+ void *_RESTRICT option_value, socklen_t *_RESTRICT option_len)
+{
+ int i, r;
+ size_t size;
+
+ if (level == SOL_SOCKET && option_name == SO_RCVBUF)
+ {
+ r= ioctl(sock, NWIOGUDSRCVBUF, &size);
+ if (r == -1) {
+ return r;
+ }
+
+ getsockopt_copy(&size, sizeof(size), option_value, option_len);
+ return 0;
+ }
+
+ if (level == SOL_SOCKET && option_name == SO_SNDBUF)
+ {
+ r= ioctl(sock, NWIOGUDSSNDBUF, &size);
+ if (r == -1) {
+ return r;
+ }
+
+ getsockopt_copy(&size, sizeof(size), option_value, option_len);
+ return 0;
+ }
+
+ if (level == SOL_SOCKET && option_name == SO_TYPE)
+ {
+ r= ioctl(sock, NWIOGUDSSOTYPE, &i);
+ if (r == -1) {
+ return r;
+ }
+
+ getsockopt_copy(&i, sizeof(i), option_value, option_len);
+ return 0;
+ }
+
+ if (level == SOL_SOCKET && option_name == SO_PEERCRED)
+ {
+ struct ucred cred;
+
+ r= ioctl(sock, NWIOGUDSPEERCRED, &cred);
+ if (r == -1) {
+ return -1;
+ }
+
+ getsockopt_copy(&cred, sizeof(struct ucred), option_value,
+ option_len);
+ return 0;
+ }
+
+
+ if (level == SOL_SOCKET && option_name == SO_REUSEADDR)
+ {
+ i = 1; /* as long as nobody is listen()ing on the address,
+ * it can be reused without waiting for a
+ * timeout to expire.
+ */
+ getsockopt_copy(&i, sizeof(i), option_value, option_len);
+ return 0;
+ }
+
+ if (level == SOL_SOCKET && option_name == SO_PASSCRED)
+ {
+ i = 1; /* option is always 'on' */
+ getsockopt_copy(&i, sizeof(i), option_value, option_len);
+ return 0;
+ }
+
+#if DEBUG
+ fprintf(stderr, "_uds_getsocketopt: level %d, name %d\n",
+ level, option_name);
+#endif
+
+ errno= ENOSYS;
+ return -1;
+}
--- /dev/null
+/*
+gettimeofday.c
+*/
+
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+#include <sys/time.h>
+
+#ifdef __weak_alias
+__weak_alias(gettimeofday, _gettimeofday)
+#endif
+
+int gettimeofday(struct timeval *_RESTRICT tp, void *_RESTRICT tzp)
+{
+ message m;
+
+ if (_syscall(PM_PROC_NR, GETTIMEOFDAY, &m) < 0)
+ return -1;
+
+ tp->tv_sec = m.m2_l1;
+ tp->tv_usec = m.m2_l2;
+
+ return 0;
+}
+
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+#include <unistd.h>
+
+#ifdef __weak_alias
+__weak_alias(getuid, _getuid)
+#endif
+
+PUBLIC uid_t getuid()
+{
+ message m;
+
+ return( (uid_t) _syscall(PM_PROC_NR, GETUID, &m));
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+#include <sys/ioctl.h>
+
+#ifdef __weak_alias
+__weak_alias(ioctl, _ioctl)
+#endif
+
+PUBLIC int ioctl(fd, request, data)
+int fd;
+int request;
+void *data;
+{
+ message m;
+
+ m.TTY_LINE = fd;
+ m.TTY_REQUEST = request;
+ m.ADDRESS = (char *) data;
+ return(_syscall(VFS_PROC_NR, IOCTL, &m));
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+#include <unistd.h>
+
+int issetugid(void)
+{
+#warning Unsecure. Implement me.
+ return 0;
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+#include <signal.h>
+
+#ifdef __weak_alias
+__weak_alias(kill, _kill)
+#endif
+
+PUBLIC int kill(proc, sig)
+int proc; /* which process is to be sent the signal */
+int sig; /* signal number */
+{
+ message m;
+
+ m.m1_i1 = proc;
+ m.m1_i2 = sig;
+ return(_syscall(PM_PROC_NR, KILL, &m));
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+#include <string.h>
+#include <unistd.h>
+
+#ifdef __weak_alias
+__weak_alias(link, _link)
+#endif
+
+PUBLIC int link(name, name2)
+_CONST char *name, *name2;
+{
+ message m;
+
+ m.m1_i1 = strlen(name) + 1;
+ m.m1_i2 = strlen(name2) + 1;
+ m.m1_p1 = (char *) name;
+ m.m1_p2 = (char *) name2;
+ return(_syscall(VFS_PROC_NR, LINK, &m));
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+#include <net/gen/in.h>
+#include <net/gen/tcp.h>
+#include <net/gen/tcp_io.h>
+#include <net/gen/udp.h>
+#include <net/gen/udp_io.h>
+
+#define DEBUG 0
+
+int listen(int sock, int backlog)
+{
+ int r;
+
+ r= ioctl(sock, NWIOTCPLISTENQ, &backlog);
+ if (r != -1 || errno != EBADIOCTL)
+ return r;
+
+ r= ioctl(sock, NWIOSUDSBLOG, &backlog);
+ if (r != -1 || errno != EBADIOCTL)
+ return r;
+
+#if DEBUG
+ fprintf(stderr, "listen: not implemented for fd %d\n", sock);
+#endif
+ errno= ENOSYS;
+ return -1;
+}
+
--- /dev/null
+#include <sys/cdefs.h>
+#include <lib.h>
+#include "namespace.h"
+
+#include <string.h>
+
+void _loadname(name, msgptr)
+const char *name;
+message *msgptr;
+{
+/* This function is used to load a string into a type m3 message. If the
+ * string fits in the message, it is copied there. If not, a pointer to
+ * it is passed.
+ */
+
+ register size_t k;
+
+ k = strlen(name) + 1;
+ msgptr->m3_i1 = k;
+ msgptr->m3_p1 = (char *) name;
+ if (k <= M3_STRING) strcpy(msgptr->m3_ca1, name);
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+#include <unistd.h>
+
+#ifdef __weak_alias
+__weak_alias(lseek, _lseek)
+#endif
+
+PUBLIC off_t lseek(fd, offset, whence)
+int fd;
+off_t offset;
+int whence;
+{
+ message m;
+
+ m.m2_i1 = fd;
+ m.m2_l1 = offset;
+ m.m2_i2 = whence;
+ if (_syscall(VFS_PROC_NR, LSEEK, &m) < 0) return( (off_t) -1);
+ return( (off_t) m.m2_l1);
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+#include <unistd.h>
+#include <minix/u64.h>
+
+PUBLIC int lseek64(fd, offset, whence, newpos)
+int fd;
+u64_t offset;
+int whence;
+u64_t *newpos;
+{
+ message m;
+
+ m.m2_i1 = fd;
+ m.m2_l1 = ex64lo(offset);
+ m.m2_l2 = ex64hi(offset);
+ m.m2_i2 = whence;
+ if (_syscall(VFS_PROC_NR, LLSEEK, &m) < 0) return -1;
+ if (newpos)
+ *newpos= make64(m.m2_l1, m.m2_l2);
+ return 0;
+}
--- /dev/null
+#include <sys/cdefs.h>
+#define _SYSTEM 1
+#define _MINIX 1
+
+#include <minix/ansi.h>
+#include <minix/callnr.h>
+#include <minix/com.h>
+#include <minix/config.h>
+#include <minix/ipc.h>
+#include <minix/endpoint.h>
+#include <minix/sysutil.h>
+#include <minix/syslib.h>
+#include <minix/const.h>
+#include <minix/type.h>
+#include <minix/ds.h>
+#include <minix/rs.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <lib.h>
+
+int minix_rs_lookup(const char *name, endpoint_t *value)
+{
+ message m;
+ size_t len_key;
+
+ len_key = strlen(name)+1;
+
+ m.RS_NAME = (char *) name;
+ m.RS_NAME_LEN = len_key;
+
+ if (_syscall(RS_PROC_NR, RS_LOOKUP, &m) != -1) {
+ *value = m.RS_ENDPOINT;
+ return OK;
+ }
+
+ return -1;
+}
+
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+#include <sys/stat.h>
+#include <string.h>
+
+#ifdef __weak_alias
+__weak_alias(mkdir, _mkdir)
+#endif
+
+PUBLIC int mkdir(const char *name, mode_t mode)
+{
+ message m;
+
+ m.m1_i1 = strlen(name) + 1;
+ m.m1_i2 = mode;
+ m.m1_p1 = (char *) name;
+ return(_syscall(VFS_PROC_NR, MKDIR, &m));
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+#include <sys/stat.h>
+#include <unistd.h>
+
+#ifdef __weak_alias
+__weak_alias(mkfifo, _mkfifo)
+#endif
+
+PUBLIC int mkfifo(const char *name, mode_t mode)
+{
+ return mknod(name, mode | S_IFIFO, (dev_t) 0);
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+PUBLIC int mknod(const char *name, mode_t mode, dev_t dev)
+{
+ message m;
+
+ m.m1_i1 = strlen(name) + 1;
+ m.m1_i2 = mode;
+ m.m1_i3 = dev;
+ m.m1_p1 = (char *) name;
+ m.m1_p2 = (char *) ((int) 0); /* obsolete size field */
+ return(_syscall(VFS_PROC_NR, MKNOD, &m));
+}
--- /dev/null
+#define _SYSTEM 1
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+/* INCLUDES HERE */
+
+#ifdef __weak_alias
+__weak_alias(mmap, _mmap)
+__weak_alias(munmap, _munmap)
+__weak_alias(munmap_text, _munmap_text)
+__weak_alias(vm_remap, _vm_remap)
+__weak_alias(vm_unmap, _vm_unmap)
+__weak_alias(vm_getphys, _vm_getphys)
+__weak_alias(vm_getrefcount, _vm_getrefcount)
+#endif
+
+
+#include <sys/mman.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
+
+PUBLIC void *mmap(void *addr, size_t len, int prot, int flags,
+ int fd, off_t offset)
+{
+ message m;
+ int r;
+
+ m.VMM_ADDR = (vir_bytes) addr;
+ m.VMM_LEN = len;
+ m.VMM_PROT = prot;
+ m.VMM_FLAGS = flags;
+ m.VMM_FD = fd;
+ m.VMM_OFFSET = offset;
+
+ r = _syscall(VM_PROC_NR, VM_MMAP, &m);
+
+ if(r != OK) {
+ return MAP_FAILED;
+ }
+
+ return (void *) m.VMM_RETADDR;
+}
+
+PUBLIC int munmap(void *addr, size_t len)
+{
+ message m;
+
+ m.VMUM_ADDR = addr;
+ m.VMUM_LEN = len;
+
+ return _syscall(VM_PROC_NR, VM_MUNMAP, &m);
+}
+
+
+PUBLIC int munmap_text(void *addr, size_t len)
+{
+ message m;
+
+ m.VMUM_ADDR = addr;
+ m.VMUM_LEN = len;
+
+ return _syscall(VM_PROC_NR, VM_MUNMAP_TEXT, &m);
+}
+
+PUBLIC void *vm_remap(endpoint_t d,
+ endpoint_t s,
+ void *da,
+ void *sa,
+ size_t size)
+{
+ message m;
+ int r;
+
+ m.VMRE_D = d;
+ m.VMRE_S = s;
+ m.VMRE_DA = (char *) da;
+ m.VMRE_SA = (char *) sa;
+ m.VMRE_SIZE = size;
+
+ r = _syscall(VM_PROC_NR, VM_REMAP, &m);
+ if (r != OK)
+ return MAP_FAILED;
+ return (void *) m.VMRE_RETA;
+}
+
+PUBLIC int vm_unmap(endpoint_t endpt, void *addr)
+{
+ message m;
+
+ m.VMUN_ENDPT = endpt;
+ m.VMUN_ADDR = (long) addr;
+
+ return _syscall(VM_PROC_NR, VM_SHM_UNMAP, &m);
+}
+
+PUBLIC unsigned long vm_getphys(int endpt, void *addr)
+{
+ message m;
+ int r;
+
+ m.VMPHYS_ENDPT = endpt;
+ m.VMPHYS_ADDR = (long) addr;
+
+ r = _syscall(VM_PROC_NR, VM_GETPHYS, &m);
+ if (r != OK)
+ return 0;
+ return m.VMPHYS_RETA;
+}
+
+PUBLIC u8_t vm_getrefcount(endpoint_t endpt, void *addr)
+{
+ message m;
+ int r;
+
+ m.VMREFCNT_ENDPT = endpt;
+ m.VMREFCNT_ADDR = (long) addr;
+
+ r = _syscall(VM_PROC_NR, VM_GETREF, &m);
+ if (r != OK)
+ return (u8_t) -1;
+ return (u8_t) m.VMREFCNT_RETC;
+}
+
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+#include <string.h>
+#include <sys/mount.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <minix/syslib.h>
+#include <minix/rs.h>
+#include <paths.h>
+#define OK 0
+
+#ifdef __weak_alias
+__weak_alias(mount, _mount)
+__weak_alias(umount, _umount)
+__weak_alias(umount2, _umount2)
+#endif
+
+
+#define FSPATH "/sbin/"
+#define FSDEFAULT "mfs"
+
+PRIVATE int rs_down(char *label)
+{
+ char cmd[200];
+ if(strlen(_PATH_SERVICE)+strlen(label)+50 >= sizeof(cmd))
+ return -1;
+ sprintf(cmd, _PATH_SERVICE " down '%s'", label);
+ return system(cmd);
+}
+
+PUBLIC int mount(special, name, mountflags, type, args)
+char *name, *special, *type, *args;
+int mountflags;
+{
+ int r;
+ message m;
+ struct stat statbuf;
+ char label[16];
+ char path[60];
+ char cmd[200];
+ char *p;
+ int reuse = 0;
+ int use_existing = 0;
+
+ /* Default values. */
+ if (type == NULL) type = FSDEFAULT;
+ if (args == NULL) args = "";
+ reuse = 0;
+
+ /* Check mount flags */
+ if(mountflags & MS_REUSE) {
+ reuse = 1;
+ mountflags &= ~MS_REUSE; /* Temporary: turn off to not confuse VFS */
+ }
+
+ if(mountflags & MS_EXISTING) {
+ use_existing = 1;
+ mountflags &= ~MS_EXISTING; /* Temporary: turn off to not confuse VFS */
+ }
+
+ /* Make a label for the file system process. This label must be unique and
+ * may currently not exceed 16 characters including terminating null. For
+ * requests with an associated block device, we use the last path component
+ * name of the block special file (truncated to 12 characters, which is
+ * hopefully enough). For requests with no associated block device, we use
+ * the device number and inode of the mount point, in hexadecimal form.
+ */
+ if (!use_existing) {
+ if (special) {
+ p = strrchr(special, '/');
+ p = p ? p + 1 : special;
+ if (strchr(p, '\'')) {
+ errno = EINVAL;
+ return -1;
+ }
+ sprintf(label, "fs_%.12s", p);
+ } else {
+ if (stat(name, &statbuf) < 0) return -1;
+ sprintf(label, "fs_%04x%x", statbuf.st_dev, statbuf.st_ino);
+ }
+ } else {
+ /* label to long? */
+ if (strlen(type) < 16) {
+ sprintf(label, "%s", type);
+ } else {
+ errno = ENOMEM;
+ return -1;
+ }
+ }
+
+ /* Tell VFS that we are passing in a 16-byte label. */
+ mountflags |= MS_LABEL16;
+
+ /* See if the given type is even remotely valid. */
+ if(strlen(FSPATH)+strlen(type) >= sizeof(path)) {
+ errno = E2BIG;
+ return -1;
+ }
+ strcpy(path, FSPATH);
+ strcat(path, type);
+
+ if(stat(path, &statbuf) != 0) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ /* Sanity check on user input. */
+ if(strchr(args, '\'')) {
+ errno = EINVAL;
+ return -1;
+ }
+ /* start the fs-server if not using existing one */
+ if (!use_existing) {
+ if(strlen(_PATH_SERVICE)+strlen(path)+strlen(label)+
+ strlen(args)+50 >= sizeof(cmd)) {
+ errno = E2BIG;
+ return -1;
+ }
+
+ sprintf(cmd, _PATH_SERVICE " %sup %s -label '%s' -args '%s%s'",
+ reuse ? "-r ": "", path, label, args[0] ? "-o " : "", args);
+
+ if((r = system(cmd)) != 0) {
+ fprintf(stderr, "mount: couldn't run %s\n", cmd);
+ errno = r;
+ return -1;
+ }
+ }
+
+ /* Now perform mount(). */
+ m.m1_i1 = special ? strlen(special) + 1 : 0;
+ m.m1_i2 = strlen(name) + 1;
+ m.m1_i3 = mountflags;
+ m.m1_p1 = special;
+ m.m1_p2 = name;
+ m.m1_p3 = label;
+ r = _syscall(VFS_PROC_NR, MOUNT, &m);
+
+ if(r != OK) {
+ /* If mount() failed, tell RS to shutdown MFS process.
+ * No error check - won't do anything with this error anyway.
+ */
+ rs_down(label);
+ }
+
+ return r;
+}
+
+PUBLIC int umount(name)
+_CONST char *name;
+{
+ return umount2(name, 0);
+}
+
+PUBLIC int umount2(name, flags)
+_CONST char *name;
+int flags;
+{
+ message m;
+ int r;
+
+
+ _loadname(name, &m);
+ r = _syscall(VFS_PROC_NR, UMOUNT, &m);
+
+ /* don't shut down the driver when exist flag is set */
+ if (!(flags & MS_EXISTING)) {
+ if (r == OK) {
+ /* VFS returns the label of the unmounted file system in the reply.
+ * As of writing, the size of the m3_ca1 field is 16 bytes.
+ */
+ rs_down(m.m3_ca1);
+ }
+ }
+
+ return r;
+}
--- /dev/null
+/* nanosleep() - Sleep for a number of seconds. Author: Erik van der Kouwe
+ * 25 July 2009
+ */
+
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+#include <unistd.h>
+#include <errno.h>
+#include <time.h>
+#include <sys/select.h>
+#include <sys/time.h>
+
+#define MSEC_PER_SEC 1000
+#define USEC_PER_MSEC 1000
+#define NSEC_PER_USEC 1000
+
+#define USEC_PER_SEC (USEC_PER_MSEC * MSEC_PER_SEC)
+#define NSEC_PER_SEC (NSEC_PER_USEC * USEC_PER_SEC)
+
+int nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
+{
+ struct timeval timeout, timestart = { 0, 0 }, timeend;
+ int errno_select, r;
+ struct timespec rqt;
+
+ /* check parameters */
+ if (!rqtp)
+ return EFAULT;
+
+ if (rqtp->tv_sec < 0 ||
+ rqtp->tv_nsec < 0 ||
+ rqtp->tv_nsec >= NSEC_PER_SEC)
+ return EINVAL;
+
+ /* store *rqtp to make sure it is not overwritten */
+ rqt = *rqtp;
+
+ /* keep track of start time if needed */
+ if (rmtp)
+ {
+ rmtp->tv_sec = 0;
+ rmtp->tv_nsec = 0;
+ if (gettimeofday(×tart, NULL) < 0)
+ return -1;
+ }
+
+ /* use select to wait */
+ timeout.tv_sec = rqt.tv_sec;
+ timeout.tv_usec = (rqt.tv_nsec + NSEC_PER_USEC - 1) / NSEC_PER_USEC;
+ r = select(0, NULL, NULL, NULL, &timeout);
+
+ /* return remaining time only if requested */
+ /* if select succeeded then we slept all time */
+ if (!rmtp || r >= 0)
+ return r;
+
+ /* measure end time; preserve errno */
+ errno_select = errno;
+ if (gettimeofday(&timeend, NULL) < 0)
+ return -1;
+
+ errno = errno_select;
+
+ /* compute remaining time */
+ rmtp->tv_sec = rqt.tv_sec - (timeend.tv_sec - timestart.tv_sec);
+ rmtp->tv_nsec = rqt.tv_nsec - (timeend.tv_usec - timestart.tv_usec) * NSEC_PER_USEC;
+
+ /* bring remaining time into canonical form */
+ while (rmtp->tv_nsec < 0)
+ {
+ rmtp->tv_sec -= 1;
+ rmtp->tv_nsec += NSEC_PER_SEC;
+ }
+
+ while (rmtp->tv_nsec > NSEC_PER_SEC)
+ {
+ rmtp->tv_sec += 1;
+ rmtp->tv_nsec -= NSEC_PER_SEC;
+ }
+
+ /* remaining time must not be negative */
+ if (rmtp->tv_sec < 0)
+ {
+ rmtp->tv_sec = 0;
+ rmtp->tv_nsec = 0;
+ }
+
+ return r;
+}
+
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+#include <fcntl.h>
+#include <stdarg.h>
+#include <string.h>
+
+#ifdef __weak_alias
+__weak_alias(open, _open)
+#endif
+
+#if _ANSI
+PUBLIC int open(const char *name, int flags, ...)
+#else
+PUBLIC int open(const char *name, int flags)
+#endif
+{
+ va_list argp;
+ message m;
+
+ va_start(argp, flags);
+ if (flags & O_CREAT) {
+ m.m1_i1 = strlen(name) + 1;
+ m.m1_i2 = flags;
+ /* Since it's a vararg parameter that is smaller than
+ * an int, the mode was passed as an int.
+ */
+ m.m1_i3 = va_arg(argp, int);
+ m.m1_p1 = (char *) name;
+ } else {
+ _loadname(name, &m);
+ m.m3_i2 = flags;
+ }
+ va_end(argp);
+ return (_syscall(VFS_PROC_NR, OPEN, &m));
+}
--- /dev/null
+/* POSIX pathconf (Sec. 5.7.1) Author: Andy Tanenbaum */
+
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+
+#ifdef __weak_alias
+__weak_alias(pathconf, _pathconf)
+#endif
+
+PUBLIC long pathconf(path, name)
+_CONST char *path; /* name of file being interrogated */
+int name; /* property being inspected */
+{
+/* POSIX allows some of the values in <limits.h> to be increased at
+ * run time. The pathconf and fpathconf functions allow these values
+ * to be checked at run time. MINIX does not use this facility.
+ * The run-time limits are those given in <limits.h>.
+ */
+
+ int fd;
+ long val;
+
+ if ( (fd = open(path, O_RDONLY)) < 0) return(-1L);
+ val = fpathconf(fd, name);
+ close(fd);
+ return(val);
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+#include <unistd.h>
+
+#ifdef __weak_alias
+__weak_alias(pipe, _pipe)
+#endif
+
+int pipe(fild)
+int fild[2];
+{
+ message m;
+
+ if (_syscall(VFS_PROC_NR, PIPE, &m) < 0) return(-1);
+ fild[0] = m.m1_i1;
+ fild[1] = m.m1_i2;
+ return(0);
+}
--- /dev/null
+/* $NetBSD: poll.c,v 1.3 2008/04/29 05:46:08 martin Exp $ */
+
+/*-
+ * Copyright (c) 2003 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Charles Blundell.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``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 FOUNDATION OR CONTRIBUTORS
+ * 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/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <sys/poll.h>
+#include <errno.h>
+
+int
+poll(struct pollfd *p, nfds_t nfds, int timout)
+{
+ fd_set rd, wr, except;
+ struct timeval tv;
+ nfds_t i;
+ int highfd, rval;
+
+ /*
+ * select cannot tell us much wrt POLL*BAND, POLLPRI, POLLHUP or
+ * POLLNVAL.
+ */
+ FD_ZERO(&rd);
+ FD_ZERO(&wr);
+ FD_ZERO(&except);
+
+ highfd = -1;
+ for (i = 0; i < nfds; i++) {
+ if (p[i].fd < 0)
+ continue;
+ if (p[i].fd >= FD_SETSIZE) {
+ errno = EINVAL;
+ return -1;
+ }
+ if (p[i].fd > highfd)
+ highfd = p[i].fd;
+
+ if (p[i].events & (POLLIN|POLLRDNORM|POLLRDBAND|POLLPRI))
+ FD_SET(p[i].fd, &rd);
+ if (p[i].events & (POLLOUT|POLLWRNORM|POLLWRBAND))
+ FD_SET(p[i].fd, &wr);
+ FD_SET(p[i].fd, &except);
+ }
+
+ tv.tv_sec = timout / 1000;
+ tv.tv_usec = (timout % 1000) * 1000;
+
+ rval = select(highfd + 1, &rd, &wr, &except,
+ timout == -1 ? NULL : &tv);
+ if (rval <= 0)
+ return rval;
+
+ rval = 0;
+ for (i = 0; i < nfds; i++) {
+ p[i].revents = 0;
+ if (FD_ISSET(p[i].fd, &rd))
+ p[i].revents |= POLLIN|POLLRDNORM|POLLRDBAND|POLLPRI;
+ if (FD_ISSET(p[i].fd, &wr))
+ p[i].revents |= POLLOUT|POLLWRNORM|POLLWRBAND;
+ if (FD_ISSET(p[i].fd, &except))
+ p[i].revents |= POLLERR;
+ /* XXX: POLLHUP/POLLNVAL? */
+ if (p[i].revents != 0)
+ rval++;
+ }
+ return rval;
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+#include <unistd.h>
+
+#ifdef __weak_alias
+__weak_alias(pread, _pread)
+#endif
+
+#include <lib.h>
+#include <unistd.h>
+
+ssize_t pread(int fd, void *buffer, size_t nbytes, off_t where)
+{
+ off_t here;
+ ssize_t r;
+
+ if((here = lseek(fd, 0, SEEK_CUR)) < 0)
+ return -1;
+
+ if(lseek(fd, where, SEEK_SET) < 0)
+ return -1;
+
+ if((r=read(fd, buffer, nbytes)) < 0) {
+ int e = errno;
+ lseek(fd, here, SEEK_SET);
+ errno = e;
+ return -1;
+ }
+
+ if(lseek(fd, here, SEEK_SET) < 0)
+ return -1;
+
+ return r;
+}
+
--- /dev/null
+/*
+priority.c
+*/
+
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/resource.h>
+#include <lib.h>
+#include <unistd.h>
+#include <string.h>
+#include <stddef.h>
+
+
+int getpriority(int which, int who)
+{
+ int v;
+ message m;
+
+ m.m1_i1 = which;
+ m.m1_i2 = who;
+
+ /* GETPRIORITY returns negative for error.
+ * Otherwise, it returns the priority plus the minimum
+ * priority, to distiginuish from error. We have to
+ * correct for this. (The user program has to check errno
+ * to see if something really went wrong.)
+ */
+
+ if((v = _syscall(PM_PROC_NR, GETPRIORITY, &m)) < 0) {
+ return v;
+ }
+
+ return v + PRIO_MIN;
+}
+
+int setpriority(int which, int who, int prio)
+{
+ message m;
+
+ m.m1_i1 = which;
+ m.m1_i2 = who;
+ m.m1_i3 = prio;
+
+ return _syscall(PM_PROC_NR, SETPRIORITY, &m);
+}
+
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+#include <sys/ptrace.h>
+
+#ifdef __weak_alias
+__weak_alias(ptrace, _ptrace)
+#endif
+
+long ptrace(int req, pid_t pid, long addr, long data)
+{
+ message m;
+
+ m.m2_i1 = pid;
+ m.m2_i2 = req;
+ m.PMTRACE_ADDR = addr;
+ m.m2_l2 = data;
+ if (_syscall(PM_PROC_NR, PTRACE, &m) < 0) return(-1);
+
+ /* There was no error, but -1 is a legal return value. Clear errno if
+ * necessary to distinguish this case. _syscall has set errno to nonzero
+ * for the error case.
+ */
+ if (m.m2_l2 == -1) errno = 0;
+ return(m.m2_l2);
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+#include <unistd.h>
+
+#ifdef __weak_alias
+__weak_alias(pwrite, _pwrite)
+#endif
+
+ssize_t pwrite(int fd, const void *buffer, size_t nbytes, off_t where)
+{
+ off_t here;
+ ssize_t w;
+
+ if((here = lseek(fd, 0, SEEK_CUR)) < 0)
+ return -1;
+
+ if(lseek(fd, where, SEEK_SET) < 0)
+ return -1;
+
+ if((w=write(fd, buffer, nbytes)) < 0) {
+ int e = errno;
+ lseek(fd, here, SEEK_SET);
+ errno = e;
+ return -1;
+ }
+
+ if(lseek(fd, here, SEEK_SET) < 0)
+ return -1;
+
+ return w;
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include <lib.h>
+#include "namespace.h"
+
+#include <unistd.h>
+
+#ifdef __weak_alias
+__weak_alias(read, _read)
+#endif
+
+ssize_t read(fd, buffer, nbytes)
+int fd;
+void *buffer;
+size_t nbytes;
+{
+ message m;
+
+ m.m1_i1 = fd;
+ m.m1_i2 = nbytes;
+ m.m1_p1 = (char *) buffer;
+ return(_syscall(VFS_PROC_NR, READ, &m));
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include <lib.h>
+#include "namespace.h"
+
+#include <unistd.h>
+#include <string.h>
+
+#ifdef __weak_alias
+__weak_alias(readlink, _readlink)
+#endif
+
+int readlink(name, buffer, bufsiz)
+const char *name;
+char *buffer;
+size_t bufsiz;
+{
+ message m;
+
+ m.m1_i1 = strlen(name) + 1;
+ m.m1_i2 = bufsiz;
+ m.m1_p1 = (char *) name;
+ m.m1_p2 = (char *) buffer;
+
+ return(_syscall(VFS_PROC_NR, RDLNK, &m));
+}
--- /dev/null
+/* reboot.c - Systemcall interface to mm/signal.c::do_reboot()
+
+ author: Edvard Tuinder v892231@si.hhs.NL
+ */
+
+#include <sys/cdefs.h>
+#include <lib.h>
+#include "namespace.h"
+
+#include <unistd.h>
+#include <sys/reboot.h>
+#include <stdarg.h>
+
+int reboot(int how, ...)
+{
+ message m;
+ va_list ap;
+
+ va_start(ap, how);
+ if ((m.m1_i1 = how) == RBT_MONITOR) {
+ m.m1_p1 = va_arg(ap, char *);
+ m.m1_i2 = va_arg(ap, size_t);
+ }
+ va_end(ap);
+
+ return _syscall(PM_PROC_NR, REBOOT, &m);
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include <minix/ansi.h>
+#include "namespace.h"
+
+#undef NDEBUG
+
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+#include <net/gen/in.h>
+#include <net/gen/tcp.h>
+#include <net/gen/tcp_io.h>
+#include <net/gen/udp.h>
+#include <net/gen/udp_hdr.h>
+#include <net/gen/udp_io.h>
+
+#define DEBUG 0
+
+static ssize_t _tcp_recvfrom(int sock, void *_RESTRICT buffer, size_t length,
+ int flags, struct sockaddr *_RESTRICT address,
+ socklen_t *_RESTRICT address_len, nwio_tcpconf_t *tcpconfp);
+static ssize_t _udp_recvfrom(int sock, void *_RESTRICT buffer, size_t length,
+ int flags, struct sockaddr *_RESTRICT address,
+ socklen_t *_RESTRICT address_len, nwio_udpopt_t *udpoptp);
+static ssize_t _uds_recvfrom_conn(int sock, void *_RESTRICT buffer,
+ size_t length, int flags, struct sockaddr *_RESTRICT address,
+ socklen_t *_RESTRICT address_len, struct sockaddr_un *uds_addr);
+static ssize_t _uds_recvfrom_dgram(int sock, void *_RESTRICT buffer,
+ size_t length, int flags, struct sockaddr *_RESTRICT address,
+ socklen_t *_RESTRICT address_len);
+
+ssize_t recvfrom(int sock, void *_RESTRICT buffer, size_t length,
+ int flags, struct sockaddr *_RESTRICT address,
+ socklen_t *_RESTRICT address_len)
+{
+ int r;
+ nwio_tcpconf_t tcpconf;
+ nwio_udpopt_t udpopt;
+ struct sockaddr_un uds_addr;
+ int uds_sotype = -1;
+
+#if DEBUG
+ fprintf(stderr, "recvfrom: for fd %d\n", sock);
+#endif
+
+ r= ioctl(sock, NWIOGTCPCONF, &tcpconf);
+ if (r != -1 || (errno != ENOTTY && errno != EBADIOCTL))
+ {
+ if (r == -1)
+ return r;
+ return _tcp_recvfrom(sock, buffer, length, flags,
+ address, address_len, &tcpconf);
+ }
+
+ r= ioctl(sock, NWIOGUDPOPT, &udpopt);
+ if (r != -1 || (errno != ENOTTY && errno != EBADIOCTL))
+ {
+ if (r == -1)
+ return r;
+ return _udp_recvfrom(sock, buffer, length, flags,
+ address, address_len, &udpopt);
+ }
+
+ r= ioctl(sock, NWIOGUDSSOTYPE, &uds_sotype);
+ if (r != -1 || (errno != ENOTTY && errno != EBADIOCTL))
+ {
+
+ if (r == -1) {
+ return r;
+ }
+
+ if (uds_sotype == SOCK_DGRAM) {
+ return _uds_recvfrom_dgram(sock, buffer,
+ length, flags, address, address_len);
+ } else {
+ return _uds_recvfrom_conn(sock, buffer,
+ length, flags, address, address_len,
+ &uds_addr);
+ }
+ }
+
+#if DEBUG
+ fprintf(stderr, "recvfrom: not implemented for fd %d\n", sock);
+#endif
+ errno= ENOSYS;
+ assert(0);
+ return -1;
+}
+
+static ssize_t _tcp_recvfrom(int sock, void *_RESTRICT buffer, size_t length,
+ int flags, struct sockaddr *_RESTRICT address,
+ socklen_t *_RESTRICT address_len, nwio_tcpconf_t *tcpconfp)
+{
+ int r;
+ size_t len;
+ struct sockaddr_in sin;
+
+ if (flags != 0)
+ {
+#if DEBUG
+ fprintf(stderr, "recvfrom(tcp): flags not implemented\n");
+#endif
+ errno= ENOSYS;
+ return -1;
+ }
+
+ r = read(sock, buffer, length);
+
+ if (r >= 0 && address != NULL)
+ {
+ sin.sin_family= AF_INET;
+ sin.sin_addr.s_addr= tcpconfp->nwtc_remaddr;
+ sin.sin_port= tcpconfp->nwtc_remport;
+ len= *address_len;
+ if (len > sizeof(sin))
+ len= sizeof(sin);
+ memcpy(address, &sin, len);
+ *address_len= sizeof(sin);
+ }
+
+ return r;
+}
+
+static ssize_t _udp_recvfrom(int sock, void *_RESTRICT buffer, size_t length,
+ int flags, struct sockaddr *_RESTRICT address,
+ socklen_t *_RESTRICT address_len, nwio_udpopt_t *udpoptp)
+{
+ int r, t_errno;
+ size_t buflen, len;
+ void *buf;
+ udp_io_hdr_t *io_hdrp;
+ struct sockaddr_in sin;
+
+ if (flags)
+ {
+#if DEBUG
+ fprintf(stderr, "recvfrom(udp): flags not implemented\n");
+#endif
+ errno= ENOSYS;
+ return -1;
+ }
+
+ if (udpoptp->nwuo_flags & NWUO_RWDATONLY)
+ {
+ if (address != NULL &&
+ (udpoptp->nwuo_flags & (NWUO_RA_SET | NWUO_RP_SET)) !=
+ (NWUO_RA_SET | NWUO_RP_SET))
+ {
+
+#if DEBUG
+ fprintf(stderr,
+ "recvfrom(udp): RWDATONLY on unconnected socket\n");
+#endif
+ errno= ENOTCONN;
+ return -1;
+ }
+
+ r= read(sock, buffer, length);
+ if (r == -1)
+ return r;
+
+ if (address != NULL)
+ {
+ sin.sin_family= AF_INET;
+ sin.sin_addr.s_addr= udpoptp->nwuo_remaddr;
+ sin.sin_port= udpoptp->nwuo_remport;
+ len= *address_len;
+ if (len > sizeof(sin))
+ len= sizeof(sin);
+ memcpy(address, &sin, len);
+ *address_len= sizeof(sin);
+ }
+
+ return r;
+ }
+
+ buflen= sizeof(*io_hdrp) + length;
+ if (buflen < length)
+ {
+ /* Overflow */
+ errno= EMSGSIZE;
+ return -1;
+ }
+ buf= malloc(buflen);
+ if (buf == NULL)
+ return -1;
+
+ r= read(sock, buf, buflen);
+ if (r == -1)
+ {
+ t_errno= errno;
+#if DEBUG
+ fprintf(stderr, "recvfrom(udp): read failed: %s\n",
+ strerror(errno));
+ fprintf(stderr, "udp opt flags = 0x%x\n", udpoptp->nwuo_flags);
+#endif
+ free(buf);
+ errno= t_errno;
+ return -1;
+ }
+
+ assert(r >= sizeof(*io_hdrp));
+ length= r-sizeof(*io_hdrp);
+
+ io_hdrp= buf;
+ memcpy(buffer, &io_hdrp[1], length);
+
+ if (address != NULL)
+ {
+ sin.sin_family= AF_INET;
+ sin.sin_addr.s_addr= io_hdrp->uih_src_addr;
+ sin.sin_port= io_hdrp->uih_src_port;
+ len= *address_len;
+ if (len > sizeof(sin))
+ len= sizeof(sin);
+ memcpy(address, &sin, len);
+ *address_len= sizeof(sin);
+ }
+ free(buf);
+ return length;
+}
+
+static ssize_t _uds_recvfrom_conn(int sock, void *_RESTRICT buffer,
+ size_t length, int flags, struct sockaddr *_RESTRICT address,
+ socklen_t *_RESTRICT address_len, struct sockaddr_un *uds_addr)
+{
+ int r;
+ size_t len;
+
+ /* for connection oriented unix domain sockets (SOCK_STREAM /
+ * SOCK_SEQPACKET)
+ */
+
+ if (flags != 0)
+ {
+#if DEBUG
+ fprintf(stderr, "recvfrom(uds): flags not implemented\n");
+#endif
+ errno= ENOSYS;
+ return -1;
+ }
+
+ r = read(sock, buffer, length);
+
+ if (r >= 0 && address != NULL)
+ {
+
+ len= *address_len;
+ if (len > sizeof(struct sockaddr_un))
+ len= sizeof(struct sockaddr_un);
+ memcpy(address, uds_addr, len);
+ *address_len= sizeof(struct sockaddr_un);
+ }
+
+ return r;
+}
+
+static ssize_t _uds_recvfrom_dgram(int sock, void *_RESTRICT buffer,
+ size_t length, int flags, struct sockaddr *_RESTRICT address,
+ socklen_t *_RESTRICT address_len)
+{
+ int r;
+ size_t len;
+
+ /* for connectionless unix domain sockets (SOCK_DGRAM) */
+
+ if (flags != 0)
+ {
+#if DEBUG
+ fprintf(stderr, "recvfrom(uds): flags not implemented\n");
+#endif
+ errno= ENOSYS;
+ return -1;
+ }
+
+ r = read(sock, buffer, length);
+
+ if (r >= 0 && address != NULL)
+ {
+ len= *address_len;
+ if (len > sizeof(struct sockaddr_un))
+ len= sizeof(struct sockaddr_un);
+ ioctl(sock, NWIOGUDSFADDR, address);
+ *address_len= sizeof(struct sockaddr_un);
+ }
+
+ return r;
+}
+
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+
+#undef NDEBUG
+
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <sys/ioc_net.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/un.h>
+
+#define DEBUG 0
+
+static ssize_t _uds_recvmsg_conn(int sock, struct msghdr *msg, int flags);
+static ssize_t _uds_recvmsg_dgram(int sock, struct msghdr *msg, int flags);
+
+ssize_t recvmsg(int sock, struct msghdr *msg, int flags)
+{
+ int r;
+ int uds_sotype;
+
+ if (msg == NULL) {
+ errno= EFAULT;
+ return -1;
+ }
+
+ r= ioctl(sock, NWIOGUDSSOTYPE, &uds_sotype);
+ if (r != -1 || (errno != ENOTTY && errno != EBADIOCTL)) {
+ if (r == -1) {
+ return r;
+ }
+
+ if (uds_sotype == SOCK_DGRAM) {
+ return _uds_recvmsg_dgram(sock, msg, flags);
+ } else {
+ return _uds_recvmsg_conn(sock, msg, flags);
+ }
+ }
+
+#if DEBUG
+ fprintf(stderr, "recvmsg: not implemented for fd %d\n", sock);
+#endif
+
+ errno= ENOSYS;
+ return -1;
+}
+
+static ssize_t _uds_recvmsg_conn(int sock, struct msghdr *msg, int flags)
+{
+ int r, rc;
+
+ if (flags != 0) {
+#if DEBUG
+ fprintf(stderr, "recvmsg(uds): flags not implemented\n");
+#endif
+ errno= ENOSYS;
+ return -1;
+ }
+
+ r= readv(sock, msg->msg_iov, msg->msg_iovlen);
+
+ if (r >= 0 && msg->msg_name && msg->msg_namelen > 0) {
+ getpeername(sock, msg->msg_name, &msg->msg_namelen);
+ }
+
+ /* get control data */
+ if (r >= 0 && msg->msg_control && msg->msg_controllen > 0) {
+ struct msg_control msg_ctrl;
+
+ memset(&msg_ctrl, '\0', sizeof(struct msg_control));
+ msg_ctrl.msg_controllen = msg->msg_controllen;
+ rc = ioctl(sock, NWIOGUDSCTRL, &msg_ctrl);
+ if (rc == -1) {
+ return rc;
+ }
+
+ if (msg_ctrl.msg_controllen <= msg->msg_controllen) {
+ memcpy(msg->msg_control, msg_ctrl.msg_control,
+ msg_ctrl.msg_controllen);
+ msg->msg_controllen = msg_ctrl.msg_controllen;
+ }
+ }
+
+ msg->msg_flags = 0;
+
+ return r;
+}
+
+static ssize_t _uds_recvmsg_dgram(int sock, struct msghdr *msg, int flags)
+{
+ int r, rc;
+
+ if (flags != 0) {
+#if DEBUG
+ fprintf(stderr, "recvmsg(uds): flags not implemented\n");
+#endif
+ errno= ENOSYS;
+ return -1;
+ }
+
+ r= readv(sock, msg->msg_iov, msg->msg_iovlen);
+
+ if (r >= 0 && msg->msg_name &&
+ msg->msg_namelen >= sizeof(struct sockaddr_un))
+ {
+ rc= ioctl(sock, NWIOGUDSFADDR, msg->msg_name);
+ if (rc == -1) {
+ return rc;
+ }
+ msg->msg_namelen= sizeof(struct sockaddr_un);
+ }
+
+ /* get control data */
+ if (r >= 0 && msg->msg_control && msg->msg_controllen > 0) {
+ struct msg_control msg_ctrl;
+
+ memset(&msg_ctrl, '\0', sizeof(struct msg_control));
+ msg_ctrl.msg_controllen = msg->msg_controllen;
+ rc = ioctl(sock, NWIOGUDSCTRL, &msg_ctrl);
+ if (rc == -1) {
+ return rc;
+ }
+
+ if (msg_ctrl.msg_controllen <= msg->msg_controllen) {
+ memcpy(msg->msg_control, msg_ctrl.msg_control,
+ msg_ctrl.msg_controllen);
+ msg->msg_controllen = msg_ctrl.msg_controllen;
+ }
+ }
+
+ msg->msg_flags = 0;
+
+ return r;
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include <lib.h>
+#include "namespace.h"
+
+#include <string.h>
+#include <stdio.h>
+
+int rename(name, name2)
+const char *name, *name2;
+{
+ message m;
+
+ m.m1_i1 = strlen(name) + 1;
+ m.m1_i2 = strlen(name2) + 1;
+ m.m1_p1 = (char *) name;
+ m.m1_p2 = (char *) name2;
+ return(_syscall(VFS_PROC_NR, RENAME, &m));
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include <lib.h>
+#include "namespace.h"
+
+#ifdef __weak_alias
+__weak_alias(rmdir, _rmdir)
+#endif
+
+#include <unistd.h>
+
+int rmdir(name)
+const char *name;
+{
+ message m;
+
+ _loadname(name, &m);
+ return(_syscall(VFS_PROC_NR, RMDIR, &m));
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+#include <unistd.h>
+
+#ifdef __weak_alias
+__weak_alias(sbrk, _sbrk)
+#endif
+
+extern char *_brksize;
+
+PUBLIC void *sbrk(incr)
+intptr_t incr;
+{
+ char *newsize, *oldsize;
+
+ oldsize = _brksize;
+ newsize = _brksize + incr;
+ if ((incr > 0 && newsize < oldsize) || (incr < 0 && newsize > oldsize))
+ return( (char *) -1);
+ if (brk(newsize) == 0)
+ return(oldsize);
+ else
+ return( (char *) -1);
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include <lib.h>
+#include "namespace.h"
+
+#include <sys/time.h>
+#include <sys/select.h>
+
+int select(int nfds,
+ fd_set *readfds, fd_set *writefds, fd_set *errorfds,
+ struct timeval *timeout)
+{
+ message m;
+
+ m.SEL_NFDS = nfds;
+ m.SEL_READFDS = (char *) readfds;
+ m.SEL_WRITEFDS = (char *) writefds;
+ m.SEL_ERRORFDS = (char *) errorfds;
+ m.SEL_TIMEOUT = (char *) timeout;
+
+ return (_syscall(VFS_PROC_NR, SELECT, &m));
+}
+
--- /dev/null
+#define __USE_MISC
+#define _SYSTEM 1
+#define _MINIX 1
+
+#include <sys/cdefs.h>
+#include <lib.h>
+#include "namespace.h"
+
+#include <lib.h>
+#include <minix/rs.h>
+
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/sem.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <errno.h>
+
+#ifdef __weak_alias
+__weak_alias(sem, _sem)
+#endif
+
+static int get_ipc_endpt(endpoint_t *pt)
+{
+ return minix_rs_lookup("ipc", pt);
+}
+
+/* Get semaphore. */
+int semget(key_t key, int nsems, int semflag)
+{
+ message m;
+ endpoint_t ipc_pt;
+ int r;
+
+ if (get_ipc_endpt(&ipc_pt) != OK) {
+ errno = ENOSYS;
+ return -1;
+ }
+
+ m.SEMGET_KEY = key;
+ m.SEMGET_NR = nsems;
+ m.SEMGET_FLAG = semflag;
+
+ r = _syscall(ipc_pt, IPC_SEMGET, &m);
+ if (r != OK)
+ return r;
+
+ return m.SEMGET_RETID;
+}
+
+/* Semaphore control operation. */
+int semctl(int semid, int semnum, int cmd, ...)
+{
+ message m;
+ endpoint_t ipc_pt;
+ va_list ap;
+ int r;
+
+ if (get_ipc_endpt(&ipc_pt) != OK) {
+ errno = ENOSYS;
+ return -1;
+ }
+
+ m.SEMCTL_ID = semid;
+ m.SEMCTL_NUM = semnum;
+ m.SEMCTL_CMD = cmd;
+ va_start(ap, cmd);
+ if (cmd == IPC_STAT || cmd == IPC_SET || cmd == IPC_INFO ||
+ cmd == SEM_INFO || cmd == SEM_STAT || cmd == GETALL ||
+ cmd == SETALL || cmd == SETVAL)
+ m.SEMCTL_OPT = (long) va_arg(ap, long);
+ va_end(ap);
+
+ r = _syscall(ipc_pt, IPC_SEMCTL, &m);
+ if ((r != -1) && (cmd == GETNCNT || cmd == GETZCNT || cmd == GETPID ||
+ cmd == GETVAL || cmd == IPC_INFO || cmd == SEM_INFO ||
+ cmd == SEM_STAT))
+ return m.SHMCTL_RET;
+ return r;
+}
+
+/* Operate on semaphore. */
+int semop(int semid, struct sembuf *sops, size_t nsops)
+{
+ message m;
+ endpoint_t ipc_pt;
+
+ if (get_ipc_endpt(&ipc_pt) != OK) {
+ errno = ENOSYS;
+ return -1;
+ }
+
+ m.SEMOP_ID = semid;
+ m.SEMOP_OPS = (long) sops;
+ m.SEMOP_SIZE = nsops;
+
+ return _syscall(ipc_pt, IPC_SEMOP, &m);
+}
+
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+
+#undef NDEBUG
+
+#include <errno.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <sys/ioc_net.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/un.h>
+
+#define DEBUG 0
+
+static ssize_t _uds_sendmsg_conn(int sock, const struct msghdr *msg,
+ int flags);
+static ssize_t _uds_sendmsg_dgram(int sock, const struct msghdr *msg,
+ int flags);
+
+ssize_t sendmsg(int sock, const struct msghdr *msg, int flags)
+{
+ int r;
+ int uds_sotype;
+
+ if (msg == NULL) {
+ errno= EFAULT;
+ return -1;
+ }
+
+ r= ioctl(sock, NWIOGUDSSOTYPE, &uds_sotype);
+ if (r != -1 || (errno != ENOTTY && errno != EBADIOCTL)) {
+ if (r == -1) {
+ return r;
+ }
+
+ if (uds_sotype == SOCK_DGRAM) {
+ return _uds_sendmsg_dgram(sock, msg, flags);
+ } else {
+ return _uds_sendmsg_conn(sock, msg, flags);
+ }
+
+ }
+
+#if DEBUG
+ fprintf(stderr, "sendmsg: not implemented for fd %d\n", sock);
+#endif
+
+ errno= ENOSYS;
+ return -1;
+}
+
+static ssize_t _uds_sendmsg_conn(int sock, const struct msghdr *msg,
+ int flags)
+{
+ struct msg_control msg_ctrl;
+ int r;
+
+ if (flags != 0) {
+#if DEBUG
+ fprintf(stderr, "sendmsg(uds): flags not implemented\n");
+#endif
+ errno= ENOSYS;
+ return -1;
+
+ }
+
+ /* grab the control data */
+ memset(&msg_ctrl, '\0', sizeof(struct msg_control));
+ if (msg->msg_controllen > MSG_CONTROL_MAX) {
+ errno = ENOMEM;
+ return -1;
+ } else if (msg->msg_controllen > 0) {
+ memcpy(&msg_ctrl.msg_control, msg->msg_control,
+ msg->msg_controllen);
+ }
+ msg_ctrl.msg_controllen = msg->msg_controllen;
+
+ /* send the control data to PFS */
+ r= ioctl(sock, NWIOSUDSCTRL, (void *) &msg_ctrl);
+ if (r == -1) {
+ return r;
+ }
+
+ /* Silently ignore destination, if given. */
+
+ return writev(sock, msg->msg_iov, msg->msg_iovlen);
+}
+
+static ssize_t _uds_sendmsg_dgram(int sock, const struct msghdr *msg,
+ int flags)
+{
+ struct msg_control msg_ctrl;
+ struct sockaddr_un *dest_addr;
+ int i, r;
+
+ if (flags != 0) {
+#if DEBUG
+ fprintf(stderr, "sendmsg(uds): flags not implemented\n");
+#endif
+ errno= ENOSYS;
+ return -1;
+
+ }
+
+ dest_addr = msg->msg_name;
+ if (dest_addr == NULL) {
+ errno= EFAULT;
+ return -1;
+ }
+
+ /* set the target address */
+ r= ioctl(sock, NWIOSUDSTADDR, (void *) dest_addr);
+ if (r == -1) {
+ return r;
+ }
+
+ /* grab the control data */
+ memset(&msg_ctrl, '\0', sizeof(struct msg_control));
+ if (msg->msg_controllen > MSG_CONTROL_MAX) {
+ errno = ENOMEM;
+ return -1;
+ } else if (msg->msg_controllen > 0) {
+ memcpy(&msg_ctrl.msg_control, msg->msg_control,
+ msg->msg_controllen);
+ }
+ msg_ctrl.msg_controllen = msg->msg_controllen;
+
+ /* send the control data to PFS */
+ r= ioctl(sock, NWIOSUDSCTRL, (void *) &msg_ctrl);
+ if (r == -1) {
+ return r;
+ }
+
+ /* do the send */
+ return writev(sock, msg->msg_iov, msg->msg_iovlen);
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+
+#undef NDEBUG
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+#include <net/gen/in.h>
+#include <net/gen/tcp.h>
+#include <net/gen/tcp_io.h>
+#include <net/gen/udp.h>
+#include <net/gen/udp_hdr.h>
+#include <net/gen/udp_io.h>
+
+#define DEBUG 0
+
+static ssize_t _tcp_sendto(int sock, const void *message, size_t length,
+ int flags, const struct sockaddr *dest_addr, socklen_t dest_len);
+static ssize_t _udp_sendto(int sock, const void *message, size_t length,
+ int flags, const struct sockaddr *dest_addr, socklen_t dest_len,
+ nwio_udpopt_t *udpoptp);
+static ssize_t _uds_sendto_conn(int sock, const void *message, size_t length,
+ int flags, const struct sockaddr *dest_addr, socklen_t dest_len);
+static ssize_t _uds_sendto_dgram(int sock, const void *message, size_t length,
+ int flags, const struct sockaddr *dest_addr, socklen_t dest_len);
+
+ssize_t sendto(int sock, const void *message, size_t length, int flags,
+ const struct sockaddr *dest_addr, socklen_t dest_len)
+{
+ int r;
+ nwio_tcpopt_t tcpopt;
+ nwio_udpopt_t udpopt;
+ struct sockaddr_un uds_addr;
+ int uds_sotype = -1;
+
+ r= ioctl(sock, NWIOGTCPOPT, &tcpopt);
+ if (r != -1 || (errno != ENOTTY && errno != EBADIOCTL))
+ {
+ if (r == -1)
+ return r;
+ return _tcp_sendto(sock, message, length, flags,
+ dest_addr, dest_len);
+ }
+
+ r= ioctl(sock, NWIOGUDPOPT, &udpopt);
+ if (r != -1 || (errno != ENOTTY && errno != EBADIOCTL))
+ {
+ if (r == -1)
+ return r;
+ return _udp_sendto(sock, message, length, flags,
+ dest_addr, dest_len, &udpopt);
+ }
+
+ r= ioctl(sock, NWIOGUDSSOTYPE, &uds_sotype);
+ if (r != -1 || (errno != ENOTTY && errno != EBADIOCTL))
+ {
+ if (r == -1) {
+ return r;
+ }
+
+ if (uds_sotype == SOCK_DGRAM) {
+
+ return _uds_sendto_dgram(sock, message,
+ length, flags,dest_addr, dest_len);
+ } else {
+
+ return _uds_sendto_conn(sock, message,
+ length, flags, dest_addr, dest_len);
+ }
+ }
+
+#if DEBUG
+ fprintf(stderr, "sendto: not implemented for fd %d\n", sock);
+#endif
+ errno= ENOSYS;
+ return -1;
+}
+
+static ssize_t _tcp_sendto(int sock, const void *message, size_t length,
+ int flags, const struct sockaddr *dest_addr, socklen_t dest_len)
+{
+
+ if (flags != 0) {
+#if DEBUG
+ fprintf(stderr, "sendto(tcp): flags not implemented\n");
+#endif
+ errno= ENOSYS;
+ return -1;
+ }
+
+ /* Silently ignore destination, if given. */
+
+ return write(sock, message, length);
+}
+
+static ssize_t _udp_sendto(int sock, const void *message, size_t length,
+ int flags, const struct sockaddr *dest_addr, socklen_t dest_len,
+ nwio_udpopt_t *udpoptp)
+{
+ int r, t_errno;
+ size_t buflen;
+ void *buf;
+ struct sockaddr_in *sinp;
+ udp_io_hdr_t *io_hdrp;
+
+ if (flags)
+ {
+#if DEBUG
+ fprintf(stderr, "sendto(udp): flags not implemented\n");
+#endif
+ errno= ENOSYS;
+ return -1;
+ }
+
+ if (udpoptp->nwuo_flags & NWUO_RWDATONLY)
+ return write(sock, message, length);
+
+ if ((udpoptp->nwuo_flags & NWUO_RP_ANY) ||
+ (udpoptp->nwuo_flags & NWUO_RA_ANY))
+ {
+ if (!dest_addr)
+ {
+ errno= ENOTCONN;
+ return -1;
+ }
+
+ /* Check destination address */
+ if (dest_len < sizeof(*sinp))
+ {
+ errno= EINVAL;
+ return -1;
+ }
+ sinp= (struct sockaddr_in *)dest_addr;
+ if (sinp->sin_family != AF_INET)
+ {
+ errno= EAFNOSUPPORT;
+ return -1;
+ }
+ }
+
+ buflen= sizeof(*io_hdrp) + length;
+ if (buflen < length)
+ {
+ /* Overflow */
+ errno= EMSGSIZE;
+ return -1;
+ }
+ buf= malloc(buflen);
+ if (buf == NULL)
+ return -1;
+
+ io_hdrp= buf;
+ io_hdrp->uih_src_addr= 0; /* Unused */
+ io_hdrp->uih_src_port= 0; /* Will cause error if NWUO_LP_ANY */
+ if (udpoptp->nwuo_flags & NWUO_RA_ANY)
+ io_hdrp->uih_dst_addr= sinp->sin_addr.s_addr;
+ else
+ io_hdrp->uih_dst_addr= 0;
+ if (udpoptp->nwuo_flags & NWUO_RP_ANY)
+ io_hdrp->uih_dst_port= sinp->sin_port;
+ else
+ io_hdrp->uih_dst_port= 0;
+ io_hdrp->uih_ip_opt_len= 0;
+ io_hdrp->uih_data_len= 0;
+
+ memcpy(&io_hdrp[1], message, length);
+ r= write(sock, buf, buflen);
+ if (r == -1)
+ {
+ t_errno= errno;
+ free(buf);
+ errno= t_errno;
+ return -1;
+ }
+ assert(r == buflen);
+ free(buf);
+ return length;
+}
+
+static ssize_t _uds_sendto_conn(int sock, const void *message, size_t length,
+ int flags, const struct sockaddr *dest_addr, socklen_t dest_len)
+{
+
+ /* for connection oriented unix domain sockets (SOCK_STREAM /
+ * SOCK_SEQPACKET)
+ */
+
+ if (flags != 0) {
+#if DEBUG
+ fprintf(stderr, "sendto(uds): flags not implemented\n");
+#endif
+ errno= ENOSYS;
+ return -1;
+ }
+
+ /* Silently ignore destination, if given. */
+
+ return write(sock, message, length);
+}
+
+static ssize_t _uds_sendto_dgram(int sock, const void *message, size_t length,
+ int flags, const struct sockaddr *dest_addr, socklen_t dest_len)
+{
+ int r;
+
+ /* for connectionless unix domain sockets (SOCK_DGRAM) */
+
+ if (flags != 0) {
+#if DEBUG
+ fprintf(stderr, "sendto(uds): flags not implemented\n");
+#endif
+ errno= ENOSYS;
+ return -1;
+ }
+
+ if (dest_addr == NULL) {
+ errno = EFAULT;
+ return -1;
+ }
+
+ /* set the target address */
+ r= ioctl(sock, NWIOSUDSTADDR, (void *) dest_addr);
+ if (r == -1) {
+ return r;
+ }
+
+ /* do the send */
+ return write(sock, message, length);
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include <lib.h>
+#include "namespace.h"
+
+#ifdef __weak_alias
+__weak_alias(setgid, _setgid)
+__weak_alias(setegid, _setegid)
+#endif
+
+#include <unistd.h>
+
+int setgid(gid_t grp)
+{
+ message m;
+
+ m.m1_i1 = (int) grp;
+ return(_syscall(PM_PROC_NR, SETGID, &m));
+}
+
+int setegid(gid_t grp)
+{
+ message m;
+
+ m.m1_i1 = (int) grp;
+ return(_syscall(PM_PROC_NR, SETEGID, &m));
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include <lib.h>
+#include "namespace.h"
+
+#ifdef __weak_alias
+__weak_alias(setgroups, _setgroups)
+#endif
+
+#include <unistd.h>
+
+int setgroups(int ngroups, const gid_t *gidset)
+{
+ message m;
+
+ m.m1_p1 = (char *) gidset;
+ m.m1_i1 = ngroups;
+
+ return(_syscall(PM_PROC_NR, SETGROUPS, &m));
+}
+
+
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+#include <sys/time.h>
+
+/*
+ * This is the implementation of the function to
+ * invoke the interval timer setting system call.
+ */
+int setitimer(int which, const struct itimerval *_RESTRICT value,
+ struct itimerval *_RESTRICT ovalue)
+{
+ message m;
+
+ /* A null pointer for 'value' would make setitimer behave like getitimer,
+ * which is not according to the specification, so disallow null pointers.
+ */
+ if (value == NULL) return(EINVAL);
+
+ m.m1_i1 = which;
+ m.m1_p1 = (char *) value;
+ m.m1_p2 = (char *) ovalue;
+
+ return _syscall(PM_PROC_NR, ITIMER, &m);
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include <lib.h>
+#include "namespace.h"
+
+#include <unistd.h>
+
+#ifdef __weak_alias
+__weak_alias(setsid, _setsid)
+#endif
+
+pid_t setsid()
+{
+ message m;
+
+ return(_syscall(PM_PROC_NR, SETSID, &m));
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netinet/tcp.h>
+
+#include <net/gen/in.h>
+#include <net/gen/tcp.h>
+#include <net/gen/tcp_io.h>
+#include <net/gen/udp.h>
+#include <net/gen/udp_io.h>
+
+#define DEBUG 0
+
+static int _tcp_setsockopt(int sock, int level, int option_name,
+ const void *option_value, socklen_t option_len);
+
+static int _udp_setsockopt(int sock, int level, int option_name,
+ const void *option_value, socklen_t option_len);
+
+static int _uds_setsockopt(int sock, int level, int option_name,
+ const void *option_value, socklen_t option_len);
+
+int setsockopt(int sock, int level, int option_name,
+ const void *option_value, socklen_t option_len)
+{
+ int r;
+ nwio_tcpopt_t tcpopt;
+ nwio_udpopt_t udpopt;
+ struct sockaddr_un uds_addr;
+
+ r= ioctl(sock, NWIOGTCPOPT, &tcpopt);
+ if (r != -1 || (errno != ENOTTY && errno != EBADIOCTL))
+ {
+ if (r == -1)
+ {
+ /* Bad file descriptor */
+ return -1;
+ }
+ return _tcp_setsockopt(sock, level, option_name,
+ option_value, option_len);
+ }
+
+ r= ioctl(sock, NWIOGUDPOPT, &udpopt);
+ if (r != -1 || (errno != ENOTTY && errno != EBADIOCTL))
+ {
+ if (r == -1)
+ {
+ /* Bad file descriptor */
+ return -1;
+ }
+ return _udp_setsockopt(sock, level, option_name,
+ option_value, option_len);
+ }
+
+ r= ioctl(sock, NWIOGUDSADDR, &uds_addr);
+ if (r != -1 || (errno != ENOTTY && errno != EBADIOCTL))
+ {
+ if (r == -1)
+ {
+ /* Bad file descriptor */
+ return -1;
+ }
+ return _uds_setsockopt(sock, level, option_name,
+ option_value, option_len);
+ }
+
+
+#if DEBUG
+ fprintf(stderr, "setsockopt: not implemented for fd %d\n", sock);
+#endif
+ errno= ENOTSOCK;
+ return -1;
+}
+
+static int _tcp_setsockopt(int sock, int level, int option_name,
+ const void *option_value, socklen_t option_len)
+{
+ int i;
+
+ if (level == SOL_SOCKET && option_name == SO_REUSEADDR)
+ {
+ if (option_len != sizeof(i))
+ {
+ errno= EINVAL;
+ return -1;
+ }
+ i= *(int *)option_value;
+ if (!i)
+ {
+ /* At the moment there is no way to turn off
+ * reusing addresses.
+ */
+ errno= ENOSYS;
+ return -1;
+ }
+ return 0;
+ }
+ if (level == SOL_SOCKET && option_name == SO_KEEPALIVE)
+ {
+ if (option_len != sizeof(i))
+ {
+ errno= EINVAL;
+ return -1;
+ }
+ i= *(int *)option_value;
+ if (!i)
+ {
+ /* At the moment there is no way to turn off
+ * keepalives.
+ */
+ errno= ENOSYS;
+ return -1;
+ }
+ return 0;
+ }
+ if (level == SOL_SOCKET && option_name == SO_RCVBUF)
+ {
+ if (option_len != sizeof(i))
+ {
+ errno= EINVAL;
+ return -1;
+ }
+ i= *(int *)option_value;
+ if (i > 32*1024)
+ {
+ /* The receive buffer is limited to 32K at the moment.
+ */
+ errno= ENOSYS;
+ return -1;
+ }
+ /* There is no way to reduce the receive buffer, do we have to
+ * let this call fail for smaller buffers?
+ */
+ return 0;
+ }
+ if (level == SOL_SOCKET && option_name == SO_SNDBUF)
+ {
+ if (option_len != sizeof(i))
+ {
+ errno= EINVAL;
+ return -1;
+ }
+ i= *(int *)option_value;
+ if (i > 32*1024)
+ {
+ /* The send buffer is limited to 32K at the moment.
+ */
+ errno= ENOSYS;
+ return -1;
+ }
+ /* There is no way to reduce the send buffer, do we have to
+ * let this call fail for smaller buffers?
+ */
+ return 0;
+ }
+ if (level == IPPROTO_TCP && option_name == TCP_NODELAY)
+ {
+ if (option_len != sizeof(i))
+ {
+ errno= EINVAL;
+ return -1;
+ }
+ i= *(int *)option_value;
+ if (i)
+ {
+ /* At the moment there is no way to turn on
+ * nodelay.
+ */
+ errno= ENOSYS;
+ return -1;
+ }
+ return 0;
+ }
+#if DEBUG
+ fprintf(stderr, "_tcp_setsocketopt: level %d, name %d\n",
+ level, option_name);
+#endif
+
+ errno= ENOSYS;
+ return -1;
+}
+
+static int _udp_setsockopt(int sock, int level, int option_name,
+ const void *option_value, socklen_t option_len)
+{
+#if DEBUG
+ fprintf(stderr, "_udp_setsocketopt: level %d, name %d\n",
+ level, option_name);
+#endif
+
+ errno= ENOSYS;
+ return -1;
+}
+
+
+static int _uds_setsockopt(int sock, int level, int option_name,
+ const void *option_value, socklen_t option_len)
+{
+ int i;
+ size_t size;
+
+ if (level == SOL_SOCKET && option_name == SO_RCVBUF)
+ {
+ if (option_len != sizeof(size))
+ {
+ errno= EINVAL;
+ return -1;
+ }
+ size= *(size_t *)option_value;
+ return ioctl(sock, NWIOSUDSRCVBUF, &size);
+ }
+
+ if (level == SOL_SOCKET && option_name == SO_SNDBUF)
+ {
+ if (option_len != sizeof(size))
+ {
+ errno= EINVAL;
+ return -1;
+ }
+ size= *(size_t *)option_value;
+ return ioctl(sock, NWIOSUDSSNDBUF, &size);
+ }
+
+ if (level == SOL_SOCKET && option_name == SO_REUSEADDR)
+ {
+ if (option_len != sizeof(i))
+ {
+ errno= EINVAL;
+ return -1;
+ }
+ i= *(int *)option_value;
+ if (!i)
+ {
+ /* At the moment there is no way to turn off
+ * reusing addresses.
+ */
+ errno= ENOSYS;
+ return -1;
+ }
+ return 0;
+ }
+
+ if (level == SOL_SOCKET && option_name == SO_PASSCRED)
+ {
+ if (option_len != sizeof(i))
+ {
+ errno= EINVAL;
+ return -1;
+ }
+ i= *(int *)option_value;
+ if (!i)
+ {
+ /* credentials can always be received. */
+ errno= ENOSYS;
+ return -1;
+ }
+ return 0;
+ }
+
+#if DEBUG
+ fprintf(stderr, "_uds_setsocketopt: level %d, name %d\n",
+ level, option_name);
+#endif
+
+ errno= ENOSYS;
+ return -1;
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include <lib.h>
+#include "namespace.h"
+
+#include <sys/time.h>
+#include <time.h>
+
+int settimeofday(const struct timeval *tp, const void *tzp)
+{
+ /* Use intermediate variable because stime param is not const */
+ time_t sec = tp->tv_sec;
+
+ /* Ignore time zones */
+ return stime(&sec);
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include <lib.h>
+#include "namespace.h"
+
+#include <unistd.h>
+
+#ifdef __weak_alias
+__weak_alias(setuid, _setuid)
+__weak_alias(seteuid, _seteuid)
+#endif
+
+int setuid(uid_t usr)
+{
+ message m;
+
+ m.m1_i1 = usr;
+ return(_syscall(PM_PROC_NR, SETUID, &m));
+}
+
+int seteuid(uid_t usr)
+{
+ message m;
+
+ m.m1_i1 = usr;
+ return(_syscall(PM_PROC_NR, SETEUID, &m));
+}
--- /dev/null
+#define _SYSTEM 1
+#define _MINIX 1
+
+#include <sys/cdefs.h>
+#include <lib.h>
+#include "namespace.h"
+
+#include <minix/rs.h>
+
+#include <lib.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#ifdef __weak_alias
+__weak_alias(shmat, _shmat)
+__weak_alias(shmdt, _shmdt)
+#endif
+
+
+static int get_ipc_endpt(endpoint_t *pt)
+{
+ return minix_rs_lookup("ipc", pt);
+}
+
+/* Attach shared memory segment. */
+void *shmat(int shmid, const void *shmaddr, int shmflg)
+{
+ message m;
+ endpoint_t ipc_pt;
+ int r;
+
+ if (get_ipc_endpt(&ipc_pt) != OK) {
+ errno = ENOSYS;
+ return NULL;
+ }
+
+ m.SHMAT_ID = shmid;
+ m.SHMAT_ADDR = (long) shmaddr;
+ m.SHMAT_FLAG = shmflg;
+
+ r = _syscall(ipc_pt, IPC_SHMAT, &m);
+ if (r != OK)
+ return (void *) -1;
+ return (void *) m.SHMAT_RETADDR;
+}
+
+/* Deattach shared memory segment. */
+int shmdt(const void *shmaddr)
+{
+ message m;
+ endpoint_t ipc_pt;
+
+ if (get_ipc_endpt(&ipc_pt) != OK) {
+ errno = ENOSYS;
+ return -1;
+ }
+
+ m.SHMDT_ADDR = (long) shmaddr;
+
+ return _syscall(ipc_pt, IPC_SHMDT, &m);
+}
+
--- /dev/null
+#define _SYSTEM 1
+#define _MINIX 1
+
+#include <sys/cdefs.h>
+#include <lib.h>
+#include "namespace.h"
+
+#include <minix/rs.h>
+#include <lib.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <stdlib.h>
+#include <errno.h>
+
+static int get_ipc_endpt(endpoint_t *pt)
+{
+ return minix_rs_lookup("ipc", pt);
+}
+
+/* Shared memory control operation. */
+int shmctl(int shmid, int cmd, struct shmid_ds *buf)
+{
+ message m;
+ endpoint_t ipc_pt;
+ int r;
+
+ if (get_ipc_endpt(&ipc_pt) != OK) {
+ errno = ENOSYS;
+ return -1;
+ }
+
+ m.SHMCTL_ID = shmid;
+ m.SHMCTL_CMD = cmd;
+ m.SHMCTL_BUF = (long) buf;
+
+ r = _syscall(ipc_pt, IPC_SHMCTL, &m);
+ if ((cmd == IPC_INFO || cmd == SHM_INFO || cmd == SHM_STAT)
+ && (r == OK))
+ return m.SHMCTL_RET;
+ return r;
+}
--- /dev/null
+#define _SYSTEM 1
+#define _MINIX 1
+#include <sys/cdefs.h>
+#include <lib.h>
+#include "namespace.h"
+
+#include <minix/rs.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <stdlib.h>
+#include <errno.h>
+
+
+#ifdef __weak_alias
+__weak_alias(shmget, _shmget)
+#endif
+
+static int get_ipc_endpt(endpoint_t *pt)
+{
+ return minix_rs_lookup("ipc", pt);
+}
+
+/* Get shared memory segment. */
+int shmget(key_t key, size_t size, int shmflg)
+{
+ message m;
+ endpoint_t ipc_pt;
+ int r;
+
+ if (get_ipc_endpt(&ipc_pt) != OK) {
+ errno = ENOSYS;
+ return -1;
+ }
+
+ m.SHMGET_KEY = key;
+ m.SHMGET_SIZE = size;
+ m.SHMGET_FLAG = shmflg;
+
+ r = _syscall(ipc_pt, IPC_SHMGET, &m);
+ if (r != OK)
+ return r;
+ return m.SHMGET_RETID;
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+
+#include <errno.h>
+#include <stdio.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#include <net/gen/in.h>
+#include <net/gen/tcp.h>
+#include <net/gen/tcp_io.h>
+
+#ifdef __weak_alias
+__weak_alias(shutdown, _shutdown)
+#endif
+
+#define DEBUG 0
+
+static int _tcp_shutdown(int sock, int how);
+static int _uds_shutdown(int sock, int how);
+
+int shutdown(int sock, int how)
+{
+ int r;
+ struct sockaddr_un uds_addr;
+ nwio_tcpconf_t tcpconf;
+
+ r= ioctl(sock, NWIOGTCPCONF, &tcpconf);
+ if (r != -1 || (errno != ENOTTY && errno != EBADIOCTL))
+ {
+ if (r == -1)
+ {
+ /* Bad file descriptor */
+ return -1;
+ }
+ return _tcp_shutdown(sock, how);
+ }
+
+ r= ioctl(sock, NWIOGUDSADDR, &uds_addr);
+ if (r != -1 || (errno != ENOTTY && errno != EBADIOCTL))
+ {
+ if (r == -1)
+ {
+ /* Bad file descriptor */
+ return -1;
+ }
+ return _uds_shutdown(sock, how);
+ }
+
+#if DEBUG
+ fprintf(stderr, "shutdown: not implemented for fd %d\n", sock);
+#endif
+ errno= ENOSYS;
+ return -1;
+}
+
+static int _tcp_shutdown(int sock, int how)
+{
+ int r;
+
+ if (how == SHUT_WR || how == SHUT_RDWR)
+ {
+ r= ioctl(sock, NWIOTCPSHUTDOWN, NULL);
+ if (r == -1)
+ return -1;
+ if (how == SHUT_WR)
+ return 0;
+ }
+
+ /* We can't shutdown the read side of the socket. */
+ errno= ENOSYS;
+ return -1;
+}
+
+static int _uds_shutdown(int sock, int how)
+{
+ return ioctl(sock, NWIOSUDSSHUT, &how);
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include <lib.h>
+#include "namespace.h"
+
+#include <signal.h>
+
+int __sigreturn(void);
+
+int sigaction(sig, act, oact)
+int sig;
+const struct sigaction *act;
+struct sigaction *oact;
+{
+ message m;
+
+ m.m1_i2 = sig;
+
+ /* XXX - yet more type puns because message struct is short of types. */
+ m.m1_p1 = (char *) act;
+ m.m1_p2 = (char *) oact;
+ m.m1_p3 = (char *) __sigreturn;
+
+ return(_syscall(PM_PROC_NR, SIGACTION, &m));
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include <lib.h>
+#include "namespace.h"
+
+#include <signal.h>
+
+int sigpending(set)
+sigset_t *set;
+{
+ message m;
+
+ if (_syscall(PM_PROC_NR, SIGPENDING, &m) < 0) return(-1);
+ *set = (sigset_t) m.m2_l1;
+ return(m.m_type);
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include <lib.h>
+#include "namespace.h"
+
+#include <signal.h>
+
+int sigprocmask(how, set, oset)
+int how;
+const sigset_t *set;
+sigset_t *oset;
+{
+ message m;
+
+ if (set == (sigset_t *) NULL) {
+ m.m2_i1 = SIG_INQUIRE;
+ m.m2_l1 = 0;
+ } else {
+ m.m2_i1 = how;
+ m.m2_l1 = (long) *set;
+ }
+ if (_syscall(PM_PROC_NR, SIGPROCMASK, &m) < 0) return(-1);
+ if (oset != (sigset_t *) NULL) *oset = (sigset_t) (m.m2_l1);
+ return(m.m_type);
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include <lib.h>
+#include "namespace.h"
+
+#include <signal.h>
+#include <sys/signal.h>
+
+#ifdef __weak_alias
+__weak_alias(sigreturn, _sigreturn)
+#endif
+
+int sigreturn(scp)
+register struct sigcontext *scp;
+{
+ sigset_t set;
+
+ /* The message can't be on the stack, because the stack will vanish out
+ * from under us. The send part of sendrec will succeed, but when
+ * a message is sent to restart the current process, who knows what will
+ * be in the place formerly occupied by the message?
+ */
+ static message m;
+
+ /* Protect against race conditions by blocking all interrupts. */
+ sigfillset(&set); /* splhi */
+ sigprocmask(SIG_SETMASK, &set, (sigset_t *) NULL);
+
+ m.m2_l1 = scp->sc_mask;
+ m.m2_i2 = scp->sc_flags;
+ m.m2_p1 = (char *) scp;
+ return(_syscall(PM_PROC_NR, SIGRETURN, &m)); /* normally this doesn't return */
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include <lib.h>
+#include "namespace.h"
+
+#include <signal.h>
+
+int sigsuspend(set)
+const sigset_t *set;
+{
+ message m;
+
+ m.m2_l1 = (long) *set;
+ return(_syscall(PM_PROC_NR, SIGSUSPEND, &m));
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+
+#ifdef __weak_alias
+__weak_alias(socket, _socket)
+#endif
+
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <sys/ioc_net.h>
+
+#include <net/netlib.h>
+#include <netinet/in.h>
+
+#define DEBUG 0
+
+static int _tcp_socket(int protocol);
+static int _udp_socket(int protocol);
+static int _uds_socket(int type, int protocol);
+
+int socket(int domain, int type, int protocol)
+{
+#if DEBUG
+ fprintf(stderr, "socket: domain %d, type %d, protocol %d\n",
+ domain, type, protocol);
+#endif
+ if (domain != AF_INET && domain != AF_UNIX)
+ {
+#if DEBUG
+ fprintf(stderr, "socket: bad domain %d\n", domain);
+#endif
+ errno= EAFNOSUPPORT;
+ return -1;
+ }
+
+ if (domain == AF_UNIX && (type == SOCK_STREAM ||
+ type == SOCK_DGRAM || type == SOCK_SEQPACKET))
+ return _uds_socket(type, protocol);
+
+ if (domain == AF_INET && type == SOCK_STREAM)
+ return _tcp_socket(protocol);
+
+ if (domain == AF_INET && type == SOCK_DGRAM)
+ return _udp_socket(protocol);
+
+#if DEBUG
+ fprintf(stderr, "socket: nothing for domain %d, type %d, protocol %d\n",
+ domain, type, protocol);
+#endif
+ errno= EPROTOTYPE;
+ return -1;
+}
+
+static int _tcp_socket(int protocol)
+{
+ int fd;
+ if (protocol != 0 && protocol != IPPROTO_TCP)
+ {
+#if DEBUG
+ fprintf(stderr, "socket(tcp): bad protocol %d\n", protocol);
+#endif
+ errno= EPROTONOSUPPORT;
+ return -1;
+ }
+ fd= open(TCP_DEVICE, O_RDWR);
+ return fd;
+}
+
+static int _udp_socket(int protocol)
+{
+ int r, fd, t_errno;
+ struct sockaddr_in sin;
+
+ if (protocol != 0 && protocol != IPPROTO_UDP)
+ {
+#if DEBUG
+ fprintf(stderr, "socket(udp): bad protocol %d\n", protocol);
+#endif
+ errno= EPROTONOSUPPORT;
+ return -1;
+ }
+ fd= open(UDP_DEVICE, O_RDWR);
+ if (fd == -1)
+ return fd;
+
+ /* Bind is implict for UDP sockets? */
+ sin.sin_family= AF_INET;
+ sin.sin_addr.s_addr= INADDR_ANY;
+ sin.sin_port= 0;
+ r= bind(fd, (struct sockaddr *)&sin, sizeof(sin));
+ if (r != 0)
+ {
+ t_errno= errno;
+ close(fd);
+ errno= t_errno;
+ return -1;
+ }
+ return fd;
+}
+
+static int _uds_socket(int type, int protocol)
+{
+ int fd, r;
+ if (protocol != 0)
+ {
+#if DEBUG
+ fprintf(stderr, "socket(uds): bad protocol %d\n", protocol);
+#endif
+ errno= EPROTONOSUPPORT;
+ return -1;
+ }
+
+ fd= open(UDS_DEVICE, O_RDWR);
+ if (fd == -1) {
+ return fd;
+ }
+
+ /* set the type for the socket via ioctl (SOCK_DGRAM,
+ * SOCK_STREAM, SOCK_SEQPACKET, etc)
+ */
+ r= ioctl(fd, NWIOSUDSTYPE, &type);
+ if (r == -1) {
+ int ioctl_errno;
+
+ /* if that failed rollback socket creation */
+ ioctl_errno= errno;
+ close(fd);
+
+ /* return the error thrown by the call to ioctl */
+ errno= ioctl_errno;
+ return -1;
+ }
+
+ return fd;
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+
+#include <errno.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <net/netlib.h>
+#include <sys/ioc_net.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/un.h>
+
+#ifdef __weak_alias
+__weak_alias(socketpair, _socketpair)
+#endif
+
+#define DEBUG 0
+
+static int _uds_socketpair(int type, int protocol, int sv[2]);
+
+/*
+ * Create a pair of connected sockets
+ */
+int socketpair(int domain, int type, int protocol, int sv[2]) {
+
+#if DEBUG
+ fprintf(stderr, "socketpair: domain %d, type %d, protocol %d\n",
+ domain, type, protocol);
+#endif
+
+ if (domain != AF_UNIX)
+ {
+ errno = EAFNOSUPPORT;
+ return -1;
+ }
+
+ if (domain == AF_UNIX &&
+ (type == SOCK_STREAM || type == SOCK_SEQPACKET))
+ return _uds_socketpair(type, protocol, sv);
+
+#if DEBUG
+ fprintf(stderr,
+ "socketpair: nothing for domain %d, type %d, protocol %d\n",
+ domain, type, protocol);
+#endif
+
+ errno= EPROTOTYPE;
+ return -1;
+}
+
+static int _uds_socketpair(int type, int protocol, int sv[2])
+{
+ dev_t dev;
+ int r, i;
+ struct stat sbuf;
+
+ if (protocol != 0)
+ {
+#if DEBUG
+ fprintf(stderr, "socketpair(uds): bad protocol %d\n", protocol);
+#endif
+ errno= EPROTONOSUPPORT;
+ return -1;
+ }
+
+ /* in this 'for' loop two unconnected sockets are created */
+ for (i = 0; i < 2; i++) {
+ sv[i]= open(UDS_DEVICE, O_RDWR);
+ if (sv[i] == -1) {
+ int open_errno = errno;
+
+ if (i == 1) {
+ /* if we failed to open() the 2nd
+ * socket, we need to close the 1st
+ */
+ close(sv[0]);
+ errno = open_errno;
+ }
+
+ return -1;
+ }
+
+ /* set the type for the socket via ioctl
+ * (SOCK_STREAM, SOCK_SEQPACKET, etc)
+ */
+ r= ioctl(sv[i], NWIOSUDSTYPE, &type);
+ if (r == -1) {
+ int ioctl_errno;
+
+ /* if that failed rollback socket creation */
+ ioctl_errno= errno;
+ close(sv[i]);
+
+ if (i == 1) {
+ /* if we just closed the 2nd socket, we
+ * need to close the 1st
+ */
+ close(sv[0]);
+ }
+
+ /* return the error thrown by the call to ioctl */
+ errno= ioctl_errno;
+ return -1;
+ }
+ }
+
+ r= fstat(sv[1], &sbuf);
+ if (r == -1) {
+ int fstat_errno;
+
+ /* if that failed rollback socket creation */
+ fstat_errno= errno;
+
+ close(sv[0]);
+ close(sv[1]);
+
+ /* return the error thrown by the call to fstat */
+ errno= fstat_errno;
+ return -1;
+ }
+
+ dev = sbuf.st_dev;
+
+ /* connect the sockets sv[0] and sv[1] */
+ r= ioctl(sv[0], NWIOSUDSPAIR, &dev);
+ if (r == -1) {
+ int ioctl_errno;
+
+ /* if that failed rollback socket creation */
+ ioctl_errno= errno;
+
+ close(sv[0]);
+ close(sv[1]);
+
+ /* return the error thrown by the call to ioctl */
+ errno= ioctl_errno;
+ return -1;
+ }
+
+
+ return 0;
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+
+#ifdef __weak_alias
+#define sprofile _sprofile
+__weak_alias(sprofile, _sprofile)
+#endif
+
+#include <lib.h>
+#include <minix/profile.h>
+
+int sprofile(int action,
+ int size,
+ int freq,
+ int type,
+ void *ctl_ptr,
+ void *mem_ptr)
+{
+ message m;
+
+ m.PROF_ACTION = action;
+ m.PROF_MEM_SIZE = size;
+ m.PROF_FREQ = freq;
+ m.PROF_INTR_TYPE = type;
+ m.PROF_CTL_PTR = (void *) ctl_ptr;
+ m.PROF_MEM_PTR = (void *) mem_ptr;
+
+ return _syscall(PM_PROC_NR, SPROF, &m);
+}
+
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+#ifdef __weak_alias
+__weak_alias(stat, _stat)
+__weak_alias(fstat, _fstat)
+__weak_alias(lstat, _lstat)
+#ifdef __MINIX_EMULATE_NETBSD_STAT
+__weak_alias(_stat, __emu_netbsd_stat)
+__weak_alias(_fstat, __emu_netbsd_fstat)
+__weak_alias(_lstat, __emu_netbsd_lstat)
+#else
+__weak_alias(_stat, __orig_minix_stat)
+__weak_alias(_fstat, __orig_minix_fstat)
+__weak_alias(_lstat, __orig_minix_lstat)
+#endif
+#else /* !__weak_alias */
+#ifdef __MINIX_EMULATE_NETBSD_STAT
+#define __emu_netbsd_stat stat
+#define __emu_netbsd_fstat fstat
+#define __emu_netbsd_lstat lstat
+#else
+#define __orig_minix_stat stat
+#define __orig_minix_fstat fstat
+#define __orig_minix_lstat lstat
+#endif
+#endif /* !__weak_alias */
+
+#include <sys/stat.h>
+#include <string.h>
+
+int __orig_minix_stat(name, buffer)
+const char *name;
+struct __minix_stat *buffer;
+{
+ message m;
+
+ m.m1_i1 = strlen(name) + 1;
+ m.m1_p1 = (char *) name;
+ m.m1_p2 = (char *) buffer;
+ return(_syscall(VFS_PROC_NR, STAT, &m));
+}
+
+int __orig_minix_fstat(fd, buffer)
+int fd;
+struct __minix_stat *buffer;
+{
+ message m;
+
+ m.m1_i1 = fd;
+ m.m1_p1 = (char *) buffer;
+ return(_syscall(VFS_PROC_NR, FSTAT, &m));
+}
+
+int __orig_minix_lstat(name, buffer)
+const char *name;
+struct __minix_stat *buffer;
+{
+ message m;
+ int r;
+
+ m.m1_i1 = strlen(name) + 1;
+ m.m1_p1 = (char *) name;
+ m.m1_p2 = (char *) buffer;
+ if((r = _syscall(VFS_PROC_NR, LSTAT, &m)) >= 0 || errno != ENOSYS)
+ return r;
+ return __orig_minix_stat(name, buffer);
+}
+
+/*
+ * NetBSD Fields Emulation.
+ */
+
+static void __emulate_netbsd_fields(struct __netbsd_stat *buffer)
+{
+ /* Emulated NetBSD fields. */
+ buffer->st_atimespec.tv_sec = buffer->st_atime;
+ buffer->st_atimespec.tv_nsec = 0;
+ buffer->st_mtimespec.tv_sec = buffer->st_mtime;
+ buffer->st_mtimespec.tv_nsec = 0;
+ buffer->st_ctimespec.tv_sec = buffer->st_ctime;
+ buffer->st_ctimespec.tv_nsec = 0;
+ buffer->st_birthtimespec.tv_sec = 0;
+ buffer->st_birthtimespec.tv_nsec = 0;
+ buffer->st_blocks = (buffer->st_size / S_BLKSIZE) + 1;
+ buffer->st_blksize = MINIX_ST_BLKSIZE;
+ buffer->st_flags = 0;
+ buffer->st_gen = 0;
+}
+
+const int __emu_netbsd_stat(name, buffer)
+const char *name;
+struct __netbsd_stat *buffer;
+{
+ int r;
+
+ r = __orig_minix_stat(name, (struct __minix_stat *)buffer);
+ if (r < 0)
+ return r;
+ __emulate_netbsd_fields(buffer);
+ return r;
+}
+
+int __emu_netbsd_fstat(fd, buffer)
+int fd;
+struct __netbsd_stat *buffer;
+{
+ int r;
+ r = __orig_minix_fstat(fd, (struct __minix_stat *)buffer);
+ if ( r < 0 )
+ return r;
+ __emulate_netbsd_fields(buffer);
+ return r;
+}
+
+int __emu_netbsd_lstat(name, buffer)
+const char *name;
+struct __netbsd_stat *buffer;
+{
+ int r;
+
+ r = __orig_minix_lstat(name, (struct __minix_stat *)buffer);
+ if ( r < 0 )
+ return r;
+ __emulate_netbsd_fields(buffer);
+ return r;
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include <lib.h>
+#include "namespace.h"
+
+#include <sys/statvfs.h>
+#include <string.h>
+
+#ifdef __weak_alias
+__weak_alias(statvfs, _statvfs)
+#endif
+
+int statvfs(name, buffer)
+const char *name;
+struct statvfs *buffer;
+{
+ message m;
+
+ m.STATVFS_LEN = strlen(name) + 1;
+ m.STATVFS_NAME = (char *) name;
+ m.STATVFS_BUF = (char *) buffer;
+ return(_syscall(VFS_PROC_NR, STATVFS, &m));
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include <lib.h>
+#include "namespace.h"
+
+#include <time.h>
+
+#ifdef __weak_alias
+__weak_alias(stime, _stime)
+#endif
+
+int stime(long *top)
+{
+ message m;
+
+ m.m2_l1 = *top;
+ return(_syscall(PM_PROC_NR, STIME, &m));
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include <lib.h>
+#include "namespace.h"
+
+#ifdef __weak_alias
+__weak_alias(symlink, _symlink)
+#endif
+
+#include <string.h>
+#include <unistd.h>
+
+int symlink(name, name2)
+const char *name, *name2;
+{
+ message m;
+
+ m.m1_i1 = strlen(name) + 1;
+ m.m1_i2 = strlen(name2) + 1;
+ m.m1_p1 = (char *) name;
+ m.m1_p2 = (char *) name2;
+ return(_syscall(VFS_PROC_NR, SYMLINK, &m));
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include <lib.h>
+#include "namespace.h"
+
+#ifdef __weak_alias
+__weak_alias(sync, _sync)
+#endif
+
+#include <unistd.h>
+
+void sync()
+{
+ message m;
+
+ (void)(_syscall(VFS_PROC_NR, SYNC, &m));
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include <lib.h>
+#include "namespace.h"
+
+#ifdef __weak_alias
+__weak_alias(syscall, _syscall)
+#endif
+
+int _syscall(endpoint_t who, int syscallnr, message *msgptr)
+{
+ int status;
+
+ msgptr->m_type = syscallnr;
+ status = _sendrec(who, msgptr);
+ if (status != 0) {
+ /* 'sendrec' itself failed. */
+ /* XXX - strerror doesn't know all the codes */
+ msgptr->m_type = status;
+ }
+ if (msgptr->m_type < 0) {
+ errno = -msgptr->m_type;
+ return(-1);
+ }
+ return(msgptr->m_type);
+}
--- /dev/null
+/* sysuname(2) - transfer uname(3) strings. Author: Kees J. Bot
+ * 5 Dec 1992
+ */
+
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+int sysuname(int req, int field, char *value, size_t len)
+{
+ message m;
+
+ m.m1_i1 = req;
+ m.m1_i2 = field;
+ m.m1_i3 = len;
+ m.m1_p1 = value;
+
+ /* Clear unused fields */
+ m.m1_p2 = NULL;
+ m.m1_p3 = NULL;
+
+ return _syscall(PM_PROC_NR, SYSUNAME, &m);
+}
+
+/*
+ * $PchId: _sysuname.c,v 1.4 1995/11/27 19:42:09 philip Exp $
+ */
--- /dev/null
+#include <sys/cdefs.h>
+#include "namespace.h"
+#include <lib.h>
+
+#ifdef __weak_alias
+__weak_alias(truncate, _truncate)
+#endif
+
+#include <string.h>
+#include <unistd.h>
+
+
+int truncate(const char *_path, off_t _length)
+{
+ message m;
+ m.m2_p1 = (char *) _path;
+ m.m2_i1 = strlen(_path)+1;
+ m.m2_l1 = _length;
+
+ return(_syscall(VFS_PROC_NR, TRUNCATE, &m));
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include <lib.h>
+#include "namespace.h"
+
+#include <sys/stat.h>
+
+#ifdef __weak_alias
+__weak_alias(umask, _umask)
+#endif
+
+mode_t umask(mode_t complmode)
+{
+ message m;
+
+ m.m1_i1 = complmode;
+ return( (mode_t) _syscall(VFS_PROC_NR, UMASK, &m));
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include <lib.h>
+#include "namespace.h"
+
+#include <unistd.h>
+
+#ifdef __weak_alias
+__weak_alias(unlink, _unlink)
+#endif
+
+int unlink(name)
+const char *name;
+{
+ message m;
+
+ _loadname(name, &m);
+ return(_syscall(VFS_PROC_NR, UNLINK, &m));
+}
--- /dev/null
+#include <sys/cdefs.h>
+#include <lib.h>
+#include "namespace.h"
+
+#include <assert.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+#include <sys/uio.h>
+#include <unistd.h>
+
+#define VECTORIO_READ 1
+#define VECTORIO_WRITE 2
+
+#ifdef __weak_alias
+__weak_alias(writev, _writev)
+__weak_alias(readv, _readv)
+#endif
+
+static ssize_t vectorio_buffer(int fildes, const struct iovec *iov,
+ int iovcnt, int readwrite, ssize_t totallen)
+{
+ char *buffer;
+ int iovidx, errno_saved;
+ ssize_t copied, len, r;
+
+ /* allocate buffer */
+ buffer = (char *) malloc(totallen);
+ if (!buffer)
+ return -1;
+
+ /* perform the actual read/write for the entire buffer */
+ switch (readwrite)
+ {
+ case VECTORIO_READ:
+ /* first read, then copy buffers (only part read) */
+ r = read(fildes, buffer, totallen);
+
+ copied = 0;
+ iovidx = 0;
+ while (copied < r)
+ {
+ assert(iovidx < iovcnt);
+ len = MIN(r - copied, iov[iovidx].iov_len);
+ memcpy(iov[iovidx++].iov_base, buffer + copied, len);
+ copied += len;
+ }
+ assert(r < 0 || r == copied);
+ break;
+
+ case VECTORIO_WRITE:
+ /* first copy buffers, then write */
+ copied = 0;
+ for (iovidx = 0; iovidx < iovcnt; iovidx++)
+ {
+ memcpy(buffer + copied, iov[iovidx].iov_base,
+ iov[iovidx].iov_len);
+ copied += iov[iovidx].iov_len;
+ }
+ assert(copied == totallen);
+
+ r = write(fildes, buffer, totallen);
+ break;
+
+ default:
+ assert(0);
+ errno = EINVAL;
+ r = -1;
+ }
+
+ /* free the buffer, keeping errno unchanged */
+ errno_saved = errno;
+ free(buffer);
+ errno = errno_saved;
+
+ return r;
+}
+
+static ssize_t vectorio(int fildes, const struct iovec *iov,
+ int iovcnt, int readwrite)
+{
+ int i;
+ ssize_t totallen;
+
+ /* parameter sanity checks */
+ if (iovcnt > IOV_MAX)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ totallen = 0;
+ for (i = 0; i < iovcnt; i++)
+ {
+ /* don't read/write anything in case of possible overflow */
+ if ((ssize_t) (totallen + iov[i].iov_len) < totallen)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+ totallen += iov[i].iov_len;
+
+ /* report on NULL pointers */
+ if (iov[i].iov_len && !iov[i].iov_base)
+ {
+ errno = EFAULT;
+ return -1;
+ }
+ }
+
+ /* anything to do? */
+ if (totallen == 0)
+ return 0;
+
+ /*
+ * there aught to be a system call here; instead we use an intermediate
+ * buffer; this is preferred over multiple read/write calls because
+ * this function has to be atomic
+ */
+ return vectorio_buffer(fildes, iov, iovcnt, readwrite, totallen);
+}
+
+ssize_t readv(int fildes, const struct iovec *iov, int iovcnt)
+{
+ return vectorio(fildes, iov, iovcnt, VECTORIO_READ);
+}
+
+ssize_t writev(int fildes, const struct iovec *iov, int iovcnt)
+{
+ return vectorio(fildes, iov, iovcnt, VECTORIO_WRITE);
+}
+
--- /dev/null
+#include <sys/cdefs.h>
+#include <lib.h>
+#include "namespace.h"
+
+#include <unistd.h>
+
+#ifdef __weak_alias
+__weak_alias(write, _write)
+#endif
+
+ssize_t write(fd, buffer, nbytes)
+int fd;
+const void *buffer;
+size_t nbytes;
+{
+ message m;
+
+ m.m1_i1 = fd;
+ m.m1_i2 = nbytes;
+ m.m1_p1 = (char *) buffer;
+ return(_syscall(VFS_PROC_NR, WRITE, &m));
+}
+