Initial Spring 2016 commit.
This commit is contained in:
13
userland/lib/Makefile
Normal file
13
userland/lib/Makefile
Normal file
@@ -0,0 +1,13 @@
|
||||
#
|
||||
# Makefile for src/lib (sources for libraries installed in /lib)
|
||||
#
|
||||
# Note that all includes are found in src/include - the "includes"
|
||||
# make rule for installing .h files does not come here.
|
||||
#
|
||||
|
||||
TOP=../..
|
||||
.include "$(TOP)/mk/os161.config.mk"
|
||||
|
||||
SUBDIRS=crt0 libc libtest hostcompat
|
||||
|
||||
.include "$(TOP)/mk/os161.subdir.mk"
|
27
userland/lib/crt0/Makefile
Normal file
27
userland/lib/crt0/Makefile
Normal file
@@ -0,0 +1,27 @@
|
||||
#
|
||||
# Makefile for crt0.o
|
||||
#
|
||||
|
||||
TOP=../../..
|
||||
.include "$(TOP)/mk/os161.config.mk"
|
||||
|
||||
SRCS=$(MACHINE)/crt0.S
|
||||
MKDIRS=$(INSTALLTOP)/lib $(OSTREE)/lib $(MYBUILDDIR)
|
||||
|
||||
.include "$(TOP)/mk/os161.baserules.mk"
|
||||
.include "$(TOP)/mk/os161.compile.mk"
|
||||
|
||||
all-local: $(MYBUILDDIR) .WAIT $(OBJS)
|
||||
|
||||
install-staging-local: $(INSTALLTOP)/lib .WAIT
|
||||
install-local: $(OSTREE)/lib .WAIT
|
||||
|
||||
.for O in $(OBJS)
|
||||
install-staging-local: $(INSTALLTOP)/lib/$(O:T)
|
||||
$(INSTALLTOP)/lib/$(O:T): $(O)
|
||||
cp $(O) $(INSTALLTOP)/lib/$(O:T)
|
||||
|
||||
install-local: $(OSTREE)/lib/$(O:T)
|
||||
$(OSTREE)/lib/$(O:T): $(O)
|
||||
cp $(O) $(OSTREE)/lib/$(O:T)
|
||||
.endfor
|
97
userland/lib/crt0/mips/crt0.S
Normal file
97
userland/lib/crt0/mips/crt0.S
Normal file
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* crt0.o for MIPS r2000/r3000.
|
||||
*
|
||||
* crt stands for "C runtime".
|
||||
*
|
||||
* Basically, this is the startup code that gets invoked before main(),
|
||||
* and regains control when main returns.
|
||||
*
|
||||
* All we really do is save copies of argv and environ for use by libc
|
||||
* funcions (e.g. err* and warn*), and call exit when main returns.
|
||||
*/
|
||||
|
||||
#include <kern/mips/regdefs.h>
|
||||
#include <kern/syscall.h>
|
||||
|
||||
.set noreorder /* so we can use delay slots explicitly */
|
||||
|
||||
.text
|
||||
.globl __start
|
||||
.type __start,@function
|
||||
.ent __start
|
||||
__start:
|
||||
/* Load the "global pointer" register */
|
||||
la gp, _gp
|
||||
|
||||
/*
|
||||
* We expect that the kernel passes argc in a0, argv in a1,
|
||||
* and environ in a2. We do not expect the kernel to set up a
|
||||
* complete stack frame, however.
|
||||
*
|
||||
* The MIPS ABI decrees that every caller will leave 16 bytes of
|
||||
* space in the bottom of its stack frame for writing back the
|
||||
* values of a0-a3, even when calling functions that take fewer
|
||||
* than four arguments. It also requires the stack to be aligned
|
||||
* to an 8-byte boundary. (This is because of 64-bit MIPS, which
|
||||
* we're not dealing with... but we'll conform to the standard.)
|
||||
*/
|
||||
li t0, 0xfffffff8 /* mask for stack alignment */
|
||||
and sp, sp, t0 /* align the stack */
|
||||
addiu sp, sp, -16 /* create our frame */
|
||||
|
||||
sw a1, __argv /* save second arg (argv) in __argv for use later */
|
||||
sw a2, __environ /* save third arg (environ) for use later */
|
||||
|
||||
jal main /* call main */
|
||||
nop /* delay slot */
|
||||
|
||||
/*
|
||||
* Now, we have the return value of main in v0.
|
||||
*
|
||||
* Move it to s0 (which is callee-save) so we still have
|
||||
* it in case exit() returns.
|
||||
*
|
||||
* Also move it to a0 so it's the argument to exit.
|
||||
*/
|
||||
move s0, v0 /* save return value */
|
||||
1:
|
||||
jal exit /* call exit() */
|
||||
move a0, s0 /* Set argument (in delay slot) */
|
||||
|
||||
/*
|
||||
* exit() does not return. (Even if _exit() is not implemented
|
||||
* so *it* returns, exit() is supposed to take care of that.)
|
||||
* But just in case, loop and try again.
|
||||
*/
|
||||
b 1b /* loop back */
|
||||
nop /* delay slot */
|
||||
.end __start
|
55
userland/lib/hostcompat/Makefile
Normal file
55
userland/lib/hostcompat/Makefile
Normal file
@@ -0,0 +1,55 @@
|
||||
#
|
||||
# Makefile for hostcompat library
|
||||
#
|
||||
# defs.mk contains two special settings for us.
|
||||
#
|
||||
# COMPAT_CFLAGS contains our configuration cflags.
|
||||
# COMPAT_TARGETS are additional targets to run at install time.
|
||||
#
|
||||
# COMPAT_CFLAGS may include any of the following:
|
||||
#
|
||||
# -DNEED_ERR Compile err, errx, etc.
|
||||
# -DNEED_NTOHLL Compile ntohll and htonll
|
||||
#
|
||||
# COMPAT_TARGETS may include any of the following:
|
||||
#
|
||||
# install-errh Install an <err.h>
|
||||
#
|
||||
|
||||
TOP=../../..
|
||||
.include "$(TOP)/mk/os161.config.mk"
|
||||
|
||||
LIB=hostcompat
|
||||
SRCS=err.c ntohll.c time.c hostcompat.c
|
||||
|
||||
HOST_CFLAGS+=$(COMPAT_CFLAGS)
|
||||
|
||||
MKDIRS=$(INSTALLTOP)/hostinclude
|
||||
|
||||
.include "$(TOP)/mk/os161.hostlib.mk"
|
||||
|
||||
# XXX: installheaders.sh should be made flexible enough to be used here
|
||||
includes: $(INSTALLTOP)/hostinclude .WAIT $(COMPAT_TARGETS)
|
||||
@if diff hostcompat.h \
|
||||
$(INSTALLTOP)/hostinclude/hostcompat.h > /dev/null 2>&1; then \
|
||||
:; \
|
||||
else \
|
||||
echo cp hostcompat.h $(INSTALLTOP)/hostinclude/; \
|
||||
cp hostcompat.h $(INSTALLTOP)/hostinclude/; \
|
||||
fi
|
||||
[ -h $(INSTALLTOP)/hostinclude/kern ] || \
|
||||
ln -sf ../include/kern $(INSTALLTOP)/hostinclude/kern
|
||||
|
||||
install-errh:
|
||||
@if diff host-err.h \
|
||||
$(INSTALLTOP)/hostinclude/err.h > /dev/null 2>&1; then \
|
||||
:; \
|
||||
else \
|
||||
echo cp host-err.h $(INSTALLTOP)/hostinclude/err.h; \
|
||||
cp host-err.h $(INSTALLTOP)/hostinclude/err.h; \
|
||||
fi
|
||||
|
||||
# Recompile these if the config changes, as they might change with it
|
||||
err.o ntohll.o: $(TOP)/defs.mk
|
||||
|
||||
.PHONY: includes install-errh
|
167
userland/lib/hostcompat/err.c
Normal file
167
userland/lib/hostcompat/err.c
Normal file
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 4.4BSD error printing functions.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "host-err.h"
|
||||
|
||||
#ifdef NEED_ERR
|
||||
|
||||
/*
|
||||
* This is initialized by hostcompat_init
|
||||
*/
|
||||
extern const char *hostcompat_progname;
|
||||
|
||||
/*
|
||||
* Common routine for all the *err* and *warn* functions.
|
||||
*/
|
||||
static
|
||||
void
|
||||
hostcompat_printerr(int use_errno, const char *fmt, va_list ap)
|
||||
{
|
||||
const char *errmsg;
|
||||
|
||||
/*
|
||||
* Get the error message for the current errno.
|
||||
* Do this early, before doing anything that might change the
|
||||
* value in errno.
|
||||
*/
|
||||
errmsg = strerror(errno);
|
||||
|
||||
/*
|
||||
* Look up the program name.
|
||||
* Strictly speaking we should pull off the rightmost
|
||||
* path component of argv[0] and use that as the program
|
||||
* name (this is how BSD err* prints) but it doesn't make
|
||||
* much difference.
|
||||
*/
|
||||
if (hostcompat_progname != NULL) {
|
||||
fprintf(stderr, "%s: ", hostcompat_progname);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "libhostcompat: hostcompat_init not called\n");
|
||||
fprintf(stderr, "libhostcompat-program: ");
|
||||
}
|
||||
|
||||
/* process the printf format and args */
|
||||
vfprintf(stderr, fmt, ap);
|
||||
|
||||
if (use_errno) {
|
||||
/* if we're using errno, print the error string from above. */
|
||||
fprintf(stderr, ": %s\n", errmsg);
|
||||
}
|
||||
else {
|
||||
/* otherwise, just a newline. */
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The va_list versions of the warn/err functions.
|
||||
*/
|
||||
|
||||
/* warn/vwarn: use errno, don't exit */
|
||||
void
|
||||
vwarn(const char *fmt, va_list ap)
|
||||
{
|
||||
hostcompat_printerr(1, fmt, ap);
|
||||
}
|
||||
|
||||
/* warnx/vwarnx: don't use errno, don't exit */
|
||||
void
|
||||
vwarnx(const char *fmt, va_list ap)
|
||||
{
|
||||
hostcompat_printerr(0, fmt, ap);
|
||||
}
|
||||
|
||||
/* err/verr: use errno, then exit */
|
||||
void
|
||||
verr(int exitcode, const char *fmt, va_list ap)
|
||||
{
|
||||
hostcompat_printerr(1, fmt, ap);
|
||||
exit(exitcode);
|
||||
}
|
||||
|
||||
/* errx/verrx: don't use errno, but do then exit */
|
||||
void
|
||||
verrx(int exitcode, const char *fmt, va_list ap)
|
||||
{
|
||||
hostcompat_printerr(0, fmt, ap);
|
||||
exit(exitcode);
|
||||
}
|
||||
|
||||
/*
|
||||
* The non-va_list versions of the warn/err functions.
|
||||
* Just hand off to the va_list versions.
|
||||
*/
|
||||
|
||||
void
|
||||
warn(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vwarn(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void
|
||||
warnx(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vwarnx(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void
|
||||
err(int exitcode, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
verr(exitcode, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void
|
||||
errx(int exitcode, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
verrx(exitcode, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
#endif /* NEED_ERR */
|
58
userland/lib/hostcompat/host-err.h
Normal file
58
userland/lib/hostcompat/host-err.h
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef HOSTCOMPAT_ERR_H
|
||||
#define HOSTCOMPAT_ERR_H
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
/*
|
||||
* 4.4BSD error-printing functions.
|
||||
*
|
||||
* These print the program name and the supplied message, and
|
||||
* (non-*x versions only) the string for the error currently
|
||||
* stored in "errno", and a newline. The err* versions then
|
||||
* exit with the supplied exitcode.
|
||||
*
|
||||
* The v* versions are to the non-v* versions like vprintf is to
|
||||
* printf.
|
||||
*/
|
||||
|
||||
void warn(const char *fmt, ...);
|
||||
void warnx(const char *fmt, ...);
|
||||
void err(int exitcode, const char *fmt, ...);
|
||||
void errx(int exitcode, const char *fmt, ...);
|
||||
|
||||
void vwarn(const char *fmt, va_list);
|
||||
void vwarnx(const char *fmt, va_list);
|
||||
void verr(int exitcode, const char *fmt, va_list);
|
||||
void verrx(int exitcode, const char *fmt, va_list);
|
||||
|
||||
#endif /* HOSTCOMPAT_ERR_H */
|
238
userland/lib/hostcompat/hostcompat.c
Normal file
238
userland/lib/hostcompat/hostcompat.c
Normal file
@@ -0,0 +1,238 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <termios.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "hostcompat.h"
|
||||
|
||||
/*
|
||||
* The program name.
|
||||
* This is used in err.c.
|
||||
*/
|
||||
const char *hostcompat_progname = NULL;
|
||||
|
||||
/*
|
||||
* Unix tty state, for when we're running and to put it back the way it was,
|
||||
* respectively.
|
||||
*/
|
||||
static struct termios hostcompat_runtios;
|
||||
static struct termios hostcompat_savetios;
|
||||
|
||||
/*
|
||||
* Put the tty state back the way it was.
|
||||
*/
|
||||
static
|
||||
void
|
||||
hostcompat_ttyreset(void)
|
||||
{
|
||||
tcsetattr(STDIN_FILENO, TCSADRAIN, &hostcompat_savetios);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the tty state back to the way we want it for running.
|
||||
*/
|
||||
static
|
||||
void
|
||||
hostcompat_ttyresume(void)
|
||||
{
|
||||
tcsetattr(STDIN_FILENO, TCSADRAIN, &hostcompat_runtios);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up the tty state stuff.
|
||||
*/
|
||||
static
|
||||
int
|
||||
hostcompat_ttysetup(void)
|
||||
{
|
||||
struct termios tios;
|
||||
|
||||
/* Get the current tty state. */
|
||||
if (tcgetattr(STDIN_FILENO, &tios) < 0) {
|
||||
/* stdin is not a tty */
|
||||
return -1;
|
||||
}
|
||||
|
||||
hostcompat_savetios = tios;
|
||||
|
||||
/* Turn off canonical ("cooked") input. */
|
||||
tios.c_lflag &= ~ICANON;
|
||||
|
||||
/*
|
||||
* With canonical input off, this says how many characters must be
|
||||
* typed before read() will return.
|
||||
*/
|
||||
tios.c_cc[VMIN] = 1;
|
||||
|
||||
/* This can be used to set up read timeouts, but we don't need that. */
|
||||
tios.c_cc[VTIME] = 0;
|
||||
|
||||
/* Turn off echoing of keypresses. */
|
||||
tios.c_lflag &= ~(ECHO|ECHONL|ECHOCTL);
|
||||
|
||||
/* Do not support XON/XOFF flow control. */
|
||||
tios.c_iflag &= ~(IXON|IXOFF);
|
||||
|
||||
/* On input, we want no CR/LF translation. */
|
||||
tios.c_iflag &= ~(INLCR|IGNCR|ICRNL);
|
||||
|
||||
/* However, on output we want LF ('\n') mapped to CRLF. */
|
||||
#ifdef OCRNL /* missing on OS X */
|
||||
tios.c_oflag &= ~(OCRNL);
|
||||
#endif
|
||||
tios.c_oflag |= OPOST|ONLCR;
|
||||
|
||||
/* Enable keyboard signals (^C, ^Z, etc.) because they're useful. */
|
||||
tios.c_lflag |= ISIG;
|
||||
|
||||
/* Set the new tty state. */
|
||||
hostcompat_runtios = tios;
|
||||
tcsetattr(STDIN_FILENO, TCSADRAIN, &tios);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Signal handler for all the fatal signals (SIGSEGV, SIGTERM, etc.)
|
||||
*/
|
||||
static
|
||||
void
|
||||
hostcompat_die(int sig)
|
||||
{
|
||||
/* Set the tty back to the way we found it */
|
||||
hostcompat_ttyreset();
|
||||
|
||||
/* Make sure the default action will occur when we get another signal*/
|
||||
signal(sig, SIG_DFL);
|
||||
|
||||
/* Post the signal back to ourselves, to cause the right exit status.*/
|
||||
kill(getpid(), sig);
|
||||
|
||||
/* Just in case. */
|
||||
_exit(255);
|
||||
}
|
||||
|
||||
/*
|
||||
* Signal handler for the stop signals (SIGTSTP, SIGTTIN, etc.)
|
||||
*/
|
||||
static
|
||||
void
|
||||
hostcompat_stop(int sig)
|
||||
{
|
||||
/* Set the tty back to the way we found it */
|
||||
hostcompat_ttyreset();
|
||||
|
||||
/* Make sure the default action will occur when we get another signal*/
|
||||
signal(sig, SIG_DFL);
|
||||
|
||||
/* Post the signal back to ourselves. */
|
||||
kill(getpid(), sig);
|
||||
}
|
||||
|
||||
/*
|
||||
* Signal handler for SIGCONT.
|
||||
*/
|
||||
static
|
||||
void
|
||||
hostcompat_cont(int sig)
|
||||
{
|
||||
(void)sig;
|
||||
|
||||
/* Set the tty to the way we want it for running. */
|
||||
hostcompat_ttyresume();
|
||||
|
||||
/*
|
||||
* Reload the signal handlers for stop/continue signals, in case
|
||||
* they were set up with one-shot signals.
|
||||
*/
|
||||
signal(SIGTTIN, hostcompat_stop);
|
||||
signal(SIGTTOU, hostcompat_stop);
|
||||
signal(SIGTSTP, hostcompat_stop);
|
||||
signal(SIGCONT, hostcompat_cont);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the hostcompat library.
|
||||
*/
|
||||
void
|
||||
hostcompat_init(int argc, char *argv[])
|
||||
{
|
||||
/* Set the program name */
|
||||
if (argc > 0 && argv[0] != NULL) {
|
||||
hostcompat_progname = argv[0];
|
||||
}
|
||||
|
||||
/* Set the tty modes */
|
||||
if (hostcompat_ttysetup() < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* When exit() is called, clean up */
|
||||
atexit(hostcompat_ttyreset);
|
||||
|
||||
/* stdout/stderr should be unbuffered */
|
||||
setvbuf(stdout, NULL, _IONBF, 0);
|
||||
setvbuf(stderr, NULL, _IONBF, 0);
|
||||
|
||||
/* Catch all the fatal signals, so we can clean up */
|
||||
signal(SIGHUP, hostcompat_die);
|
||||
signal(SIGINT, hostcompat_die);
|
||||
signal(SIGQUIT, hostcompat_die);
|
||||
signal(SIGILL, hostcompat_die);
|
||||
signal(SIGTRAP, hostcompat_die);
|
||||
signal(SIGABRT, hostcompat_die);
|
||||
#ifdef SIGEMT
|
||||
signal(SIGEMT, hostcompat_die);
|
||||
#endif
|
||||
signal(SIGFPE, hostcompat_die);
|
||||
signal(SIGBUS, hostcompat_die);
|
||||
signal(SIGSEGV, hostcompat_die);
|
||||
signal(SIGSYS, hostcompat_die);
|
||||
signal(SIGPIPE, hostcompat_die);
|
||||
signal(SIGALRM, hostcompat_die);
|
||||
signal(SIGTERM, hostcompat_die);
|
||||
signal(SIGXCPU, hostcompat_die);
|
||||
signal(SIGXFSZ, hostcompat_die);
|
||||
signal(SIGVTALRM, hostcompat_die);
|
||||
signal(SIGPROF, hostcompat_die);
|
||||
signal(SIGUSR1, hostcompat_die);
|
||||
signal(SIGUSR2, hostcompat_die);
|
||||
|
||||
/* Catch the stop signals, so we can adjust the tty */
|
||||
signal(SIGTTIN, hostcompat_stop);
|
||||
signal(SIGTTOU, hostcompat_stop);
|
||||
signal(SIGTSTP, hostcompat_stop);
|
||||
|
||||
/* Catch the continue signal, so we can adjust the tty */
|
||||
signal(SIGCONT, hostcompat_cont);
|
||||
}
|
41
userland/lib/hostcompat/hostcompat.h
Normal file
41
userland/lib/hostcompat/hostcompat.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
|
||||
void hostcompat_init(int argc, char **argv);
|
||||
|
||||
time_t __time(time_t *secs, unsigned long *nsecs);
|
||||
|
||||
#ifdef DECLARE_NTOHLL
|
||||
uint64_t ntohll(uint64_t);
|
||||
#define htonll(x) (ntohll(x))
|
||||
#endif
|
53
userland/lib/hostcompat/ntohll.c
Normal file
53
userland/lib/hostcompat/ntohll.c
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 2014
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "hostcompat.h"
|
||||
|
||||
#ifdef NEED_NTOHLL
|
||||
|
||||
uint64_t
|
||||
ntohll(uint64_t x)
|
||||
{
|
||||
uint32_t x0, x1, y0, y1;
|
||||
|
||||
if (ntohl(1) == 1) {
|
||||
return x;
|
||||
}
|
||||
|
||||
x0 = x & 0xffffffff;
|
||||
y0 = ntohl(x0);
|
||||
x1 = x >> 32;
|
||||
y1 = ntohl(x1);
|
||||
return ((uint64_t)y0 << 32) | y1;
|
||||
}
|
||||
|
||||
#endif
|
54
userland/lib/hostcompat/time.c
Normal file
54
userland/lib/hostcompat/time.c
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* OS/161 __time implementation in terms of Unix gettimeofday().
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <string.h> /* sometimes required for NULL */
|
||||
|
||||
#include "hostcompat.h"
|
||||
|
||||
time_t
|
||||
__time(time_t *secs, unsigned long *nsecs)
|
||||
{
|
||||
struct timeval tv;
|
||||
if (gettimeofday(&tv, NULL) < 0) {
|
||||
return -1;
|
||||
}
|
||||
if (secs) {
|
||||
*secs = tv.tv_sec;
|
||||
}
|
||||
if (nsecs) {
|
||||
*nsecs = tv.tv_usec * 1000;
|
||||
}
|
||||
return tv.tv_sec;
|
||||
}
|
132
userland/lib/libc/Makefile
Normal file
132
userland/lib/libc/Makefile
Normal file
@@ -0,0 +1,132 @@
|
||||
#
|
||||
# Makefile for OS/161 C standard library
|
||||
#
|
||||
|
||||
TOP=../../..
|
||||
.include "$(TOP)/mk/os161.config.mk"
|
||||
|
||||
COMMON=$(TOP)/common/libc
|
||||
|
||||
# printf
|
||||
SRCS+=\
|
||||
$(COMMON)/printf/__printf.c \
|
||||
$(COMMON)/printf/snprintf.c
|
||||
|
||||
# stdio
|
||||
SRCS+=\
|
||||
stdio/__puts.c \
|
||||
stdio/getchar.c \
|
||||
stdio/printf.c \
|
||||
stdio/putchar.c \
|
||||
stdio/puts.c
|
||||
|
||||
# stdlib
|
||||
SRCS+=\
|
||||
stdlib/abort.c \
|
||||
$(COMMON)/stdlib/atoi.c \
|
||||
stdlib/exit.c \
|
||||
stdlib/getenv.c \
|
||||
stdlib/malloc.c \
|
||||
stdlib/qsort.c \
|
||||
stdlib/random.c \
|
||||
stdlib/system.c
|
||||
|
||||
# string
|
||||
SRCS+=\
|
||||
$(COMMON)/string/bzero.c \
|
||||
string/memcmp.c \
|
||||
$(COMMON)/string/memcpy.c \
|
||||
$(COMMON)/string/memmove.c \
|
||||
$(COMMON)/string/memset.c \
|
||||
$(COMMON)/string/strcat.c \
|
||||
$(COMMON)/string/strchr.c \
|
||||
$(COMMON)/string/strcmp.c \
|
||||
$(COMMON)/string/strcpy.c \
|
||||
string/strerror.c \
|
||||
$(COMMON)/string/strlen.c \
|
||||
$(COMMON)/string/strrchr.c \
|
||||
string/strtok.c \
|
||||
$(COMMON)/string/strtok_r.c
|
||||
|
||||
# time
|
||||
SRCS+=\
|
||||
time/time.c
|
||||
|
||||
# system call stubs
|
||||
SRCS+=\
|
||||
$(MYBUILDDIR)/syscalls.S
|
||||
|
||||
# gcc support
|
||||
COMMONGCC=$(TOP)/common/gcc-millicode
|
||||
SRCS+=\
|
||||
$(COMMONGCC)/adddi3.c \
|
||||
$(COMMONGCC)/anddi3.c \
|
||||
$(COMMONGCC)/ashldi3.c \
|
||||
$(COMMONGCC)/ashrdi3.c \
|
||||
$(COMMONGCC)/cmpdi2.c \
|
||||
$(COMMONGCC)/divdi3.c \
|
||||
$(COMMONGCC)/iordi3.c \
|
||||
$(COMMONGCC)/lshldi3.c \
|
||||
$(COMMONGCC)/lshrdi3.c \
|
||||
$(COMMONGCC)/moddi3.c \
|
||||
$(COMMONGCC)/muldi3.c \
|
||||
$(COMMONGCC)/negdi2.c \
|
||||
$(COMMONGCC)/notdi2.c \
|
||||
$(COMMONGCC)/qdivrem.c \
|
||||
$(COMMONGCC)/subdi3.c \
|
||||
$(COMMONGCC)/ucmpdi2.c \
|
||||
$(COMMONGCC)/udivdi3.c \
|
||||
$(COMMONGCC)/umoddi3.c \
|
||||
$(COMMONGCC)/xordi3.c
|
||||
|
||||
|
||||
# other stuff
|
||||
SRCS+=\
|
||||
unix/__assert.c \
|
||||
unix/err.c \
|
||||
unix/errno.c \
|
||||
unix/execvp.c \
|
||||
unix/getcwd.c \
|
||||
$(COMMON)/arch/mips/setjmp.S
|
||||
|
||||
# Name of the library.
|
||||
LIB=c
|
||||
|
||||
# Let the templates do most of the work.
|
||||
.include "$(TOP)/mk/os161.lib.mk"
|
||||
|
||||
#
|
||||
# Generate syscall entry points from system call list.
|
||||
#
|
||||
# Note that this will bomb if the kernel headers haven't been
|
||||
# installed into the staging area.
|
||||
#
|
||||
|
||||
SYSCALL_H=$(INSTALLTOP)/include/kern/syscall.h
|
||||
|
||||
# This is not ideal as it won't rebuild syscalls.S if defs.mk is removed.
|
||||
# But it's better than failing if defs.mk is not present.
|
||||
.if exists($(TOP)/defs.mk)
|
||||
$(MYBUILDDIR)/syscalls.S: $(TOP)/defs.mk
|
||||
.endif
|
||||
$(MYBUILDDIR)/syscalls.S: $(SYSCALL_H)
|
||||
$(MYBUILDDIR)/syscalls.S: syscalls/gensyscalls.sh
|
||||
$(MYBUILDDIR)/syscalls.S: arch/$(MACHINE)/syscalls-$(MACHINE).S
|
||||
-rm -f $@ $@.tmp
|
||||
echo '/* Automatically generated; do not edit */' > $@.tmp
|
||||
cat arch/$(MACHINE)/syscalls-$(MACHINE).S >> $@.tmp
|
||||
syscalls/gensyscalls.sh < $(SYSCALL_H) >> $@.tmp
|
||||
mv -f $@.tmp $@
|
||||
|
||||
clean: cleanhere
|
||||
cleanhere:
|
||||
rm -f $(MYBUILDDIR)/syscalls.S
|
||||
|
||||
predepend:
|
||||
$(MAKE) $(MYBUILDDIR)/syscalls.S
|
||||
|
||||
.PHONY: clean cleanhere depend predepend
|
||||
|
||||
# Have the machine-dependent stuff depend on defs.mk in case MACHINE
|
||||
# or PLATFORM changes.
|
||||
setjmp.o: $(TOP)/defs.mk
|
95
userland/lib/libc/arch/mips/syscalls-mips.S
Normal file
95
userland/lib/libc/arch/mips/syscalls-mips.S
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is copied to syscalls.S, and then the actual syscalls are
|
||||
* appended as lines of the form
|
||||
* SYSCALL(symbol, number)
|
||||
*
|
||||
* Warning: gccs before 3.0 run cpp in -traditional mode on .S files.
|
||||
* So if you use an older gcc you'll need to change the token pasting
|
||||
* in SYSCALL().
|
||||
*/
|
||||
|
||||
#include <kern/syscall.h>
|
||||
#include <machine/regdefs.h>
|
||||
|
||||
/*
|
||||
* Definition for each syscall.
|
||||
* All we do is load the syscall number into v0, the register the
|
||||
* kernel expects to find it in, and jump to the shared syscall code.
|
||||
* (Note that the addiu instruction is in the jump's delay slot.)
|
||||
*/
|
||||
#define SYSCALL(sym, num) \
|
||||
.set noreorder ; \
|
||||
.globl sym ; \
|
||||
.type sym,@function ; \
|
||||
.ent sym ; \
|
||||
sym: ; \
|
||||
j __syscall ; \
|
||||
addiu v0, $0, SYS_##sym ; \
|
||||
.end sym ; \
|
||||
.set reorder
|
||||
|
||||
/*
|
||||
* Now, the shared system call code.
|
||||
* The MIPS syscall ABI is as follows:
|
||||
*
|
||||
* On entry, call number in v0. The rest is like a normal function
|
||||
* call: four args in a0-a3, the other args on the stack.
|
||||
*
|
||||
* On successful return, zero in a3 register; return value in v0
|
||||
* (v0 and v1 for a 64-bit return value).
|
||||
*
|
||||
* On error return, nonzero in a3 register; errno value in v0.
|
||||
*
|
||||
* The use of a3 as a return register to hold the success flag is
|
||||
* gross, but I didn't make it up.
|
||||
*
|
||||
* Note that by longstanding Unix convention and POSIX decree, errno
|
||||
* is not to be set unless the call actually fails.
|
||||
*/
|
||||
|
||||
.set noreorder
|
||||
.text
|
||||
.type __syscall,@function
|
||||
.ent __syscall
|
||||
__syscall:
|
||||
syscall /* make system call */
|
||||
beq a3, $0, 1f /* if a3 is zero, call succeeded */
|
||||
nop /* delay slot */
|
||||
sw v0, errno /* call failed: store errno */
|
||||
li v1, -1 /* and force return value to -1 */
|
||||
li v0, -1
|
||||
1:
|
||||
j ra /* return */
|
||||
nop /* delay slot */
|
||||
.end __syscall
|
||||
.set reorder
|
||||
|
53
userland/lib/libc/stdio/__puts.c
Normal file
53
userland/lib/libc/stdio/__puts.c
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009, 2015
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/*
|
||||
* Nonstandard (hence the __) version of puts that doesn't append
|
||||
* a newline.
|
||||
*
|
||||
* Returns the length of the string printed.
|
||||
*/
|
||||
|
||||
int
|
||||
__puts(const char *str)
|
||||
{
|
||||
size_t len;
|
||||
ssize_t ret;
|
||||
|
||||
len = strlen(str);
|
||||
ret = write(STDOUT_FILENO, str, len);
|
||||
if (ret == -1) {
|
||||
return EOF;
|
||||
}
|
||||
return len;
|
||||
}
|
56
userland/lib/libc/stdio/getchar.c
Normal file
56
userland/lib/libc/stdio/getchar.c
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/*
|
||||
* C standard I/O function - read character from stdin
|
||||
* and return it or the symbolic constant EOF (-1).
|
||||
*/
|
||||
|
||||
int
|
||||
getchar(void)
|
||||
{
|
||||
char ch;
|
||||
int len;
|
||||
|
||||
len = read(STDIN_FILENO, &ch, 1);
|
||||
if (len<=0) {
|
||||
/* end of file or error */
|
||||
return EOF;
|
||||
}
|
||||
|
||||
/*
|
||||
* Cast through unsigned char, to prevent sign extension. This
|
||||
* sends back values on the range 0-255, rather than -128 to 127,
|
||||
* so EOF can be distinguished from legal input.
|
||||
*/
|
||||
return (int)(unsigned char)ch;
|
||||
}
|
78
userland/lib/libc/stdio/printf.c
Normal file
78
userland/lib/libc/stdio/printf.c
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009, 2015
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
/*
|
||||
* printf - C standard I/O function.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Function passed to __vprintf to do the actual output.
|
||||
*/
|
||||
static
|
||||
void
|
||||
__printf_send(void *mydata, const char *data, size_t len)
|
||||
{
|
||||
ssize_t ret;
|
||||
int *err = mydata;
|
||||
|
||||
ret = write(STDOUT_FILENO, data, len);
|
||||
*err = (ret == -1) ? errno : 0;
|
||||
}
|
||||
|
||||
/* printf: hand off to vprintf */
|
||||
int
|
||||
printf(const char *fmt, ...)
|
||||
{
|
||||
int chars;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
chars = vprintf(fmt, ap);
|
||||
va_end(ap);
|
||||
return chars;
|
||||
}
|
||||
|
||||
/* vprintf: call __vprintf to do the work. */
|
||||
int
|
||||
vprintf(const char *fmt, va_list ap)
|
||||
{
|
||||
int chars, err;
|
||||
chars = __vprintf(__printf_send, &err, fmt, ap);
|
||||
if (err) {
|
||||
errno = err;
|
||||
return -1;
|
||||
}
|
||||
return chars;
|
||||
}
|
50
userland/lib/libc/stdio/putchar.c
Normal file
50
userland/lib/libc/stdio/putchar.c
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/*
|
||||
* C standard function - print a single character.
|
||||
*
|
||||
* Properly, stdio is supposed to be buffered, but for present purposes
|
||||
* writing that code is not really worthwhile.
|
||||
*/
|
||||
|
||||
int
|
||||
putchar(int ch)
|
||||
{
|
||||
char c = ch;
|
||||
int len;
|
||||
len = write(STDOUT_FILENO, &c, 1);
|
||||
if (len<=0) {
|
||||
return EOF;
|
||||
}
|
||||
return ch;
|
||||
}
|
42
userland/lib/libc/stdio/puts.c
Normal file
42
userland/lib/libc/stdio/puts.c
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
* C standard I/O function - print a string and a newline.
|
||||
*/
|
||||
|
||||
int
|
||||
puts(const char *s)
|
||||
{
|
||||
__puts(s);
|
||||
putchar('\n');
|
||||
return 0;
|
||||
}
|
45
userland/lib/libc/stdlib/abort.c
Normal file
45
userland/lib/libc/stdlib/abort.c
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/*
|
||||
* C standard function: panic exit from a user program.
|
||||
*
|
||||
* On most Unix systems, this sends the current process a fatal signal.
|
||||
* We can't do that (no signals in OS/161) so we just exit with a
|
||||
* nonzero exit code, skipping any libc cleanup.
|
||||
*/
|
||||
|
||||
void
|
||||
abort(void)
|
||||
{
|
||||
_exit(255);
|
||||
}
|
83
userland/lib/libc/stdlib/exit.c
Normal file
83
userland/lib/libc/stdlib/exit.c
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/*
|
||||
* C standard function: exit process.
|
||||
*/
|
||||
|
||||
void
|
||||
exit(int code)
|
||||
{
|
||||
/*
|
||||
* In a more complicated libc, this would call functions registered
|
||||
* with atexit() before calling the syscall to actually exit.
|
||||
*/
|
||||
|
||||
#ifdef __mips__
|
||||
/*
|
||||
* Because gcc knows that _exit doesn't return, if we call it
|
||||
* directly it will drop any code that follows it. This means
|
||||
* that if _exit *does* return, as happens before it's
|
||||
* implemented, undefined and usually weird behavior ensues.
|
||||
*
|
||||
* As a hack (this is quite gross) do the call by hand in an
|
||||
* asm block. Then gcc doesn't know what it is, and won't
|
||||
* optimize the following code out, and we can make sure
|
||||
* that exit() at least really does not return.
|
||||
*
|
||||
* This asm block violates gcc's asm rules by destroying a
|
||||
* register it doesn't declare ($4, which is a0) but this
|
||||
* hopefully doesn't matter as the only local it can lose
|
||||
* track of is "code" and we don't use it afterwards.
|
||||
*/
|
||||
__asm volatile("jal _exit;" /* call _exit */
|
||||
"move $4, %0" /* put code in a0 (delay slot) */
|
||||
: /* no outputs */
|
||||
: "r" (code)); /* code is an input */
|
||||
/*
|
||||
* Ok, exiting doesn't work; see if we can get our process
|
||||
* killed by making an illegal memory access. Use a magic
|
||||
* number address so the symptoms are recognizable and
|
||||
* unlikely to occur by accident otherwise.
|
||||
*/
|
||||
__asm volatile("li $2, 0xeeeee00f;" /* load magic addr into v0 */
|
||||
"lw $2, 0($2)" /* fetch from it */
|
||||
:: ); /* no args */
|
||||
#else
|
||||
_exit(code);
|
||||
#endif
|
||||
/*
|
||||
* We can't return; so if we can't exit, the only other choice
|
||||
* is to loop.
|
||||
*/
|
||||
while (1) { }
|
||||
}
|
78
userland/lib/libc/stdlib/getenv.c
Normal file
78
userland/lib/libc/stdlib/getenv.c
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 2013
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* getenv(): ANSI C
|
||||
*
|
||||
* Get an environment variable.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is initialized by crt0, though it actually lives in errno.c
|
||||
*/
|
||||
extern char **__environ;
|
||||
|
||||
/*
|
||||
* This is what we use by default if the kernel didn't supply an
|
||||
* environment.
|
||||
*/
|
||||
static const char *__default_environ[] = {
|
||||
"PATH=/bin:/sbin:/testbin",
|
||||
"SHELL=/bin/sh",
|
||||
"TERM=vt220",
|
||||
NULL
|
||||
};
|
||||
|
||||
char *
|
||||
getenv(const char *var)
|
||||
{
|
||||
size_t varlen, thislen;
|
||||
char *s;
|
||||
unsigned i;
|
||||
|
||||
if (__environ == NULL) {
|
||||
__environ = (char **)__default_environ;
|
||||
}
|
||||
varlen = strlen(var);
|
||||
for (i=0; __environ[i] != NULL; i++) {
|
||||
s = strchr(__environ[i], '=');
|
||||
if (s == NULL) {
|
||||
/* ? */
|
||||
continue;
|
||||
}
|
||||
thislen = s - __environ[i];
|
||||
if (thislen == varlen && !memcmp(__environ[i], var, thislen)) {
|
||||
return s + 1;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
591
userland/lib/libc/stdlib/malloc.c
Normal file
591
userland/lib/libc/stdlib/malloc.c
Normal file
@@ -0,0 +1,591 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009, 2014
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* User-level malloc and free implementation.
|
||||
*
|
||||
* This is a basic first-fit allocator. It's intended to be simple and
|
||||
* easy to follow. It performs abysmally if the heap becomes larger than
|
||||
* physical memory. To get (much) better out-of-core performance, port
|
||||
* the kernel's malloc. :-)
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h> // for uintptr_t on non-OS/161 platforms
|
||||
#include <unistd.h>
|
||||
#include <err.h>
|
||||
#include <assert.h>
|
||||
|
||||
#undef MALLOCDEBUG
|
||||
|
||||
#if defined(__mips__) || defined(__i386__)
|
||||
#define MALLOC32
|
||||
#elif defined(__alpha__) || defined(__x86_64__)
|
||||
#define MALLOC64
|
||||
#else
|
||||
#error "please fix me"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* malloc block header.
|
||||
*
|
||||
* mh_prevblock is the downwards offset to the previous header, 0 if this
|
||||
* is the bottom of the heap.
|
||||
*
|
||||
* mh_nextblock is the upwards offset to the next header.
|
||||
*
|
||||
* mh_pad is unused.
|
||||
* mh_inuse is 1 if the block is in use, 0 if it is free.
|
||||
* mh_magic* should always be a fixed value.
|
||||
*
|
||||
* MBLOCKSIZE should equal sizeof(struct mheader) and be a power of 2.
|
||||
* MBLOCKSHIFT is the log base 2 of MBLOCKSIZE.
|
||||
* MMAGIC is the value for mh_magic*.
|
||||
*/
|
||||
struct mheader {
|
||||
|
||||
#if defined(MALLOC32)
|
||||
#define MBLOCKSIZE 8
|
||||
#define MBLOCKSHIFT 3
|
||||
#define MMAGIC 2
|
||||
/*
|
||||
* 32-bit platform. size_t is 32 bits (4 bytes).
|
||||
* Block size is 8 bytes.
|
||||
*/
|
||||
unsigned mh_prevblock:29;
|
||||
unsigned mh_pad:1;
|
||||
unsigned mh_magic1:2;
|
||||
|
||||
unsigned mh_nextblock:29;
|
||||
unsigned mh_inuse:1;
|
||||
unsigned mh_magic2:2;
|
||||
|
||||
#elif defined(MALLOC64)
|
||||
#define MBLOCKSIZE 16
|
||||
#define MBLOCKSHIFT 4
|
||||
#define MMAGIC 6
|
||||
/*
|
||||
* 64-bit platform. size_t is 64 bits (8 bytes)
|
||||
* Block size is 16 bytes.
|
||||
*/
|
||||
unsigned mh_prevblock:60;
|
||||
unsigned mh_pad:1;
|
||||
unsigned mh_magic1:3;
|
||||
|
||||
unsigned mh_nextblock:60;
|
||||
unsigned mh_inuse:1;
|
||||
unsigned mh_magic2:3;
|
||||
|
||||
#else
|
||||
#error "please fix me"
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
* Operator macros on struct mheader.
|
||||
*
|
||||
* M_NEXT/PREVOFF: return offset to next/previous header
|
||||
* M_NEXT/PREV: return next/previous header
|
||||
*
|
||||
* M_DATA: return data pointer of a header
|
||||
* M_SIZE: return data size of a header
|
||||
*
|
||||
* M_OK: true if the magic values are correct
|
||||
*
|
||||
* M_MKFIELD: prepare a value for mh_next/prevblock.
|
||||
* (value should include the header size)
|
||||
*/
|
||||
|
||||
#define M_NEXTOFF(mh) ((size_t)(((size_t)((mh)->mh_nextblock))<<MBLOCKSHIFT))
|
||||
#define M_PREVOFF(mh) ((size_t)(((size_t)((mh)->mh_prevblock))<<MBLOCKSHIFT))
|
||||
#define M_NEXT(mh) ((struct mheader *)(((char*)(mh))+M_NEXTOFF(mh)))
|
||||
#define M_PREV(mh) ((struct mheader *)(((char*)(mh))-M_PREVOFF(mh)))
|
||||
|
||||
#define M_DATA(mh) ((void *)((mh)+1))
|
||||
#define M_SIZE(mh) (M_NEXTOFF(mh)-MBLOCKSIZE)
|
||||
|
||||
#define M_OK(mh) ((mh)->mh_magic1==MMAGIC && (mh)->mh_magic2==MMAGIC)
|
||||
|
||||
#define M_MKFIELD(off) ((off)>>MBLOCKSHIFT)
|
||||
|
||||
/*
|
||||
* System page size. In POSIX you're supposed to call
|
||||
* sysconf(_SC_PAGESIZE). If _SC_PAGESIZE isn't defined, as on OS/161,
|
||||
* assume 4K.
|
||||
*/
|
||||
|
||||
#ifdef _SC_PAGESIZE
|
||||
static size_t __malloc_pagesize;
|
||||
#define PAGE_SIZE __malloc_pagesize
|
||||
#else
|
||||
#define PAGE_SIZE 4096
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
/*
|
||||
* Static variables - the bottom and top addresses of the heap.
|
||||
*/
|
||||
static uintptr_t __heapbase, __heaptop;
|
||||
|
||||
/*
|
||||
* Setup function.
|
||||
*/
|
||||
static
|
||||
void
|
||||
__malloc_init(void)
|
||||
{
|
||||
void *x;
|
||||
|
||||
/*
|
||||
* Check various assumed properties of the sizes.
|
||||
*/
|
||||
if (sizeof(struct mheader) != MBLOCKSIZE) {
|
||||
errx(1, "malloc: Internal error - MBLOCKSIZE wrong");
|
||||
}
|
||||
if ((MBLOCKSIZE & (MBLOCKSIZE-1))!=0) {
|
||||
errx(1, "malloc: Internal error - MBLOCKSIZE not power of 2");
|
||||
}
|
||||
if (1<<MBLOCKSHIFT != MBLOCKSIZE) {
|
||||
errx(1, "malloc: Internal error - MBLOCKSHIFT wrong");
|
||||
}
|
||||
|
||||
/* init should only be called once. */
|
||||
if (__heapbase!=0 || __heaptop!=0) {
|
||||
errx(1, "malloc: Internal error - bad init call");
|
||||
}
|
||||
|
||||
/* Get the page size, if needed. */
|
||||
#ifdef _SC_PAGESIZE
|
||||
__malloc_pagesize = sysconf(_SC_PAGESIZE);
|
||||
#endif
|
||||
|
||||
/* Use sbrk to find the base of the heap. */
|
||||
x = sbrk(0);
|
||||
if (x==(void *)-1) {
|
||||
err(1, "malloc: initial sbrk failed");
|
||||
}
|
||||
if (x==(void *) 0) {
|
||||
errx(1, "malloc: Internal error - heap began at 0");
|
||||
}
|
||||
__heapbase = __heaptop = (uintptr_t)x;
|
||||
|
||||
/*
|
||||
* Make sure the heap base is aligned the way we want it.
|
||||
* (On OS/161, it will begin on a page boundary. But on
|
||||
* an arbitrary Unix, it may not be, as traditionally it
|
||||
* begins at _end.)
|
||||
*/
|
||||
|
||||
if (__heapbase % MBLOCKSIZE != 0) {
|
||||
size_t adjust = MBLOCKSIZE - (__heapbase % MBLOCKSIZE);
|
||||
x = sbrk(adjust);
|
||||
if (x==(void *)-1) {
|
||||
err(1, "malloc: sbrk failed aligning heap base");
|
||||
}
|
||||
if ((uintptr_t)x != __heapbase) {
|
||||
err(1, "malloc: heap base moved during init");
|
||||
}
|
||||
#ifdef MALLOCDEBUG
|
||||
warnx("malloc: adjusted heap base upwards by %lu bytes",
|
||||
(unsigned long) adjust);
|
||||
#endif
|
||||
__heapbase += adjust;
|
||||
__heaptop = __heapbase;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef MALLOCDEBUG
|
||||
|
||||
/*
|
||||
* Debugging print function to iterate and dump the entire heap.
|
||||
*/
|
||||
static
|
||||
void
|
||||
__malloc_dump(void)
|
||||
{
|
||||
struct mheader *mh;
|
||||
uintptr_t i;
|
||||
size_t rightprevblock;
|
||||
|
||||
warnx("heap: ************************************************");
|
||||
|
||||
rightprevblock = 0;
|
||||
for (i=__heapbase; i<__heaptop; i += M_NEXTOFF(mh)) {
|
||||
mh = (struct mheader *) i;
|
||||
if (!M_OK(mh)) {
|
||||
errx(1, "malloc: Heap corrupt; header at 0x%lx"
|
||||
" has bad magic bits",
|
||||
(unsigned long) i);
|
||||
}
|
||||
if (mh->mh_prevblock != rightprevblock) {
|
||||
errx(1, "malloc: Heap corrupt; header at 0x%lx"
|
||||
" has bad previous-block size %lu "
|
||||
"(should be %lu)",
|
||||
(unsigned long) i,
|
||||
(unsigned long) mh->mh_prevblock << MBLOCKSHIFT,
|
||||
(unsigned long) rightprevblock << MBLOCKSHIFT);
|
||||
}
|
||||
rightprevblock = mh->mh_nextblock;
|
||||
|
||||
warnx("heap: 0x%lx 0x%-6lx (next: 0x%lx) %s",
|
||||
(unsigned long) i + MBLOCKSIZE,
|
||||
(unsigned long) M_SIZE(mh),
|
||||
(unsigned long) (i+M_NEXTOFF(mh)),
|
||||
mh->mh_inuse ? "INUSE" : "FREE");
|
||||
}
|
||||
if (i!=__heaptop) {
|
||||
errx(1, "malloc: Heap corrupt; ran off end");
|
||||
}
|
||||
|
||||
warnx("heap: ************************************************");
|
||||
}
|
||||
|
||||
#endif /* MALLOCDEBUG */
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
/*
|
||||
* Get more memory (at the top of the heap) using sbrk, and
|
||||
* return a pointer to it.
|
||||
*/
|
||||
static
|
||||
void *
|
||||
__malloc_sbrk(size_t size)
|
||||
{
|
||||
void *x;
|
||||
|
||||
x = sbrk(size);
|
||||
if (x == (void *)-1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((uintptr_t)x != __heaptop) {
|
||||
errx(1, "malloc: Internal error - "
|
||||
"heap top moved itself from 0x%lx to 0x%lx",
|
||||
(unsigned long) __heaptop,
|
||||
(unsigned long) (uintptr_t) x);
|
||||
}
|
||||
__heaptop += size;
|
||||
return x;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make a new (free) block from the block passed in, leaving size
|
||||
* bytes for data in the current block. size must be a multiple of
|
||||
* MBLOCKSIZE.
|
||||
*
|
||||
* Only split if the excess space is at least twice the blocksize -
|
||||
* one blocksize to hold a header and one for data.
|
||||
*/
|
||||
static
|
||||
void
|
||||
__malloc_split(struct mheader *mh, size_t size)
|
||||
{
|
||||
struct mheader *mhnext, *mhnew;
|
||||
size_t oldsize;
|
||||
|
||||
if (size % MBLOCKSIZE != 0) {
|
||||
errx(1, "malloc: Internal error (size %lu passed to split)",
|
||||
(unsigned long) size);
|
||||
}
|
||||
|
||||
if (M_SIZE(mh) - size < 2*MBLOCKSIZE) {
|
||||
/* no room */
|
||||
return;
|
||||
}
|
||||
|
||||
mhnext = M_NEXT(mh);
|
||||
|
||||
oldsize = M_SIZE(mh);
|
||||
mh->mh_nextblock = M_MKFIELD(size + MBLOCKSIZE);
|
||||
|
||||
mhnew = M_NEXT(mh);
|
||||
if (mhnew==mhnext) {
|
||||
errx(1, "malloc: Internal error (split screwed up?)");
|
||||
}
|
||||
|
||||
mhnew->mh_prevblock = M_MKFIELD(size + MBLOCKSIZE);
|
||||
mhnew->mh_pad = 0;
|
||||
mhnew->mh_magic1 = MMAGIC;
|
||||
mhnew->mh_nextblock = M_MKFIELD(oldsize - size);
|
||||
mhnew->mh_inuse = 0;
|
||||
mhnew->mh_magic2 = MMAGIC;
|
||||
|
||||
if (mhnext != (struct mheader *) __heaptop) {
|
||||
mhnext->mh_prevblock = mhnew->mh_nextblock;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* malloc itself.
|
||||
*/
|
||||
void *
|
||||
malloc(size_t size)
|
||||
{
|
||||
struct mheader *mh;
|
||||
uintptr_t i;
|
||||
size_t rightprevblock;
|
||||
size_t morespace;
|
||||
void *p;
|
||||
|
||||
if (__heapbase==0) {
|
||||
__malloc_init();
|
||||
}
|
||||
if (__heapbase==0 || __heaptop==0 || __heapbase > __heaptop) {
|
||||
warnx("malloc: Internal error - local data corrupt");
|
||||
errx(1, "malloc: heapbase 0x%lx; heaptop 0x%lx",
|
||||
(unsigned long) __heapbase, (unsigned long) __heaptop);
|
||||
}
|
||||
|
||||
#ifdef MALLOCDEBUG
|
||||
warnx("malloc: about to allocate %lu (0x%lx) bytes",
|
||||
(unsigned long) size, (unsigned long) size);
|
||||
__malloc_dump();
|
||||
#endif
|
||||
|
||||
/* Round size up to an integral number of blocks. */
|
||||
size = ((size + MBLOCKSIZE - 1) & ~(size_t)(MBLOCKSIZE-1));
|
||||
|
||||
/*
|
||||
* First-fit search algorithm for available blocks.
|
||||
* Check to make sure the next/previous sizes all agree.
|
||||
*/
|
||||
rightprevblock = 0;
|
||||
mh = NULL;
|
||||
for (i=__heapbase; i<__heaptop; i += M_NEXTOFF(mh)) {
|
||||
mh = (struct mheader *) i;
|
||||
if (!M_OK(mh)) {
|
||||
errx(1, "malloc: Heap corrupt; header at 0x%lx"
|
||||
" has bad magic bits",
|
||||
(unsigned long) i);
|
||||
}
|
||||
if (mh->mh_prevblock != rightprevblock) {
|
||||
errx(1, "malloc: Heap corrupt; header at 0x%lx"
|
||||
" has bad previous-block size %lu "
|
||||
"(should be %lu)",
|
||||
(unsigned long) i,
|
||||
(unsigned long) mh->mh_prevblock << MBLOCKSHIFT,
|
||||
(unsigned long) rightprevblock << MBLOCKSHIFT);
|
||||
}
|
||||
rightprevblock = mh->mh_nextblock;
|
||||
|
||||
/* Can't allocate a block that's in use. */
|
||||
if (mh->mh_inuse) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Can't allocate a block that isn't big enough. */
|
||||
if (M_SIZE(mh) < size) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Try splitting block. */
|
||||
__malloc_split(mh, size);
|
||||
|
||||
/*
|
||||
* Now, allocate.
|
||||
*/
|
||||
mh->mh_inuse = 1;
|
||||
|
||||
#ifdef MALLOCDEBUG
|
||||
warnx("malloc: allocating at %p", M_DATA(mh));
|
||||
__malloc_dump();
|
||||
#endif
|
||||
return M_DATA(mh);
|
||||
}
|
||||
if (i!=__heaptop) {
|
||||
errx(1, "malloc: Heap corrupt; ran off end");
|
||||
}
|
||||
|
||||
/*
|
||||
* Didn't find anything. Expand the heap.
|
||||
*
|
||||
* If the heap is nonempty and the top block (the one mh is
|
||||
* left pointing to after the above loop) is free, we can
|
||||
* expand it. Otherwise we need a new block.
|
||||
*/
|
||||
if (mh != NULL && !mh->mh_inuse) {
|
||||
assert(size > M_SIZE(mh));
|
||||
morespace = size - M_SIZE(mh);
|
||||
}
|
||||
else {
|
||||
morespace = MBLOCKSIZE + size;
|
||||
}
|
||||
|
||||
/* Round the amount of space we ask for up to a whole page. */
|
||||
morespace = PAGE_SIZE * ((morespace + PAGE_SIZE - 1) / PAGE_SIZE);
|
||||
|
||||
p = __malloc_sbrk(morespace);
|
||||
if (p == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (mh != NULL && !mh->mh_inuse) {
|
||||
/* update old header */
|
||||
mh->mh_nextblock = M_MKFIELD(M_NEXTOFF(mh) + morespace);
|
||||
mh->mh_inuse = 1;
|
||||
}
|
||||
else {
|
||||
/* fill out new header */
|
||||
mh = p;
|
||||
mh->mh_prevblock = rightprevblock;
|
||||
mh->mh_magic1 = MMAGIC;
|
||||
mh->mh_magic2 = MMAGIC;
|
||||
mh->mh_pad = 0;
|
||||
mh->mh_inuse = 1;
|
||||
mh->mh_nextblock = M_MKFIELD(morespace);
|
||||
}
|
||||
|
||||
/*
|
||||
* Either way, try splitting the block we got as because of
|
||||
* the page rounding it might be quite a bit bigger than we
|
||||
* needed.
|
||||
*/
|
||||
__malloc_split(mh, size);
|
||||
|
||||
#ifdef MALLOCDEBUG
|
||||
warnx("malloc: allocating at %p", M_DATA(mh));
|
||||
__malloc_dump();
|
||||
#endif
|
||||
return M_DATA(mh);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
/*
|
||||
* Clear a range of memory with 0xdeadbeef.
|
||||
* ptr must be suitably aligned.
|
||||
*/
|
||||
static
|
||||
void
|
||||
__malloc_deadbeef(void *ptr, size_t size)
|
||||
{
|
||||
uint32_t *x = ptr;
|
||||
size_t i, n = size/sizeof(uint32_t);
|
||||
for (i=0; i<n; i++) {
|
||||
x[i] = 0xdeadbeef;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Attempt to merge two adjacent blocks (mh below mhnext).
|
||||
*/
|
||||
static
|
||||
void
|
||||
__malloc_trymerge(struct mheader *mh, struct mheader *mhnext)
|
||||
{
|
||||
struct mheader *mhnextnext;
|
||||
|
||||
if (mh->mh_nextblock != mhnext->mh_prevblock) {
|
||||
errx(1, "free: Heap corrupt (%p and %p inconsistent)",
|
||||
mh, mhnext);
|
||||
}
|
||||
if (mh->mh_inuse || mhnext->mh_inuse) {
|
||||
/* can't merge */
|
||||
return;
|
||||
}
|
||||
|
||||
mhnextnext = M_NEXT(mhnext);
|
||||
|
||||
mh->mh_nextblock = M_MKFIELD(MBLOCKSIZE + M_SIZE(mh) +
|
||||
MBLOCKSIZE + M_SIZE(mhnext));
|
||||
|
||||
if (mhnextnext != (struct mheader *)__heaptop) {
|
||||
mhnextnext->mh_prevblock = mh->mh_nextblock;
|
||||
}
|
||||
|
||||
/* Deadbeef out the memory used by the now-obsolete header */
|
||||
__malloc_deadbeef(mhnext, sizeof(struct mheader));
|
||||
}
|
||||
|
||||
/*
|
||||
* The actual free() implementation.
|
||||
*/
|
||||
void
|
||||
free(void *x)
|
||||
{
|
||||
struct mheader *mh, *mhnext, *mhprev;
|
||||
|
||||
if (x==NULL) {
|
||||
/* safest practice */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Consistency check. */
|
||||
if (__heapbase==0 || __heaptop==0 || __heapbase > __heaptop) {
|
||||
warnx("free: Internal error - local data corrupt");
|
||||
errx(1, "free: heapbase 0x%lx; heaptop 0x%lx",
|
||||
(unsigned long) __heapbase, (unsigned long) __heaptop);
|
||||
}
|
||||
|
||||
/* Don't allow freeing pointers that aren't on the heap. */
|
||||
if ((uintptr_t)x < __heapbase || (uintptr_t)x >= __heaptop) {
|
||||
errx(1, "free: Invalid pointer %p freed (out of range)", x);
|
||||
}
|
||||
|
||||
#ifdef MALLOCDEBUG
|
||||
warnx("free: about to free %p", x);
|
||||
__malloc_dump();
|
||||
#endif
|
||||
|
||||
mh = ((struct mheader *)x)-1;
|
||||
if (!M_OK(mh)) {
|
||||
errx(1, "free: Invalid pointer %p freed (corrupt header)", x);
|
||||
}
|
||||
|
||||
if (!mh->mh_inuse) {
|
||||
errx(1, "free: Invalid pointer %p freed (already free)", x);
|
||||
}
|
||||
|
||||
/* mark it free */
|
||||
mh->mh_inuse = 0;
|
||||
|
||||
/* wipe it */
|
||||
__malloc_deadbeef(M_DATA(mh), M_SIZE(mh));
|
||||
|
||||
/* Try merging with the block above (but not if we're at the top) */
|
||||
mhnext = M_NEXT(mh);
|
||||
if (mhnext != (struct mheader *)__heaptop) {
|
||||
__malloc_trymerge(mh, mhnext);
|
||||
}
|
||||
|
||||
/* Try merging with the block below (but not if we're at the bottom) */
|
||||
if (mh != (struct mheader *)__heapbase) {
|
||||
mhprev = M_PREV(mh);
|
||||
__malloc_trymerge(mhprev, mh);
|
||||
}
|
||||
|
||||
#ifdef MALLOCDEBUG
|
||||
warnx("free: freed %p", x);
|
||||
__malloc_dump();
|
||||
#endif
|
||||
}
|
145
userland/lib/libc/stdlib/qsort.c
Normal file
145
userland/lib/libc/stdlib/qsort.c
Normal file
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Copyright (c) 2014
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
/*
|
||||
* qsort() for OS/161, where it isn't in libc.
|
||||
*/
|
||||
void
|
||||
qsort(void *vdata, unsigned num, size_t size,
|
||||
int (*f)(const void *, const void *))
|
||||
{
|
||||
unsigned pivot, head, tail;
|
||||
char *data = vdata;
|
||||
char tmp[size];
|
||||
|
||||
#define COMPARE(aa, bb) \
|
||||
((aa) == (bb) ? 0 : f(data + (aa) * size, data + (bb) * size))
|
||||
#define EXCHANGE(aa, bb) \
|
||||
memcpy(tmp, data + (aa) * size, size); \
|
||||
memcpy(data + (aa) * size, data + (bb) * size, size); \
|
||||
memcpy(data + (bb) * size, tmp, size)
|
||||
|
||||
|
||||
if (num <= 1) {
|
||||
return;
|
||||
}
|
||||
if (num == 2) {
|
||||
if (COMPARE(0, 1) > 0) {
|
||||
EXCHANGE(0, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 1. Pick a pivot value. For simplicity, always use the
|
||||
* middle of the array.
|
||||
*/
|
||||
pivot = num / 2;
|
||||
|
||||
/*
|
||||
* 2. Shift all values less than or equal to the pivot value
|
||||
* to the front of the array.
|
||||
*/
|
||||
head = 0;
|
||||
tail = num - 1;
|
||||
|
||||
while (head < tail) {
|
||||
if (COMPARE(head, pivot) <= 0) {
|
||||
head++;
|
||||
}
|
||||
else if (COMPARE(tail, pivot) > 0) {
|
||||
tail--;
|
||||
}
|
||||
else {
|
||||
EXCHANGE(head, tail);
|
||||
if (pivot == head) {
|
||||
pivot = tail;
|
||||
}
|
||||
else if (pivot == tail) {
|
||||
pivot = head;
|
||||
}
|
||||
head++;
|
||||
tail--;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 3. If there's an even number of elements and we swapped the
|
||||
* last two, the head and tail indexes will cross. In this
|
||||
* case the first entry on the tail side is tail+1. If there's
|
||||
* an odd number of elements, we stop with head == tail, and
|
||||
* the first entry on the tail side is this value (hence,
|
||||
* tail) if it's is greater than the pivot value, and the next
|
||||
* element (hence, tail+1) if it's less than or equal to the
|
||||
* pivot value.
|
||||
*
|
||||
* Henceforth use "tail" to hold the index of the first entry
|
||||
* of the back portion of the array.
|
||||
*/
|
||||
if (head > tail || COMPARE(head, pivot) <= 0) {
|
||||
tail++;
|
||||
}
|
||||
|
||||
/*
|
||||
* 4. If we got a bad pivot that gave us only one partition,
|
||||
* because of the order of the advances in the loop above it
|
||||
* will always put everything in the front portion of the
|
||||
* array (so tail == num). This happens if we picked the
|
||||
* largest value. Move the pivot to the end, if necessary, lop
|
||||
* off all values equal to it, and recurse on the rest. (If
|
||||
* there is no rest, the array is already sorted and we're
|
||||
* done.)
|
||||
*/
|
||||
if (tail == num) {
|
||||
if (pivot < num - 1) {
|
||||
if (COMPARE(pivot, num - 1) > 0) {
|
||||
EXCHANGE(pivot, num - 1);
|
||||
}
|
||||
}
|
||||
tail = num - 1;
|
||||
while (tail > 0 && COMPARE(tail - 1, tail) == 0) {
|
||||
tail--;
|
||||
}
|
||||
if (tail > 0) {
|
||||
qsort(vdata, tail, size, f);
|
||||
}
|
||||
return;
|
||||
}
|
||||
assert(tail > 0 && tail < num);
|
||||
|
||||
/*
|
||||
* 5. Recurse on each subpart of the array.
|
||||
*/
|
||||
qsort(vdata, tail, size, f);
|
||||
qsort((char *)vdata + tail * size, num - tail, size, f);
|
||||
}
|
453
userland/lib/libc/stdlib/random.c
Normal file
453
userland/lib/libc/stdlib/random.c
Normal file
@@ -0,0 +1,453 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* From:
|
||||
* NetBSD: random.c,v 1.19 2000/01/22 22:19:20 mycroft Exp
|
||||
*
|
||||
* Hacked gruesomely for OS/161.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/*
|
||||
* For a thread-safe libc, declare a lock for this file and change
|
||||
* these to be nonempty.
|
||||
*/
|
||||
#define LOCKME()
|
||||
#define UNLOCKME()
|
||||
|
||||
static void srandom_unlocked(unsigned long);
|
||||
static long random_unlocked(void);
|
||||
|
||||
|
||||
/*
|
||||
* random.c:
|
||||
*
|
||||
* An improved random number generation package. In addition to the standard
|
||||
* rand()/srand() like interface, this package also has a special state info
|
||||
* interface. The initstate() routine is called with a seed, an array of
|
||||
* bytes, and a count of how many bytes are being passed in; this array is
|
||||
* then initialized to contain information for random number generation with
|
||||
* that much state information. Good sizes for the amount of state
|
||||
* information are 32, 64, 128, and 256 bytes. The state can be switched by
|
||||
* calling the setstate() routine with the same array as was initiallized
|
||||
* with initstate(). By default, the package runs with 128 bytes of state
|
||||
* information and generates far better random numbers than a linear
|
||||
* congruential generator. If the amount of state information is less than
|
||||
* 32 bytes, a simple linear congruential R.N.G. is used.
|
||||
*
|
||||
* Internally, the state information is treated as an array of longs; the
|
||||
* zeroeth element of the array is the type of R.N.G. being used (small
|
||||
* integer); the remainder of the array is the state information for the
|
||||
* R.N.G. Thus, 32 bytes of state information will give 7 longs worth of
|
||||
* state information, which will allow a degree seven polynomial. (Note:
|
||||
* the zeroeth word of state information also has some other information
|
||||
* stored in it -- see setstate() for details).
|
||||
*
|
||||
* The random number generation technique is a linear feedback shift register
|
||||
* approach, employing trinomials (since there are fewer terms to sum up that
|
||||
* way). In this approach, the least significant bit of all the numbers in
|
||||
* the state table will act as a linear feedback shift register, and will
|
||||
* have period 2^deg - 1 (where deg is the degree of the polynomial being
|
||||
* used, assuming that the polynomial is irreducible and primitive). The
|
||||
* higher order bits will have longer periods, since their values are also
|
||||
* influenced by pseudo-random carries out of the lower bits. The total
|
||||
* period of the generator is approximately deg*(2**deg - 1); thus doubling
|
||||
* the amount of state information has a vast influence on the period of the
|
||||
* generator. Note: the deg*(2**deg - 1) is an approximation only good for
|
||||
* large deg, when the period of the shift register is the dominant factor.
|
||||
* With deg equal to seven, the period is actually much longer than the
|
||||
* 7*(2**7 - 1) predicted by this formula.
|
||||
*
|
||||
* Modified 28 December 1994 by Jacob S. Rosenberg.
|
||||
* The following changes have been made:
|
||||
* All references to the type u_int have been changed to unsigned long.
|
||||
* All references to type int have been changed to type long. Other
|
||||
* cleanups have been made as well. A warning for both initstate and
|
||||
* setstate has been inserted to the effect that on Sparc platforms
|
||||
* the 'arg_state' variable must be forced to begin on word boundaries.
|
||||
* This can be easily done by casting a long integer array to char *.
|
||||
* The overall logic has been left STRICTLY alone. This software was
|
||||
* tested on both a VAX and Sun SpacsStation with exactly the same
|
||||
* results. The new version and the original give IDENTICAL results.
|
||||
* The new version is somewhat faster than the original. As the
|
||||
* documentation says: "By default, the package runs with 128 bytes of
|
||||
* state information and generates far better random numbers than a linear
|
||||
* congruential generator. If the amount of state information is less than
|
||||
* 32 bytes, a simple linear congruential R.N.G. is used." For a buffer of
|
||||
* 128 bytes, this new version runs about 19 percent faster and for a 16
|
||||
* byte buffer it is about 5 percent faster.
|
||||
*/
|
||||
|
||||
/*
|
||||
* For each of the currently supported random number generators, we have a
|
||||
* break value on the amount of state information (you need at least this
|
||||
* many bytes of state info to support this random number generator), a degree
|
||||
* for the polynomial (actually a trinomial) that the R.N.G. is based on, and
|
||||
* the separation between the two lower order coefficients of the trinomial.
|
||||
*/
|
||||
#define TYPE_0 0 /* linear congruential */
|
||||
#define BREAK_0 8
|
||||
#define DEG_0 0
|
||||
#define SEP_0 0
|
||||
|
||||
#define TYPE_1 1 /* x**7 + x**3 + 1 */
|
||||
#define BREAK_1 32
|
||||
#define DEG_1 7
|
||||
#define SEP_1 3
|
||||
|
||||
#define TYPE_2 2 /* x**15 + x + 1 */
|
||||
#define BREAK_2 64
|
||||
#define DEG_2 15
|
||||
#define SEP_2 1
|
||||
|
||||
#define TYPE_3 3 /* x**31 + x**3 + 1 */
|
||||
#define BREAK_3 128
|
||||
#define DEG_3 31
|
||||
#define SEP_3 3
|
||||
|
||||
#define TYPE_4 4 /* x**63 + x + 1 */
|
||||
#define BREAK_4 256
|
||||
#define DEG_4 63
|
||||
#define SEP_4 1
|
||||
|
||||
/*
|
||||
* Array versions of the above information to make code run faster --
|
||||
* relies on fact that TYPE_i == i.
|
||||
*/
|
||||
#define MAX_TYPES 5 /* max number of types above */
|
||||
|
||||
static const int degrees[MAX_TYPES] = { DEG_0, DEG_1, DEG_2, DEG_3, DEG_4 };
|
||||
static const int seps[MAX_TYPES] = { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 };
|
||||
|
||||
/*
|
||||
* Initially, everything is set up as if from:
|
||||
*
|
||||
* initstate(1, &randtbl, 128);
|
||||
*
|
||||
* Note that this initialization takes advantage of the fact that srandom()
|
||||
* advances the front and rear pointers 10*rand_deg times, and hence the
|
||||
* rear pointer which starts at 0 will also end up at zero; thus the zeroeth
|
||||
* element of the state information, which contains info about the current
|
||||
* position of the rear pointer is just
|
||||
*
|
||||
* MAX_TYPES * (rptr - state) + TYPE_3 == TYPE_3.
|
||||
*/
|
||||
|
||||
static long randtbl[DEG_3 + 1] = {
|
||||
TYPE_3,
|
||||
(long)0x9a319039L, (long)0x32d9c024L, (long)0x9b663182L,
|
||||
(long)0x5da1f342L, (long)0xde3b81e0L, (long)0xdf0a6fb5L,
|
||||
(long)0xf103bc02L, (long)0x48f340fbL, (long)0x7449e56bL,
|
||||
(long)0xbeb1dbb0L, (long)0xab5c5918L, (long)0x946554fdL,
|
||||
(long)0x8c2e680fL, (long)0xeb3d799fL, (long)0xb11ee0b7L,
|
||||
(long)0x2d436b86L, (long)0xda672e2aL, (long)0x1588ca88L,
|
||||
(long)0xe369735dL, (long)0x904f35f7L, (long)0xd7158fd6L,
|
||||
(long)0x6fa6f051L, (long)0x616e6b96L, (long)0xac94efdcL,
|
||||
(long)0x36413f93L, (long)0xc622c298L, (long)0xf5a42ab8L,
|
||||
(long)0x8a88d77bL, (long)0xf5ad9d0eL, (long)0x8999220bL,
|
||||
(long)0x27fb47b9L,
|
||||
};
|
||||
|
||||
/*
|
||||
* fptr and rptr are two pointers into the state info, a front and a rear
|
||||
* pointer. These two pointers are always rand_sep places aparts, as they
|
||||
* cycle cyclically through the state information. (Yes, this does mean we
|
||||
* could get away with just one pointer, but the code for random() is more
|
||||
* efficient this way). The pointers are left positioned as they would be
|
||||
* from the call
|
||||
*
|
||||
* initstate(1, randtbl, 128);
|
||||
*
|
||||
* (The position of the rear pointer, rptr, is really 0 (as explained above
|
||||
* in the initialization of randtbl) because the state table pointer is set
|
||||
* to point to randtbl[1] (as explained below).
|
||||
*/
|
||||
static long *fptr = &randtbl[SEP_3 + 1];
|
||||
static long *rptr = &randtbl[1];
|
||||
|
||||
/*
|
||||
* The following things are the pointer to the state information table, the
|
||||
* type of the current generator, the degree of the current polynomial being
|
||||
* used, and the separation between the two pointers. Note that for efficiency
|
||||
* of random(), we remember the first location of the state information, not
|
||||
* the zeroeth. Hence it is valid to access state[-1], which is used to
|
||||
* store the type of the R.N.G. Also, we remember the last location, since
|
||||
* this is more efficient than indexing every time to find the address of
|
||||
* the last element to see if the front and rear pointers have wrapped.
|
||||
*/
|
||||
static long *state = &randtbl[1];
|
||||
static long rand_type = TYPE_3;
|
||||
static int rand_deg = DEG_3;
|
||||
static int rand_sep = SEP_3;
|
||||
static long *end_ptr = &randtbl[DEG_3 + 1];
|
||||
|
||||
/*
|
||||
* srandom:
|
||||
*
|
||||
* Initialize the random number generator based on the given seed. If the
|
||||
* type is the trivial no-state-information type, just remember the seed.
|
||||
* Otherwise, initializes state[] based on the given "seed" via a linear
|
||||
* congruential generator. Then, the pointers are set to known locations
|
||||
* that are exactly rand_sep places apart. Lastly, it cycles the state
|
||||
* information a given number of times to get rid of any initial dependencies
|
||||
* introduced by the L.C.R.N.G. Note that the initialization of randtbl[]
|
||||
* for default usage relies on values produced by this routine.
|
||||
*/
|
||||
static
|
||||
void
|
||||
srandom_unlocked(unsigned long x)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (rand_type == TYPE_0)
|
||||
state[0] = x;
|
||||
else {
|
||||
state[0] = x;
|
||||
for (i = 1; i < rand_deg; i++)
|
||||
state[i] = 1103515245L * state[i - 1] + 12345L;
|
||||
fptr = &state[rand_sep];
|
||||
rptr = &state[0];
|
||||
for (i = 0; i < 10 * rand_deg; i++)
|
||||
(void)random_unlocked();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
srandom(unsigned long x)
|
||||
{
|
||||
|
||||
LOCKME();
|
||||
srandom_unlocked(x);
|
||||
UNLOCKME();
|
||||
}
|
||||
|
||||
/*
|
||||
* initstate:
|
||||
*
|
||||
* Initialize the state information in the given array of n bytes for future
|
||||
* random number generation. Based on the number of bytes we are given, and
|
||||
* the break values for the different R.N.G.'s, we choose the best (largest)
|
||||
* one we can and set things up for it. srandom() is then called to
|
||||
* initialize the state information.
|
||||
*
|
||||
* Note that on return from srandom(), we set state[-1] to be the type
|
||||
* multiplexed with the current value of the rear pointer; this is so
|
||||
* successive calls to initstate() won't lose this information and will be
|
||||
* able to restart with setstate().
|
||||
*
|
||||
* Note: the first thing we do is save the current state, if any, just like
|
||||
* setstate() so that it doesn't matter when initstate is called.
|
||||
*
|
||||
* Returns a pointer to the old state.
|
||||
*
|
||||
* Note: The Sparc platform requires that arg_state begin on a long
|
||||
* word boundary; otherwise a bus error will occur. Even so, lint will
|
||||
* complain about mis-alignment, but you should disregard these messages.
|
||||
*/
|
||||
char *
|
||||
initstate(
|
||||
unsigned long seed, /* seed for R.N.G. */
|
||||
char *arg_state, /* pointer to state array */
|
||||
size_t n) /* # bytes of state info */
|
||||
{
|
||||
void *ostate = (void *)(&state[-1]);
|
||||
long *long_arg_state;
|
||||
|
||||
assert(arg_state != NULL);
|
||||
|
||||
long_arg_state = (long *)(void *)arg_state;
|
||||
|
||||
LOCKME();
|
||||
if (rand_type == TYPE_0)
|
||||
state[-1] = rand_type;
|
||||
else
|
||||
state[-1] = MAX_TYPES * (rptr - state) + rand_type;
|
||||
if (n < BREAK_0) {
|
||||
UNLOCKME();
|
||||
return (NULL);
|
||||
} else if (n < BREAK_1) {
|
||||
rand_type = TYPE_0;
|
||||
rand_deg = DEG_0;
|
||||
rand_sep = SEP_0;
|
||||
} else if (n < BREAK_2) {
|
||||
rand_type = TYPE_1;
|
||||
rand_deg = DEG_1;
|
||||
rand_sep = SEP_1;
|
||||
} else if (n < BREAK_3) {
|
||||
rand_type = TYPE_2;
|
||||
rand_deg = DEG_2;
|
||||
rand_sep = SEP_2;
|
||||
} else if (n < BREAK_4) {
|
||||
rand_type = TYPE_3;
|
||||
rand_deg = DEG_3;
|
||||
rand_sep = SEP_3;
|
||||
} else {
|
||||
rand_type = TYPE_4;
|
||||
rand_deg = DEG_4;
|
||||
rand_sep = SEP_4;
|
||||
}
|
||||
state = (long *) (long_arg_state + 1); /* first location */
|
||||
end_ptr = &state[rand_deg]; /* must set end_ptr before srandom */
|
||||
srandom_unlocked(seed);
|
||||
if (rand_type == TYPE_0)
|
||||
long_arg_state[0] = rand_type;
|
||||
else
|
||||
long_arg_state[0] = MAX_TYPES * (rptr - state) + rand_type;
|
||||
UNLOCKME();
|
||||
return((char *)ostate);
|
||||
}
|
||||
|
||||
/*
|
||||
* setstate:
|
||||
*
|
||||
* Restore the state from the given state array.
|
||||
*
|
||||
* Note: it is important that we also remember the locations of the pointers
|
||||
* in the current state information, and restore the locations of the pointers
|
||||
* from the old state information. This is done by multiplexing the pointer
|
||||
* location into the zeroeth word of the state information.
|
||||
*
|
||||
* Note that due to the order in which things are done, it is OK to call
|
||||
* setstate() with the same state as the current state.
|
||||
*
|
||||
* Returns a pointer to the old state information.
|
||||
*
|
||||
* Note: The Sparc platform requires that arg_state begin on a long
|
||||
* word boundary; otherwise a bus error will occur. Even so, lint will
|
||||
* complain about mis-alignment, but you should disregard these messages.
|
||||
*/
|
||||
char *
|
||||
setstate(char *arg_state) /* pointer to state array */
|
||||
{
|
||||
long *new_state;
|
||||
int type;
|
||||
int rear;
|
||||
void *ostate = (void *)(&state[-1]);
|
||||
|
||||
assert(arg_state != NULL);
|
||||
|
||||
new_state = (long *)(void *)arg_state;
|
||||
type = (int)(new_state[0] % MAX_TYPES);
|
||||
rear = (int)(new_state[0] / MAX_TYPES);
|
||||
|
||||
LOCKME();
|
||||
if (rand_type == TYPE_0)
|
||||
state[-1] = rand_type;
|
||||
else
|
||||
state[-1] = MAX_TYPES * (rptr - state) + rand_type;
|
||||
switch(type) {
|
||||
case TYPE_0:
|
||||
case TYPE_1:
|
||||
case TYPE_2:
|
||||
case TYPE_3:
|
||||
case TYPE_4:
|
||||
rand_type = type;
|
||||
rand_deg = degrees[type];
|
||||
rand_sep = seps[type];
|
||||
break;
|
||||
default:
|
||||
UNLOCKME();
|
||||
return (NULL);
|
||||
}
|
||||
state = (long *) (new_state + 1);
|
||||
if (rand_type != TYPE_0) {
|
||||
rptr = &state[rear];
|
||||
fptr = &state[(rear + rand_sep) % rand_deg];
|
||||
}
|
||||
end_ptr = &state[rand_deg]; /* set end_ptr too */
|
||||
UNLOCKME();
|
||||
return((char *)ostate);
|
||||
}
|
||||
|
||||
/*
|
||||
* random:
|
||||
*
|
||||
* If we are using the trivial TYPE_0 R.N.G., just do the old linear
|
||||
* congruential bit. Otherwise, we do our fancy trinomial stuff, which is
|
||||
* the same in all the other cases due to all the global variables that have
|
||||
* been set up. The basic operation is to add the number at the rear pointer
|
||||
* into the one at the front pointer. Then both pointers are advanced to
|
||||
* the next location cyclically in the table. The value returned is the sum
|
||||
* generated, reduced to 31 bits by throwing away the "least random" low bit.
|
||||
*
|
||||
* Note: the code takes advantage of the fact that both the front and
|
||||
* rear pointers can't wrap on the same call by not testing the rear
|
||||
* pointer if the front one has wrapped.
|
||||
*
|
||||
* Returns a 31-bit random number.
|
||||
*/
|
||||
static
|
||||
long
|
||||
random_unlocked(void)
|
||||
{
|
||||
long i;
|
||||
long *f, *r;
|
||||
|
||||
if (rand_type == TYPE_0) {
|
||||
i = state[0];
|
||||
state[0] = i = (i * 1103515245L + 12345L) & 0x7fffffff;
|
||||
} else {
|
||||
/*
|
||||
* Use local variables rather than static variables for speed.
|
||||
*/
|
||||
f = fptr; r = rptr;
|
||||
*f += *r;
|
||||
/* chucking least random bit */
|
||||
i = ((unsigned long)*f >> 1) & 0x7fffffff;
|
||||
if (++f >= end_ptr) {
|
||||
f = state;
|
||||
++r;
|
||||
}
|
||||
else if (++r >= end_ptr) {
|
||||
r = state;
|
||||
}
|
||||
|
||||
fptr = f; rptr = r;
|
||||
}
|
||||
return(i);
|
||||
}
|
||||
|
||||
long
|
||||
random(void)
|
||||
{
|
||||
long r;
|
||||
|
||||
LOCKME();
|
||||
r = random_unlocked();
|
||||
UNLOCKME();
|
||||
return (r);
|
||||
}
|
91
userland/lib/libc/stdlib/system.c
Normal file
91
userland/lib/libc/stdlib/system.c
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* system(): ANSI C
|
||||
*
|
||||
* Run a command.
|
||||
*/
|
||||
|
||||
#define MAXCMDSIZE 2048
|
||||
#define MAXARGS 128
|
||||
|
||||
int
|
||||
system(const char *cmd)
|
||||
{
|
||||
/*
|
||||
* Ordinarily, you call the shell to process the command.
|
||||
* But we don't know that the shell can do that. So, do it
|
||||
* ourselves.
|
||||
*/
|
||||
|
||||
char tmp[MAXCMDSIZE];
|
||||
char *argv[MAXARGS+1];
|
||||
int nargs=0;
|
||||
char *s;
|
||||
int pid, status;
|
||||
|
||||
if (strlen(cmd) >= sizeof(tmp)) {
|
||||
errno = E2BIG;
|
||||
return -1;
|
||||
}
|
||||
strcpy(tmp, cmd);
|
||||
|
||||
for (s = strtok(tmp, " \t"); s; s = strtok(NULL, " \t")) {
|
||||
if (nargs < MAXARGS) {
|
||||
argv[nargs++] = s;
|
||||
}
|
||||
else {
|
||||
errno = E2BIG;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
argv[nargs] = NULL;
|
||||
|
||||
pid = fork();
|
||||
switch (pid) {
|
||||
case -1:
|
||||
return -1;
|
||||
case 0:
|
||||
/* child */
|
||||
execv(argv[0], argv);
|
||||
/* exec only returns if it fails */
|
||||
_exit(255);
|
||||
default:
|
||||
/* parent */
|
||||
waitpid(pid, &status, 0);
|
||||
return status;
|
||||
}
|
||||
}
|
50
userland/lib/libc/string/memcmp.c
Normal file
50
userland/lib/libc/string/memcmp.c
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* Standard C string function: compare two memory blocks and return
|
||||
* their sort order.
|
||||
*/
|
||||
|
||||
int
|
||||
memcmp(const void *av, const void *bv, size_t len)
|
||||
{
|
||||
const unsigned char *a = av;
|
||||
const unsigned char *b = bv;
|
||||
size_t i;
|
||||
|
||||
for (i=0; i<len; i++) {
|
||||
if (a[i] != b[i]) {
|
||||
return (int)(a[i] - b[i]);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
43
userland/lib/libc/string/strerror.c
Normal file
43
userland/lib/libc/string/strerror.c
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <kern/errmsg.h>
|
||||
|
||||
/*
|
||||
* Standard C function to return a string for a given errno.
|
||||
*/
|
||||
const char *
|
||||
strerror(int errcode)
|
||||
{
|
||||
if (errcode>=0 && errcode < sys_nerr) {
|
||||
return sys_errlist[errcode];
|
||||
}
|
||||
return "Unknown error number";
|
||||
}
|
38
userland/lib/libc/string/strtok.c
Normal file
38
userland/lib/libc/string/strtok.c
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
static char *__strtok_context;
|
||||
|
||||
char *
|
||||
strtok(char *str, const char *seps)
|
||||
{
|
||||
return strtok_r(str, seps, &__strtok_context);
|
||||
}
|
25
userland/lib/libc/syscalls/gensyscalls.sh
Executable file
25
userland/lib/libc/syscalls/gensyscalls.sh
Executable file
@@ -0,0 +1,25 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# gensyscalls.sh
|
||||
# Usage: ./gensyscalls.sh < syscalls.h
|
||||
#
|
||||
# Parses the kernel's syscalls.h into the body of syscalls.S
|
||||
#
|
||||
|
||||
# tabs to spaces, just in case
|
||||
tr '\t' ' ' |\
|
||||
awk '
|
||||
# Do not read the parts of the file that are not between the markers.
|
||||
/^\/\*CALLBEGIN\*\// { look=1; }
|
||||
/^\/\*CALLEND\*\// { look=0; }
|
||||
|
||||
# And, do not read lines that do not match the approximate right pattern.
|
||||
look && /^#define SYS_/ && NF==3 {
|
||||
sub("^SYS_", "", $2);
|
||||
# print the name of the call and the number.
|
||||
print $2, $3;
|
||||
}
|
||||
' | awk '{
|
||||
# output something simple that will work in syscalls.S.
|
||||
printf "SYSCALL(%s, %s)\n", $1, $2;
|
||||
}'
|
42
userland/lib/libc/time/time.c
Normal file
42
userland/lib/libc/time/time.c
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
/*
|
||||
* POSIX C function: retrieve time in seconds since the epoch.
|
||||
* Uses the OS/161 system call __time, which does the same thing
|
||||
* but also returns nanoseconds.
|
||||
*/
|
||||
|
||||
time_t
|
||||
time(time_t *t)
|
||||
{
|
||||
return __time(t, NULL);
|
||||
}
|
50
userland/lib/libc/unix/__assert.c
Normal file
50
userland/lib/libc/unix/__assert.c
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* Function that gets called when an assert() fails.
|
||||
* Print a message to stderr and bail out of the program.
|
||||
*/
|
||||
|
||||
void
|
||||
__bad_assert(const char *file, int line, const char *expr)
|
||||
{
|
||||
char buf[256];
|
||||
snprintf(buf, sizeof(buf), "Assertion failed: %s (%s line %d)\n",
|
||||
expr, file, line);
|
||||
|
||||
write(STDERR_FILENO, buf, strlen(buf));
|
||||
abort();
|
||||
}
|
191
userland/lib/libc/unix/err.c
Normal file
191
userland/lib/libc/unix/err.c
Normal file
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
|
||||
/*
|
||||
* 4.4BSD error printing functions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is initialized by crt0, though it actually lives in errno.c
|
||||
*/
|
||||
extern char **__argv;
|
||||
|
||||
/*
|
||||
* Routine to print error message text to stderr.
|
||||
*/
|
||||
static
|
||||
void
|
||||
__senderr(void *junk, const char *data, size_t len)
|
||||
{
|
||||
(void)junk; /* not needed or used */
|
||||
|
||||
write(STDERR_FILENO, data, len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Shortcut to call __senderr on a null-terminated string.
|
||||
* (__senderr is set up to be called by __vprintf.)
|
||||
*/
|
||||
static
|
||||
void
|
||||
__senderrstr(const char *str)
|
||||
{
|
||||
__senderr(NULL, str, strlen(str));
|
||||
}
|
||||
|
||||
/*
|
||||
* Common routine for all the *err* and *warn* functions.
|
||||
*/
|
||||
static
|
||||
void
|
||||
__printerr(int use_errno, const char *fmt, va_list ap)
|
||||
{
|
||||
const char *errmsg;
|
||||
const char *prog;
|
||||
|
||||
/*
|
||||
* Get the error message for the current errno.
|
||||
* Do this early, before doing anything that might change the
|
||||
* value in errno.
|
||||
*/
|
||||
errmsg = strerror(errno);
|
||||
|
||||
/*
|
||||
* Look up the program name.
|
||||
* Strictly speaking we should pull off the rightmost
|
||||
* path component of argv[0] and use that as the program
|
||||
* name (this is how BSD err* prints) but it doesn't make
|
||||
* much difference.
|
||||
*/
|
||||
if (__argv!=NULL && __argv[0]!=NULL) {
|
||||
prog = __argv[0];
|
||||
}
|
||||
else {
|
||||
prog = "(program name unknown)";
|
||||
}
|
||||
|
||||
/* print the program name */
|
||||
__senderrstr(prog);
|
||||
__senderrstr(": ");
|
||||
|
||||
/* process the printf format and args */
|
||||
__vprintf(__senderr, NULL, fmt, ap);
|
||||
|
||||
/* if we're using errno, print the error string from above. */
|
||||
if (use_errno) {
|
||||
__senderrstr(": ");
|
||||
__senderrstr(errmsg);
|
||||
}
|
||||
|
||||
/* and always add a newline. */
|
||||
__senderrstr("\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* The va_list versions of the warn/err functions.
|
||||
*/
|
||||
|
||||
/* warn/vwarn: use errno, don't exit */
|
||||
void
|
||||
vwarn(const char *fmt, va_list ap)
|
||||
{
|
||||
__printerr(1, fmt, ap);
|
||||
}
|
||||
|
||||
/* warnx/vwarnx: don't use errno, don't exit */
|
||||
void
|
||||
vwarnx(const char *fmt, va_list ap)
|
||||
{
|
||||
__printerr(0, fmt, ap);
|
||||
}
|
||||
|
||||
/* err/verr: use errno, then exit */
|
||||
void
|
||||
verr(int exitcode, const char *fmt, va_list ap)
|
||||
{
|
||||
__printerr(1, fmt, ap);
|
||||
exit(exitcode);
|
||||
}
|
||||
|
||||
/* errx/verrx: don't use errno, but do then exit */
|
||||
void
|
||||
verrx(int exitcode, const char *fmt, va_list ap)
|
||||
{
|
||||
__printerr(0, fmt, ap);
|
||||
exit(exitcode);
|
||||
}
|
||||
|
||||
/*
|
||||
* The non-va_list versions of the warn/err functions.
|
||||
* Just hand off to the va_list versions.
|
||||
*/
|
||||
|
||||
void
|
||||
warn(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vwarn(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void
|
||||
warnx(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vwarnx(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void
|
||||
err(int exitcode, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
verr(exitcode, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void
|
||||
errx(int exitcode, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
verrx(exitcode, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
45
userland/lib/libc/unix/errno.c
Normal file
45
userland/lib/libc/unix/errno.c
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
/*
|
||||
* Source file that declares the space for the global variable errno.
|
||||
*
|
||||
* We also declare the space for __argv, which is used by the err*
|
||||
* functions, and __environ, which is used by getenv(). Since these
|
||||
* are set by crt0, they are always referenced in every program;
|
||||
* putting them here prevents gratuitously linking all the err* and
|
||||
* warn* functions (and thus printf) into every program.
|
||||
*/
|
||||
|
||||
char **__argv;
|
||||
char **__environ;
|
||||
|
||||
int errno;
|
91
userland/lib/libc/unix/execvp.c
Normal file
91
userland/lib/libc/unix/execvp.c
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) 2013
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
|
||||
/*
|
||||
* POSIX C function: exec a program on the search path. Tries
|
||||
* execv() repeatedly until one of the choices works.
|
||||
*/
|
||||
int
|
||||
execvp(const char *prog, char *const *args)
|
||||
{
|
||||
const char *searchpath, *s, *t;
|
||||
char progpath[PATH_MAX];
|
||||
size_t len;
|
||||
|
||||
if (strchr(prog, '/') != NULL) {
|
||||
execv(prog, args);
|
||||
return -1;
|
||||
}
|
||||
|
||||
searchpath = getenv("PATH");
|
||||
if (searchpath == NULL) {
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (s = searchpath; s != NULL; s = t) {
|
||||
t = strchr(s, ':');
|
||||
if (t != NULL) {
|
||||
len = t - s;
|
||||
/* advance past the colon */
|
||||
t++;
|
||||
}
|
||||
else {
|
||||
len = strlen(s);
|
||||
}
|
||||
if (len == 0) {
|
||||
continue;
|
||||
}
|
||||
if (len >= sizeof(progpath)) {
|
||||
continue;
|
||||
}
|
||||
memcpy(progpath, s, len);
|
||||
snprintf(progpath + len, sizeof(progpath) - len, "/%s", prog);
|
||||
execv(progpath, args);
|
||||
switch (errno) {
|
||||
case ENOENT:
|
||||
case ENOTDIR:
|
||||
case ENOEXEC:
|
||||
/* routine errors, try next dir */
|
||||
break;
|
||||
default:
|
||||
/* oops, let's fail */
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
}
|
56
userland/lib/libc/unix/getcwd.c
Normal file
56
userland/lib/libc/unix/getcwd.c
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
/*
|
||||
* POSIX C function: retrieve current working directory.
|
||||
* Uses the system call __getcwd(), which does essentially
|
||||
* all the work.
|
||||
*/
|
||||
|
||||
char *
|
||||
getcwd(char *buf, size_t buflen)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (buflen < 1) {
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
r = __getcwd(buf, buflen-1);
|
||||
if (r < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buf[r] = 0;
|
||||
return buf;
|
||||
}
|
11
userland/lib/libtest/Makefile
Normal file
11
userland/lib/libtest/Makefile
Normal file
@@ -0,0 +1,11 @@
|
||||
#
|
||||
# libtest - library of common test support code
|
||||
#
|
||||
|
||||
TOP=../../..
|
||||
.include "$(TOP)/mk/os161.config.mk"
|
||||
|
||||
SRCS=triple.c quint.c
|
||||
LIB=test
|
||||
|
||||
.include "$(TOP)/mk/os161.lib.mk"
|
111
userland/lib/libtest/quint.c
Normal file
111
userland/lib/libtest/quint.c
Normal file
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009, 2013
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* quint.c
|
||||
*
|
||||
* Runs five copies of some subprogram.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <err.h>
|
||||
#include <test/quint.h>
|
||||
|
||||
static
|
||||
pid_t
|
||||
spawnv(const char *prog, char **argv)
|
||||
{
|
||||
pid_t pid = fork();
|
||||
switch (pid) {
|
||||
case -1:
|
||||
err(1, "fork");
|
||||
case 0:
|
||||
/* child */
|
||||
execv(prog, argv);
|
||||
err(1, "%s: execv", prog);
|
||||
default:
|
||||
/* parent */
|
||||
break;
|
||||
}
|
||||
return pid;
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
dowait(int index, int pid)
|
||||
{
|
||||
int status;
|
||||
|
||||
if (waitpid(pid, &status, 0)<0) {
|
||||
warn("waitpid for copy #%d (pid %d)", index, pid);
|
||||
return 1;
|
||||
}
|
||||
else if (WIFSIGNALED(status)) {
|
||||
warnx("copy #%d (pid %d): signal %d", index, pid,
|
||||
WTERMSIG(status));
|
||||
return 1;
|
||||
}
|
||||
else if (WEXITSTATUS(status) != 0) {
|
||||
warnx("copy #%d (pid %d): exit %d", index, pid,
|
||||
WEXITSTATUS(status));
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
quint(const char *prog)
|
||||
{
|
||||
pid_t pids[5];
|
||||
int i, failures = 0;
|
||||
char *args[2];
|
||||
|
||||
/* set up the argv */
|
||||
args[0]=(char *)prog;
|
||||
args[1]=NULL;
|
||||
|
||||
warnx("Starting: running five copies of %s...", prog);
|
||||
|
||||
for (i=0; i<5; i++) {
|
||||
pids[i]=spawnv(args[0], args);
|
||||
}
|
||||
|
||||
for (i=0; i<5; i++) {
|
||||
failures += dowait(i, pids[i]);
|
||||
}
|
||||
|
||||
if (failures > 0) {
|
||||
warnx("%d failures", failures);
|
||||
}
|
||||
else {
|
||||
warnx("Congratulations! You passed.");
|
||||
}
|
||||
}
|
||||
|
111
userland/lib/libtest/triple.c
Normal file
111
userland/lib/libtest/triple.c
Normal file
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* triple.c
|
||||
*
|
||||
* Runs three copies of some subprogram.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <err.h>
|
||||
#include <test/triple.h>
|
||||
|
||||
static
|
||||
pid_t
|
||||
spawnv(const char *prog, char **argv)
|
||||
{
|
||||
pid_t pid = fork();
|
||||
switch (pid) {
|
||||
case -1:
|
||||
err(1, "fork");
|
||||
case 0:
|
||||
/* child */
|
||||
execv(prog, argv);
|
||||
err(1, "%s: execv", prog);
|
||||
default:
|
||||
/* parent */
|
||||
break;
|
||||
}
|
||||
return pid;
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
dowait(int index, int pid)
|
||||
{
|
||||
int status;
|
||||
|
||||
if (waitpid(pid, &status, 0)<0) {
|
||||
warn("waitpid for copy #%d (pid %d)", index, pid);
|
||||
return 1;
|
||||
}
|
||||
else if (WIFSIGNALED(status)) {
|
||||
warnx("copy #%d (pid %d): signal %d", index, pid,
|
||||
WTERMSIG(status));
|
||||
return 1;
|
||||
}
|
||||
else if (WEXITSTATUS(status) != 0) {
|
||||
warnx("copy #%d (pid %d): exit %d", index, pid,
|
||||
WEXITSTATUS(status));
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
triple(const char *prog)
|
||||
{
|
||||
pid_t pids[3];
|
||||
int i, failures = 0;
|
||||
char *args[2];
|
||||
|
||||
/* set up the argv */
|
||||
args[0]=(char *)prog;
|
||||
args[1]=NULL;
|
||||
|
||||
warnx("Starting: running three copies of %s...", prog);
|
||||
|
||||
for (i=0; i<3; i++) {
|
||||
pids[i]=spawnv(args[0], args);
|
||||
}
|
||||
|
||||
for (i=0; i<3; i++) {
|
||||
failures += dowait(i, pids[i]);
|
||||
}
|
||||
|
||||
if (failures > 0) {
|
||||
warnx("%d failures", failures);
|
||||
}
|
||||
else {
|
||||
warnx("Congratulations! You passed.");
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user