Add NBSDLibc Minix specific files.

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.
This commit is contained in:
Gianluca Guida 2011-02-17 17:11:09 +00:00
parent d6e6ee3043
commit 4f294c247f
135 changed files with 7210 additions and 0 deletions

View file

@ -0,0 +1,9 @@
# rts sources
.PATH: ${.CURDIR}/arch/${ARCH}/sys-minix
SRCS+= \
__sigreturn.S \
_ipc.S \
_senda.S \
brksize.S \
ucontext.S

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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 */

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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

View file

@ -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 */

View file

@ -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);
}

View file

@ -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;
}
}

View file

@ -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);
}

View file

@ -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 $
*/

View file

@ -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));
}

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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. */
;
}

View file

@ -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;
}
}

View file

@ -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

View file

@ -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"

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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(;;) { }
}

View file

@ -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));
}

View file

@ -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 */
}

View file

@ -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;
}

View file

@ -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));
}

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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));
}

View file

@ -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));
}

View file

@ -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));
}

View file

@ -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));
}

View file

@ -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));
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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));
}

View file

@ -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));
}
}

View file

@ -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

View file

@ -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;
}

View file

@ -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));
}

View file

@ -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));
}

View file

@ -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));
}

View file

@ -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 **/

View file

@ -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));
}

View file

@ -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);
}
}

View file

@ -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));
}

View file

@ -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));
}

View file

@ -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));
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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));
}

View file

@ -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));
}

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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));
}

View file

@ -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));
}

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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));
}

View file

@ -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));
}

View file

@ -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;
}

View file

@ -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));
}

View file

@ -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));
}

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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));
}

View file

@ -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);
}

View file

@ -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));
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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));
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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));
}

View file

@ -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));
}

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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));
}

View file

@ -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));
}

View file

@ -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);
}

Some files were not shown because too many files have changed in this diff Show more