clang-format

This commit is contained in:
2024-09-10 13:03:02 -04:00
parent 53c617d779
commit d66450e427
381 changed files with 28864 additions and 34170 deletions

View File

@@ -48,45 +48,40 @@ 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;
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);
/*
* 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: ");
}
/*
* 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);
/* 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");
}
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");
}
}
/*
@@ -94,33 +89,21 @@ hostcompat_printerr(int use_errno, const char *fmt, va_list ap)
*/
/* warn/vwarn: use errno, don't exit */
void
vwarn(const char *fmt, va_list ap)
{
hostcompat_printerr(1, fmt, ap);
}
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);
}
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);
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);
void verrx(int exitcode, const char *fmt, va_list ap) {
hostcompat_printerr(0, fmt, ap);
exit(exitcode);
}
/*
@@ -128,40 +111,32 @@ verrx(int exitcode, const char *fmt, va_list ap)
* 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 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 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 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);
void errx(int exitcode, const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
verrx(exitcode, fmt, ap);
va_end(ap);
}
#endif /* NEED_ERR */

View File

@@ -27,7 +27,6 @@
* SUCH DAMAGE.
*/
#ifndef HOSTCOMPAT_ERR_H
#define HOSTCOMPAT_ERR_H

View File

@@ -51,188 +51,168 @@ 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);
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);
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;
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;
}
/* Get the current tty state. */
if (tcgetattr(STDIN_FILENO, &tios) < 0) {
/* stdin is not a tty */
return -1;
}
hostcompat_savetios = tios;
hostcompat_savetios = tios;
/* Turn off canonical ("cooked") input. */
tios.c_lflag &= ~ICANON;
/* 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;
/*
* 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;
/* 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);
/* Turn off echoing of keypresses. */
tios.c_lflag &= ~(ECHO | ECHONL | ECHOCTL);
/* Do not support XON/XOFF flow control. */
tios.c_iflag &= ~(IXON|IXOFF);
/* 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);
/* 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);
/* 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;
tios.c_oflag |= OPOST | ONLCR;
/* Enable keyboard signals (^C, ^Z, etc.) because they're useful. */
tios.c_lflag |= ISIG;
/* 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);
/* Set the new tty state. */
hostcompat_runtios = tios;
tcsetattr(STDIN_FILENO, TCSADRAIN, &tios);
return 0;
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();
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);
/* 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);
/* Post the signal back to ourselves, to cause the right exit status.*/
kill(getpid(), sig);
/* Just in case. */
_exit(255);
/* 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();
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);
/* 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);
/* Post the signal back to ourselves. */
kill(getpid(), sig);
}
/*
* Signal handler for SIGCONT.
*/
static
void
hostcompat_cont(int sig)
{
(void)sig;
static void hostcompat_cont(int sig) {
(void)sig;
/* Set the tty to the way we want it for running. */
hostcompat_ttyresume();
/* 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);
/*
* 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];
}
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;
}
/* Set the tty modes */
if (hostcompat_ttysetup() < 0) {
return;
}
/* When exit() is called, clean up */
atexit(hostcompat_ttyreset);
/* When exit() is called, clean up */
atexit(hostcompat_ttyreset);
/* stdout/stderr should be unbuffered */
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stderr, NULL, _IONBF, 0);
/* 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);
/* 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);
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);
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 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);
/* Catch the continue signal, so we can adjust the tty */
signal(SIGCONT, hostcompat_cont);
}

View File

@@ -27,7 +27,6 @@
* SUCH DAMAGE.
*/
#include <sys/types.h>
#include <stdint.h>

View File

@@ -34,20 +34,18 @@
#ifdef NEED_NTOHLL
uint64_t
ntohll(uint64_t x)
{
uint32_t x0, x1, y0, y1;
uint64_t ntohll(uint64_t x) {
uint32_t x0, x1, y0, y1;
if (ntohl(1) == 1) {
return x;
}
if (ntohl(1) == 1) {
return x;
}
x0 = x & 0xffffffff;
y0 = ntohl(x0);
x1 = x >> 32;
y1 = ntohl(x1);
return ((uint64_t)y0 << 32) | y1;
x0 = x & 0xffffffff;
y0 = ntohl(x0);
x1 = x >> 32;
y1 = ntohl(x1);
return ((uint64_t)y0 << 32) | y1;
}
#endif

View File

@@ -33,22 +33,20 @@
#include <sys/types.h>
#include <sys/time.h>
#include <string.h> /* sometimes required for NULL */
#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;
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;
}

View File

