diff --git a/configure.ac b/configure.ac index 57848bb..09b9dad 100644 --- a/configure.ac +++ b/configure.ac @@ -64,7 +64,7 @@ AC_TYPE_GETGROUPS AC_FUNC_MMAP AC_CHECK_FUNCS(strerror strtol lstat setrlimit sigrelse sighold sigaction \ -sysconf sigsetjmp getrusage) +sysconf sigsetjmp getrusage mmap mprotect) AC_CACHE_CHECK(whether getenv can be redefined, es_cv_local_getenv, [if test "$ac_cv_header_stdlib_h" = no || test "$ac_cv_header_stdc" = no; then diff --git a/gc.c b/gc.c index a5ab0db..946ee31 100644 --- a/gc.c +++ b/gc.c @@ -56,85 +56,24 @@ static size_t minspace = MIN_minspace; /* minimum number of bytes in a new space #define VERBOSE(p) NOP #endif - -/* - * GCPROTECT - * to use the GCPROTECT option, you must provide the following functions - * initmmu - * take - * release - * invalidate - * revalidate - * for your operating system - */ +#ifndef MAP_ANONYMOUS +#ifdef MAP_ANON +#define MAP_ANONYMOUS MAP_ANON +#endif +#endif #if GCPROTECT -#if __MACH__ - -/* mach versions of mmu operations */ - -#include -#include - -#define PAGEROUND(n) ((n) + vm_page_size - 1) &~ (vm_page_size - 1) - -/* initmmu -- initialization for memory management calls */ -static void initmmu(void) { -} - -/* take -- allocate memory for a space */ -static void *take(size_t n) { - vm_address_t addr; - kern_return_t error = vm_allocate(task_self(), &addr, n, TRUE); - if (error != KERN_SUCCESS) { - mach_error("vm_allocate", error); - esexit(1); - } - memset((void *) addr, 0xC9, n); - return (void *) addr; -} - -/* release -- deallocate a range of memory */ -static void release(void *p, size_t n) { - kern_return_t error = vm_deallocate(task_self(), (vm_address_t) p, n); - if (error != KERN_SUCCESS) { - mach_error("vm_deallocate", error); - esexit(1); - } -} - -/* invalidate -- disable access to a range of memory */ -static void invalidate(void *p, size_t n) { - kern_return_t error = vm_protect(task_self(), (vm_address_t) p, n, FALSE, 0); - if (error != KERN_SUCCESS) { - mach_error("vm_protect 0", error); - esexit(1); - } -} - -/* revalidate -- enable access to a range of memory */ -static void revalidate(void *p, size_t n) { - kern_return_t error = - vm_protect(task_self(), (vm_address_t) p, n, FALSE, VM_PROT_READ|VM_PROT_WRITE); - if (error != KERN_SUCCESS) { - mach_error("vm_protect VM_PROT_READ|VM_PROT_WRITE", error); - esexit(1); - } - memset(p, 0x4F, n); -} - -#else /* !__MACH__ */ - -/* sunos-derived mmap(2) version of mmu operations */ - +#if HAVE_MMAP #include +#endif static int pagesize; #define PAGEROUND(n) ((n) + pagesize - 1) &~ (pagesize - 1) /* take -- allocate memory for a space */ static void *take(size_t n) { - caddr_t addr; + void *addr; +#if HAVE_MMAP #ifdef MAP_ANONYMOUS addr = mmap(0, n, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); #else @@ -143,28 +82,40 @@ static void *take(size_t n) { devzero = eopen("/dev/zero", oOpen); addr = mmap(0, n, PROT_READ|PROT_WRITE, MAP_PRIVATE, devzero, 0); #endif - if (addr == (caddr_t) -1) + if (addr == MAP_FAILED) panic("mmap: %s", esstrerror(errno)); +#else /* !HAVE_MMAP */ + addr = ealloc(n); +#endif memset(addr, 0xA5, n); return addr; } /* release -- deallocate a range of memory */ static void release(void *p, size_t n) { +#if HAVE_MMAP if (munmap(p, n) == -1) panic("munmap: %s", esstrerror(errno)); +#else + efree(p); +#endif } /* invalidate -- disable access to a range of memory */ static void invalidate(void *p, size_t n) { + memset(p, 0x5e, n); +#if HAVE_MMAP && HAVE_MPROTECT if (mprotect(p, n, PROT_NONE) == -1) panic("mprotect(PROT_NONE): %s", esstrerror(errno)); +#endif } /* revalidate -- enable access to a range of memory */ static void revalidate(void *p, size_t n) { +#if HAVE_MMAP && HAVE_MPROTECT if (mprotect(p, n, PROT_READ|PROT_WRITE) == -1) panic("mprotect(PROT_READ|PROT_WRITE): %s", esstrerror(errno)); +#endif } /* initmmu -- initialization for memory management calls */ @@ -175,8 +126,6 @@ static void initmmu(void) { pagesize = getpagesize(); #endif } - -#endif /* !__MACH__ */ #endif /* GCPROTECT */ @@ -194,7 +143,7 @@ static Space *mkspace(Space *space, Space *next) { Space *sp; if (space->bot == NULL) sp = NULL; - else if (SPACESIZE(space) < minspace) + else if ((size_t) SPACESIZE(space) < minspace) sp = space; else { sp = space->next; @@ -302,8 +251,8 @@ extern void globalroot(void *addr) { /* exceptionroot -- add an exception to the list of rooted exceptions */ extern void exceptionroot(Root *root, List **e) { - Root *r; #if ASSERTIONS + Root *r; for (r = exceptionrootlist; r != NULL; r = r->next) assert(r->p != (void **)e); #endif diff --git a/input.c b/input.c index f187766..13b7f26 100644 --- a/input.c +++ b/input.c @@ -227,7 +227,7 @@ static int getverbose(Input *in) { } /* eoffill -- report eof when called to fill input buffer */ -static int eoffill(Input *in) { +static int eoffill(Input UNUSED *in) { assert(in->fd == -1); return EOF; } diff --git a/main.c b/main.c index 9f5abaf..e7e6cb0 100644 --- a/main.c +++ b/main.c @@ -82,6 +82,8 @@ static Noreturn usage(void) { " -p don't load functions from the environment\n" " -o don't open stdin, stdout, and stderr if they were closed\n" " -d don't ignore SIGQUIT or SIGTERM\n" + ); + eprint("" #if GCINFO " -I print garbage collector information\n" #endif @@ -109,8 +111,8 @@ int main(int argc, char **argv0) { Boolean keepclosed = FALSE; /* -o */ Ref(const char *volatile, cmd, NULL); /* -c */ - initgc(); initconv(); + initgc(); if (argc == 0) { argc = 1; diff --git a/match.c b/match.c index d419c8f..1204cb6 100644 --- a/match.c +++ b/match.c @@ -28,7 +28,7 @@ static int rangematch(const char *p, const char *q, char c) { Boolean neg; Boolean matched = FALSE; Boolean advanceq = (q != QUOTED && q != UNQUOTED); -#define QX(expr) (advanceq ? (expr) : (void)0) +#define QX(expr) (advanceq ? (expr) : 0) if (*p == '~' && !ISQUOTED(q, 0)) { p++, QX(q++); neg = TRUE; diff --git a/prim.c b/prim.c index 13a66ae..74d7866 100644 --- a/prim.c +++ b/prim.c @@ -6,11 +6,11 @@ static Dict *prims; extern List *prim(char *s, List *list, Binding *binding, int evalflags) { - List *(*p)(List *, Binding *, int); - p = (List *(*)(List *, Binding *, int)) dictget(prims, s); + Prim *p; + p = (Prim *) dictget(prims, s); if (p == NULL) fail("es:prim", "unknown primitive: %s", s); - return (*p)(list, binding, evalflags); + return (p->prim)(list, binding, evalflags); } static char *list_prefix; diff --git a/prim.h b/prim.h index 68e346b..a6a0db0 100644 --- a/prim.h +++ b/prim.h @@ -1,12 +1,16 @@ /* prim.h -- definitions for es primitives ($Revision: 1.1.1.1 $) */ +typedef struct { List *(*prim)(List *, Binding *, int); } Prim; + #define PRIM(name) static List *CONCAT(prim_,name)( \ List UNUSED *list, Binding UNUSED *binding, int UNUSED evalflags \ ) -#define X(name) (primdict = dictput( \ +#define X(name) STMT( \ + static Prim CONCAT(prim_struct_,name) = { CONCAT(prim_,name) }; \ + primdict = dictput( \ primdict, \ STRING(name), \ - (void *) CONCAT(prim_,name) \ + (void *) &CONCAT(prim_struct_,name) \ )) extern Dict *initprims_controlflow(Dict *primdict); /* prim-ctl.c */ diff --git a/print.c b/print.c index 87cb40a..f0efcd1 100644 --- a/print.c +++ b/print.c @@ -263,6 +263,10 @@ extern int printfmt(Format *format, const char *fmt) { * the public entry points */ +#ifndef va_copy +#define va_copy __va_copy +#endif + extern int fmtprint VARARGS2(Format *, format, const char *, fmt) { int n = -format->flushed; #if NO_VA_LIST_ASSIGN diff --git a/stdenv.h b/stdenv.h index 8caab1c..98bfbf8 100644 --- a/stdenv.h +++ b/stdenv.h @@ -165,6 +165,11 @@ extern void *qsort( #define STRING(s) #s #endif +/* this is not a principled fallback, but it should work on most systems */ +#ifndef NSIG +#define NSIG 64 +#endif + /* * types we use throughout es diff --git a/var.c b/var.c index 9421965..a2f50e2 100644 --- a/var.c +++ b/var.c @@ -114,6 +114,8 @@ static Boolean isexported(const char *name) { /* setnoexport -- mark a list of variable names not for export */ extern void setnoexport(List *list) { + static char noexportchar = '!'; + isdirty = TRUE; if (list == NULL) { noexport = NULL; @@ -121,7 +123,7 @@ extern void setnoexport(List *list) { } gcdisable(); for (noexport = mkdict(); list != NULL; list = list->next) - noexport = dictput(noexport, getstr(list->term), (void *) setnoexport); + noexport = dictput(noexport, getstr(list->term), &noexportchar); gcenable(); }