]> Zhao Yanbai Git Server - minix.git/commitdiff
Add NBSDLibc Minix specific files.
authorGianluca Guida <gianluca@minix3.org>
Thu, 17 Feb 2011 17:11:09 +0000 (17:11 +0000)
committerGianluca Guida <gianluca@minix3.org>
Thu, 17 Feb 2011 17:11:09 +0000 (17:11 +0000)
This patch mainly copies and modifies files existing in
the current libc implementing minix specific functions.

To keep consisten with the NetBSD libc, we remove
namespace stubs and we use "namespace.h" and weak
links.

135 files changed:
lib/nbsd_libc/arch/i386/sys-minix/Makefile.inc [new file with mode: 0644]
lib/nbsd_libc/arch/i386/sys-minix/__sigreturn.S [new file with mode: 0644]
lib/nbsd_libc/arch/i386/sys-minix/_ipc.S [new file with mode: 0644]
lib/nbsd_libc/arch/i386/sys-minix/_senda.S [new file with mode: 0644]
lib/nbsd_libc/arch/i386/sys-minix/brksize.S [new file with mode: 0644]
lib/nbsd_libc/arch/i386/sys-minix/ucontext.S [new file with mode: 0644]
lib/nbsd_libc/gen/minix/clock.c [new file with mode: 0644]
lib/nbsd_libc/gen/minix/getdomainname.c [new file with mode: 0644]
lib/nbsd_libc/gen/minix/gethostname.c [new file with mode: 0644]
lib/nbsd_libc/gen/minix/getloadavg.c [new file with mode: 0644]
lib/nbsd_libc/gen/minix/getpagesize.c [new file with mode: 0644]
lib/nbsd_libc/gen/minix/getpass.c [new file with mode: 0644]
lib/nbsd_libc/gen/minix/getprogname.c [new file with mode: 0644]
lib/nbsd_libc/gen/minix/popen.c [new file with mode: 0644]
lib/nbsd_libc/gen/minix/raise.c [new file with mode: 0644]
lib/nbsd_libc/gen/minix/sysconf.c [new file with mode: 0644]
lib/nbsd_libc/gen/minix/times.c [new file with mode: 0644]
lib/nbsd_libc/gen/minix/uname.c [new file with mode: 0644]
lib/nbsd_libc/gen/minix/utime.c [new file with mode: 0644]
lib/nbsd_libc/gen/minix/wait.c [new file with mode: 0644]
lib/nbsd_libc/gen/minix/waitpid.c [new file with mode: 0644]
lib/nbsd_libc/net/minix/getifaddrs.c [new file with mode: 0644]
lib/nbsd_libc/net/minix/getpeereid.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/MISSING_SYSCALLS [new file with mode: 0644]
lib/nbsd_libc/sys-minix/Makefile.inc [new file with mode: 0644]
lib/nbsd_libc/sys-minix/__getcwd.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/__getlogin.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/_exit.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/_mcontext.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/_ucontext.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/accept.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/access.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/bind.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/brk.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/chdir.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/chmod.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/chown.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/chroot.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/close.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/connect.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/cprofile.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/dup.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/dup2.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/environ.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/execve.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/fchmod.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/fchown.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/fcntl.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/flock.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/fork.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/fpathconf.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/fstatvfs.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/fsync.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/ftruncate.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/getdents.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/getegid.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/geteuid.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/getgid.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/getgroups.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/getitimer.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/getpeername.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/getpgrp.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/getpid.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/getppid.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/getrlimit.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/getsockname.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/getsockopt.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/gettimeofday.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/getuid.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/ioctl.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/issetugid.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/kill.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/link.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/listen.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/loadname.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/lseek.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/lseek64.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/minix_rs.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/mkdir.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/mkfifo.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/mknod.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/mmap.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/mount.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/nanosleep.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/open.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/pathconf.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/pipe.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/poll.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/pread.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/priority.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/ptrace.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/pwrite.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/read.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/readlink.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/reboot.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/recvfrom.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/recvmsg.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/rename.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/rmdir.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/sbrk.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/select.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/sem.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/sendmsg.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/sendto.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/setgid.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/setgroups.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/setitimer.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/setsid.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/setsockopt.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/settimeofday.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/setuid.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/shmat.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/shmctl.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/shmget.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/shutdown.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/sigaction.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/sigpending.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/sigprocmask.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/sigreturn.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/sigsuspend.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/socket.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/socketpair.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/sprofile.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/stat.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/statvfs.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/stime.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/symlink.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/sync.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/syscall.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/sysuname.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/truncate.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/umask.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/unlink.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/vectorio.c [new file with mode: 0644]
lib/nbsd_libc/sys-minix/write.c [new file with mode: 0644]

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