@@ -38,16 +38,14 @@
* Returns the length of the string printed.
*/
int
__puts(const char *str)
{
size_t len;
ssize_t ret;
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;
len = strlen(str);
ret = write(STDOUT_FILENO, str, len);
if (ret == -1) {
return EOF;
}
return len;
}

View File

@@ -35,22 +35,20 @@
* and return it or the symbolic constant EOF (-1).
*/
int
getchar(void)
{
char ch;
int len;
int getchar(void) {
char ch;
int len;
len = read(STDIN_FILENO, &ch, 1);
if (len<=0) {
/* end of file or error */
return EOF;
}
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;
/*
* 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;
}

View File

@@ -36,43 +36,35 @@
* 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;
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;
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;
int printf(const char *fmt, ...) {
int chars;
va_list ap;
va_start(ap, fmt);
chars = vprintf(fmt, ap);
va_end(ap);
return chars;
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;
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;
}

View File

@@ -37,14 +37,12 @@
* 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;
int putchar(int ch) {
char c = ch;
int len;
len = write(STDOUT_FILENO, &c, 1);
if (len <= 0) {
return EOF;
}
return ch;
}

View File

@@ -33,10 +33,8 @@
* C standard I/O function - print a string and a newline.
*/
int
puts(const char *s)
{
__puts(s);
putchar('\n');
return 0;
int puts(const char *s) {
__puts(s);
putchar('\n');
return 0;
}

View File

@@ -38,8 +38,4 @@
* nonzero exit code, skipping any libc cleanup.
*/
void
abort(void)
{
_exit(255);
}
void abort(void) { _exit(255); }

View File

@@ -34,50 +34,49 @@
* 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.
*/
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 */
/*
* 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);
_exit(code);
#endif
/*
* We can't return; so if we can't exit, the only other choice
* is to loop.
*/
while (1) { }
/*
* We can't return; so if we can't exit, the only other choice
* is to loop.
*/
while (1) {
}
}

View File

@@ -45,34 +45,28 @@ 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
};
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;
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;
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;
}

View File

@@ -37,7 +37,7 @@
*/
#include <stdlib.h>
#include <stdint.h> // for uintptr_t on non-OS/161 platforms
#include <stdint.h> // for uintptr_t on non-OS/161 platforms
#include <unistd.h>
#include <err.h>
#include <assert.h>
@@ -74,33 +74,33 @@ struct mheader {
#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;
/*
* 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;
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;
/*
* 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;
unsigned mh_nextblock : 60;
unsigned mh_inuse : 1;
unsigned mh_magic2 : 3;
#else
#error "please fix me"
@@ -122,17 +122,17 @@ struct mheader {
* (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_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_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_OK(mh) ((mh)->mh_magic1 == MMAGIC && (mh)->mh_magic2 == MMAGIC)
#define M_MKFIELD(off) ((off)>>MBLOCKSHIFT)
#define M_MKFIELD(off) ((off) >> MBLOCKSHIFT)
/*
* System page size. In POSIX you're supposed to call
@@ -157,68 +157,65 @@ static uintptr_t __heapbase, __heaptop;
/*
* Setup function.
*/
static
void
__malloc_init(void)
{
void *x;
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");
}
/*
* 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");
}
/* 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. */
/* Get the page size, if needed. */
#ifdef _SC_PAGESIZE
__malloc_pagesize = sysconf(_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;
/* 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.)
*/
/*
* 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");
}
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);
warnx("malloc: adjusted heap base upwards by %lu bytes",
(unsigned long)adjust);
#endif
__heapbase += adjust;
__heaptop = __heapbase;
}
__heapbase += adjust;
__heaptop = __heapbase;
}
}
////////////////////////////////////////////////////////////
@@ -228,45 +225,41 @@ __malloc_init(void)
/*
* Debugging print function to iterate and dump the entire heap.
*/
static
void
__malloc_dump(void)
{
struct mheader *mh;
uintptr_t i;
size_t rightprevblock;
static void __malloc_dump(void) {
struct mheader *mh;
uintptr_t i;
size_t rightprevblock;
warnx("heap: ************************************************");
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;
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: 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: ************************************************");
warnx("heap: ************************************************");
}
#endif /* MALLOCDEBUG */
@@ -277,25 +270,22 @@ __malloc_dump(void)
* 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;
static void *__malloc_sbrk(size_t size) {
void *x;
x = sbrk(size);
if (x == (void *)-1) {
return NULL;
}
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;
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;
}
/*
@@ -306,177 +296,171 @@ __malloc_sbrk(size_t size)
* 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;
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 (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;
}
if (M_SIZE(mh) - size < 2 * MBLOCKSIZE) {
/* no room */
return;
}
mhnext = M_NEXT(mh);
mhnext = M_NEXT(mh);
oldsize = M_SIZE(mh);
mh->mh_nextblock = M_MKFIELD(size + MBLOCKSIZE);
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 = 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;
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;
}
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;
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);
}
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();
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));
/* 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;
/*
* 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's in use. */
if (mh->mh_inuse) {
continue;
}
/* Can't allocate a block that isn't big enough. */
if (M_SIZE(mh) < size) {
continue;
}
/* Can't allocate a block that isn't big enough. */
if (M_SIZE(mh) < size) {
continue;
}
/* Try splitting block. */
__malloc_split(mh, size);
/* Try splitting block. */
__malloc_split(mh, size);
/*
* Now, allocate.
*/
mh->mh_inuse = 1;
/*
* Now, allocate.
*/
mh->mh_inuse = 1;
#ifdef MALLOCDEBUG
warnx("malloc: allocating at %p", M_DATA(mh));
__malloc_dump();
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");
}
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;
}
/*
* 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);
/* 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;
}
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);
}
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);
/*
* 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();
warnx("malloc: allocating at %p", M_DATA(mh));
__malloc_dump();
#endif
return M_DATA(mh);
return M_DATA(mh);
}
////////////////////////////////////////////////////////////
@@ -485,107 +469,98 @@ malloc(size_t size)
* 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;
}
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;
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;
}
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);
mhnextnext = M_NEXT(mhnext);
mh->mh_nextblock = M_MKFIELD(MBLOCKSIZE + M_SIZE(mh) +
MBLOCKSIZE + M_SIZE(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;
}
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));
/* 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;
void free(void *x) {
struct mheader *mh, *mhnext, *mhprev;
if (x==NULL) {
/* safest practice */
return;
}
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);
}
/* 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);
}
/* 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();
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);
}
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);
}
if (!mh->mh_inuse) {
errx(1, "free: Invalid pointer %p freed (already free)", x);
}
/* mark it free */
mh->mh_inuse = 0;
/* mark it free */
mh->mh_inuse = 0;
/* wipe it */
__malloc_deadbeef(M_DATA(mh), M_SIZE(mh));
/* 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 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);
}
/* 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();
warnx("free: freed %p", x);
__malloc_dump();
#endif
}

View File

@@ -34,112 +34,106 @@
/*
* 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];
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)
#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;
}
}
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;
/*
* 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;
/*
* 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--;
}
}
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++;
}
/*
* 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);
/*
* 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);
/*
* 5. Recurse on each subpart of the array.
*/
qsort(vdata, tail, size, f);
qsort((char *)vdata + tail * size, num - tail, size, f);
}

