New sources layout
Change-Id: Ic716f336b7071063997cf5b4dae6d50e0b4631e9
This commit is contained in:
@@ -111,7 +111,7 @@ SUBDIR+= pkgconfig
|
||||
.include "${.CURDIR}/thread-stub/Makefile.inc"
|
||||
.include "${.CURDIR}/time/Makefile.inc"
|
||||
.if defined(__MINIX)
|
||||
.include "${.CURDIR}/sys-minix/Makefile.inc"
|
||||
.include "${NETBSDSRCDIR}/minix/lib/libc/sys/Makefile.inc"
|
||||
.else
|
||||
.include "${.CURDIR}/tls/Makefile.inc"
|
||||
.endif
|
||||
|
||||
@@ -27,7 +27,7 @@ SRCS+= _setjmp.S
|
||||
SRCS+= sigsetjmp.S
|
||||
|
||||
.if defined(__MINIX)
|
||||
# Already defined in sys-minix
|
||||
# Already defined in minix/lib/libc/arch/arm/sys
|
||||
.else
|
||||
SRCS+= makecontext.c resumecontext.c swapcontext.S
|
||||
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
# rts sources
|
||||
HERE=${ARCHDIR}/sys-minix
|
||||
.PATH: ${HERE}
|
||||
|
||||
TMP=ucontextoffsets.h.tmp
|
||||
CF=${HERE}/ucontextoffsets.cf
|
||||
|
||||
INCS+=ucontextoffsets.h
|
||||
|
||||
ucontext.o: ucontextoffsets.h
|
||||
|
||||
SRCS+= \
|
||||
__sigreturn.S \
|
||||
_do_kernel_call_intr.S \
|
||||
_ipc.S \
|
||||
brksize.S \
|
||||
get_minix_kerninfo.S \
|
||||
ucontext.S
|
||||
|
||||
ucontextoffsets.h: ${CF}
|
||||
ucontextoffsets.h: ${NETBSDSRCDIR}/sys/sys/ucontext.h
|
||||
ucontextoffsets.h: ${NETBSDSRCDIR}/include/arch/${MACHINE_ARCH}/include/stackframe.h
|
||||
ucontextoffsets.h:
|
||||
${_MKTARGET_CREATE}
|
||||
cat ${CF} | \
|
||||
${TOOL_GENASSYM} -- ${CC} ${CFLAGS} ${CPPFLAGS} ${PROF} >$TMP && \
|
||||
mv -f $TMP $@
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
/* 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)
|
||||
pop {r0} /* load sigframe.sf_scp into r0 as parameter */
|
||||
b _C_LABEL(sigreturn) /* _sigreturn(struct sigcontext *sf_scpcopy) */
|
||||
@@ -1,8 +0,0 @@
|
||||
#include <minix/ipcconst.h>
|
||||
#include <machine/asm.h>
|
||||
|
||||
ENTRY(_do_kernel_call_intr)
|
||||
/* r0 already holds msg ptr */
|
||||
mov r3, #KERVEC_INTR /* r3 determines the SVC type */
|
||||
svc #0 /* trap to kernel */
|
||||
bx lr
|
||||
@@ -1,74 +0,0 @@
|
||||
#include <minix/ipcconst.h>
|
||||
#include <machine/asm.h>
|
||||
|
||||
/**========================================================================* */
|
||||
/* IPC assembly routines * */
|
||||
/**========================================================================* */
|
||||
ENTRY(_ipc_send_intr)
|
||||
push {fp}
|
||||
mov fp, sp
|
||||
mov r2, r1 /* r2 = msg ptr */
|
||||
mov r1, r0 /* r1 = src_dest */
|
||||
mov r0, #SEND /* _ipc_send(dest, ptr) */
|
||||
mov r3, #IPCVEC_INTR /* r3 determines the SVC type */
|
||||
svc #0 /* trap to kernel */
|
||||
pop {fp}
|
||||
bx lr
|
||||
|
||||
ENTRY(_ipc_receive_intr)
|
||||
push {fp}
|
||||
mov fp, sp
|
||||
push {r2} /* save status ptr */
|
||||
mov r2, r1 /* r2 = msg ptr */
|
||||
mov r1, r0 /* r1 = src_dest */
|
||||
mov r0, #RECEIVE /* _ipc_receive(src, ptr) */
|
||||
mov r3, #IPCVEC_INTR /* r3 determines the SVC type */
|
||||
svc #0 /* trap to kernel */
|
||||
pop {r2} /* restore status ptr */
|
||||
str r1, [r2]
|
||||
pop {fp}
|
||||
bx lr
|
||||
|
||||
ENTRY(_ipc_sendrec_intr)
|
||||
push {fp}
|
||||
mov fp, sp
|
||||
mov r2, r1 /* r2 = msg ptr */
|
||||
mov r1, r0 /* r1 = src_dest */
|
||||
mov r0, #SENDREC /* _ipc_sendrec(srcdest, ptr) */
|
||||
mov r3, #IPCVEC_INTR /* r3 determines the SVC type */
|
||||
svc #0 /* trap to kernel */
|
||||
pop {fp}
|
||||
bx lr
|
||||
|
||||
ENTRY(_ipc_notify_intr)
|
||||
push {fp}
|
||||
mov fp, sp
|
||||
mov r1, r0 /* r1 = src_dest */
|
||||
mov r0, #NOTIFY /* _ipc_notify(srcdst) */
|
||||
mov r3, #IPCVEC_INTR /* r3 determines the SVC type */
|
||||
svc #0 /* trap to kernel */
|
||||
pop {fp}
|
||||
bx lr
|
||||
|
||||
ENTRY(_ipc_sendnb_intr)
|
||||
push {fp}
|
||||
mov fp, sp
|
||||
mov r2, r1 /* r2 = msg ptr */
|
||||
mov r1, r0 /* r1 = src_dest */
|
||||
mov r0, #SENDNB /* _ipc_sendnb(dest, ptr) */
|
||||
mov r3, #IPCVEC_INTR /* r3 determines the SVC type */
|
||||
svc #0 /* trap to kernel */
|
||||
pop {fp}
|
||||
bx lr
|
||||
|
||||
ENTRY(_ipc_senda_intr)
|
||||
push {fp}
|
||||
mov fp, sp
|
||||
mov r2, r0 /* r2 = table */
|
||||
/* r1 already holds count */
|
||||
mov r0, #SENDA /* _ipc_senda(table, count) */
|
||||
mov r3, #IPCVEC_INTR /* r3 determines the SVC type */
|
||||
svc #0 /* trap to kernel */
|
||||
pop {fp}
|
||||
bx lr
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
.globl _end
|
||||
.globl _brksize
|
||||
|
||||
.data
|
||||
_brksize: .long _end
|
||||
@@ -1,17 +0,0 @@
|
||||
#include <minix/ipcconst.h>
|
||||
#include <machine/asm.h>
|
||||
|
||||
ENTRY(get_minix_kerninfo)
|
||||
push {fp}
|
||||
mov fp, sp
|
||||
push {r0}
|
||||
mov r1, #0
|
||||
mov r2, #0
|
||||
mov r0, #MINIX_KERNINFO /* _get_minix_kerninfo() */
|
||||
mov r3, #IPCVEC_INTR /* r3 determines the SVC type */
|
||||
svc #0 /* trap to kernel */
|
||||
pop {r2} /* r2 = return struct ptr (was r0) */
|
||||
str r1, [r2]
|
||||
pop {fp}
|
||||
bx lr
|
||||
|
||||
@@ -1,143 +0,0 @@
|
||||
#include <machine/asm.h>
|
||||
#include <ucontextoffsets.h>
|
||||
|
||||
|
||||
IMPORT(getuctx)
|
||||
IMPORT(setuctx)
|
||||
IMPORT(resumecontext)
|
||||
|
||||
|
||||
/* int getcontext(ucontext_t *ucp)
|
||||
* Initialise the structure pointed to by ucp to the current user context
|
||||
* of the calling thread. */
|
||||
ENTRY(getcontext)
|
||||
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 r3, lr /* Save return address:
|
||||
* When setcontext or swapcontext is called,
|
||||
* we jump to this address and continue
|
||||
* running. */
|
||||
|
||||
/* r0 = ucp */
|
||||
|
||||
/* Check null pointer */
|
||||
cmp r0, #0 /* ucp == NULL? */
|
||||
bne 3f /* Not null, continue */
|
||||
mov r1, #EFAULT
|
||||
ldr r2, =_C_LABEL(errno)
|
||||
str r1, [r2] /* errno = EFAULT */
|
||||
mov r0, #-1 /* return -1 */
|
||||
bx lr
|
||||
|
||||
3: /* Check flags */
|
||||
ldr r1, [r0, #UC_FLAGS] /* r1 = ucp->uc_flags */
|
||||
and r1, r1, #[_UC_IGNFPU|_UC_IGNSIGM]
|
||||
cmp r1, #[_UC_IGNFPU|_UC_IGNSIGM] /* Allowed to ignore both? */
|
||||
beq 1f /* If so, skip getuctx */
|
||||
|
||||
0:
|
||||
push {r0, r3}
|
||||
bl _C_LABEL(getuctx) /* getuctx(ucp) */
|
||||
pop {r0, r3}
|
||||
|
||||
1:
|
||||
/* Save the context */
|
||||
mov lr, r3 /* Restore lr */
|
||||
str lr, [r0, #LRREG] /* Save lr */
|
||||
str lr, [r0, #PCREG] /* Save real RTA in mcp struct */
|
||||
str sp, [r0, #SPREG] /* Save stack pointer */
|
||||
str fp, [r0, #FPREG] /* Save fp */
|
||||
str r4, [r0, #REG4] /* Save r4 */
|
||||
str r5, [r0, #REG5] /* Save r5 */
|
||||
str r6, [r0, #REG6] /* Save r6 */
|
||||
str r7, [r0, #REG7] /* Save r7 */
|
||||
str r8, [r0, #REG8] /* Save r8 */
|
||||
str r9, [r0, #REG9] /* Save r9 */
|
||||
str r10, [r0, #REG10] /* Save r10 */
|
||||
|
||||
ldr r1, =MCF_MAGIC
|
||||
str r1, [r0, #MAGIC] /* Set magic value */
|
||||
|
||||
mov r1, #0
|
||||
str r1, [r0, #REG0] /* Return 0 */
|
||||
mov r0, #0 /* Return 0 */
|
||||
|
||||
2:
|
||||
bx lr /* 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. */
|
||||
|
||||
/* r0 = ucp */
|
||||
|
||||
/* Check null pointer */
|
||||
cmp r0, #0 /* ucp == NULL? */
|
||||
bne 3f /* Not null, continue */
|
||||
mov r1, #EFAULT
|
||||
ldr r2, =_C_LABEL(errno)
|
||||
str r1, [r2] /* errno = EFAULT */
|
||||
mov r0, #-1 /* return -1 */
|
||||
bx lr
|
||||
|
||||
3: /* Check flags */
|
||||
ldr r1, [r0, #MAGIC] /* r1 = ucp->mc_context.mc_magic */
|
||||
ldr r2, =MCF_MAGIC
|
||||
cmp r1, r2 /* is the magic value set (is context valid)?*/
|
||||
beq 4f /* is set, proceed */
|
||||
mov r1, #EINVAL /* not set, return error code */
|
||||
ldr r2, =_C_LABEL(errno)
|
||||
str r1, [r2] /* errno = EINVAL */
|
||||
mov r0, #-1 /* return -1 */
|
||||
bx lr
|
||||
|
||||
|
||||
4: ldr r1, [r0, #UC_FLAGS] /* r1 = ucp->uc_flags */
|
||||
and r1, r1, #[_UC_IGNFPU|_UC_IGNSIGM]
|
||||
cmp r1, #[_UC_IGNFPU|_UC_IGNSIGM] /* Allowed to ignore both? */
|
||||
beq 1f /* Neither are set, so don't bother restoring FPU
|
||||
* state and signal mask */
|
||||
|
||||
push {r0, r3}
|
||||
0: bl _C_LABEL(setuctx) /* setuctx(ucp) */
|
||||
pop {r0, r3}
|
||||
|
||||
1: /* Restore the registers */
|
||||
ldr r4, [r0, #REG4] /* Restore r4 */
|
||||
ldr r5, [r0, #REG5] /* Restore r5 */
|
||||
ldr r6, [r0, #REG6] /* Restore r6 */
|
||||
ldr r7, [r0, #REG7] /* Restore r7 */
|
||||
ldr r8, [r0, #REG8] /* Restore r8 */
|
||||
ldr r9, [r0, #REG9] /* Restore r9 */
|
||||
ldr r10, [r0, #REG10] /* Restore r10 */
|
||||
ldr r12, [r0, #REG12] /* Restore r12 */
|
||||
ldr fp, [r0, #FPREG] /* Restore fp */
|
||||
ldr sp, [r0, #SPREG] /* Restore sp */
|
||||
ldr lr, [r0, #LRREG] /* Restore lr */
|
||||
mov r3, r0
|
||||
ldr r0, [r3, #REG0] /* Restore r0 */
|
||||
2:
|
||||
ldr pc, [r3, #PCREG] /* Restore pc */
|
||||
|
||||
|
||||
/* void ctx_start()
|
||||
* A wrapper to call resumecontext. Makecontext puts the ucp in r4.
|
||||
* This function moves the ucp into r0 so that the ucp is the first
|
||||
* parameter for resumecontext. The call to resumecontext will start
|
||||
* the next context in the linked list (or exit the program if there
|
||||
* is no context). */
|
||||
ENTRY(ctx_start)
|
||||
mov r0, r4
|
||||
b _C_LABEL(resumecontext)
|
||||
@@ -1,31 +0,0 @@
|
||||
|
||||
include <minix/type.h>
|
||||
include <sys/ucontext.h>
|
||||
include <sys/errno.h>
|
||||
include <machine/mcontext.h>
|
||||
|
||||
struct __ucontext
|
||||
member UC_FLAGS uc_flags
|
||||
member UC_LINK uc_link
|
||||
member MAGIC uc_mcontext.mc_magic
|
||||
member REG0 uc_mcontext.__gregs[_REG_R0]
|
||||
member REG1 uc_mcontext.__gregs[_REG_R1]
|
||||
member REG2 uc_mcontext.__gregs[_REG_R2]
|
||||
member REG3 uc_mcontext.__gregs[_REG_R3]
|
||||
member REG4 uc_mcontext.__gregs[_REG_R4]
|
||||
member REG5 uc_mcontext.__gregs[_REG_R5]
|
||||
member REG6 uc_mcontext.__gregs[_REG_R6]
|
||||
member REG7 uc_mcontext.__gregs[_REG_R7]
|
||||
member REG8 uc_mcontext.__gregs[_REG_R8]
|
||||
member REG9 uc_mcontext.__gregs[_REG_R9]
|
||||
member REG10 uc_mcontext.__gregs[_REG_R10]
|
||||
member FPREG uc_mcontext.__gregs[_REG_FP]
|
||||
member REG12 uc_mcontext.__gregs[_REG_R12]
|
||||
member SPREG uc_mcontext.__gregs[_REG_SP]
|
||||
member LRREG uc_mcontext.__gregs[_REG_LR]
|
||||
member PCREG uc_mcontext.__gregs[_REG_PC]
|
||||
define EFAULT EFAULT
|
||||
define EINVAL EINVAL
|
||||
define MCF_MAGIC MCF_MAGIC
|
||||
define _UC_IGNFPU _UC_IGNFPU
|
||||
define _UC_IGNSIGM _UC_IGNSIGM
|
||||
@@ -9,7 +9,7 @@ SRCS+= alloca.S byte_swap_2.S byte_swap_4.S fabs.S \
|
||||
SRCS+= setjmp.S _setjmp.S sigsetjmp.S
|
||||
|
||||
.if defined(__MINIX)
|
||||
# Already defined in sys-minix
|
||||
# Already defined in minix/lib/libc/arch/i386/sys
|
||||
.else
|
||||
SRCS+= resumecontext.S swapcontext.S
|
||||
.endif
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
# rts sources
|
||||
HERE=${ARCHDIR}/sys-minix
|
||||
.PATH: ${HERE}
|
||||
|
||||
TMP=ucontextoffsets.h.tmp
|
||||
CF=${HERE}/ucontextoffsets.cf
|
||||
|
||||
INCS+=ucontextoffsets.h
|
||||
|
||||
ucontext.o: ucontextoffsets.h
|
||||
|
||||
SRCS+= \
|
||||
__sigreturn.S \
|
||||
_do_kernel_call_intr.S \
|
||||
_ipc.S \
|
||||
brksize.S \
|
||||
get_minix_kerninfo.S \
|
||||
ucontext.S
|
||||
|
||||
ucontextoffsets.h: ${CF}
|
||||
ucontextoffsets.h: ${NETBSDSRCDIR}/sys/sys/ucontext.h
|
||||
ucontextoffsets.h: ${NETBSDSRCDIR}/include/arch/${MACHINE_ARCH}/include/stackframe.h
|
||||
ucontextoffsets.h:
|
||||
${_MKTARGET_CREATE}
|
||||
cat ${CF} | \
|
||||
${TOOL_GENASSYM} -- ${CC} ${CFLAGS} ${CPPFLAGS} ${PROF} >$TMP && \
|
||||
mv -f $TMP $@
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
/* 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
|
||||
#ifndef __PIC__
|
||||
jmp _C_LABEL(sigreturn)
|
||||
#else
|
||||
PIC_PROLOGUE /* push %ebx, but we do not care */
|
||||
pop %eax /* special knowledge of how PIC works: discard pushed EBX */
|
||||
jmp PIC_PLT(_C_LABEL(sigreturn))
|
||||
#endif /* PIC */
|
||||
@@ -1,8 +0,0 @@
|
||||
#include <minix/ipcconst.h>
|
||||
#include <machine/asm.h>
|
||||
|
||||
ENTRY(_do_kernel_call_intr)
|
||||
/* pass the message pointer to kernel in the %eax register */
|
||||
movl 4(%esp), %eax
|
||||
int $KERVEC_INTR
|
||||
ret
|
||||
@@ -1,88 +0,0 @@
|
||||
#include <minix/ipcconst.h>
|
||||
#include <machine/asm.h>
|
||||
|
||||
SRC_DST = 8 /* source/ destination process */
|
||||
MESSAGE = 12 /* message pointer */
|
||||
STATUS = 16 /* status pointer */
|
||||
|
||||
/* For _ipc_senda() */
|
||||
MSGTAB = 8 /* message table */
|
||||
TABCOUNT = 12 /* number of entries in message table */
|
||||
|
||||
/**========================================================================* */
|
||||
/* IPC assembly routines * */
|
||||
/**========================================================================* */
|
||||
/* all message passing routines save ebx, but destroy eax and ecx. */
|
||||
ENTRY(_ipc_send_intr)
|
||||
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 /* _ipc_send(dest, ptr) */
|
||||
int $IPCVEC_INTR /* trap to the kernel */
|
||||
pop %ebx
|
||||
pop %ebp
|
||||
ret
|
||||
|
||||
ENTRY(_ipc_receive_intr)
|
||||
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 /* _ipc_receive(src, ptr) */
|
||||
int $IPCVEC_INTR /* trap to the kernel */
|
||||
movl STATUS(%ebp), %ecx /* ecx = status pointer */
|
||||
movl %ebx, (%ecx)
|
||||
pop %ebx
|
||||
pop %ebp
|
||||
ret
|
||||
|
||||
ENTRY(_ipc_sendrec_intr)
|
||||
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 /* _ipc_sendrec(srcdest, ptr) */
|
||||
int $IPCVEC_INTR /* trap to the kernel */
|
||||
pop %ebx
|
||||
pop %ebp
|
||||
ret
|
||||
|
||||
ENTRY(_ipc_notify_intr)
|
||||
push %ebp
|
||||
movl %esp, %ebp
|
||||
push %ebx
|
||||
movl SRC_DST(%ebp), %eax /* eax = destination */
|
||||
movl $NOTIFY, %ecx /* _ipc_notify(srcdst) */
|
||||
int $IPCVEC_INTR /* trap to the kernel */
|
||||
pop %ebx
|
||||
pop %ebp
|
||||
ret
|
||||
|
||||
ENTRY(_ipc_sendnb_intr)
|
||||
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 /* _ipc_sendnb(dest, ptr) */
|
||||
int $IPCVEC_INTR /* trap to the kernel */
|
||||
pop %ebx
|
||||
pop %ebp
|
||||
ret
|
||||
|
||||
ENTRY(_ipc_senda_intr)
|
||||
push %ebp
|
||||
movl %esp, %ebp
|
||||
push %ebx
|
||||
movl TABCOUNT(%ebp), %eax /* eax = count */
|
||||
movl MSGTAB(%ebp), %ebx /* ebx = table */
|
||||
movl $SENDA, %ecx /* _ipc_senda(table, count) */
|
||||
int $IPCVEC_INTR /* trap to the kernel */
|
||||
pop %ebx
|
||||
pop %ebp
|
||||
ret
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
.globl _end
|
||||
.globl _brksize
|
||||
|
||||
.data
|
||||
_brksize: .long _end
|
||||
@@ -1,17 +0,0 @@
|
||||
#include <minix/ipcconst.h>
|
||||
#include <machine/asm.h>
|
||||
|
||||
ENTRY(get_minix_kerninfo)
|
||||
push %ebp
|
||||
movl %esp, %ebp
|
||||
push %ebx
|
||||
movl $0, %eax
|
||||
movl $0, %ebx
|
||||
movl $MINIX_KERNINFO, %ecx
|
||||
int $IPCVEC_INTR /* trap to the kernel */
|
||||
movl 8(%ebp), %ecx /* ecx = return struct ptr */
|
||||
movl %ebx, (%ecx)
|
||||
pop %ebx
|
||||
pop %ebp
|
||||
ret
|
||||
|
||||
@@ -1,144 +0,0 @@
|
||||
#include <machine/asm.h>
|
||||
#include <ucontextoffsets.h>
|
||||
|
||||
IMPORT(getuctx)
|
||||
IMPORT(setuctx)
|
||||
IMPORT(resumecontext)
|
||||
|
||||
.globl _C_LABEL(__errno)
|
||||
|
||||
/* int getcontext(ucontext_t *ucp)
|
||||
* Initialise the structure pointed to by ucp to the current user context
|
||||
* of the calling thread. */
|
||||
ENTRY(getcontext)
|
||||
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 4(%esp), %edx /* edx = ucp */
|
||||
/* Check null pointer */
|
||||
cmp $0, %edx /* edx == NULL? */
|
||||
jne 3f /* Not null, continue */
|
||||
PIC_PROLOGUE
|
||||
call PIC_PLT(_C_LABEL(__errno))
|
||||
PIC_EPILOGUE
|
||||
movl $EFAULT, (%eax)
|
||||
xor %eax, %eax
|
||||
dec %eax /* return -1 */
|
||||
ret
|
||||
|
||||
3: /* Check flags */
|
||||
mov UC_FLAGS(%edx), %eax /* eax = ucp->uc_flags */
|
||||
and $[_UC_IGNFPU|_UC_IGNSIGM], %eax
|
||||
cmp $[_UC_IGNFPU|_UC_IGNSIGM], %eax
|
||||
jz 5f /* Ignore both, skip getuctx */
|
||||
PIC_PROLOGUE
|
||||
push %edx /* push a copy for us */
|
||||
push %edx /* push a copy as function argument */
|
||||
call PIC_PLT(_C_LABEL(getuctx)) /* getuctx(ucp) */
|
||||
pop %edx /* clean up stack */
|
||||
pop %edx /* clean up stack and restore edx */
|
||||
PIC_EPILOGUE
|
||||
|
||||
5:
|
||||
/* Save the context */
|
||||
pop PC(%edx) /* Save real RTA in mcp struct */
|
||||
mov %esp, SP(%edx) /* Save stack pointer (now pointing to ucp) */
|
||||
/* Save GP registers (except EAX and EDX) */
|
||||
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 */
|
||||
xor %eax, %eax /* Return 0 */
|
||||
jmp *PC(%edx) /* Return 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, %edx
|
||||
0: push %edx /* preserve errno */
|
||||
PIC_PROLOGUE
|
||||
call PIC_PLT(_C_LABEL(__errno))
|
||||
PIC_EPILOGUE
|
||||
pop %edx
|
||||
movl %edx, (%eax)
|
||||
xor %eax, %eax
|
||||
dec %eax /* return -1 */
|
||||
ret
|
||||
|
||||
3: /* Check flags */
|
||||
cmpl $MCF_MAGIC, MAGIC(%edx) /* is the magic value set (is context valid)?*/
|
||||
jz 4f /* is set, proceed */
|
||||
movl $EINVAL, %edx /* not set, return error code */
|
||||
jmp 0b
|
||||
|
||||
|
||||
4: mov UC_FLAGS(%edx), %eax /* eax = ucp->uc_flags */
|
||||
and $[_UC_IGNFPU|_UC_IGNSIGM], %eax
|
||||
cmp $[_UC_IGNFPU|_UC_IGNSIGM], %eax
|
||||
jz 5f /* Ignore both, so don't bother restoring FPU
|
||||
* state and signal mask */
|
||||
|
||||
PIC_PROLOGUE
|
||||
push %edx /* push a copy for us */
|
||||
push %edx /* push a copy as function argument */
|
||||
call PIC_PLT(_C_LABEL(setuctx)) /* setuctx(ucp) */
|
||||
pop %edx /* clean up stack */
|
||||
pop %edx /* clean up stack and restore edx */
|
||||
PIC_EPILOGUE
|
||||
|
||||
5: /* Restore the registers (except EAX and EDX) */
|
||||
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 */
|
||||
xor %eax, %eax /* Return 0 */
|
||||
jmp *PC(%edx) /* Return to RTA */
|
||||
|
||||
/* 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).
|
||||
*
|
||||
* Since PIC needs the EBX register, which is pushed on the stack by
|
||||
* PIC_PROLOGUE, we need an extra of salsa here.
|
||||
*/
|
||||
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) */
|
||||
PIC_PROLOGUE /* may push %ebx, but we do not care */
|
||||
mov %esi, %esp /* Clean up stack, keep %ebx = &GOT */
|
||||
/* ucp is now at the top of the stack again */
|
||||
call PIC_PLT(_C_LABEL(resumecontext)) /* resumecontext(ucp) */
|
||||
ret /* never reached */
|
||||
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
|
||||
include <minix/type.h>
|
||||
include <sys/ucontext.h>
|
||||
include <sys/errno.h>
|
||||
include <machine/mcontext.h>
|
||||
|
||||
struct __ucontext
|
||||
member UC_FLAGS uc_flags
|
||||
member UC_LINK uc_link
|
||||
member MAGIC uc_mcontext.mc_magic
|
||||
member DI uc_mcontext.__gregs[_REG_EDI]
|
||||
member SI uc_mcontext.__gregs[_REG_ESI]
|
||||
member BP uc_mcontext.__gregs[_REG_EBP]
|
||||
member AX uc_mcontext.__gregs[_REG_EAX]
|
||||
member BX uc_mcontext.__gregs[_REG_EBX]
|
||||
member CX uc_mcontext.__gregs[_REG_ECX]
|
||||
member DX uc_mcontext.__gregs[_REG_EDX]
|
||||
member PC uc_mcontext.__gregs[_REG_EIP]
|
||||
member SP uc_mcontext.__gregs[_REG_ESP]
|
||||
define EFAULT EFAULT
|
||||
define EINVAL EINVAL
|
||||
define MCF_MAGIC MCF_MAGIC
|
||||
define _UC_IGNFPU _UC_IGNFPU
|
||||
define _UC_IGNSIGM _UC_IGNSIGM
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
# gen sources
|
||||
.if defined(__MINIX)
|
||||
.PATH: ${.CURDIR}/gen/minix
|
||||
.PATH: ${NETBSDSRCDIR}/minix/lib/libc/gen
|
||||
.endif # defined(__MINIX)
|
||||
.PATH: ${ARCHDIR}/gen ${.CURDIR}/gen
|
||||
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
/* getdomainname() Author: Kees J. Bot
|
||||
* 2 Dec 1994
|
||||
*/
|
||||
#define nil 0
|
||||
#include "namespace.h"
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __weak_alias
|
||||
__weak_alias(getdomainname, _getdomainname)
|
||||
#endif
|
||||
|
||||
int getdomainname(char *result, size_t size)
|
||||
{
|
||||
char nodename[256];
|
||||
char *domain;
|
||||
|
||||
if (gethostname(nodename, sizeof(nodename)) < 0)
|
||||
return -1;
|
||||
nodename[sizeof(nodename)-1]= 0;
|
||||
if ((domain = strchr(nodename, '.')) != NULL)
|
||||
strncpy(result, domain+1, size);
|
||||
else
|
||||
result[0] = '\0';
|
||||
|
||||
if (size > 0) result[size-1]= 0;
|
||||
return 0;
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
/* 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 <minix/paths.h>
|
||||
|
||||
#ifdef __weak_alias
|
||||
__weak_alias(gethostname, _gethostname)
|
||||
#endif
|
||||
|
||||
int gethostname(char *buf, size_t len)
|
||||
{
|
||||
int fd;
|
||||
int r;
|
||||
char *nl;
|
||||
|
||||
if ((fd= open(_PATH_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;
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
#include <sys/cdefs.h>
|
||||
#include "namespace.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <minix/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;
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
/*
|
||||
getpagesize.c
|
||||
*/
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/types.h>
|
||||
#include "namespace.h"
|
||||
|
||||
#include <machine/param.h>
|
||||
#include <machine/vmparam.h>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef __weak_alias
|
||||
__weak_alias(getpagesize, _getpagesize)
|
||||
#endif
|
||||
|
||||
int getpagesize(void)
|
||||
{
|
||||
return PAGE_SIZE;
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
/* getpass() - read a password Author: Kees J. Bot
|
||||
* Feb 16 1993
|
||||
*/
|
||||
#include <sys/cdefs.h>
|
||||
#include "namespace.h"
|
||||
|
||||
#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;
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
/*
|
||||
* (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);
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
/* 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 <errno.h>
|
||||
#include <minix/paths.h>
|
||||
|
||||
#ifdef __weak_alias
|
||||
__weak_alias(sethostname, _sethostname)
|
||||
#endif
|
||||
|
||||
int sethostname(const char *buf, size_t len)
|
||||
{
|
||||
int fd;
|
||||
int r;
|
||||
int tmperr;
|
||||
char name[20];
|
||||
strlcpy(name, "/tmp/hostname.XXXXX",sizeof(name));
|
||||
fd = mkstemp(name);
|
||||
|
||||
if (fd == -1)
|
||||
return -1;
|
||||
|
||||
r = fchmod(fd, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
||||
|
||||
if (r == -1) {
|
||||
tmperr = errno;
|
||||
close(fd);
|
||||
unlink(name);
|
||||
errno = tmperr;
|
||||
return -1;
|
||||
}
|
||||
|
||||
r = write(fd, buf, len);
|
||||
tmperr = errno;
|
||||
close(fd);
|
||||
|
||||
if (r == -1) {
|
||||
unlink(name);
|
||||
errno = tmperr;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (r < len) {
|
||||
unlink(name);
|
||||
errno = ENOSPC;
|
||||
return -1;
|
||||
}
|
||||
|
||||
r = rename(name, _PATH_HOSTNAME_FILE);
|
||||
|
||||
if (r == -1) {
|
||||
tmperr = errno;
|
||||
unlink(name);
|
||||
errno = tmperr;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
/* 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 <minix/paths.h>
|
||||
|
||||
#ifdef __weak_alias
|
||||
__weak_alias(sysconf, __sysconf)
|
||||
#endif
|
||||
|
||||
static u32_t get_hz(void)
|
||||
{
|
||||
FILE *fp;
|
||||
u32_t hz;
|
||||
int r;
|
||||
|
||||
if ((fp = fopen(_PATH_PROC "hz", "r")) != NULL)
|
||||
{
|
||||
r = fscanf(fp, "%u", &hz);
|
||||
|
||||
fclose(fp);
|
||||
|
||||
if (r == 1)
|
||||
return hz;
|
||||
}
|
||||
|
||||
return DEFAULT_HZ;
|
||||
}
|
||||
|
||||
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) _POSIX_STREAM_MAX;
|
||||
|
||||
case _SC_TZNAME_MAX:
|
||||
return (long) _POSIX_TZNAME_MAX;
|
||||
|
||||
case _SC_PAGESIZE:
|
||||
return getpagesize();
|
||||
|
||||
case _SC_LINE_MAX:
|
||||
return (long) LINE_MAX;
|
||||
|
||||
default:
|
||||
errno = EINVAL;
|
||||
return -1L;
|
||||
}
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
/* 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(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 $
|
||||
*/
|
||||
@@ -1,22 +0,0 @@
|
||||
#include <sys/cdefs.h>
|
||||
#include <lib.h>
|
||||
#include "namespace.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#ifdef __weak_alias
|
||||
__weak_alias(wait, _wait)
|
||||
#endif
|
||||
|
||||
pid_t wait(int * status)
|
||||
{
|
||||
message m;
|
||||
|
||||
memset(&m, 0, sizeof(m));
|
||||
m.m_lc_pm_waitpid.pid = -1;
|
||||
m.m_lc_pm_waitpid.options = 0;
|
||||
if (_syscall(PM_PROC_NR, PM_WAITPID, &m) < 0) return(-1);
|
||||
if (status != 0) *status = m.m_pm_lc_waitpid.status;
|
||||
return(m.m_type);
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
#include <sys/cdefs.h>
|
||||
#include <lib.h>
|
||||
#include "namespace.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#ifdef __weak_alias
|
||||
__weak_alias(waitpid, _waitpid)
|
||||
#endif
|
||||
|
||||
pid_t waitpid(pid_t pid, int *status, int options)
|
||||
{
|
||||
message m;
|
||||
|
||||
memset(&m, 0, sizeof(m));
|
||||
m.m_lc_pm_waitpid.pid = pid;
|
||||
m.m_lc_pm_waitpid.options = options;
|
||||
if (_syscall(PM_PROC_NR, PM_WAITPID, &m) < 0) return(-1);
|
||||
if (status != 0) *status = m.m_pm_lc_waitpid.status;
|
||||
return m.m_type;
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
# MINIX Specifics sources
|
||||
.PATH: ${.CURDIR}/minix
|
||||
|
||||
SRCS+= minix-malloc.c minix-calloc.c
|
||||
SRCS+= minix-malloc-debug.c
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
#include <minix/u64.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
/* malloc-debug.c */
|
||||
void *_dbg_malloc(size_t size);
|
||||
void *_dbg_realloc(void *oldp, size_t size);
|
||||
void _dbg_free(void *ptr);
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
/* $Header$ */
|
||||
#include <stdlib.h>
|
||||
|
||||
/* replace undef by define */
|
||||
#define ALIGN_EIGHT_BYTES /* Use 8-byte alignment. */
|
||||
|
||||
#ifdef ALIGN_EIGHT_BYTES
|
||||
#define ALIGN_SIZE 8
|
||||
#else
|
||||
#define ALIGN_SIZE sizeof(size_t)
|
||||
#endif
|
||||
|
||||
#define ALIGN(x) (((x) + (ALIGN_SIZE - 1)) & ~(ALIGN_SIZE - 1))
|
||||
|
||||
void *
|
||||
calloc(size_t nelem, size_t elsize)
|
||||
{
|
||||
register char *p;
|
||||
register size_t *q;
|
||||
size_t size = ALIGN(nelem * elsize);
|
||||
|
||||
p = malloc(size);
|
||||
if (p == NULL) return NULL;
|
||||
q = (size_t *) (p + size);
|
||||
while ((char *) q > p) *--q = 0;
|
||||
return p;
|
||||
}
|
||||
|
||||
@@ -1,245 +0,0 @@
|
||||
/* pointless without assertions */
|
||||
#ifdef NDEBUG
|
||||
#undef NDEBUG
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <machine/vm.h>
|
||||
#include <machine/vmparam.h>
|
||||
#include <minix/minlib.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "malloc-debug.h"
|
||||
|
||||
#if 0
|
||||
#include <stdio.h>
|
||||
static int reenter;
|
||||
#define LOG(args) if (!reenter) { reenter++; printf args; reenter--; }
|
||||
#else
|
||||
#define LOG(args)
|
||||
#endif
|
||||
|
||||
struct block {
|
||||
size_t size;
|
||||
unsigned magic;
|
||||
};
|
||||
|
||||
static u8_t *ptr_min, *ptr_max;
|
||||
|
||||
static unsigned long page_round_down(unsigned long x)
|
||||
{
|
||||
return x - x % PAGE_SIZE;
|
||||
}
|
||||
|
||||
static unsigned long page_round_up(unsigned long x)
|
||||
{
|
||||
unsigned long rem;
|
||||
|
||||
rem = x % PAGE_SIZE;
|
||||
if (rem)
|
||||
x += PAGE_SIZE - rem;
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
#define page_round_down_ptr(x) ((u8_t *) page_round_down((unsigned long) (x)))
|
||||
#define page_round_up_ptr(x) ((u8_t *) page_round_up((unsigned long) (x)))
|
||||
|
||||
static unsigned long block_compute_magic(struct block *block)
|
||||
{
|
||||
return (unsigned long) block + block->size + 0xDEADBEEFUL;
|
||||
}
|
||||
|
||||
static size_t block_get_totalsize(size_t size)
|
||||
{
|
||||
return page_round_up(sizeof(struct block) + size);
|
||||
}
|
||||
|
||||
static u8_t *block_get_endptr(struct block *block)
|
||||
{
|
||||
return (u8_t *) block + block_get_totalsize(block->size);
|
||||
}
|
||||
|
||||
static u8_t *block_get_dataptr(struct block *block)
|
||||
{
|
||||
return block_get_endptr(block) - block->size;
|
||||
}
|
||||
|
||||
static void block_check(struct block *block)
|
||||
{
|
||||
u8_t *dataptr, *p;
|
||||
|
||||
/* check location */
|
||||
assert(block);
|
||||
assert(!((unsigned long) block % PAGE_SIZE));
|
||||
assert((u8_t *) block >= ptr_min);
|
||||
assert((u8_t *) block <= ptr_max);
|
||||
|
||||
/* check size */
|
||||
assert(block->size > 0);
|
||||
|
||||
/* check fillers */
|
||||
assert(block->magic == block_compute_magic(block));
|
||||
dataptr = block_get_dataptr(block);
|
||||
for (p = (u8_t *) (block + 1); p < dataptr; p++)
|
||||
assert(*p == ((unsigned long) p & 0xff));
|
||||
}
|
||||
|
||||
static struct block *block_alloc(size_t size)
|
||||
{
|
||||
struct block *block;
|
||||
u8_t *dataptr, *p, *ptr;
|
||||
unsigned page_index, page_index_max;
|
||||
size_t sizerem, totalsize;
|
||||
u64_t tsc;
|
||||
|
||||
LOG(("block_alloc; size=0x%x\n", size));
|
||||
assert(size > 0);
|
||||
|
||||
/* round size up to machine word size */
|
||||
sizerem = size % sizeof(long);
|
||||
if (sizerem)
|
||||
size += sizeof(long) - sizerem;
|
||||
|
||||
/* initialize address range */
|
||||
if (!ptr_min && !ptr_max) {
|
||||
/* keep a safe distance from areas that are in use:
|
||||
* - 4MB from the break (should not change if traditional
|
||||
* malloc is not used so a small margin is sufficient
|
||||
* - 256MB from the stack (big margin because memory beyond
|
||||
* this may be allocated by mmap when the address space
|
||||
* starts to fill up)
|
||||
*/
|
||||
ptr_min = page_round_up_ptr((u8_t *) sbrk(0) + 0x400000);
|
||||
ptr_max = page_round_down_ptr((u8_t *) &size - 0x10000000);
|
||||
}
|
||||
assert(ptr_min);
|
||||
assert(ptr_max);
|
||||
assert(ptr_min < ptr_max);
|
||||
|
||||
/* select address at random */
|
||||
tsc = 0;
|
||||
/* LSC FIXME Broken for now... */
|
||||
/* read_tsc_64(&tsc); */
|
||||
totalsize = block_get_totalsize(size);
|
||||
page_index_max = (ptr_max - ptr_min - totalsize) / PAGE_SIZE;
|
||||
page_index = (page_index_max > 0) ? (ex64lo(tsc) % page_index_max) : 0;
|
||||
ptr = ptr_min + page_index * PAGE_SIZE;
|
||||
|
||||
/* allocate block */
|
||||
block = (struct block *) mmap(
|
||||
ptr, /* addr */
|
||||
totalsize, /* len */
|
||||
PROT_READ|PROT_WRITE, /* prot */
|
||||
MAP_PREALLOC, /* flags */
|
||||
-1, /* fd */
|
||||
0); /* offset */
|
||||
if (block == MAP_FAILED) {
|
||||
/* mmap call failed */
|
||||
abort();
|
||||
}
|
||||
|
||||
/* block may not be at the requested location if that is in use */
|
||||
if (ptr_min > (u8_t *) block)
|
||||
ptr_min = (u8_t *) block;
|
||||
|
||||
if (ptr_max < (u8_t *) block)
|
||||
ptr_max = (u8_t *) block;
|
||||
|
||||
/* initialize block, including fillers */
|
||||
block->size = size;
|
||||
block->magic = block_compute_magic(block);
|
||||
dataptr = block_get_dataptr(block);
|
||||
for (p = (u8_t *) (block + 1); p < dataptr; p++)
|
||||
*p = ((unsigned long) p & 0xff);
|
||||
|
||||
LOG(("block_alloc; block=0x%x\n", block));
|
||||
return block;
|
||||
}
|
||||
|
||||
static struct block *block_find(const void *ptr)
|
||||
{
|
||||
struct block *block;
|
||||
|
||||
LOG(("block_find; ptr=0x%x\n", ptr));
|
||||
assert(ptr);
|
||||
|
||||
/* locate block based on pointer, then check whether it is valid */
|
||||
block = (struct block *) page_round_down(
|
||||
(unsigned long) ((struct block *) __UNCONST(ptr) - 1));
|
||||
block_check(block);
|
||||
LOG(("block_find; block=0x%x\n", block));
|
||||
return block;
|
||||
}
|
||||
|
||||
static void block_free(struct block *block)
|
||||
{
|
||||
LOG(("block_free; block=0x%x\n", block));
|
||||
assert(block);
|
||||
|
||||
/* simply unmap the block */
|
||||
if (munmap(block, block_get_totalsize(block->size)) < 0) {
|
||||
/* munmap call failed */
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
void *_dbg_malloc(size_t size)
|
||||
{
|
||||
struct block *newblock;
|
||||
u8_t *ptr;
|
||||
|
||||
LOG(("_dbg_malloc; size=0x%x\n", size));
|
||||
assert(size > 0); /* enforced by regular malloc */
|
||||
|
||||
newblock = block_alloc(size);
|
||||
if (!newblock)
|
||||
return NULL;
|
||||
|
||||
ptr = block_get_dataptr(newblock);
|
||||
LOG(("_dbg_malloc; ptr=0x%x\n", ptr));
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void *_dbg_realloc(void *oldp, size_t size)
|
||||
{
|
||||
u8_t *newp;
|
||||
struct block *oldblock, *newblock;
|
||||
|
||||
LOG(("_dbg_realloc; oldp=0x%x; size=0x%x\n", oldp, size));
|
||||
assert(oldp); /* enforced by regular realloc */
|
||||
assert(size > 0); /* enforced by regular realloc */
|
||||
|
||||
/* always allocate new block */
|
||||
newblock = block_alloc(size);
|
||||
if (!newblock)
|
||||
return NULL;
|
||||
|
||||
/* copy the data */
|
||||
oldblock = block_find(oldp);
|
||||
memcpy(block_get_dataptr(newblock),
|
||||
block_get_dataptr(oldblock),
|
||||
MIN(newblock->size, oldblock->size));
|
||||
|
||||
/* deallocate old block */
|
||||
block_free(oldblock);
|
||||
|
||||
newp = block_get_dataptr(newblock);
|
||||
LOG(("_dbg_realloc; newp=0x%x\n", newp));
|
||||
return newp;
|
||||
}
|
||||
|
||||
void _dbg_free(void *ptr)
|
||||
{
|
||||
LOG(("_dbg_free; ptr=0x%x\n", ptr));
|
||||
assert(ptr); /* enforced by regular free */
|
||||
|
||||
/* find the block and free it */
|
||||
block_free(block_find(ptr));
|
||||
|
||||
LOG(("_dbg_free done\n"));
|
||||
}
|
||||
|
||||
@@ -1,250 +0,0 @@
|
||||
/* $Header$ */
|
||||
|
||||
/* replace undef by define */
|
||||
#define ALIGN_EIGHT_BYTES /* Use 8-byte alignment. */
|
||||
#define DEBUG /* check assertions */
|
||||
#undef SLOWDEBUG /* some extra test loops (requires DEBUG) */
|
||||
|
||||
#ifndef DEBUG
|
||||
#define NDEBUG
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "malloc-debug.h"
|
||||
|
||||
static int no_debug = -1;
|
||||
#define CHECK_DBG(statement) \
|
||||
if (no_debug <= 0) { \
|
||||
if (no_debug < 0) no_debug = getenv("MALLOC_DEBUG") ? 0 : 1; \
|
||||
if (no_debug == 0) { statement; } \
|
||||
}
|
||||
|
||||
#define ptrint int
|
||||
|
||||
#define BRKSIZE 4096
|
||||
#ifdef ALIGN_EIGHT_BYTES
|
||||
#define PTRSIZE 8
|
||||
#else
|
||||
#define PTRSIZE ((int) sizeof(void *))
|
||||
#endif
|
||||
#define Align(x,a) (((x) + (a - 1)) & ~(a - 1))
|
||||
#define NextSlot(p) (* (void **) ((p) - PTRSIZE))
|
||||
#define NextFree(p) (* (void **) (p))
|
||||
|
||||
/*
|
||||
* A short explanation of the data structure and algorithms.
|
||||
* An area returned by malloc() is called a slot. Each slot
|
||||
* contains the number of bytes requested, but preceeded by
|
||||
* an extra pointer to the next the slot in memory.
|
||||
* '_bottom' and '_top' point to the first/last slot.
|
||||
* More memory is asked for using brk() and appended to top.
|
||||
* The list of free slots is maintained to keep malloc() fast.
|
||||
* '_empty' points the the first free slot. Free slots are
|
||||
* linked together by a pointer at the start of the
|
||||
* user visable part, so just after the next-slot pointer.
|
||||
* Free slots are merged together by free().
|
||||
*
|
||||
* Since modern processors prefer 8-byte alignment, we now pretend
|
||||
* our pointers are 8 bytes wide.
|
||||
*/
|
||||
|
||||
extern void *_sbrk(int);
|
||||
extern int _brk(void *);
|
||||
static void *_bottom, *_top, *_empty;
|
||||
|
||||
static int grow(size_t len)
|
||||
{
|
||||
register char *p;
|
||||
|
||||
assert(NextSlot((char *)_top) == 0);
|
||||
if ((char *) _top + len < (char *) _top
|
||||
|| (p = (char *)Align((ptrint)_top + len, BRKSIZE)) < (char *) _top ) {
|
||||
errno = ENOMEM;
|
||||
return(0);
|
||||
}
|
||||
if (_brk(p) != 0)
|
||||
return(0);
|
||||
NextSlot((char *)_top) = p;
|
||||
NextSlot(p) = 0;
|
||||
free(_top);
|
||||
_top = p;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void *
|
||||
malloc(const size_t size)
|
||||
{
|
||||
register char *prev, *p, *next, *new;
|
||||
unsigned ntries;
|
||||
|
||||
if (size == 0)
|
||||
return NULL;
|
||||
|
||||
CHECK_DBG(return _dbg_malloc(size));
|
||||
|
||||
for (ntries = 0; ntries < 2; ntries++) {
|
||||
unsigned len = Align(size, PTRSIZE) + PTRSIZE;
|
||||
if (len < 2 * PTRSIZE) {
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
if (_bottom == 0) {
|
||||
if ((p = _sbrk(2 * PTRSIZE)) == (char *) -1)
|
||||
return NULL;
|
||||
p = (char *) Align((ptrint)p, PTRSIZE);
|
||||
p += PTRSIZE;
|
||||
_top = _bottom = p;
|
||||
NextSlot(p) = 0;
|
||||
}
|
||||
#ifdef SLOWDEBUG
|
||||
for (p = _bottom; (next = NextSlot(p)) != 0; p = next)
|
||||
assert(next > p);
|
||||
assert(p == _top);
|
||||
#endif
|
||||
for (prev = 0, p = _empty; p != 0; prev = p, p = NextFree(p)) {
|
||||
next = NextSlot(p);
|
||||
new = p + len; /* easily overflows!! */
|
||||
if (new > next || new <= p)
|
||||
continue; /* too small */
|
||||
if (new + PTRSIZE < next) { /* too big, so split */
|
||||
/* + PTRSIZE avoids tiny slots on free list */
|
||||
NextSlot(new) = next;
|
||||
NextSlot(p) = new;
|
||||
NextFree(new) = NextFree(p);
|
||||
NextFree(p) = new;
|
||||
}
|
||||
if (prev)
|
||||
NextFree(prev) = NextFree(p);
|
||||
else
|
||||
_empty = NextFree(p);
|
||||
return p;
|
||||
}
|
||||
if (grow(len) == 0)
|
||||
break;
|
||||
}
|
||||
assert(ntries != 2);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *
|
||||
realloc(void *oldp, size_t size)
|
||||
{
|
||||
register char *prev, *p, *next, *new;
|
||||
char *old = oldp;
|
||||
register size_t len, n;
|
||||
|
||||
if (old == 0)
|
||||
return malloc(size);
|
||||
if (size == 0) {
|
||||
free(old);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CHECK_DBG(return _dbg_realloc(oldp, size));
|
||||
|
||||
len = Align(size, PTRSIZE) + PTRSIZE;
|
||||
next = NextSlot(old);
|
||||
n = (int)(next - old); /* old length */
|
||||
/*
|
||||
* extend old if there is any free space just behind it
|
||||
*/
|
||||
for (prev = 0, p = _empty; p != 0; prev = p, p = NextFree(p)) {
|
||||
if (p > next)
|
||||
break;
|
||||
if (p == next) { /* 'next' is a free slot: merge */
|
||||
NextSlot(old) = NextSlot(p);
|
||||
if (prev)
|
||||
NextFree(prev) = NextFree(p);
|
||||
else
|
||||
_empty = NextFree(p);
|
||||
next = NextSlot(old);
|
||||
break;
|
||||
}
|
||||
}
|
||||
new = old + len;
|
||||
/*
|
||||
* Can we use the old, possibly extended slot?
|
||||
*/
|
||||
if (new <= next && new >= old) { /* it does fit */
|
||||
if (new + PTRSIZE < next) { /* too big, so split */
|
||||
/* + PTRSIZE avoids tiny slots on free list */
|
||||
NextSlot(new) = next;
|
||||
NextSlot(old) = new;
|
||||
free(new);
|
||||
}
|
||||
return old;
|
||||
}
|
||||
if ((new = malloc(size)) == NULL) /* it didn't fit */
|
||||
return NULL;
|
||||
memcpy(new, old, n); /* n < size */
|
||||
free(old);
|
||||
return new;
|
||||
}
|
||||
|
||||
void
|
||||
free(void *ptr)
|
||||
{
|
||||
register char *prev, *next;
|
||||
char *p = ptr;
|
||||
|
||||
if (p == 0)
|
||||
return;
|
||||
|
||||
CHECK_DBG(_dbg_free(ptr); return);
|
||||
|
||||
#ifdef SLOWDEBUG
|
||||
{
|
||||
int found;
|
||||
char *curr;
|
||||
|
||||
/* block must be in block list */
|
||||
assert(_bottom);
|
||||
found = 0;
|
||||
for (curr = _bottom; (next = NextSlot(curr)) != 0; curr = next) {
|
||||
assert(next > curr);
|
||||
if (curr == p) found = 1;
|
||||
}
|
||||
if (curr == p) found = 1;
|
||||
assert(found);
|
||||
|
||||
/* block must not be in free list */
|
||||
if (_empty) {
|
||||
found = 0;
|
||||
for (curr = _empty; (next = NextFree(curr)) != 0; curr = next) {
|
||||
assert(next > curr);
|
||||
if (curr == p) found = 1;
|
||||
}
|
||||
if (curr == p) found = 1;
|
||||
assert(!found);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
assert((char *) NextSlot(p) > p);
|
||||
for (prev = 0, next = _empty; next != 0; prev = next, next = NextFree(next))
|
||||
if (p < next)
|
||||
break;
|
||||
NextFree(p) = next;
|
||||
if (prev)
|
||||
NextFree(prev) = p;
|
||||
else
|
||||
_empty = p;
|
||||
if (next) {
|
||||
assert((char *) NextSlot(p) <= next);
|
||||
if (NextSlot(p) == next) { /* merge p and next */
|
||||
NextSlot(p) = NextSlot(next);
|
||||
NextFree(p) = NextFree(next);
|
||||
}
|
||||
}
|
||||
if (prev) {
|
||||
assert((char *) NextSlot(prev) <= p);
|
||||
if (NextSlot(prev) == p) { /* merge prev and p */
|
||||
NextSlot(prev) = NextSlot(p);
|
||||
NextFree(prev) = NextFree(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
# net sources
|
||||
.if defined(__MINIX)
|
||||
.PATH: ${.CURDIR}/net/minix
|
||||
.PATH: ${NETBSDSRCDIR}/minix/lib/libc/net
|
||||
|
||||
CPPFLAGS.getpeereid.c+= -D_MINIX_SYSTEM=1
|
||||
CPPFLAGS.getsockopt.c+= -D_MINIX_SYSTEM=1
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
#include <namespace.h>
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/gen/in.h>
|
||||
#include <net/gen/ip_io.h>
|
||||
#include <net/gen/tcp.h>
|
||||
#include <net/gen/udp.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <ifaddrs.h>
|
||||
|
||||
#if defined(__weak_alias)
|
||||
__weak_alias(getifaddrs,_getifaddrs)
|
||||
__weak_alias(freeifaddrs,_freeifaddrs)
|
||||
#endif
|
||||
|
||||
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 = __UNCONST("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;
|
||||
|
||||
*ifap = NULL;
|
||||
|
||||
if(fd < 0) {
|
||||
char *ipd;
|
||||
|
||||
if(!(ipd = getenv("IP_DEVICE")))
|
||||
ipd = __UNCONST("/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. */
|
||||
;
|
||||
}
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ucred.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 uucred cred;
|
||||
socklen_t ucred_length;
|
||||
|
||||
/* Initialize Data Structures */
|
||||
ucred_length = sizeof(struct uucred);
|
||||
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.cr_uid;
|
||||
*egid = cred.cr_gid;
|
||||
return 0;
|
||||
} else {
|
||||
/* Failure - getsockopt takes care of setting errno */
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,7 @@ SRCS+= erand48_ieee754.c
|
||||
.if (${USE_JEMALLOC} != "no")
|
||||
SRCS+= jemalloc.c
|
||||
.elif (${USE_MINIXMALLOC:Uno} != "no")
|
||||
.include "../minix/Makefile.inc"
|
||||
.include "${NETBSDSRCDIR}/minix/lib/libc/Makefile.inc"
|
||||
.else
|
||||
SRCS+= malloc.c
|
||||
.endif
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
_lwp_*
|
||||
acct
|
||||
lchmod
|
||||
lchown
|
||||
clone
|
||||
extattr_*
|
||||
fhopen
|
||||
fhstat
|
||||
fhstatvfs
|
||||
fsync_range
|
||||
getfh
|
||||
__setlogin
|
||||
getpgid
|
||||
setrlimit
|
||||
getrusage
|
||||
getsid
|
||||
issetugid /* WARNING: Always returns 0 in this impl. */
|
||||
kevent
|
||||
kqueue
|
||||
ktrace
|
||||
lfs_*
|
||||
madvise
|
||||
mincore
|
||||
minherit
|
||||
mlock
|
||||
mlockall
|
||||
munlock
|
||||
munlockall
|
||||
modctl
|
||||
mprotect
|
||||
mq_timedreceive
|
||||
mq_timedsend
|
||||
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_gettime
|
||||
timer_settime
|
||||
undelete
|
||||
utrace
|
||||
uuidgen
|
||||
vadvise
|
||||
@@ -1,35 +0,0 @@
|
||||
.PATH: ${.CURDIR}/sys-minix
|
||||
|
||||
SRCS+= accept.c access.c adjtime.c bind.c brk.c sbrk.c m_closefrom.c getsid.c \
|
||||
chdir.c chmod.c fchmod.c chown.c fchown.c chroot.c close.c \
|
||||
clock_getres.c clock_gettime.c clock_settime.c \
|
||||
connect.c dup.c dup2.c execve.c fcntl.c flock.c fpathconf.c fork.c \
|
||||
fstatfs.c fstatvfs.c fsync.c ftruncate.c gcov_flush.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 \
|
||||
getvfsstat.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 svrctl.c \
|
||||
symlink.c \
|
||||
sync.c syscall.c sysuname.c truncate.c umask.c unlink.c write.c \
|
||||
utimensat.c utimes.c futimes.c lutimes.c futimens.c \
|
||||
_exit.c _ucontext.c environ.c __getcwd.c vfork.c sizeup.c init.c \
|
||||
getrusage.c setrlimit.c setpgid.c
|
||||
|
||||
# Minix specific syscalls / utils.
|
||||
SRCS+= cprofile.c sprofile.c stack_utils.c _mcontext.c
|
||||
|
||||
# Emulation for missing lchown/lchmod
|
||||
OBJS+= lchown.o lchmod.o
|
||||
lchown.o lchown.pico lchown.bc: ${NETBSDSRCDIR}/tools/compat/lchown.c
|
||||
lchmod.o lchmod.pico lchmod.bc: ${NETBSDSRCDIR}/tools/compat/lchmod.c
|
||||
|
||||
.include "${ARCHDIR}/sys-minix/Makefile.inc"
|
||||
@@ -1,142 +0,0 @@
|
||||
/* getcwd() - get the name of the current working directory.
|
||||
* Author: Kees J. Bot
|
||||
* 30 Apr 1989
|
||||
*/
|
||||
|
||||
#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>
|
||||
|
||||
/* libc-private interface */
|
||||
int __getcwd(char *, size_t);
|
||||
|
||||
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;
|
||||
const char *dotdot = "..";
|
||||
int cycle;
|
||||
|
||||
if (path == NULL || size <= 1) { errno= EINVAL; return -1; }
|
||||
|
||||
p= path + size;
|
||||
*--p = 0;
|
||||
|
||||
if (stat(".", ¤t) < 0) return -1;
|
||||
|
||||
while (1) {
|
||||
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;
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
/* 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;
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
#include <sys/cdefs.h>
|
||||
#include "namespace.h"
|
||||
#include <lib.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef __weak_alias
|
||||
__weak_alias(_Exit, _exit)
|
||||
#endif
|
||||
|
||||
__dead void _exit(status)
|
||||
int status;
|
||||
{
|
||||
void (*suicide)(void);
|
||||
message m;
|
||||
|
||||
memset(&m, 0, sizeof(m));
|
||||
m.m_lc_pm_exit.status = status;
|
||||
_syscall(PM_PROC_NR, PM_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(;;) { }
|
||||
}
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* mcontext.c
|
||||
*/
|
||||
#include <sys/cdefs.h>
|
||||
#include <lib.h>
|
||||
#include <namespace.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <ucontext.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int setmcontext(const mcontext_t *mcp)
|
||||
{
|
||||
message m;
|
||||
|
||||
memset(&m, 0, sizeof(m));
|
||||
m.m_lc_pm_mcontext.ctx = (vir_bytes)mcp;
|
||||
|
||||
return(_syscall(PM_PROC_NR, PM_SETMCONTEXT, &m));
|
||||
}
|
||||
|
||||
|
||||
int getmcontext(mcontext_t *mcp)
|
||||
{
|
||||
message m;
|
||||
|
||||
memset(&m, 0, sizeof(m));
|
||||
m.m_lc_pm_mcontext.ctx = (vir_bytes)mcp;
|
||||
|
||||
return(_syscall(PM_PROC_NR, PM_GETMCONTEXT, &m));
|
||||
}
|
||||
|
||||
@@ -1,261 +0,0 @@
|
||||
#include <sys/cdefs.h>
|
||||
#include <namespace.h>
|
||||
#include <lib.h>
|
||||
#include <machine/stackframe.h>
|
||||
#include <sys/cdefs.h>
|
||||
#include <ucontext.h>
|
||||
#include <signal.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
void ctx_start(void (*)(void), int, ...);
|
||||
|
||||
/*===========================================================================*
|
||||
* setuctx *
|
||||
*===========================================================================*/
|
||||
int setuctx(const ucontext_t *ucp)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (ucp == NULL) {
|
||||
errno = EFAULT;
|
||||
return(-1);
|
||||
}
|
||||
|
||||
if (!(ucp->uc_flags & _UC_IGNSIGM)) {
|
||||
/* Set signal mask */
|
||||
if ((r = sigprocmask(SIG_SETMASK, &ucp->uc_sigmask, NULL)) == -1)
|
||||
return(r);
|
||||
}
|
||||
|
||||
if (!(ucp->uc_flags & _UC_IGNFPU)) {
|
||||
if ((r = setmcontext(&(ucp->uc_mcontext))) == -1)
|
||||
return(r);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/*===========================================================================*
|
||||
* getuctx *
|
||||
*===========================================================================*/
|
||||
int getuctx(ucontext_t *ucp)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (ucp == NULL) {
|
||||
errno = EFAULT;
|
||||
return(-1);
|
||||
}
|
||||
|
||||
if (!(ucp->uc_flags & _UC_IGNSIGM)) {
|
||||
/* Get signal mask */
|
||||
if ((r = sigprocmask(0, NULL, &ucp->uc_sigmask)) == -1)
|
||||
return(r);
|
||||
}
|
||||
|
||||
if (!(ucp->uc_flags & _UC_IGNFPU)) {
|
||||
if ((r = getmcontext(&(ucp->uc_mcontext))) != 0)
|
||||
return(r);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/*===========================================================================*
|
||||
* makecontext *
|
||||
*===========================================================================*/
|
||||
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;
|
||||
_UC_MACHINE_SET_STACK(ucp, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ucp->uc_mcontext.mc_magic == MCF_MAGIC) {
|
||||
#if defined(__i386__)
|
||||
/* 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. */
|
||||
_UC_MACHINE_SET_EBP(ucp, 0); /* Clear frame pointer */
|
||||
_UC_MACHINE_SET_STACK(ucp, (reg_t) stack_top);
|
||||
_UC_MACHINE_SET_PC(ucp, (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). */
|
||||
_UC_MACHINE_SET_ESI(ucp, (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) {
|
||||
_UC_MACHINE_SET_STACK(ucp, 0);
|
||||
}
|
||||
#elif defined(__arm__)
|
||||
/* 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 the
|
||||
requested function. When the function finishes, it returns to the
|
||||
_ctx_start wrapper that calls resumecontext (after setting up
|
||||
resumecontext's parameter).
|
||||
|
||||
The first four arguments for the function will be passed in
|
||||
regs r0-r3 as specified by the ABI, and the rest will go on
|
||||
the stack. The ucp is saved in r4 so that we can
|
||||
eventually pass it to resumecontext. The r4 register is
|
||||
callee-preserved, so the ucp will remain valid in r4 when
|
||||
_ctx_start runs. _ctx_start will move the ucp from r4 into
|
||||
r0, so that the ucp is the first paramater for resumecontext.
|
||||
Then, _ctx_start will call 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' routine arguments that don't fit in r0-r3 */
|
||||
if (argc > 4)
|
||||
stack_top -= argc - 4;
|
||||
|
||||
/* Adjust the machine context to point to the top of this stack and the
|
||||
program counter to the 'func' entry point. Set lr to ctx_start, so
|
||||
ctx_start runs after 'func'. Save ucp in r4 */
|
||||
_UC_MACHINE_SET_FP(ucp, 0); /* Clear frame pointer */
|
||||
_UC_MACHINE_SET_STACK(ucp, (reg_t) stack_top);
|
||||
_UC_MACHINE_SET_PC(ucp, (reg_t) func);
|
||||
_UC_MACHINE_SET_LR(ucp, (reg_t) ctx_start);
|
||||
_UC_MACHINE_SET_R4(ucp, (reg_t) ucp);
|
||||
|
||||
/* Copy arguments to r0-r3 and stack. */
|
||||
va_start(ap, argc);
|
||||
/* Pass up to four arguments in registers. */
|
||||
if (argc-- > 0)
|
||||
_UC_MACHINE_SET_R0(ucp, va_arg(ap, uintptr_t));
|
||||
if (argc-- > 0)
|
||||
_UC_MACHINE_SET_R1(ucp, va_arg(ap, uintptr_t));
|
||||
if (argc-- > 0)
|
||||
_UC_MACHINE_SET_R2(ucp, va_arg(ap, uintptr_t));
|
||||
if (argc-- > 0)
|
||||
_UC_MACHINE_SET_R3(ucp, va_arg(ap, uintptr_t));
|
||||
/* Pass the rest on the stack. */
|
||||
while (argc-- > 0) {
|
||||
*stack_top++ = va_arg(ap, uintptr_t);
|
||||
}
|
||||
va_end(ap);
|
||||
|
||||
/* 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) {
|
||||
_UC_MACHINE_SET_STACK(ucp, 0);
|
||||
}
|
||||
#else
|
||||
# error "Unsupported platform"
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*===========================================================================*
|
||||
* swapcontext *
|
||||
*===========================================================================*/
|
||||
int swapcontext(ucontext_t *oucp, const ucontext_t *ucp)
|
||||
{
|
||||
int r;
|
||||
|
||||
if ((oucp == NULL) || (ucp == NULL)) {
|
||||
errno = EFAULT;
|
||||
return(-1);
|
||||
}
|
||||
|
||||
if (_UC_MACHINE_STACK(ucp) == 0) {
|
||||
/* No stack space. Bail out. */
|
||||
errno = ENOMEM;
|
||||
return(-1);
|
||||
}
|
||||
|
||||
oucp->uc_flags &= ~_UC_SWAPPED;
|
||||
r = getcontext(oucp);
|
||||
if ((r == 0) && !(oucp->uc_flags & _UC_SWAPPED)) {
|
||||
oucp->uc_flags |= _UC_SWAPPED;
|
||||
r = setcontext(ucp);
|
||||
}
|
||||
|
||||
return(r);
|
||||
}
|
||||
|
||||
|
||||
/*===========================================================================*
|
||||
* resumecontext *
|
||||
*===========================================================================*/
|
||||
__dead
|
||||
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 */
|
||||
}
|
||||
|
||||
@@ -1,136 +0,0 @@
|
||||
#include <sys/cdefs.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)
|
||||
return r;
|
||||
|
||||
r= _uds_accept(sock, address, address_len);
|
||||
if (r != -1 || errno != ENOTTY)
|
||||
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= 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;
|
||||
|
||||
/* Copy file descriptor flags from the listening socket. */
|
||||
fcntl(s1, F_SETFL, fcntl(sock, F_GETFL));
|
||||
|
||||
r= ioctl(s1, NWIOSUDSACCEPT, address);
|
||||
if (r == -1) {
|
||||
int ioctl_errno = errno;
|
||||
close(s1);
|
||||
errno = ioctl_errno;
|
||||
return r;
|
||||
}
|
||||
|
||||
return s1;
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
#include <sys/cdefs.h>
|
||||
#include "namespace.h"
|
||||
#include <lib.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int access(name, mode)
|
||||
const char *name;
|
||||
int mode;
|
||||
{
|
||||
message m;
|
||||
|
||||
memset(&m, 0, sizeof(m));
|
||||
m.m_lc_vfs_path.mode = mode;
|
||||
_loadname(name, &m);
|
||||
return(_syscall(VFS_PROC_NR, VFS_ACCESS, &m));
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
#include <sys/cdefs.h>
|
||||
#include <lib.h>
|
||||
#include "namespace.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
|
||||
#ifdef __weak_alias
|
||||
__weak_alias(adjtime, __adjtime50);
|
||||
#endif
|
||||
|
||||
int adjtime(const struct timeval *delta, struct timeval *olddelta)
|
||||
{
|
||||
message m;
|
||||
|
||||
memset(&m, 0, sizeof(m));
|
||||
m.m_lc_pm_time.clk_id = CLOCK_REALTIME;
|
||||
m.m_lc_pm_time.now = 0; /* use adjtime() method to slowly adjust the clock. */
|
||||
m.m_lc_pm_time.sec = delta->tv_sec;
|
||||
m.m_lc_pm_time.nsec = delta->tv_usec * 1000; /* convert usec to nsec */
|
||||
|
||||
if (_syscall(PM_PROC_NR, PM_CLOCK_SETTIME, &m) < 0)
|
||||
return -1;
|
||||
|
||||
if (olddelta != NULL) {
|
||||
/* the kernel returns immediately and the adjustment happens in the
|
||||
* background. Also, any currently running adjustment is stopped by
|
||||
* another call to adjtime(2), so the only values possible on Minix
|
||||
* for olddelta are those of delta.
|
||||
*/
|
||||
olddelta->tv_sec = delta->tv_sec;
|
||||
olddelta->tv_usec = delta->tv_usec;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,213 +0,0 @@
|
||||
#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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (r == -1)
|
||||
return r;
|
||||
return _udp_bind(sock, address, address_len, &udpopt);
|
||||
}
|
||||
|
||||
r= ioctl(sock, NWIOGUDSADDR, &uds_addr);
|
||||
if (r != -1 || errno != ENOTTY)
|
||||
{
|
||||
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 *) __UNCONST(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 *) __UNCONST(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 _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 *) __UNCONST(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 *) __UNCONST(address));
|
||||
|
||||
if (r == -1 && did_mknod) {
|
||||
|
||||
/* bind() failed in pfs, so we roll back the
|
||||
* file system change
|
||||
*/
|
||||
unlink(((struct sockaddr_un *) __UNCONST(address))->sun_path);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
#include <sys/cdefs.h>
|
||||
#include "namespace.h"
|
||||
#include <lib.h>
|
||||
|
||||
#include <string.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.
|
||||
* 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.
|
||||
*/
|
||||
int brk(addr)
|
||||
void *addr;
|
||||
{
|
||||
message m;
|
||||
|
||||
if (addr != _brksize) {
|
||||
memset(&m, 0, sizeof(m));
|
||||
m.m_lc_vm_brk.addr = addr;
|
||||
if (_syscall(VM_PROC_NR, VM_BRK, &m) < 0) return(-1);
|
||||
_brksize = addr;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
#include <sys/cdefs.h>
|
||||
#include "namespace.h"
|
||||
#include <lib.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int chdir(name)
|
||||
const char *name;
|
||||
{
|
||||
message m;
|
||||
|
||||
memset(&m, 0, sizeof(m));
|
||||
_loadname(name, &m);
|
||||
return(_syscall(VFS_PROC_NR, VFS_CHDIR, &m));
|
||||
}
|
||||
|
||||
int fchdir(fd)
|
||||
int fd;
|
||||
{
|
||||
message m;
|
||||
|
||||
memset(&m, 0, sizeof(m));
|
||||
m.m_lc_vfs_fchdir.fd = fd;
|
||||
return(_syscall(VFS_PROC_NR, VFS_FCHDIR, &m));
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
#include <sys/cdefs.h>
|
||||
#include "namespace.h"
|
||||
#include <lib.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
int chmod(const char *name, mode_t mode)
|
||||
{
|
||||
message m;
|
||||
|
||||
memset(&m, 0, sizeof(m));
|
||||
m.m_lc_vfs_path.mode = mode;
|
||||
_loadname(name, &m);
|
||||
return(_syscall(VFS_PROC_NR, VFS_CHMOD, &m));
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
#include <sys/cdefs.h>
|
||||
#include "namespace.h"
|
||||
#include <lib.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef __weak_alias
|
||||
__weak_alias(__posix_chown, chown)
|
||||
#endif
|
||||
|
||||
int chown(const char *name, uid_t owner, gid_t grp)
|
||||
{
|
||||
message m;
|
||||
|
||||
memset(&m, 0, sizeof(m));
|
||||
m.m_lc_vfs_chown.len = strlen(name) + 1;
|
||||
m.m_lc_vfs_chown.owner = owner;
|
||||
m.m_lc_vfs_chown.group = grp;
|
||||
m.m_lc_vfs_chown.name = (vir_bytes)name;
|
||||
return(_syscall(VFS_PROC_NR, VFS_CHOWN, &m));
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
#include <sys/cdefs.h>
|
||||
#include "namespace.h"
|
||||
#include <lib.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int chroot(name)
|
||||
const char *name;
|
||||
{
|
||||
message m;
|
||||
|
||||
memset(&m, 0, sizeof(m));
|
||||
_loadname(name, &m);
|
||||
return(_syscall(VFS_PROC_NR, VFS_CHROOT, &m));
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
#include <sys/cdefs.h>
|
||||
#include <lib.h>
|
||||
#include "namespace.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#ifdef __weak_alias
|
||||
__weak_alias(clock_getres, __clock_getres50);
|
||||
#endif
|
||||
|
||||
int clock_getres(clockid_t clock_id, struct timespec *res)
|
||||
{
|
||||
message m;
|
||||
|
||||
memset(&m, 0, sizeof(m));
|
||||
m.m_lc_pm_time.clk_id = clock_id;
|
||||
|
||||
if (_syscall(PM_PROC_NR, PM_CLOCK_GETRES, &m) < 0)
|
||||
return -1;
|
||||
|
||||
res->tv_sec = m.m_pm_lc_time.sec;
|
||||
res->tv_nsec = m.m_pm_lc_time.nsec;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
#include <sys/cdefs.h>
|
||||
#include <lib.h>
|
||||
#include "namespace.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#ifdef __weak_alias
|
||||
__weak_alias(clock_gettime, __clock_gettime50);
|
||||
#endif
|
||||
|
||||
int clock_gettime(clockid_t clock_id, struct timespec *res)
|
||||
{
|
||||
message m;
|
||||
|
||||
memset(&m, 0, sizeof(m));
|
||||
m.m_lc_pm_time.clk_id = clock_id;
|
||||
|
||||
if (_syscall(PM_PROC_NR, PM_CLOCK_GETTIME, &m) < 0)
|
||||
return -1;
|
||||
|
||||
res->tv_sec = m.m_pm_lc_time.sec;
|
||||
res->tv_nsec = m.m_pm_lc_time.nsec;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
#include <sys/cdefs.h>
|
||||
#include <lib.h>
|
||||
#include "namespace.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#ifdef __weak_alias
|
||||
__weak_alias(clock_settime, __clock_settime50);
|
||||
#endif
|
||||
|
||||
int clock_settime(clockid_t clock_id, const struct timespec *ts)
|
||||
{
|
||||
message m;
|
||||
|
||||
memset(&m, 0, sizeof(m));
|
||||
m.m_lc_pm_time.clk_id = clock_id;
|
||||
m.m_lc_pm_time.now = 1; /* set time immediately. don't use adjtime() method. */
|
||||
m.m_lc_pm_time.sec = ts->tv_sec;
|
||||
m.m_lc_pm_time.nsec = ts->tv_nsec;
|
||||
|
||||
if (_syscall(PM_PROC_NR, PM_CLOCK_SETTIME, &m) < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
#include <sys/cdefs.h>
|
||||
#include "namespace.h"
|
||||
#include <lib.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int close(fd)
|
||||
int fd;
|
||||
{
|
||||
message m;
|
||||
|
||||
memset(&m, 0, sizeof(m));
|
||||
m.m_lc_vfs_close.fd = fd;
|
||||
return(_syscall(VFS_PROC_NR, VFS_CLOSE, &m));
|
||||
}
|
||||
@@ -1,176 +0,0 @@
|
||||
#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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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 != 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 *) __UNCONST(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 *) __UNCONST(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 *) __UNCONST(address));
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
#include <sys/cdefs.h>
|
||||
#include "namespace.h"
|
||||
|
||||
#ifdef __weak_alias
|
||||
__weak_alias(cprofile, _cprofile)
|
||||
#endif
|
||||
|
||||
#include <lib.h>
|
||||
#include <string.h>
|
||||
#include <minix/profile.h>
|
||||
|
||||
int cprofile(int action, int size, void *ctl_ptr, void *mem_ptr)
|
||||
{
|
||||
message m;
|
||||
|
||||
memset(&m, 0, sizeof(m));
|
||||
m.m_lc_pm_cprof.action = action;
|
||||
m.m_lc_pm_cprof.mem_size = size;
|
||||
m.m_lc_pm_cprof.ctl_ptr = ctl_ptr;
|
||||
m.m_lc_pm_cprof.mem_ptr = mem_ptr;
|
||||
|
||||
return _syscall(PM_PROC_NR, PM_CPROF, &m);
|
||||
}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
#include <sys/cdefs.h>
|
||||
#include "namespace.h"
|
||||
#include <lib.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int dup(fd)
|
||||
int fd;
|
||||
{
|
||||
return(fcntl(fd, F_DUPFD, 0));
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
#include <sys/cdefs.h>
|
||||
#include "namespace.h"
|
||||
#include <lib.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
char **environ = (char **) 0x53535353;
|
||||
@@ -1,59 +0,0 @@
|
||||
/* execve() - basic program execution call */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include "namespace.h"
|
||||
#include <lib.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
#include <minix/param.h>
|
||||
#include <sys/exec_elf.h>
|
||||
#include <sys/exec.h>
|
||||
|
||||
int execve(const char *path, char * const *argv, char * const *envp)
|
||||
{
|
||||
message m;
|
||||
size_t frame_size = 0; /* Size of the new initial stack. */
|
||||
int argc = 0; /* Argument count. */
|
||||
int envc = 0; /* Environment count */
|
||||
char overflow = 0; /* No overflow yet. */
|
||||
char *frame;
|
||||
struct ps_strings *psp;
|
||||
int vsp = 0; /* (virtual) Stack pointer in new address space. */
|
||||
|
||||
minix_stack_params(path, argv, envp, &frame_size, &overflow,
|
||||
&argc, &envc);
|
||||
|
||||
/* The party is off if there is an overflow. */
|
||||
if (overflow) {
|
||||
errno = E2BIG;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Allocate space for the stack frame. */
|
||||
if ((frame = (char *) sbrk(frame_size)) == (char *) -1) {
|
||||
errno = E2BIG;
|
||||
return -1;
|
||||
}
|
||||
|
||||
minix_stack_fill(path, argc, argv, envc, envp, frame_size, frame,
|
||||
&vsp, &psp);
|
||||
|
||||
/* Clear unused message fields */
|
||||
memset(&m, 0, sizeof(m));
|
||||
|
||||
/* We can finally make the system call. */
|
||||
m.m_lc_pm_exec.name = (vir_bytes)path;
|
||||
m.m_lc_pm_exec.namelen = strlen(path) + 1;
|
||||
m.m_lc_pm_exec.frame = (vir_bytes)frame;
|
||||
m.m_lc_pm_exec.framelen = frame_size;
|
||||
m.m_lc_pm_exec.ps_str = (vir_bytes)(vsp + ((char *)psp - frame));
|
||||
|
||||
(void) _syscall(PM_PROC_NR, PM_EXEC, &m);
|
||||
|
||||
/* Failure, return the memory used for the frame and exit. */
|
||||
(void) sbrk(-frame_size);
|
||||
|
||||
return -1;
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
#include <sys/cdefs.h>
|
||||
#include "namespace.h"
|
||||
#include <lib.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
int fchmod(int fd, mode_t mode)
|
||||
{
|
||||
message m;
|
||||
|
||||
memset(&m, 0, sizeof(m));
|
||||
m.m_lc_vfs_fchmod.fd = fd;
|
||||
m.m_lc_vfs_fchmod.mode = mode;
|
||||
return(_syscall(VFS_PROC_NR, VFS_FCHMOD, &m));
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
#include <sys/cdefs.h>
|
||||
#include "namespace.h"
|
||||
#include <lib.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef __weak_alias
|
||||
__weak_alias(__posix_fchown, fchown)
|
||||
#endif
|
||||
|
||||
int fchown(int fd, uid_t owner, gid_t grp)
|
||||
{
|
||||
message m;
|
||||
|
||||
memset(&m, 0, sizeof(m));
|
||||
m.m_lc_vfs_chown.fd = fd;
|
||||
m.m_lc_vfs_chown.owner = owner;
|
||||
m.m_lc_vfs_chown.group = grp;
|
||||
return(_syscall(VFS_PROC_NR, VFS_FCHOWN, &m));
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
#include <sys/cdefs.h>
|
||||
#include "namespace.h"
|
||||
#include <lib.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
int fcntl(int fd, int cmd, ...)
|
||||
{
|
||||
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.
|
||||
*/
|
||||
memset(&m, 0, sizeof(m));
|
||||
|
||||
/* Adjust for the stupid cases. */
|
||||
switch(cmd) {
|
||||
case F_DUPFD:
|
||||
case F_SETFD:
|
||||
case F_SETFL:
|
||||
m.m_lc_vfs_fcntl.arg_int = va_arg(argp, int);
|
||||
break;
|
||||
case F_GETLK:
|
||||
case F_SETLK:
|
||||
case F_SETLKW:
|
||||
case F_FREESP:
|
||||
m.m_lc_vfs_fcntl.arg_ptr = va_arg(argp, struct flock *);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Clean up and make the system call. */
|
||||
va_end(argp);
|
||||
m.m_lc_vfs_fcntl.fd = fd;
|
||||
m.m_lc_vfs_fcntl.cmd = cmd;
|
||||
return(_syscall(VFS_PROC_NR, VFS_FCNTL, &m));
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
/* 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>
|
||||
|
||||
/*
|
||||
* 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 **/
|
||||
@@ -1,18 +0,0 @@
|
||||
#include <sys/cdefs.h>
|
||||
#include "namespace.h"
|
||||
#include <lib.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef __weak_alias
|
||||
__weak_alias(fork, _fork)
|
||||
#endif
|
||||
|
||||
pid_t fork(void)
|
||||
{
|
||||
message m;
|
||||
|
||||
memset(&m, 0, sizeof(m));
|
||||
return(_syscall(PM_PROC_NR, PM_FORK, &m));
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
/* 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>
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
#include <sys/cdefs.h>
|
||||
#include <lib.h>
|
||||
#include "namespace.h"
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/statfs.h>
|
||||
#include <sys/statvfs.h>
|
||||
|
||||
int fstatfs(int fd, struct statfs *buffer)
|
||||
{
|
||||
struct statvfs svbuffer;
|
||||
int r;
|
||||
|
||||
if ((r = fstatvfs(fd, &svbuffer)) != 0)
|
||||
return r;
|
||||
|
||||
buffer->f_bsize = svbuffer.f_bsize;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
#include <sys/cdefs.h>
|
||||
#include "namespace.h"
|
||||
#include <lib.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <sys/statvfs.h>
|
||||
|
||||
#if defined(__weak_alias)
|
||||
__weak_alias(fstatvfs, _fstatvfs)
|
||||
#endif
|
||||
|
||||
int fstatvfs1(int fd, struct statvfs *buffer, int flags)
|
||||
{
|
||||
message m;
|
||||
|
||||
memset(&m, 0, sizeof(m));
|
||||
m.m_lc_vfs_statvfs1.fd = fd;
|
||||
m.m_lc_vfs_statvfs1.buf = (vir_bytes)buffer;
|
||||
m.m_lc_vfs_statvfs1.flags = flags;
|
||||
return(_syscall(VFS_PROC_NR, VFS_FSTATVFS1, &m));
|
||||
}
|
||||
|
||||
int fstatvfs(int fd, struct statvfs *buffer)
|
||||
{
|
||||
return fstatvfs1(fd, buffer, ST_WAIT);
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
#include <sys/cdefs.h>
|
||||
#include "namespace.h"
|
||||
#include <lib.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int fsync(int fd)
|
||||
{
|
||||
message m;
|
||||
|
||||
memset(&m, 0, sizeof(m));
|
||||
m.m_lc_vfs_fsync.fd = fd;
|
||||
|
||||
return(_syscall(VFS_PROC_NR, VFS_FSYNC, &m));
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
#include <sys/cdefs.h>
|
||||
#include "namespace.h"
|
||||
#include <lib.h>
|
||||
|
||||
#include <minix/u64.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef __weak_alias
|
||||
__weak_alias(ftruncate, _ftruncate)
|
||||
#endif
|
||||
|
||||
int ftruncate(int _fd, off_t _length)
|
||||
{
|
||||
message m;
|
||||
|
||||
memset(&m, 0, sizeof(m));
|
||||
m.m_lc_vfs_truncate.offset = _length;
|
||||
m.m_lc_vfs_truncate.fd = _fd;
|
||||
|
||||
return(_syscall(VFS_PROC_NR, VFS_FTRUNCATE, &m));
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
#include <sys/cdefs.h>
|
||||
#include "namespace.h"
|
||||
#include <lib.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
int futimens(int fd, const struct timespec tv[2])
|
||||
{
|
||||
message m;
|
||||
static const struct timespec now[2] = { {0, UTIME_NOW}, {0, UTIME_NOW} };
|
||||
|
||||
if (tv == NULL) tv = now;
|
||||
|
||||
memset(&m, 0, sizeof(m));
|
||||
m.m_vfs_utimens.fd = fd;
|
||||
m.m_vfs_utimens.atime = tv[0].tv_sec;
|
||||
m.m_vfs_utimens.mtime = tv[1].tv_sec;
|
||||
m.m_vfs_utimens.ansec = tv[0].tv_nsec;
|
||||
m.m_vfs_utimens.mnsec = tv[1].tv_nsec;
|
||||
m.m_vfs_utimens.name = NULL;
|
||||
m.m_vfs_utimens.flags = 0;
|
||||
|
||||
return(_syscall(VFS_PROC_NR, VFS_UTIMENS, &m));
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
#include <sys/cdefs.h>
|
||||
#include "namespace.h"
|
||||
#include <lib.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#ifdef __weak_alias
|
||||
__weak_alias(futimes, __futimes50)
|
||||
#endif
|
||||
|
||||
int futimes(int fd, const struct timeval tv[2])
|
||||
{
|
||||
message m;
|
||||
|
||||
memset(&m, 0, sizeof(m));
|
||||
m.m_vfs_utimens.fd = fd;
|
||||
if (tv == NULL) {
|
||||
m.m_vfs_utimens.atime = m.m_vfs_utimens.mtime = 0;
|
||||
m.m_vfs_utimens.ansec = m.m_vfs_utimens.mnsec = UTIME_NOW;
|
||||
}
|
||||
else {
|
||||
m.m_vfs_utimens.atime = tv[0].tv_sec;
|
||||
m.m_vfs_utimens.mtime = tv[1].tv_sec;
|
||||
m.m_vfs_utimens.ansec = tv[0].tv_usec * 1000;
|
||||
m.m_vfs_utimens.mnsec = tv[1].tv_usec * 1000;
|
||||
}
|
||||
m.m_vfs_utimens.name = NULL;
|
||||
m.m_vfs_utimens.flags = 0;
|
||||
|
||||
return(_syscall(VFS_PROC_NR, VFS_UTIMENS, &m));
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
#include <lib.h>
|
||||
#include <string.h>
|
||||
#include <minix/gcov.h>
|
||||
|
||||
int gcov_flush_svr(char *buff, int buff_sz, int server_nr)
|
||||
{
|
||||
message m;
|
||||
|
||||
memset(&m, 0, sizeof(m));
|
||||
m.m_lc_vfs_gcov.buff_p = buff;
|
||||
m.m_lc_vfs_gcov.buff_sz = buff_sz;
|
||||
m.m_lc_vfs_gcov.pid = server_nr;
|
||||
|
||||
/* Make the call to server. It will call the gcov library,
|
||||
* buffer the stdio requests, and copy the buffer to this user
|
||||
* space
|
||||
*/
|
||||
return _syscall(VFS_PROC_NR, VFS_GCOV_FLUSH, &m);
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
#include <sys/cdefs.h>
|
||||
#include "namespace.h"
|
||||
#include <lib.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <dirent.h>
|
||||
|
||||
ssize_t getdents(int fd, char *buffer, size_t nbytes)
|
||||
{
|
||||
message m;
|
||||
|
||||
memset(&m, 0, sizeof(m));
|
||||
m.m_lc_vfs_readwrite.fd = fd;
|
||||
m.m_lc_vfs_readwrite.len = nbytes;
|
||||
m.m_lc_vfs_readwrite.buf = (vir_bytes)buffer;
|
||||
return _syscall(VFS_PROC_NR, VFS_GETDENTS, &m);
|
||||
}
|
||||
|
||||
#if defined(__minix) && defined(__weak_alias)
|
||||
__weak_alias(getdents, __getdents30)
|
||||
#endif
|
||||
@@ -1,20 +0,0 @@
|
||||
#include <sys/cdefs.h>
|
||||
#include "namespace.h"
|
||||
#include <lib.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
gid_t getegid(void)
|
||||
{
|
||||
message m;
|
||||
|
||||
memset(&m, 0, sizeof(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, PM_GETGID, &m) < 0) return(-1);
|
||||
return(m.m_pm_lc_getgid.egid);
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
#include <sys/cdefs.h>
|
||||
#include "namespace.h"
|
||||
#include <lib.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
uid_t geteuid(void)
|
||||
{
|
||||
message m;
|
||||
|
||||
memset(&m, 0, sizeof(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, PM_GETUID, &m) < 0) return(-1);
|
||||
return(m.m_pm_lc_getuid.euid);
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
#include <sys/cdefs.h>
|
||||
#include "namespace.h"
|
||||
#include <lib.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
gid_t getgid(void)
|
||||
{
|
||||
message m;
|
||||
|
||||
memset(&m, 0, sizeof(m));
|
||||
return( (gid_t) _syscall(PM_PROC_NR, PM_GETGID, &m));
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
/*
|
||||
getgroups.c
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include "namespace.h"
|
||||
#include <lib.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int getgroups(int ngroups, gid_t *arr)
|
||||
{
|
||||
message m;
|
||||
|
||||
memset(&m, 0, sizeof(m));
|
||||
m.m_lc_pm_groups.num = ngroups;
|
||||
m.m_lc_pm_groups.ptr = (vir_bytes)arr;
|
||||
|
||||
return(_syscall(PM_PROC_NR, PM_GETGROUPS, &m));
|
||||
}
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
#include <sys/cdefs.h>
|
||||
#include "namespace.h"
|
||||
#include <lib.h>
|
||||
|
||||
#include <string.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;
|
||||
|
||||
memset(&m, 0, sizeof(m));
|
||||
m.m_lc_pm_itimer.which = which;
|
||||
m.m_lc_pm_itimer.value = 0; /* only retrieve the timer */
|
||||
m.m_lc_pm_itimer.ovalue = (vir_bytes)value;
|
||||
|
||||
return _syscall(PM_PROC_NR, PM_ITIMER, &m);
|
||||
}
|
||||
|
||||
#if defined(__minix) && defined(__weak_alias)
|
||||
__weak_alias(getitimer, __getitimer50)
|
||||
#endif
|
||||
@@ -1,156 +0,0 @@
|
||||
#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>
|
||||
#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 _udp_getpeername(int sock, struct sockaddr *__restrict address,
|
||||
socklen_t *__restrict address_len, nwio_udpopt_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;
|
||||
nwio_udpopt_t udpopt;
|
||||
struct sockaddr_un uds_addr;
|
||||
|
||||
r= ioctl(sock, NWIOGTCPCONF, &tcpconf);
|
||||
if (r != -1 || errno != ENOTTY)
|
||||
{
|
||||
if (r == -1)
|
||||
{
|
||||
/* Bad file descriptor */
|
||||
return -1;
|
||||
}
|
||||
return _tcp_getpeername(sock, address, address_len,
|
||||
&tcpconf);
|
||||
}
|
||||
|
||||
r= ioctl(sock, NWIOGUDPOPT, &udpopt);
|
||||
if (r != -1 || errno != ENOTTY)
|
||||
{
|
||||
if (r == -1)
|
||||
{
|
||||
/* Bad file descriptor */
|
||||
return -1;
|
||||
}
|
||||
return _udp_getpeername(sock, address, address_len,
|
||||
&udpopt);
|
||||
}
|
||||
|
||||
r= ioctl(sock, NWIOGUDSPADDR, &uds_addr);
|
||||
if (r != -1 || errno != ENOTTY)
|
||||
{
|
||||
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;
|
||||
sin.sin_len = sizeof(sin);
|
||||
|
||||
len= *address_len;
|
||||
if (len > sizeof(sin))
|
||||
len= sizeof(sin);
|
||||
memcpy(address, &sin, len);
|
||||
*address_len= len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _udp_getpeername(int sock, struct sockaddr *__restrict address,
|
||||
socklen_t *__restrict address_len, nwio_udpopt_t *udpopt)
|
||||
{
|
||||
socklen_t len;
|
||||
struct sockaddr_in sin;
|
||||
|
||||
if (udpopt->nwuo_remaddr == 0 ||
|
||||
udpopt->nwuo_remport == 0)
|
||||
{
|
||||
errno= ENOTCONN;
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&sin, '\0', sizeof(sin));
|
||||
sin.sin_family= AF_INET;
|
||||
sin.sin_addr.s_addr= udpopt->nwuo_remaddr;
|
||||
sin.sin_port= udpopt->nwuo_remport;
|
||||
sin.sin_len = sizeof(sin);
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
#include <sys/cdefs.h>
|
||||
#include "namespace.h"
|
||||
#include <lib.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
pid_t getpgrp(void)
|
||||
{
|
||||
message m;
|
||||
|
||||
memset(&m, 0, sizeof(m));
|
||||
return(_syscall(PM_PROC_NR, PM_GETPGRP, &m));
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
#include <sys/cdefs.h>
|
||||
#include "namespace.h"
|
||||
#include <lib.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
pid_t getpid(void)
|
||||
{
|
||||
message m;
|
||||
|
||||
memset(&m, 0, sizeof(m));
|
||||
return(_syscall(PM_PROC_NR, PM_GETPID, &m));
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
#include <sys/cdefs.h>
|
||||
#include "namespace.h"
|
||||
#include <lib.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
pid_t getppid(void)
|
||||
{
|
||||
message m;
|
||||
|
||||
memset(&m, 0, sizeof(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, PM_GETPID, &m) < 0) return(-1);
|
||||
return(m.m_pm_lc_getpid.parent_pid);
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
/* 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_CPU:
|
||||
case RLIMIT_FSIZE:
|
||||
case RLIMIT_DATA:
|
||||
case RLIMIT_STACK:
|
||||
case RLIMIT_CORE:
|
||||
case RLIMIT_RSS:
|
||||
case RLIMIT_MEMLOCK:
|
||||
case RLIMIT_NPROC:
|
||||
case RLIMIT_SBSIZE:
|
||||
case RLIMIT_AS:
|
||||
/* case RLIMIT_VMEM: Same as RLIMIT_AS */
|
||||
case RLIMIT_NTHR:
|
||||
/* 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;
|
||||
}
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
#include <sys/cdefs.h>
|
||||
#include "namespace.h"
|
||||
#include <lib.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/resource.h>
|
||||
|
||||
int getrusage(int who, struct rusage *r_usage)
|
||||
{
|
||||
int rc;
|
||||
message m;
|
||||
|
||||
memset(&m, 0, sizeof(m));
|
||||
m.m_lc_pm_rusage.who = who;
|
||||
m.m_lc_pm_rusage.addr = (vir_bytes)r_usage;
|
||||
|
||||
if (r_usage == NULL) {
|
||||
errno = EFAULT;
|
||||
return -1;
|
||||
}
|
||||
if (who != RUSAGE_SELF && who != RUSAGE_CHILDREN) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(r_usage, 0, sizeof(struct rusage));
|
||||
if ((rc = _syscall(PM_PROC_NR, PM_GETRUSAGE, &m)) < 0)
|
||||
return rc;
|
||||
|
||||
memset(&m, 0, sizeof(m));
|
||||
m.m_lc_vfs_rusage.addr = (vir_bytes)r_usage;
|
||||
if ((rc = _syscall(VFS_PROC_NR, VFS_GETRUSAGE, &m)) < 0)
|
||||
return rc;
|
||||
|
||||
memset(&m, 0, sizeof(m));
|
||||
m.m_lc_vm_rusage.addr = (vir_bytes)r_usage;
|
||||
return _syscall(VM_PROC_NR, VM_GETRUSAGE, &m);
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
#include <sys/cdefs.h>
|
||||
#include "namespace.h"
|
||||
#include <lib.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
pid_t getsid(pid_t p)
|
||||
{
|
||||
message m;
|
||||
|
||||
memset(&m, 0, sizeof(m));
|
||||
m.m_lc_pm_getsid.pid = p;
|
||||
return(_syscall(PM_PROC_NR, PM_GETSID, &m));
|
||||
}
|
||||
@@ -1,174 +0,0 @@
|
||||
/*
|
||||
|
||||
getsockname()
|
||||
|
||||
from socket emulation library for Minix 2.0.x
|
||||
|
||||
*/
|
||||
|
||||
#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>
|
||||
#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 _udp_getsockname(int fd, struct sockaddr *__restrict address,
|
||||
socklen_t *__restrict address_len, nwio_udpopt_t *udpopt);
|
||||
|
||||
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;
|
||||
nwio_udpopt_t udpopt;
|
||||
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)
|
||||
{
|
||||
if (r == -1)
|
||||
{
|
||||
/* Bad file descriptor */
|
||||
return -1;
|
||||
}
|
||||
|
||||
return _tcp_getsockname(fd, address, address_len, &tcpconf);
|
||||
}
|
||||
|
||||
r= ioctl(fd, NWIOGUDPOPT, &udpopt);
|
||||
if (r != -1 || errno != ENOTTY)
|
||||
{
|
||||
if (r == -1)
|
||||
{
|
||||
/* Bad file descriptor */
|
||||
return -1;
|
||||
}
|
||||
|
||||
return _udp_getsockname(fd, address, address_len, &udpopt);
|
||||
}
|
||||
|
||||
r= ioctl(fd, NWIOGUDSADDR, &uds_addr);
|
||||
if (r != -1 || errno != ENOTTY)
|
||||
{
|
||||
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;
|
||||
sin.sin_len= sizeof(sin);
|
||||
|
||||
len= *address_len;
|
||||
if (len > sizeof(sin))
|
||||
len= sizeof(sin);
|
||||
memcpy(address, &sin, len);
|
||||
*address_len= len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _udp_getsockname(int fd, struct sockaddr *__restrict address,
|
||||
socklen_t *__restrict address_len, nwio_udpopt_t *udpopt)
|
||||
{
|
||||
socklen_t len;
|
||||
struct sockaddr_in sin;
|
||||
|
||||
#ifdef DEBUG1
|
||||
fprintf(stderr, "mnx_getsockname: from %s, %u",
|
||||
inet_ntoa(udpopt->nwuo_remaddr),
|
||||
ntohs(udpopt->nwuo_remport));
|
||||
fprintf(stderr," for %s, %u\n",
|
||||
inet_ntoa(udpopt->nwuo_locaddr),
|
||||
ntohs(udpopt->nwuo_locport));
|
||||
#endif
|
||||
|
||||
memset(&sin, '\0', sizeof(sin));
|
||||
sin.sin_family= AF_INET;
|
||||
sin.sin_addr.s_addr= udpopt->nwuo_locaddr ;
|
||||
sin.sin_port= udpopt->nwuo_locport;
|
||||
sin.sin_len= sizeof(sin);
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -1,257 +0,0 @@
|
||||
#include <sys/cdefs.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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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 uucred cred;
|
||||
|
||||
r= ioctl(sock, NWIOGUDSPEERCRED, &cred);
|
||||
if (r == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
getsockopt_copy(&cred, sizeof(struct uucred), 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;
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
/*
|
||||
gettimeofday.c
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include "namespace.h"
|
||||
#include <lib.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
int gettimeofday(struct timeval *__restrict tp, void *__restrict tzp)
|
||||
{
|
||||
message m;
|
||||
|
||||
memset(&m, 0, sizeof(m));
|
||||
|
||||
if (_syscall(PM_PROC_NR, PM_GETTIMEOFDAY, &m) < 0)
|
||||
return -1;
|
||||
|
||||
tp->tv_sec = m.m_pm_lc_time.sec;
|
||||
tp->tv_usec = m.m_pm_lc_time.nsec / 1000;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
#include <sys/cdefs.h>
|
||||
#include "namespace.h"
|
||||
#include <lib.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
uid_t getuid(void)
|
||||
{
|
||||
message m;
|
||||
|
||||
memset(&m, 0, sizeof(m));
|
||||
return( (uid_t) _syscall(PM_PROC_NR, PM_GETUID, &m));
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
#include <sys/cdefs.h>
|
||||
#include <lib.h>
|
||||
#include "namespace.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <sys/statvfs.h>
|
||||
|
||||
int getvfsstat(struct statvfs *buf, size_t bufsize, int flags)
|
||||
{
|
||||
message m;
|
||||
|
||||
memset(&m, 0, sizeof(m));
|
||||
m.m_lc_vfs_getvfsstat.buf = (vir_bytes) buf;
|
||||
m.m_lc_vfs_getvfsstat.len = bufsize;
|
||||
m.m_lc_vfs_getvfsstat.flags = flags;
|
||||
return(_syscall(VFS_PROC_NR, VFS_GETVFSSTAT, &m));
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <minix/ipc.h>
|
||||
|
||||
/* Minix kernel info, IPC functions pointers */
|
||||
struct minix_kerninfo *_minix_kerninfo = NULL;
|
||||
|
||||
void __minix_init(void) __attribute__((__constructor__, __used__));
|
||||
|
||||
struct minix_ipcvecs _minix_ipcvecs = {
|
||||
.sendrec = _ipc_sendrec_intr,
|
||||
.send = _ipc_send_intr,
|
||||
.notify = _ipc_notify_intr,
|
||||
.senda = _ipc_senda_intr,
|
||||
.sendnb = _ipc_sendnb_intr,
|
||||
.receive = _ipc_receive_intr,
|
||||
.do_kernel_call = _do_kernel_call_intr,
|
||||
};
|
||||
|
||||
void __minix_init(void)
|
||||
{
|
||||
if((get_minix_kerninfo(&_minix_kerninfo) != 0) ||
|
||||
(_minix_kerninfo->kerninfo_magic != KERNINFO_MAGIC))
|
||||
{
|
||||
_minix_kerninfo = NULL;
|
||||
}
|
||||
else if((_minix_kerninfo->ki_flags & MINIX_KIF_IPCVECS) &&
|
||||
(_minix_kerninfo->minix_ipcvecs != NULL))
|
||||
{
|
||||
_minix_ipcvecs = *_minix_kerninfo->minix_ipcvecs;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,98 +0,0 @@
|
||||
#include <sys/cdefs.h>
|
||||
#include "namespace.h"
|
||||
#include <lib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <minix/i2c.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioccom.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
static void rewrite_i2c_netbsd_to_minix(minix_i2c_ioctl_exec_t *out,
|
||||
i2c_ioctl_exec_t *in);
|
||||
static void rewrite_i2c_minix_to_netbsd(i2c_ioctl_exec_t *out,
|
||||
minix_i2c_ioctl_exec_t *in);
|
||||
|
||||
static void rewrite_i2c_netbsd_to_minix(minix_i2c_ioctl_exec_t *out,
|
||||
i2c_ioctl_exec_t *in)
|
||||
{
|
||||
memset(out, '\0', sizeof(minix_i2c_ioctl_exec_t));
|
||||
|
||||
out->iie_op = in->iie_op;
|
||||
out->iie_addr = in->iie_addr;
|
||||
out->iie_cmdlen = I2C_EXEC_MAX_CMDLEN < in->iie_cmdlen ?
|
||||
I2C_EXEC_MAX_CMDLEN : in->iie_cmdlen;
|
||||
out->iie_buflen = I2C_EXEC_MAX_BUFLEN < in->iie_buflen ?
|
||||
I2C_EXEC_MAX_BUFLEN : in->iie_buflen;
|
||||
|
||||
if (in->iie_cmdlen > 0 && in->iie_cmd != NULL) {
|
||||
memcpy(out->iie_cmd, in->iie_cmd, in->iie_cmdlen);
|
||||
}
|
||||
|
||||
if (in->iie_buflen > 0 && in->iie_buf != NULL) {
|
||||
memcpy(out->iie_buf, in->iie_buf, in->iie_buflen);
|
||||
}
|
||||
}
|
||||
|
||||
static void rewrite_i2c_minix_to_netbsd(i2c_ioctl_exec_t *out,
|
||||
minix_i2c_ioctl_exec_t *in)
|
||||
{
|
||||
/* the only field that changes is iie_buf, everything else is the same */
|
||||
if (in->iie_buflen > 0 && in->iie_buf != NULL) {
|
||||
memcpy(out->iie_buf, in->iie_buf, in->iie_buflen);
|
||||
}
|
||||
}
|
||||
|
||||
int ioctl(int fd, unsigned long request, ...)
|
||||
{
|
||||
int r, request_save;
|
||||
message m;
|
||||
vir_bytes addr;
|
||||
void *data;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, request);
|
||||
data = va_arg(ap, void *);
|
||||
|
||||
/*
|
||||
* To support compatibility with interfaces on other systems, certain
|
||||
* requests are re-written to flat structures (i.e. without pointers).
|
||||
*/
|
||||
minix_i2c_ioctl_exec_t i2c;
|
||||
|
||||
request_save = request;
|
||||
|
||||
switch (request) {
|
||||
case I2C_IOCTL_EXEC:
|
||||
rewrite_i2c_netbsd_to_minix(&i2c, data);
|
||||
addr = (vir_bytes) &i2c;
|
||||
request = MINIX_I2C_IOCTL_EXEC;
|
||||
break;
|
||||
default:
|
||||
/* Keep original as-is */
|
||||
addr = data;
|
||||
break;
|
||||
}
|
||||
|
||||
memset(&m, 0, sizeof(m));
|
||||
m.m_lc_vfs_ioctl.fd = fd;
|
||||
m.m_lc_vfs_ioctl.req = request;
|
||||
m.m_lc_vfs_ioctl.arg = addr;
|
||||
|
||||
r = _syscall(VFS_PROC_NR, VFS_IOCTL, &m);
|
||||
|
||||
/* Translate back to original form */
|
||||
switch (request_save) {
|
||||
case I2C_IOCTL_EXEC:
|
||||
rewrite_i2c_minix_to_netbsd(data, &i2c);
|
||||
break;
|
||||
default:
|
||||
/* Nothing to do */
|
||||
break;
|
||||
}
|
||||
|
||||
va_end(ap);
|
||||
|
||||
return r;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user