diff --git a/lib/nbsd_libc/arch/i386/sys-minix/Makefile.inc b/lib/nbsd_libc/arch/i386/sys-minix/Makefile.inc new file mode 100644 index 000000000..6cf381dae --- /dev/null +++ b/lib/nbsd_libc/arch/i386/sys-minix/Makefile.inc @@ -0,0 +1,9 @@ +# rts sources +.PATH: ${.CURDIR}/arch/${ARCH}/sys-minix + +SRCS+= \ + __sigreturn.S \ + _ipc.S \ + _senda.S \ + brksize.S \ + ucontext.S diff --git a/lib/nbsd_libc/arch/i386/sys-minix/__sigreturn.S b/lib/nbsd_libc/arch/i386/sys-minix/__sigreturn.S new file mode 100644 index 000000000..01182b058 --- /dev/null +++ b/lib/nbsd_libc/arch/i386/sys-minix/__sigreturn.S @@ -0,0 +1,9 @@ +/* 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 + +IMPORT(_sigreturn) +ENTRY(__sigreturn) + addl $16, %esp + jmp _C_LABEL(_sigreturn) diff --git a/lib/nbsd_libc/arch/i386/sys-minix/_ipc.S b/lib/nbsd_libc/arch/i386/sys-minix/_ipc.S new file mode 100644 index 000000000..5d5d77811 --- /dev/null +++ b/lib/nbsd_libc/arch/i386/sys-minix/_ipc.S @@ -0,0 +1,80 @@ +#include +#include + + 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 diff --git a/lib/nbsd_libc/arch/i386/sys-minix/_senda.S b/lib/nbsd_libc/arch/i386/sys-minix/_senda.S new file mode 100644 index 000000000..a38c2c9fc --- /dev/null +++ b/lib/nbsd_libc/arch/i386/sys-minix/_senda.S @@ -0,0 +1,19 @@ +#include +#include + + 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 diff --git a/lib/nbsd_libc/arch/i386/sys-minix/brksize.S b/lib/nbsd_libc/arch/i386/sys-minix/brksize.S new file mode 100644 index 000000000..64ec062d1 --- /dev/null +++ b/lib/nbsd_libc/arch/i386/sys-minix/brksize.S @@ -0,0 +1,13 @@ +#if defined(__ELF__) +.globl _end +.globl _brksize + +.data +_brksize: .long _end +#else +.globl __brksize +.data +.extern endbss, __brksize +__brksize: +.long endbss +#endif diff --git a/lib/nbsd_libc/arch/i386/sys-minix/ucontext.S b/lib/nbsd_libc/arch/i386/sys-minix/ucontext.S new file mode 100644 index 000000000..27e237e36 --- /dev/null +++ b/lib/nbsd_libc/arch/i386/sys-minix/ucontext.S @@ -0,0 +1,210 @@ +#include + +#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 ! */ +#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 */ +#define MCF_MAGIC 0xc0ffee + +/* Values from */ +#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 */ + + diff --git a/lib/nbsd_libc/gen/minix/clock.c b/lib/nbsd_libc/gen/minix/clock.c new file mode 100644 index 000000000..efe45102e --- /dev/null +++ b/lib/nbsd_libc/gen/minix/clock.c @@ -0,0 +1,16 @@ +/* + * clock - determine the processor time used + */ +#include +#include "namespace.h" + +#include +#include + +clock_t clock(void) +{ + struct tms tms; + + times(&tms); + return tms.tms_utime; +} diff --git a/lib/nbsd_libc/gen/minix/getdomainname.c b/lib/nbsd_libc/gen/minix/getdomainname.c new file mode 100644 index 000000000..8da6942ba --- /dev/null +++ b/lib/nbsd_libc/gen/minix/getdomainname.c @@ -0,0 +1,22 @@ +/* getdomainname() Author: Kees J. Bot + * 2 Dec 1994 + */ +#define nil 0 +#include +#include +#include + +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; +} diff --git a/lib/nbsd_libc/gen/minix/gethostname.c b/lib/nbsd_libc/gen/minix/gethostname.c new file mode 100644 index 000000000..2df776a9c --- /dev/null +++ b/lib/nbsd_libc/gen/minix/gethostname.c @@ -0,0 +1,33 @@ +/* gethostname(2) system call emulation */ +#include +#include "namespace.h" + +#include +#include +#include +#include +#include +#include + +#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; +} diff --git a/lib/nbsd_libc/gen/minix/getloadavg.c b/lib/nbsd_libc/gen/minix/getloadavg.c new file mode 100644 index 000000000..33c2c46db --- /dev/null +++ b/lib/nbsd_libc/gen/minix/getloadavg.c @@ -0,0 +1,41 @@ +#include +#include "namespace.h" + +#include +#include +#include +#include +#include +#include + +#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; +} diff --git a/lib/nbsd_libc/gen/minix/getpagesize.c b/lib/nbsd_libc/gen/minix/getpagesize.c new file mode 100644 index 000000000..006f01700 --- /dev/null +++ b/lib/nbsd_libc/gen/minix/getpagesize.c @@ -0,0 +1,17 @@ +/* +getpagesize.c +*/ +#include +#include "namespace.h" + +#include +#include + +#ifdef __weak_alias +__weak_alias(getpagesize, _getpagesize) +#endif + +int getpagesize(void) +{ + return PAGE_SIZE; +} diff --git a/lib/nbsd_libc/gen/minix/getpass.c b/lib/nbsd_libc/gen/minix/getpass.c new file mode 100644 index 000000000..2f2451bb4 --- /dev/null +++ b/lib/nbsd_libc/gen/minix/getpass.c @@ -0,0 +1,75 @@ +/* getpass() - read a password Author: Kees J. Bot + * Feb 16 1993 + */ +#include +#include "namespace.h" + +#define _MINIX +#include +#include +#include +#include +#include +#include + +#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; +} diff --git a/lib/nbsd_libc/gen/minix/getprogname.c b/lib/nbsd_libc/gen/minix/getprogname.c new file mode 100644 index 000000000..56b9b6a4a --- /dev/null +++ b/lib/nbsd_libc/gen/minix/getprogname.c @@ -0,0 +1,99 @@ +/* $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. + * + * <> + */ + +#include +#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 +#include + +#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 diff --git a/lib/nbsd_libc/gen/minix/popen.c b/lib/nbsd_libc/gen/minix/popen.c new file mode 100644 index 000000000..2791485d7 --- /dev/null +++ b/lib/nbsd_libc/gen/minix/popen.c @@ -0,0 +1,128 @@ +/* + * popen - open a pipe + */ +/* $Header$ */ +#include +#include "namespace.h" +#include + +#ifdef __weak_alias +__weak_alias(popen, _popen) +__weak_alias(pclose, _pclose) +#endif + +#include +#include +#include +#include +#include + +#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 */ diff --git a/lib/nbsd_libc/gen/minix/raise.c b/lib/nbsd_libc/gen/minix/raise.c new file mode 100644 index 000000000..a7e951c6e --- /dev/null +++ b/lib/nbsd_libc/gen/minix/raise.c @@ -0,0 +1,21 @@ +/* + * (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 +#endif +#include + +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); +} diff --git a/lib/nbsd_libc/gen/minix/sysconf.c b/lib/nbsd_libc/gen/minix/sysconf.c new file mode 100644 index 000000000..df6a9acd4 --- /dev/null +++ b/lib/nbsd_libc/gen/minix/sysconf.c @@ -0,0 +1,82 @@ +/* sysconf.c POSIX 4.8.1 + * long int sysconf(int name); + * + * POSIX allows some of the values in 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 . + */ +#include +#include "namespace.h" + +#include +#include +#include +#include +#include + +#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; + } +} diff --git a/lib/nbsd_libc/gen/minix/times.c b/lib/nbsd_libc/gen/minix/times.c new file mode 100644 index 000000000..d839a3bf8 --- /dev/null +++ b/lib/nbsd_libc/gen/minix/times.c @@ -0,0 +1,23 @@ +#include +#include "namespace.h" + +#include +#include + +#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); +} diff --git a/lib/nbsd_libc/gen/minix/uname.c b/lib/nbsd_libc/gen/minix/uname.c new file mode 100644 index 000000000..70b807ab1 --- /dev/null +++ b/lib/nbsd_libc/gen/minix/uname.c @@ -0,0 +1,67 @@ +/* uname(3) - describe the machine. Author: Kees J. Bot + * 5 Dec 1992 + */ +#include +#include "namespace.h" + +#include +#include +#include +#include +#include +#include + +#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 $ + */ diff --git a/lib/nbsd_libc/gen/minix/utime.c b/lib/nbsd_libc/gen/minix/utime.c new file mode 100644 index 000000000..1d68c9c3e --- /dev/null +++ b/lib/nbsd_libc/gen/minix/utime.c @@ -0,0 +1,26 @@ +/* utime(2) for POSIX Authors: Terrence W. Holm & Edwin L. Froese */ + +#include +#include "namespace.h" +#include + +#include +#include + +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)); +} diff --git a/lib/nbsd_libc/gen/minix/wait.c b/lib/nbsd_libc/gen/minix/wait.c new file mode 100644 index 000000000..2d639c8c2 --- /dev/null +++ b/lib/nbsd_libc/gen/minix/wait.c @@ -0,0 +1,19 @@ +#include +#include +#include "namespace.h" + +#include + +#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); +} diff --git a/lib/nbsd_libc/gen/minix/waitpid.c b/lib/nbsd_libc/gen/minix/waitpid.c new file mode 100644 index 000000000..6972e6820 --- /dev/null +++ b/lib/nbsd_libc/gen/minix/waitpid.c @@ -0,0 +1,23 @@ +#include +#include +#include "namespace.h" + +#include + +#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; +} diff --git a/lib/nbsd_libc/net/minix/getifaddrs.c b/lib/nbsd_libc/net/minix/getifaddrs.c new file mode 100644 index 000000000..e7726edb9 --- /dev/null +++ b/lib/nbsd_libc/net/minix/getifaddrs.c @@ -0,0 +1,69 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +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. */ + ; +} + diff --git a/lib/nbsd_libc/net/minix/getpeereid.c b/lib/nbsd_libc/net/minix/getpeereid.c new file mode 100644 index 000000000..6da016b26 --- /dev/null +++ b/lib/nbsd_libc/net/minix/getpeereid.c @@ -0,0 +1,36 @@ +#include +#include +#include +#include + +/* + * 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; + } +} diff --git a/lib/nbsd_libc/sys-minix/MISSING_SYSCALLS b/lib/nbsd_libc/sys-minix/MISSING_SYSCALLS new file mode 100644 index 000000000..22698ab7d --- /dev/null +++ b/lib/nbsd_libc/sys-minix/MISSING_SYSCALLS @@ -0,0 +1,79 @@ +_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 diff --git a/lib/nbsd_libc/sys-minix/Makefile.inc b/lib/nbsd_libc/sys-minix/Makefile.inc new file mode 100644 index 000000000..c1fe1266a --- /dev/null +++ b/lib/nbsd_libc/sys-minix/Makefile.inc @@ -0,0 +1,24 @@ +.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" diff --git a/lib/nbsd_libc/sys-minix/__getcwd.c b/lib/nbsd_libc/sys-minix/__getcwd.c new file mode 100644 index 000000000..7fec1faad --- /dev/null +++ b/lib/nbsd_libc/sys-minix/__getcwd.c @@ -0,0 +1,140 @@ +/* getcwd() - get the name of the current working directory. + * Author: Kees J. Bot + * 30 Apr 1989 + */ + +#define chdir _chdir +#include +#include "namespace.h" + +#include +#include +#include +#include +#include +#include +#include + +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; +} diff --git a/lib/nbsd_libc/sys-minix/__getlogin.c b/lib/nbsd_libc/sys-minix/__getlogin.c new file mode 100644 index 000000000..4194db624 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/__getlogin.c @@ -0,0 +1,29 @@ +/* getlogin(3) + * + * Author: Terrence W. Holm Aug. 1988 + */ + +#include +#include "namespace.h" +#include + +#include +#include +#include +#include +#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; +} diff --git a/lib/nbsd_libc/sys-minix/_exit.c b/lib/nbsd_libc/sys-minix/_exit.c new file mode 100644 index 000000000..3cd818d98 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/_exit.c @@ -0,0 +1,29 @@ +#include +#include "namespace.h" +#include + +#include + +#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(;;) { } +} + diff --git a/lib/nbsd_libc/sys-minix/_mcontext.c b/lib/nbsd_libc/sys-minix/_mcontext.c new file mode 100644 index 000000000..bd70c9cdb --- /dev/null +++ b/lib/nbsd_libc/sys-minix/_mcontext.c @@ -0,0 +1,29 @@ +/* + * mcontext.c +*/ +#include +#include +#include + +#include +#include + +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)); +} + diff --git a/lib/nbsd_libc/sys-minix/_ucontext.c b/lib/nbsd_libc/sys-minix/_ucontext.c new file mode 100644 index 000000000..6c5e70be5 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/_ucontext.c @@ -0,0 +1,198 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +_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 */ +} + diff --git a/lib/nbsd_libc/sys-minix/accept.c b/lib/nbsd_libc/sys-minix/accept.c new file mode 100644 index 000000000..6f192bd16 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/accept.c @@ -0,0 +1,134 @@ +#include +#include +#include "namespace.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#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; +} diff --git a/lib/nbsd_libc/sys-minix/access.c b/lib/nbsd_libc/sys-minix/access.c new file mode 100644 index 000000000..218f1d1f5 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/access.c @@ -0,0 +1,20 @@ +#include +#include "namespace.h" +#include + +#include + +#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)); +} diff --git a/lib/nbsd_libc/sys-minix/bind.c b/lib/nbsd_libc/sys-minix/bind.c new file mode 100644 index 000000000..ef8d196fb --- /dev/null +++ b/lib/nbsd_libc/sys-minix/bind.c @@ -0,0 +1,244 @@ +#include +#include "namespace.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#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; +} diff --git a/lib/nbsd_libc/sys-minix/brk.c b/lib/nbsd_libc/sys-minix/brk.c new file mode 100644 index 000000000..a182dd2dc --- /dev/null +++ b/lib/nbsd_libc/sys-minix/brk.c @@ -0,0 +1,34 @@ +#include +#include "namespace.h" +#include + +#include + +#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); +} + diff --git a/lib/nbsd_libc/sys-minix/chdir.c b/lib/nbsd_libc/sys-minix/chdir.c new file mode 100644 index 000000000..03bab11f9 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/chdir.c @@ -0,0 +1,28 @@ +#include +#include "namespace.h" +#include + +#include + +#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)); +} diff --git a/lib/nbsd_libc/sys-minix/chmod.c b/lib/nbsd_libc/sys-minix/chmod.c new file mode 100644 index 000000000..50df7fe37 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/chmod.c @@ -0,0 +1,18 @@ +#include +#include "namespace.h" +#include + +#include + +#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)); +} diff --git a/lib/nbsd_libc/sys-minix/chown.c b/lib/nbsd_libc/sys-minix/chown.c new file mode 100644 index 000000000..d292677ad --- /dev/null +++ b/lib/nbsd_libc/sys-minix/chown.c @@ -0,0 +1,17 @@ +#include +#include "namespace.h" +#include + +#include +#include + +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)); +} diff --git a/lib/nbsd_libc/sys-minix/chroot.c b/lib/nbsd_libc/sys-minix/chroot.c new file mode 100644 index 000000000..e557cf0c6 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/chroot.c @@ -0,0 +1,18 @@ +#include +#include "namespace.h" +#include + +#include + +#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)); +} diff --git a/lib/nbsd_libc/sys-minix/close.c b/lib/nbsd_libc/sys-minix/close.c new file mode 100644 index 000000000..3fa75c1a5 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/close.c @@ -0,0 +1,18 @@ +#include +#include "namespace.h" +#include + +#include + +#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)); +} diff --git a/lib/nbsd_libc/sys-minix/connect.c b/lib/nbsd_libc/sys-minix/connect.c new file mode 100644 index 000000000..66f8cc8a0 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/connect.c @@ -0,0 +1,178 @@ +#include +#include "namespace.h" +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#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); +} diff --git a/lib/nbsd_libc/sys-minix/cprofile.c b/lib/nbsd_libc/sys-minix/cprofile.c new file mode 100644 index 000000000..a9bfd1189 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/cprofile.c @@ -0,0 +1,23 @@ +#include +#include "namespace.h" + +#ifdef __weak_alias +#define cprofile _cprofile +__weak_alias(cprofile, _cprofile) +#endif + +#include +#include + +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); +} + diff --git a/lib/nbsd_libc/sys-minix/dup.c b/lib/nbsd_libc/sys-minix/dup.c new file mode 100644 index 000000000..d7bd8d4b4 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/dup.c @@ -0,0 +1,16 @@ +#include +#include "namespace.h" +#include + +#include +#include + +#ifdef __weak_alias +__weak_alias(dup, _dup) +#endif + +PUBLIC int dup(fd) +int fd; +{ + return(fcntl(fd, F_DUPFD, 0)); +} diff --git a/lib/nbsd_libc/sys-minix/dup2.c b/lib/nbsd_libc/sys-minix/dup2.c new file mode 100644 index 000000000..46d632922 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/dup2.c @@ -0,0 +1,34 @@ +#include +#include "namespace.h" +#include + +#include +#include + +#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)); + } +} diff --git a/lib/nbsd_libc/sys-minix/environ.c b/lib/nbsd_libc/sys-minix/environ.c new file mode 100644 index 000000000..7e7fe73b0 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/environ.c @@ -0,0 +1,20 @@ +/* + * 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 diff --git a/lib/nbsd_libc/sys-minix/execve.c b/lib/nbsd_libc/sys-minix/execve.c new file mode 100644 index 000000000..f62a278bd --- /dev/null +++ b/lib/nbsd_libc/sys-minix/execve.c @@ -0,0 +1,118 @@ +/* execve() - basic program execution call Author: Kees J. Bot + * 21 Jan 1994 + */ +#define _MINIX_SOURCE + +#include +#include "namespace.h" +#include + +#include +#include +#include + +#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; +} diff --git a/lib/nbsd_libc/sys-minix/fchmod.c b/lib/nbsd_libc/sys-minix/fchmod.c new file mode 100644 index 000000000..69445b911 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/fchmod.c @@ -0,0 +1,18 @@ +#include +#include "namespace.h" +#include + +#include + +#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)); +} diff --git a/lib/nbsd_libc/sys-minix/fchown.c b/lib/nbsd_libc/sys-minix/fchown.c new file mode 100644 index 000000000..95f1e411c --- /dev/null +++ b/lib/nbsd_libc/sys-minix/fchown.c @@ -0,0 +1,20 @@ +#include +#include "namespace.h" +#include + +#include +#include + +#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)); +} diff --git a/lib/nbsd_libc/sys-minix/fcntl.c b/lib/nbsd_libc/sys-minix/fcntl.c new file mode 100644 index 000000000..073f088d8 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/fcntl.c @@ -0,0 +1,51 @@ +#include +#include "namespace.h" +#include + +#include +#include + +#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)); +} diff --git a/lib/nbsd_libc/sys-minix/flock.c b/lib/nbsd_libc/sys-minix/flock.c new file mode 100644 index 000000000..37a69677a --- /dev/null +++ b/lib/nbsd_libc/sys-minix/flock.c @@ -0,0 +1,38 @@ +/* Library routines + * + * Porting to Minix 2.0.0 + * Author: Giovanni Falzoni + */ + +#include +#include "namespace.h" +#include + +#include +#include +#include +#include +#include + +#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 **/ diff --git a/lib/nbsd_libc/sys-minix/fork.c b/lib/nbsd_libc/sys-minix/fork.c new file mode 100644 index 000000000..c041b961d --- /dev/null +++ b/lib/nbsd_libc/sys-minix/fork.c @@ -0,0 +1,16 @@ +#include +#include "namespace.h" +#include + +#include + +#ifdef __weak_alias +__weak_alias(fork, _fork) +#endif + +PUBLIC pid_t fork() +{ + message m; + + return(_syscall(PM_PROC_NR, FORK, &m)); +} diff --git a/lib/nbsd_libc/sys-minix/fpathconf.c b/lib/nbsd_libc/sys-minix/fpathconf.c new file mode 100644 index 000000000..a1bbb09b7 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/fpathconf.c @@ -0,0 +1,66 @@ +/* POSIX fpathconf (Sec. 5.7.1) Author: Andy Tanenbaum */ + +#include +#include "namespace.h" +#include + +#include +#include +#include +#include +#include + +#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 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 . + */ + + 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); + } +} diff --git a/lib/nbsd_libc/sys-minix/fstatvfs.c b/lib/nbsd_libc/sys-minix/fstatvfs.c new file mode 100644 index 000000000..63e4d39e5 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/fstatvfs.c @@ -0,0 +1,18 @@ +#include +#include "namespace.h" +#include + +#include + +#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)); +} diff --git a/lib/nbsd_libc/sys-minix/fsync.c b/lib/nbsd_libc/sys-minix/fsync.c new file mode 100644 index 000000000..1001529a2 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/fsync.c @@ -0,0 +1,18 @@ +#include +#include "namespace.h" +#include + +#include + +#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)); +} diff --git a/lib/nbsd_libc/sys-minix/ftruncate.c b/lib/nbsd_libc/sys-minix/ftruncate.c new file mode 100644 index 000000000..e95e258e4 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/ftruncate.c @@ -0,0 +1,19 @@ +#include +#include "namespace.h" +#include + +#include +#include + +#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)); +} diff --git a/lib/nbsd_libc/sys-minix/getdents.c b/lib/nbsd_libc/sys-minix/getdents.c new file mode 100644 index 000000000..61c4da31c --- /dev/null +++ b/lib/nbsd_libc/sys-minix/getdents.c @@ -0,0 +1,18 @@ +#include +#include "namespace.h" +#include + +#include + +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); +} diff --git a/lib/nbsd_libc/sys-minix/getegid.c b/lib/nbsd_libc/sys-minix/getegid.c new file mode 100644 index 000000000..aba33b2fb --- /dev/null +++ b/lib/nbsd_libc/sys-minix/getegid.c @@ -0,0 +1,22 @@ +#include +#include "namespace.h" +#include + +#include + +#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); +} diff --git a/lib/nbsd_libc/sys-minix/geteuid.c b/lib/nbsd_libc/sys-minix/geteuid.c new file mode 100644 index 000000000..b350ab6a6 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/geteuid.c @@ -0,0 +1,22 @@ +#include +#include "namespace.h" +#include + +#include + +#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); +} diff --git a/lib/nbsd_libc/sys-minix/getgid.c b/lib/nbsd_libc/sys-minix/getgid.c new file mode 100644 index 000000000..288612a56 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/getgid.c @@ -0,0 +1,16 @@ +#include +#include "namespace.h" +#include + +#include + +#ifdef __weak_alias +__weak_alias(getgid, _getgid) +#endif + +PUBLIC gid_t getgid() +{ + message m; + + return( (gid_t) _syscall(PM_PROC_NR, GETGID, &m)); +} diff --git a/lib/nbsd_libc/sys-minix/getgroups.c b/lib/nbsd_libc/sys-minix/getgroups.c new file mode 100644 index 000000000..ded3dc122 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/getgroups.c @@ -0,0 +1,24 @@ +/* +getgroups.c +*/ + +#include +#include "namespace.h" +#include + +#include + +#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)); +} + diff --git a/lib/nbsd_libc/sys-minix/getitimer.c b/lib/nbsd_libc/sys-minix/getitimer.c new file mode 100644 index 000000000..bb8921027 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/getitimer.c @@ -0,0 +1,20 @@ +#include +#include "namespace.h" +#include + +#include + +/* + * 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); +} diff --git a/lib/nbsd_libc/sys-minix/getpeername.c b/lib/nbsd_libc/sys-minix/getpeername.c new file mode 100644 index 000000000..27eb337bd --- /dev/null +++ b/lib/nbsd_libc/sys-minix/getpeername.c @@ -0,0 +1,111 @@ +#include +#include "namespace.h" +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#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; +} diff --git a/lib/nbsd_libc/sys-minix/getpgrp.c b/lib/nbsd_libc/sys-minix/getpgrp.c new file mode 100644 index 000000000..5b2140cb7 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/getpgrp.c @@ -0,0 +1,16 @@ +#include +#include "namespace.h" +#include + +#include + +#ifdef __weak_alias +__weak_alias(getpgrp, _getpgrp) +#endif + +PUBLIC pid_t getpgrp() +{ + message m; + + return(_syscall(PM_PROC_NR, GETPGRP, &m)); +} diff --git a/lib/nbsd_libc/sys-minix/getpid.c b/lib/nbsd_libc/sys-minix/getpid.c new file mode 100644 index 000000000..2d6d62838 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/getpid.c @@ -0,0 +1,16 @@ +#include +#include "namespace.h" +#include + +#include + +#ifdef __weak_alias +__weak_alias(getpid, _getpid) +#endif + +PUBLIC pid_t getpid() +{ + message m; + + return(_syscall(PM_PROC_NR, MINIX_GETPID, &m)); +} diff --git a/lib/nbsd_libc/sys-minix/getppid.c b/lib/nbsd_libc/sys-minix/getppid.c new file mode 100644 index 000000000..ed8d7c505 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/getppid.c @@ -0,0 +1,22 @@ +#include +#include "namespace.h" +#include + +#include + +#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); +} diff --git a/lib/nbsd_libc/sys-minix/getrlimit.c b/lib/nbsd_libc/sys-minix/getrlimit.c new file mode 100644 index 000000000..291e3daab --- /dev/null +++ b/lib/nbsd_libc/sys-minix/getrlimit.c @@ -0,0 +1,53 @@ +/* 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 +#include "namespace.h" + +#include +#include +#include +#include + +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; +} + diff --git a/lib/nbsd_libc/sys-minix/getsockname.c b/lib/nbsd_libc/sys-minix/getsockname.c new file mode 100644 index 000000000..899d095e2 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/getsockname.c @@ -0,0 +1,127 @@ +/* + + getsockname() + + from socket emulation library for Minix 2.0.x + +*/ + +#include +#include "namespace.h" +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/* +#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; +} diff --git a/lib/nbsd_libc/sys-minix/getsockopt.c b/lib/nbsd_libc/sys-minix/getsockopt.c new file mode 100644 index 000000000..28aa4d754 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/getsockopt.c @@ -0,0 +1,258 @@ +#include +#include +#include "namespace.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#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; +} diff --git a/lib/nbsd_libc/sys-minix/gettimeofday.c b/lib/nbsd_libc/sys-minix/gettimeofday.c new file mode 100644 index 000000000..10e51a263 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/gettimeofday.c @@ -0,0 +1,27 @@ +/* +gettimeofday.c +*/ + +#include +#include "namespace.h" +#include + +#include + +#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; +} + diff --git a/lib/nbsd_libc/sys-minix/getuid.c b/lib/nbsd_libc/sys-minix/getuid.c new file mode 100644 index 000000000..65e2215e1 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/getuid.c @@ -0,0 +1,16 @@ +#include +#include "namespace.h" +#include + +#include + +#ifdef __weak_alias +__weak_alias(getuid, _getuid) +#endif + +PUBLIC uid_t getuid() +{ + message m; + + return( (uid_t) _syscall(PM_PROC_NR, GETUID, &m)); +} diff --git a/lib/nbsd_libc/sys-minix/ioctl.c b/lib/nbsd_libc/sys-minix/ioctl.c new file mode 100644 index 000000000..e51e0584b --- /dev/null +++ b/lib/nbsd_libc/sys-minix/ioctl.c @@ -0,0 +1,22 @@ +#include +#include "namespace.h" +#include + +#include + +#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)); +} diff --git a/lib/nbsd_libc/sys-minix/issetugid.c b/lib/nbsd_libc/sys-minix/issetugid.c new file mode 100644 index 000000000..4472f2830 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/issetugid.c @@ -0,0 +1,11 @@ +#include +#include "namespace.h" +#include + +#include + +int issetugid(void) +{ +#warning Unsecure. Implement me. + return 0; +} diff --git a/lib/nbsd_libc/sys-minix/kill.c b/lib/nbsd_libc/sys-minix/kill.c new file mode 100644 index 000000000..8a91513f6 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/kill.c @@ -0,0 +1,20 @@ +#include +#include "namespace.h" +#include + +#include + +#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)); +} diff --git a/lib/nbsd_libc/sys-minix/link.c b/lib/nbsd_libc/sys-minix/link.c new file mode 100644 index 000000000..b4f9f71bb --- /dev/null +++ b/lib/nbsd_libc/sys-minix/link.c @@ -0,0 +1,22 @@ +#include +#include "namespace.h" +#include + +#include +#include + +#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)); +} diff --git a/lib/nbsd_libc/sys-minix/listen.c b/lib/nbsd_libc/sys-minix/listen.c new file mode 100644 index 000000000..e700b77ed --- /dev/null +++ b/lib/nbsd_libc/sys-minix/listen.c @@ -0,0 +1,37 @@ +#include +#include "namespace.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#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; +} + diff --git a/lib/nbsd_libc/sys-minix/loadname.c b/lib/nbsd_libc/sys-minix/loadname.c new file mode 100644 index 000000000..3ceb62d5c --- /dev/null +++ b/lib/nbsd_libc/sys-minix/loadname.c @@ -0,0 +1,22 @@ +#include +#include +#include "namespace.h" + +#include + +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); +} diff --git a/lib/nbsd_libc/sys-minix/lseek.c b/lib/nbsd_libc/sys-minix/lseek.c new file mode 100644 index 000000000..f994fa50b --- /dev/null +++ b/lib/nbsd_libc/sys-minix/lseek.c @@ -0,0 +1,23 @@ +#include +#include "namespace.h" +#include + +#include + +#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); +} diff --git a/lib/nbsd_libc/sys-minix/lseek64.c b/lib/nbsd_libc/sys-minix/lseek64.c new file mode 100644 index 000000000..ea562825e --- /dev/null +++ b/lib/nbsd_libc/sys-minix/lseek64.c @@ -0,0 +1,24 @@ +#include +#include "namespace.h" +#include + +#include +#include + +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; +} diff --git a/lib/nbsd_libc/sys-minix/minix_rs.c b/lib/nbsd_libc/sys-minix/minix_rs.c new file mode 100644 index 000000000..f167ca433 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/minix_rs.c @@ -0,0 +1,41 @@ +#include +#define _SYSTEM 1 +#define _MINIX 1 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +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; +} + diff --git a/lib/nbsd_libc/sys-minix/mkdir.c b/lib/nbsd_libc/sys-minix/mkdir.c new file mode 100644 index 000000000..91d61b9e2 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/mkdir.c @@ -0,0 +1,20 @@ +#include +#include "namespace.h" +#include + +#include +#include + +#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)); +} diff --git a/lib/nbsd_libc/sys-minix/mkfifo.c b/lib/nbsd_libc/sys-minix/mkfifo.c new file mode 100644 index 000000000..5e944a9b2 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/mkfifo.c @@ -0,0 +1,15 @@ +#include +#include "namespace.h" +#include + +#include +#include + +#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); +} diff --git a/lib/nbsd_libc/sys-minix/mknod.c b/lib/nbsd_libc/sys-minix/mknod.c new file mode 100644 index 000000000..19e13c515 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/mknod.c @@ -0,0 +1,20 @@ +#include +#include "namespace.h" +#include + +#include +#include +#include +#include + +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)); +} diff --git a/lib/nbsd_libc/sys-minix/mmap.c b/lib/nbsd_libc/sys-minix/mmap.c new file mode 100644 index 000000000..60b2a5b8f --- /dev/null +++ b/lib/nbsd_libc/sys-minix/mmap.c @@ -0,0 +1,125 @@ +#define _SYSTEM 1 +#include +#include "namespace.h" +#include + +/* 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 +#include +#include +#include + +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; +} + diff --git a/lib/nbsd_libc/sys-minix/mount.c b/lib/nbsd_libc/sys-minix/mount.c new file mode 100644 index 000000000..dc543a839 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/mount.c @@ -0,0 +1,180 @@ +#include +#include "namespace.h" +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#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; +} diff --git a/lib/nbsd_libc/sys-minix/nanosleep.c b/lib/nbsd_libc/sys-minix/nanosleep.c new file mode 100644 index 000000000..a8cc51406 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/nanosleep.c @@ -0,0 +1,92 @@ +/* nanosleep() - Sleep for a number of seconds. Author: Erik van der Kouwe + * 25 July 2009 + */ + +#include +#include "namespace.h" +#include + +#include +#include +#include +#include +#include + +#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; +} + diff --git a/lib/nbsd_libc/sys-minix/open.c b/lib/nbsd_libc/sys-minix/open.c new file mode 100644 index 000000000..8a8e71514 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/open.c @@ -0,0 +1,37 @@ +#include +#include "namespace.h" +#include + +#include +#include +#include + +#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)); +} diff --git a/lib/nbsd_libc/sys-minix/pathconf.c b/lib/nbsd_libc/sys-minix/pathconf.c new file mode 100644 index 000000000..70a7c1174 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/pathconf.c @@ -0,0 +1,32 @@ +/* POSIX pathconf (Sec. 5.7.1) Author: Andy Tanenbaum */ + +#include +#include "namespace.h" +#include + +#include +#include +#include + +#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 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 . + */ + + int fd; + long val; + + if ( (fd = open(path, O_RDONLY)) < 0) return(-1L); + val = fpathconf(fd, name); + close(fd); + return(val); +} diff --git a/lib/nbsd_libc/sys-minix/pipe.c b/lib/nbsd_libc/sys-minix/pipe.c new file mode 100644 index 000000000..9f883885c --- /dev/null +++ b/lib/nbsd_libc/sys-minix/pipe.c @@ -0,0 +1,20 @@ +#include +#include "namespace.h" +#include + +#include + +#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); +} diff --git a/lib/nbsd_libc/sys-minix/poll.c b/lib/nbsd_libc/sys-minix/poll.c new file mode 100644 index 000000000..72fe6238e --- /dev/null +++ b/lib/nbsd_libc/sys-minix/poll.c @@ -0,0 +1,98 @@ +/* $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 +#include "namespace.h" +#include + +#include +#include +#include +#include +#include + +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; +} diff --git a/lib/nbsd_libc/sys-minix/pread.c b/lib/nbsd_libc/sys-minix/pread.c new file mode 100644 index 000000000..566b071bc --- /dev/null +++ b/lib/nbsd_libc/sys-minix/pread.c @@ -0,0 +1,37 @@ +#include +#include "namespace.h" +#include + +#include + +#ifdef __weak_alias +__weak_alias(pread, _pread) +#endif + +#include +#include + +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; +} + diff --git a/lib/nbsd_libc/sys-minix/priority.c b/lib/nbsd_libc/sys-minix/priority.c new file mode 100644 index 000000000..451d4497a --- /dev/null +++ b/lib/nbsd_libc/sys-minix/priority.c @@ -0,0 +1,48 @@ +/* +priority.c +*/ + +#include +#include "namespace.h" +#include +#include +#include +#include +#include +#include +#include + + +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); +} + diff --git a/lib/nbsd_libc/sys-minix/ptrace.c b/lib/nbsd_libc/sys-minix/ptrace.c new file mode 100644 index 000000000..859f736f2 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/ptrace.c @@ -0,0 +1,27 @@ +#include +#include "namespace.h" +#include + +#include + +#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); +} diff --git a/lib/nbsd_libc/sys-minix/pwrite.c b/lib/nbsd_libc/sys-minix/pwrite.c new file mode 100644 index 000000000..6783804c8 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/pwrite.c @@ -0,0 +1,33 @@ +#include +#include "namespace.h" +#include + +#include + +#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; +} diff --git a/lib/nbsd_libc/sys-minix/read.c b/lib/nbsd_libc/sys-minix/read.c new file mode 100644 index 000000000..055c08b54 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/read.c @@ -0,0 +1,22 @@ +#include +#include +#include "namespace.h" + +#include + +#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)); +} diff --git a/lib/nbsd_libc/sys-minix/readlink.c b/lib/nbsd_libc/sys-minix/readlink.c new file mode 100644 index 000000000..d510799d9 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/readlink.c @@ -0,0 +1,25 @@ +#include +#include +#include "namespace.h" + +#include +#include + +#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)); +} diff --git a/lib/nbsd_libc/sys-minix/reboot.c b/lib/nbsd_libc/sys-minix/reboot.c new file mode 100644 index 000000000..7b81b9d43 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/reboot.c @@ -0,0 +1,27 @@ +/* reboot.c - Systemcall interface to mm/signal.c::do_reboot() + + author: Edvard Tuinder v892231@si.hhs.NL + */ + +#include +#include +#include "namespace.h" + +#include +#include +#include + +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); +} diff --git a/lib/nbsd_libc/sys-minix/recvfrom.c b/lib/nbsd_libc/sys-minix/recvfrom.c new file mode 100644 index 000000000..9327e7a93 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/recvfrom.c @@ -0,0 +1,296 @@ +#include +#include +#include "namespace.h" + +#undef NDEBUG + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#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; +} + diff --git a/lib/nbsd_libc/sys-minix/recvmsg.c b/lib/nbsd_libc/sys-minix/recvmsg.c new file mode 100644 index 000000000..057d7f1d5 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/recvmsg.c @@ -0,0 +1,135 @@ +#include +#include "namespace.h" + +#undef NDEBUG + +#include +#include +#include +#include +#include +#include + +#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; +} diff --git a/lib/nbsd_libc/sys-minix/rename.c b/lib/nbsd_libc/sys-minix/rename.c new file mode 100644 index 000000000..df735a087 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/rename.c @@ -0,0 +1,18 @@ +#include +#include +#include "namespace.h" + +#include +#include + +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)); +} diff --git a/lib/nbsd_libc/sys-minix/rmdir.c b/lib/nbsd_libc/sys-minix/rmdir.c new file mode 100644 index 000000000..272c1e4bf --- /dev/null +++ b/lib/nbsd_libc/sys-minix/rmdir.c @@ -0,0 +1,18 @@ +#include +#include +#include "namespace.h" + +#ifdef __weak_alias +__weak_alias(rmdir, _rmdir) +#endif + +#include + +int rmdir(name) +const char *name; +{ + message m; + + _loadname(name, &m); + return(_syscall(VFS_PROC_NR, RMDIR, &m)); +} diff --git a/lib/nbsd_libc/sys-minix/sbrk.c b/lib/nbsd_libc/sys-minix/sbrk.c new file mode 100644 index 000000000..ca947f252 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/sbrk.c @@ -0,0 +1,26 @@ +#include +#include "namespace.h" +#include + +#include + +#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); +} diff --git a/lib/nbsd_libc/sys-minix/select.c b/lib/nbsd_libc/sys-minix/select.c new file mode 100644 index 000000000..cc84b427d --- /dev/null +++ b/lib/nbsd_libc/sys-minix/select.c @@ -0,0 +1,22 @@ +#include +#include +#include "namespace.h" + +#include +#include + +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)); +} + diff --git a/lib/nbsd_libc/sys-minix/sem.c b/lib/nbsd_libc/sys-minix/sem.c new file mode 100644 index 000000000..0deab40d2 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/sem.c @@ -0,0 +1,99 @@ +#define __USE_MISC +#define _SYSTEM 1 +#define _MINIX 1 + +#include +#include +#include "namespace.h" + +#include +#include + +#include +#include +#include +#include +#include +#include + +#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); +} + diff --git a/lib/nbsd_libc/sys-minix/sendmsg.c b/lib/nbsd_libc/sys-minix/sendmsg.c new file mode 100644 index 000000000..52727cd6e --- /dev/null +++ b/lib/nbsd_libc/sys-minix/sendmsg.c @@ -0,0 +1,137 @@ +#include +#include "namespace.h" + +#undef NDEBUG + +#include +#include +#include +#include +#include +#include +#include + +#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); +} diff --git a/lib/nbsd_libc/sys-minix/sendto.c b/lib/nbsd_libc/sys-minix/sendto.c new file mode 100644 index 000000000..367c9be11 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/sendto.c @@ -0,0 +1,237 @@ +#include +#include "namespace.h" + +#undef NDEBUG + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#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); +} diff --git a/lib/nbsd_libc/sys-minix/setgid.c b/lib/nbsd_libc/sys-minix/setgid.c new file mode 100644 index 000000000..90fc6e40e --- /dev/null +++ b/lib/nbsd_libc/sys-minix/setgid.c @@ -0,0 +1,26 @@ +#include +#include +#include "namespace.h" + +#ifdef __weak_alias +__weak_alias(setgid, _setgid) +__weak_alias(setegid, _setegid) +#endif + +#include + +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)); +} diff --git a/lib/nbsd_libc/sys-minix/setgroups.c b/lib/nbsd_libc/sys-minix/setgroups.c new file mode 100644 index 000000000..eabf1f0b1 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/setgroups.c @@ -0,0 +1,21 @@ +#include +#include +#include "namespace.h" + +#ifdef __weak_alias +__weak_alias(setgroups, _setgroups) +#endif + +#include + +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)); +} + + diff --git a/lib/nbsd_libc/sys-minix/setitimer.c b/lib/nbsd_libc/sys-minix/setitimer.c new file mode 100644 index 000000000..b9234112a --- /dev/null +++ b/lib/nbsd_libc/sys-minix/setitimer.c @@ -0,0 +1,26 @@ +#include +#include "namespace.h" +#include + +#include + +/* + * 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); +} diff --git a/lib/nbsd_libc/sys-minix/setsid.c b/lib/nbsd_libc/sys-minix/setsid.c new file mode 100644 index 000000000..72b6010e0 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/setsid.c @@ -0,0 +1,16 @@ +#include +#include +#include "namespace.h" + +#include + +#ifdef __weak_alias +__weak_alias(setsid, _setsid) +#endif + +pid_t setsid() +{ + message m; + + return(_syscall(PM_PROC_NR, SETSID, &m)); +} diff --git a/lib/nbsd_libc/sys-minix/setsockopt.c b/lib/nbsd_libc/sys-minix/setsockopt.c new file mode 100644 index 000000000..2014c9051 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/setsockopt.c @@ -0,0 +1,273 @@ +#include +#include "namespace.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#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; +} diff --git a/lib/nbsd_libc/sys-minix/settimeofday.c b/lib/nbsd_libc/sys-minix/settimeofday.c new file mode 100644 index 000000000..2e47e9eed --- /dev/null +++ b/lib/nbsd_libc/sys-minix/settimeofday.c @@ -0,0 +1,15 @@ +#include +#include +#include "namespace.h" + +#include +#include + +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); +} diff --git a/lib/nbsd_libc/sys-minix/setuid.c b/lib/nbsd_libc/sys-minix/setuid.c new file mode 100644 index 000000000..0d066bea8 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/setuid.c @@ -0,0 +1,26 @@ +#include +#include +#include "namespace.h" + +#include + +#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)); +} diff --git a/lib/nbsd_libc/sys-minix/shmat.c b/lib/nbsd_libc/sys-minix/shmat.c new file mode 100644 index 000000000..6ed02ce58 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/shmat.c @@ -0,0 +1,65 @@ +#define _SYSTEM 1 +#define _MINIX 1 + +#include +#include +#include "namespace.h" + +#include + +#include +#include +#include +#include +#include +#include + +#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); +} + diff --git a/lib/nbsd_libc/sys-minix/shmctl.c b/lib/nbsd_libc/sys-minix/shmctl.c new file mode 100644 index 000000000..9ae6a5c97 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/shmctl.c @@ -0,0 +1,42 @@ +#define _SYSTEM 1 +#define _MINIX 1 + +#include +#include +#include "namespace.h" + +#include +#include +#include +#include +#include +#include +#include + +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; +} diff --git a/lib/nbsd_libc/sys-minix/shmget.c b/lib/nbsd_libc/sys-minix/shmget.c new file mode 100644 index 000000000..f1d9b7064 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/shmget.c @@ -0,0 +1,44 @@ +#define _SYSTEM 1 +#define _MINIX 1 +#include +#include +#include "namespace.h" + +#include +#include +#include +#include +#include +#include + + +#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; +} diff --git a/lib/nbsd_libc/sys-minix/shutdown.c b/lib/nbsd_libc/sys-minix/shutdown.c new file mode 100644 index 000000000..3f86cc516 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/shutdown.c @@ -0,0 +1,79 @@ +#include +#include "namespace.h" + +#include +#include +#include +#include +#include + +#include +#include +#include + +#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); +} diff --git a/lib/nbsd_libc/sys-minix/sigaction.c b/lib/nbsd_libc/sys-minix/sigaction.c new file mode 100644 index 000000000..724484d14 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/sigaction.c @@ -0,0 +1,24 @@ +#include +#include +#include "namespace.h" + +#include + +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)); +} diff --git a/lib/nbsd_libc/sys-minix/sigpending.c b/lib/nbsd_libc/sys-minix/sigpending.c new file mode 100644 index 000000000..817505f6a --- /dev/null +++ b/lib/nbsd_libc/sys-minix/sigpending.c @@ -0,0 +1,15 @@ +#include +#include +#include "namespace.h" + +#include + +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); +} diff --git a/lib/nbsd_libc/sys-minix/sigprocmask.c b/lib/nbsd_libc/sys-minix/sigprocmask.c new file mode 100644 index 000000000..e742ac620 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/sigprocmask.c @@ -0,0 +1,24 @@ +#include +#include +#include "namespace.h" + +#include + +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); +} diff --git a/lib/nbsd_libc/sys-minix/sigreturn.c b/lib/nbsd_libc/sys-minix/sigreturn.c new file mode 100644 index 000000000..d80cca991 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/sigreturn.c @@ -0,0 +1,32 @@ +#include +#include +#include "namespace.h" + +#include +#include + +#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 */ +} diff --git a/lib/nbsd_libc/sys-minix/sigsuspend.c b/lib/nbsd_libc/sys-minix/sigsuspend.c new file mode 100644 index 000000000..a9425eef9 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/sigsuspend.c @@ -0,0 +1,14 @@ +#include +#include +#include "namespace.h" + +#include + +int sigsuspend(set) +const sigset_t *set; +{ + message m; + + m.m2_l1 = (long) *set; + return(_syscall(PM_PROC_NR, SIGSUSPEND, &m)); +} diff --git a/lib/nbsd_libc/sys-minix/socket.c b/lib/nbsd_libc/sys-minix/socket.c new file mode 100644 index 000000000..e4e29dc21 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/socket.c @@ -0,0 +1,139 @@ +#include +#include "namespace.h" + +#ifdef __weak_alias +__weak_alias(socket, _socket) +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#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; +} diff --git a/lib/nbsd_libc/sys-minix/socketpair.c b/lib/nbsd_libc/sys-minix/socketpair.c new file mode 100644 index 000000000..ac1d901d7 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/socketpair.c @@ -0,0 +1,143 @@ +#include +#include "namespace.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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; +} diff --git a/lib/nbsd_libc/sys-minix/sprofile.c b/lib/nbsd_libc/sys-minix/sprofile.c new file mode 100644 index 000000000..bd9397c28 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/sprofile.c @@ -0,0 +1,30 @@ +#include +#include "namespace.h" + +#ifdef __weak_alias +#define sprofile _sprofile +__weak_alias(sprofile, _sprofile) +#endif + +#include +#include + +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); +} + diff --git a/lib/nbsd_libc/sys-minix/stat.c b/lib/nbsd_libc/sys-minix/stat.c new file mode 100644 index 000000000..21c677f05 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/stat.c @@ -0,0 +1,128 @@ +#include +#include "namespace.h" +#include + +#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 +#include + +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; +} diff --git a/lib/nbsd_libc/sys-minix/statvfs.c b/lib/nbsd_libc/sys-minix/statvfs.c new file mode 100644 index 000000000..b886c0b3e --- /dev/null +++ b/lib/nbsd_libc/sys-minix/statvfs.c @@ -0,0 +1,22 @@ +#include +#include +#include "namespace.h" + +#include +#include + +#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)); +} diff --git a/lib/nbsd_libc/sys-minix/stime.c b/lib/nbsd_libc/sys-minix/stime.c new file mode 100644 index 000000000..024e23b41 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/stime.c @@ -0,0 +1,17 @@ +#include +#include +#include "namespace.h" + +#include + +#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)); +} diff --git a/lib/nbsd_libc/sys-minix/symlink.c b/lib/nbsd_libc/sys-minix/symlink.c new file mode 100644 index 000000000..9231e2f04 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/symlink.c @@ -0,0 +1,22 @@ +#include +#include +#include "namespace.h" + +#ifdef __weak_alias +__weak_alias(symlink, _symlink) +#endif + +#include +#include + +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)); +} diff --git a/lib/nbsd_libc/sys-minix/sync.c b/lib/nbsd_libc/sys-minix/sync.c new file mode 100644 index 000000000..3bf0c3b63 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/sync.c @@ -0,0 +1,16 @@ +#include +#include +#include "namespace.h" + +#ifdef __weak_alias +__weak_alias(sync, _sync) +#endif + +#include + +void sync() +{ + message m; + + (void)(_syscall(VFS_PROC_NR, SYNC, &m)); +} diff --git a/lib/nbsd_libc/sys-minix/syscall.c b/lib/nbsd_libc/sys-minix/syscall.c new file mode 100644 index 000000000..522810835 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/syscall.c @@ -0,0 +1,25 @@ +#include +#include +#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); +} diff --git a/lib/nbsd_libc/sys-minix/sysuname.c b/lib/nbsd_libc/sys-minix/sysuname.c new file mode 100644 index 000000000..2ce733272 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/sysuname.c @@ -0,0 +1,27 @@ +/* sysuname(2) - transfer uname(3) strings. Author: Kees J. Bot + * 5 Dec 1992 + */ + +#include +#include "namespace.h" +#include + +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 $ + */ diff --git a/lib/nbsd_libc/sys-minix/truncate.c b/lib/nbsd_libc/sys-minix/truncate.c new file mode 100644 index 000000000..9028dd15d --- /dev/null +++ b/lib/nbsd_libc/sys-minix/truncate.c @@ -0,0 +1,21 @@ +#include +#include "namespace.h" +#include + +#ifdef __weak_alias +__weak_alias(truncate, _truncate) +#endif + +#include +#include + + +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)); +} diff --git a/lib/nbsd_libc/sys-minix/umask.c b/lib/nbsd_libc/sys-minix/umask.c new file mode 100644 index 000000000..e9cd43f4c --- /dev/null +++ b/lib/nbsd_libc/sys-minix/umask.c @@ -0,0 +1,17 @@ +#include +#include +#include "namespace.h" + +#include + +#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)); +} diff --git a/lib/nbsd_libc/sys-minix/unlink.c b/lib/nbsd_libc/sys-minix/unlink.c new file mode 100644 index 000000000..a8cbed13a --- /dev/null +++ b/lib/nbsd_libc/sys-minix/unlink.c @@ -0,0 +1,18 @@ +#include +#include +#include "namespace.h" + +#include + +#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)); +} diff --git a/lib/nbsd_libc/sys-minix/vectorio.c b/lib/nbsd_libc/sys-minix/vectorio.c new file mode 100644 index 000000000..6a7fcf436 --- /dev/null +++ b/lib/nbsd_libc/sys-minix/vectorio.c @@ -0,0 +1,135 @@ +#include +#include +#include "namespace.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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); +} + diff --git a/lib/nbsd_libc/sys-minix/write.c b/lib/nbsd_libc/sys-minix/write.c new file mode 100644 index 000000000..cc9f193eb --- /dev/null +++ b/lib/nbsd_libc/sys-minix/write.c @@ -0,0 +1,23 @@ +#include +#include +#include "namespace.h" + +#include + +#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)); +} +