View File

@@ -52,7 +52,6 @@
static void srandom_unlocked(unsigned long);
static long random_unlocked(void);
/*
* random.c:
*
@@ -119,39 +118,39 @@ static long random_unlocked(void);
* 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_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_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_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_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
#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 */
#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 };
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:
@@ -168,18 +167,38 @@ static const int seps[MAX_TYPES] = { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 };
*/
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,
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,
};
/*
@@ -227,32 +246,27 @@ static long *end_ptr = &randtbl[DEG_3 + 1];
* 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;
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();
}
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)
{
void srandom(unsigned long x) {
LOCKME();
srandom_unlocked(x);
UNLOCKME();
LOCKME();
srandom_unlocked(x);
UNLOCKME();
}
/*
@@ -278,57 +292,55 @@ srandom(unsigned long x)
* 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 */
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;
void *ostate = (void *)(&state[-1]);
long *long_arg_state;
assert(arg_state != NULL);
assert(arg_state != NULL);
long_arg_state = (long *)(void *)arg_state;
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);
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);
}
/*
@@ -350,47 +362,46 @@ initstate(
* 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 */
char *setstate(char *arg_state) /* pointer to state array */
{
long *new_state;
int type;
int rear;
void *ostate = (void *)(&state[-1]);
long *new_state;
int type;
int rear;
void *ostate = (void *)(&state[-1]);
assert(arg_state != NULL);
assert(arg_state != NULL);
new_state = (long *)(void *)arg_state;
type = (int)(new_state[0] % MAX_TYPES);
rear = (int)(new_state[0] / MAX_TYPES);
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);
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);
}
/*
@@ -410,44 +421,40 @@ setstate(char *arg_state) /* pointer to state array */
*
* Returns a 31-bit random number.
*/
static
long
random_unlocked(void)
{
long i;
long *f, *r;
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;
}
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);
fptr = f;
rptr = r;
}
return (i);
}
long
random(void)
{
long r;
long random(void) {
long r;
LOCKME();
r = random_unlocked();
UNLOCKME();
return (r);
LOCKME();
r = random_unlocked();
UNLOCKME();
return (r);
}

View File

@@ -39,53 +39,50 @@
*/
#define MAXCMDSIZE 2048
#define MAXARGS 128
#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.
*/
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;
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);
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;
}
}
for (s = strtok(tmp, " \t"); s; s = strtok(NULL, " \t")) {
if (nargs < MAXARGS) {
argv[nargs++] = s;
} else {
errno = E2BIG;
return 1;
}
}
argv[nargs] = NULL;
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;
}
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;
}
}

View File

@@ -34,17 +34,15 @@
* 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;
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;
for (i = 0; i < len; i++) {
if (a[i] != b[i]) {
return (int)(a[i] - b[i]);
}
}
return 0;
}

View File

@@ -33,11 +33,9 @@
/*
* 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";
const char *strerror(int errcode) {
if (errcode >= 0 && errcode < sys_nerr) {
return sys_errlist[errcode];
}
return "Unknown error number";
}

View File

@@ -31,8 +31,6 @@
static char *__strtok_context;
char *
strtok(char *str, const char *seps)
{
return strtok_r(str, seps, &__strtok_context);
char *strtok(char *str, const char *seps) {
return strtok_r(str, seps, &__strtok_context);
}

View File

@@ -35,8 +35,4 @@
* but also returns nanoseconds.
*/
time_t
time(time_t *t)
{
return __time(t, NULL);
}
time_t time(time_t *t) { return __time(t, NULL); }

View File

@@ -38,13 +38,11 @@
* 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);
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();
write(STDERR_FILENO, buf, strlen(buf));
abort();
}

View File

@@ -47,72 +47,60 @@ 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 */
static void __senderr(void *junk, const char *data, size_t len) {
(void)junk; /* not needed or used */
write(STDERR_FILENO, data, len);
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));
}
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;
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);
/*
* 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)";
}
/*
* 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(": ");
/* print the program name */
__senderrstr(prog);
__senderrstr(": ");
/* process the printf format and args */
__vprintf(__senderr, NULL, fmt, ap);
/* 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);
}
/* if we're using errno, print the error string from above. */
if (use_errno) {
__senderrstr(": ");
__senderrstr(errmsg);
}
/* and always add a newline. */
__senderrstr("\n");
/* and always add a newline. */
__senderrstr("\n");
}
/*
@@ -120,33 +108,21 @@ __printerr(int use_errno, const char *fmt, va_list ap)
*/
/* warn/vwarn: use errno, don't exit */
void
vwarn(const char *fmt, va_list ap)
{
__printerr(1, fmt, ap);
}
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);
}
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);
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);
void verrx(int exitcode, const char *fmt, va_list ap) {
__printerr(0, fmt, ap);
exit(exitcode);
}
/*
@@ -154,38 +130,30 @@ verrx(int exitcode, const char *fmt, va_list ap)
* 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 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 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 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);
void errx(int exitcode, const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
verrx(exitcode, fmt, ap);
va_end(ap);
}

View File

@@ -38,54 +38,51 @@
* 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;
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;
}
if (strchr(prog, '/') != NULL) {
execv(prog, args);
return -1;
}
searchpath = getenv("PATH");
if (searchpath == NULL) {
errno = ENOENT;
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;
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;
}

View File

@@ -36,21 +36,19 @@
* all the work.
*/
char *
getcwd(char *buf, size_t buflen)
{
int r;
char *getcwd(char *buf, size_t buflen) {
int r;
if (buflen < 1) {
errno = EINVAL;
return NULL;
}
if (buflen < 1) {
errno = EINVAL;
return NULL;
}
r = __getcwd(buf, buflen-1);
if (r < 0) {
return NULL;
}
r = __getcwd(buf, buflen - 1);
if (r < 0) {
return NULL;
}
buf[r] = 0;
return buf;
buf[r] = 0;
return buf;
}

View File

@@ -38,74 +38,60 @@
#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 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;
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;
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];
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;
/* set up the argv */
args[0] = (char *)prog;
args[1] = NULL;
warnx("Starting: running three copies of %s...", prog);
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++) {
pids[i] = spawnv(args[0], args);
}
for (i=0; i<3; i++) {
failures += dowait(i, pids[i]);
}
for (i = 0; i < 3; i++) {
failures += dowait(i, pids[i]);
}
if (failures > 0) {
warnx("%d failures", failures);
}
else {
warnx("Congratulations! You passed.");
}
if (failures > 0) {
warnx("%d failures", failures);
} else {
warnx("Congratulations! You passed.");
}
}