diff options
Diffstat (limited to 'shells')
56 files changed, 2108 insertions, 2123 deletions
diff --git a/shells/pdksh/files/Makefile.in b/shells/pdksh/files/Makefile.in index 10d7b325c70..e5385621d5f 100644 --- a/shells/pdksh/files/Makefile.in +++ b/shells/pdksh/files/Makefile.in @@ -16,7 +16,7 @@ DEFS = @DEFS@ LIBS = @LIBS@ CPPFLAGS = @CPPFLAGS@ -CFLAGS = @CFLAGS@ +CFLAGS = @CFLAGS@ "-D__RCSID(str)=void empty_nothingness()" "-D__UNCONST(a)=((void *)(unsigned long)(const void *)(a))" LDSTATIC = @LDSTATIC@ LDFLAGS = @LDFLAGS@ @@ -70,7 +70,14 @@ OS2FILES = os2/Makefile os2/config.h os2/config.status os2/configure.cmd \ os2/emacs.out os2/kshrc.ksh os2/make.sed os2/os2.c os2/os2siglist.out \ os2/README.os2 os2/NEWS.os2 os2/os2bugs os2/th.cmd os2/config.cache -all: $(SHELL_PROG)$(exe_suffix) $(SHELL_PROG).1 +all: check_cdefs real_all + +check_cdefs: .PHONY + if [ ! -e /usr/include/sys/cdefs.h ]; then \ + mkdir sys && touch sys/cdefs.h; \ + fi + +real_all: $(SHELL_PROG)$(exe_suffix) $(SHELL_PROG).1 # This shouldn't be first - some makes don't know about PRECIOUS and assume it # is the default target. diff --git a/shells/pdksh/files/alloc.c b/shells/pdksh/files/alloc.c index 722a88fe3f4..a0a6db29619 100644 --- a/shells/pdksh/files/alloc.c +++ b/shells/pdksh/files/alloc.c @@ -1,776 +1,127 @@ -/* - * area-based allocation built on malloc/free - */ - -#include "sh.h" - -#ifdef TEST_ALLOC -# define shellf printf -# ifndef DEBUG_ALLOC -# define DEBUG_ALLOC -# endif /* DEBUG_ALLOC */ -#endif /* TEST_ALLOC */ - -#ifdef MEM_DEBUG +/* $NetBSD: alloc.c,v 1.2 2008/05/31 16:47:36 tnn Exp $ */ /* - * Special versions of alloc routines if doing mem_debug + * Copyright (c) 2002 Marc Espie. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT 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 OPENBSD + * PROJECT 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. */ -Area * -_chmem_ainit(ap, file, line) - Area *ap; - const char *file; - int line; -{ - ap->freelist = (struct Block *) _chmem_newpool("ainit", (char *) 0, -1, - file, line); - if (!ap->freelist) - aerror(ap, "ainit failed (ie, newpool)"); - return ap; -} - -/* free all object in Area */ -void -_chmem_afreeall(ap, file, line) - Area *ap; - const char *file; - int line; -{ - _chmem_delpool((Chmem_poolp) ap->freelist, 0, file, line); - /* Kind of ugly, but it works */ - _chmem_ainit(ap, file, line); -} - -/* allocate object from Area */ -void * -_chmem_alloc(size, ap, file, line) - size_t size; - Area *ap; - const char *file; - int line; -{ - return _chmem_mallocp((Chmem_poolp) ap->freelist, size, file, line); -} - -/* change size of object -- like realloc */ -void * -_chmem_aresize(ptr, size, ap, file, line) - void *ptr; - size_t size; - Area *ap; - const char *file; - int line; -{ - if (!ptr) - /* Done as realloc(0, size) is not portable */ - return _chmem_mallocp((Chmem_poolp) ap->freelist, size, - file, line); - else - return _chmem_reallocp((Chmem_poolp) ap->freelist, ptr, size, - file, line); -} - -void -_chmem_afree(ptr, ap, file, line) - void *ptr; - Area *ap; - const char *file; - int line; -{ - return _chmem_freep((Chmem_poolp) ap->freelist, ptr, file, line); -} - -#else /* MEM_DEBUG */ - -# if DEBUG_ALLOC -void acheck ARGS((Area *ap)); -# define ACHECK(ap) acheck(ap) -# else /* DEBUG_ALLOC */ -# define ACHECK(ap) -# endif /* DEBUG_ALLOC */ - -#define ICELLS 200 /* number of Cells in small Block */ - -typedef union Cell Cell; -typedef struct Block Block; /* - * The Cells in a Block are organized as a set of objects. - * Each object (pointed to by dp) begins with the block it is in - * (dp-2)->block, then has a size in (dp-1)->size, which is - * followed with "size" data Cells. Free objects are - * linked together via dp->next. + * area-based allocation built on malloc/free */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: alloc.c,v 1.2 2008/05/31 16:47:36 tnn Exp $"); -#define NOBJECT_FIELDS 2 /* the block and size `fields' */ - -union Cell { - size_t size; - Cell *next; - Block *block; - struct {int _;} junk; /* alignment */ - double djunk; /* alignment */ -}; +#include "sh.h" -struct Block { - Block *next; /* list of Blocks in Area */ - Block *prev; /* previous block in list */ - Cell *freelist; /* object free list */ - Cell *last; /* &b.cell[size] */ - Cell cell [1]; /* [size] Cells for allocation */ +struct link { + struct link *prev; + struct link *next; }; -static Block aempty = {&aempty, &aempty, aempty.cell, aempty.cell}; - -static void ablockfree ARGS((Block *bp, Area *ap)); -static void *asplit ARGS((Area *ap, Block *bp, Cell *fp, Cell *fpp, int cells)); - -/* create empty Area */ Area * -ainit(ap) - register Area *ap; +ainit(Area *ap) { - ap->freelist = &aempty; - ACHECK(ap); + ap->freelist = NULL; return ap; } -/* free all object in Area */ void -afreeall(ap) - register Area *ap; +afreeall(Area *ap) { - register Block *bp; - register Block *tmp; + struct link *l, *l2; - ACHECK(ap); - bp = ap->freelist; - if (bp != NULL && bp != &aempty) { - do { - tmp = bp; - bp = bp->next; - free((void*)tmp); - } while (bp != ap->freelist); - ap->freelist = &aempty; + for (l = ap->freelist; l != NULL; l = l2) { + l2 = l->next; + free(l); } - ACHECK(ap); + ap->freelist = NULL; } -/* allocate object from Area */ -void * -alloc(size, ap) - size_t size; - register Area *ap; -{ - int cells, acells; - Block *bp = 0; - Cell *fp = 0, *fpp = 0; - - ACHECK(ap); - if (size <= 0) - aerror(ap, "allocate bad size"); - cells = (unsigned)(size + sizeof(Cell) - 1) / sizeof(Cell); - - /* allocate at least this many cells */ - acells = cells + NOBJECT_FIELDS; - - /* - * Only attempt to track small objects - let malloc deal - * with larger objects. (this way we don't have to deal with - * coalescing memory, or with releasing it to the system) - */ - if (cells <= ICELLS) { - /* find free Cell large enough */ - for (bp = ap->freelist; ; bp = bp->next) { - for (fpp = NULL, fp = bp->freelist; - fp != bp->last; fpp = fp, fp = fp->next) - { - if ((fp-1)->size >= cells) - goto Found; - } - /* wrapped around Block list, create new Block */ - if (bp->next == ap->freelist) { - bp = 0; - break; - } - } - /* Not much free space left? Allocate a big object this time */ - acells += ICELLS; - } - if (bp == 0) { - bp = (Block*) malloc(offsetof(Block, cell[acells])); - if (bp == NULL) - aerror(ap, "cannot allocate"); - if (ap->freelist == &aempty) { - ap->freelist = bp->next = bp->prev = bp; - } else { - bp->next = ap->freelist->next; - ap->freelist->next->prev = bp; - ap->freelist->next = bp; - bp->prev = ap->freelist; - } - bp->last = bp->cell + acells; - /* initial free list */ - fp = bp->freelist = bp->cell + NOBJECT_FIELDS; - (fp-1)->size = acells - NOBJECT_FIELDS; - (fp-2)->block = bp; - fp->next = bp->last; - fpp = NULL; - } - - Found: - return asplit(ap, bp, fp, fpp, cells); -} - -/* Do the work of splitting an object into allocated and (possibly) unallocated - * objects. Returns the `allocated' object. - */ -static void * -asplit(ap, bp, fp, fpp, cells) - Area *ap; - Block *bp; - Cell *fp; - Cell *fpp; - int cells; -{ - Cell *dp = fp; /* allocated object */ - int split = (fp-1)->size - cells; - - ACHECK(ap); - if (split < 0) - aerror(ap, "allocated object too small"); - if (split <= NOBJECT_FIELDS) { /* allocate all */ - fp = fp->next; - } else { /* allocate head, free tail */ - Cell *next = fp->next; /* needed, as cells may be 0 */ - ap->freelist = bp; /* next time, start looking for space here */ - (fp-1)->size = cells; - fp += cells + NOBJECT_FIELDS; - (fp-1)->size = split - NOBJECT_FIELDS; - (fp-2)->block = bp; - fp->next = next; - } - if (fpp == NULL) - bp->freelist = fp; - else - fpp->next = fp; - ACHECK(ap); - return (void*) dp; -} +#define L2P(l) ( (void *)(((char *)(l)) + sizeof(struct link)) ) +#define P2L(p) ( (struct link *)(((char *)(p)) - sizeof(struct link)) ) -/* change size of object -- like realloc */ +/* coverity[+alloc] */ void * -aresize(ptr, size, ap) - register void *ptr; - size_t size; - Area *ap; +alloc(size_t size, Area *ap) { - int cells; - Cell *dp = (Cell*) ptr; - int oldcells = dp ? (dp-1)->size : 0; + struct link *l; - ACHECK(ap); - if (size <= 0) - aerror(ap, "allocate bad size"); - /* New size (in cells) */ - cells = (unsigned)(size - 1) / sizeof(Cell) + 1; + l = malloc(sizeof(struct link) + size); + if (l == NULL) + internal_errorf(1, "unable to allocate memory"); + l->next = ap->freelist; + l->prev = NULL; + if (ap->freelist) + ap->freelist->prev = l; + ap->freelist = l; - /* Is this a large object? If so, let malloc deal with it - * directly (unless we are crossing the ICELLS border, in - * which case the alloc/free below handles it - this should - * cut down on fragmentation, and will also keep the code - * working (as it assumes size < ICELLS means it is not - * a `large object'). - */ - if (oldcells > ICELLS && cells > ICELLS) { - Block *bp = (dp-2)->block; - Block *nbp; - /* Saved in case realloc fails.. */ - Block *next = bp->next, *prev = bp->prev; - - if (bp->freelist != bp->last) - aerror(ap, "allocation resizing free pointer"); - nbp = realloc((void *) bp, - offsetof(Block, cell[cells + NOBJECT_FIELDS])); - if (!nbp) { - /* Have to clean up... */ - /* NOTE: If this code changes, similar changes may be - * needed in ablockfree(). - */ - if (next == bp) /* only block */ - ap->freelist = &aempty; - else { - next->prev = prev; - prev->next = next; - if (ap->freelist == bp) - ap->freelist = next; - } - aerror(ap, "cannot re-allocate"); - } - /* If location changed, keep pointers straight... */ - if (nbp != bp) { - if (next == bp) /* only one block */ - nbp->next = nbp->prev = nbp; - else { - next->prev = nbp; - prev->next = nbp; - } - if (ap->freelist == bp) - ap->freelist = nbp; - dp = nbp->cell + NOBJECT_FIELDS; - (dp-2)->block = nbp; - } - (dp-1)->size = cells; - nbp->last = nbp->cell + cells + NOBJECT_FIELDS; - nbp->freelist = nbp->last; - - ACHECK(ap); - return (void*) dp; - } - - /* Check if we can just grow this cell - * (need to check that cells < ICELLS so we don't make an - * object a `large' - that would mess everything up). - */ - if (dp && cells > oldcells && cells <= ICELLS) { - Cell *fp, *fpp; - Block *bp = (dp-2)->block; - int need = cells - oldcells - NOBJECT_FIELDS; - - /* XXX if we had a flag in an object indicating - * if the object was free/allocated, we could - * avoid this loop (perhaps) - */ - for (fpp = NULL, fp = bp->freelist; - fp != bp->last - && dp + oldcells + NOBJECT_FIELDS <= fp - ; fpp = fp, fp = fp->next) - { - if (dp + oldcells + NOBJECT_FIELDS == fp - && (fp-1)->size >= need) - { - Cell *np = asplit(ap, bp, fp, fpp, need); - /* May get more than we need here */ - (dp-1)->size += (np-1)->size + NOBJECT_FIELDS; - ACHECK(ap); - return ptr; - } - } - } - - /* Check if we can just shrink this cell - * (if oldcells > ICELLS, this is a large object and we leave - * it to malloc...) - * Note: this also handles cells == oldcells (a no-op). - */ - if (dp && cells <= oldcells && oldcells <= ICELLS) { - int split; - - split = oldcells - cells; - if (split <= NOBJECT_FIELDS) /* cannot split */ - ; - else { /* shrink head, free tail */ - Block *bp = (dp-2)->block; - - (dp-1)->size = cells; - dp += cells + NOBJECT_FIELDS; - (dp-1)->size = split - NOBJECT_FIELDS; - (dp-2)->block = bp; - afree((void*)dp, ap); - } - /* ACHECK() done in afree() */ - return ptr; - } - - /* Have to do it the hard way... */ - ptr = alloc(size, ap); - if (dp != NULL) { - size_t s = (dp-1)->size * sizeof(Cell); - if (s > size) - s = size; - memcpy(ptr, dp, s); - afree((void *) dp, ap); - } - /* ACHECK() done in alloc()/afree() */ - return ptr; + return L2P(l); } -void -afree(ptr, ap) - void *ptr; - register Area *ap; +/* coverity[+alloc] */ +/* coverity[+free : arg-0] */ +void * +aresize(void *ptr, size_t size, Area *ap) { - register Block *bp; - register Cell *fp, *fpp; - register Cell *dp = (Cell*)ptr; + struct link *l, *l2, *lprev, *lnext; - ACHECK(ap); - if (ptr == 0) - aerror(ap, "freeing null pointer"); - bp = (dp-2)->block; + if (ptr == NULL) + return alloc(size, ap); - /* If this is a large object, just free it up... */ - /* Release object... */ - if ((dp-1)->size > ICELLS) { - ablockfree(bp, ap); - ACHECK(ap); - return; - } - - if (dp < &bp->cell[NOBJECT_FIELDS] || dp >= bp->last) - aerror(ap, "freeing memory outside of block (corrupted?)"); - - /* find position in free list */ - /* XXX if we had prev/next pointers for objects, this loop could go */ - for (fpp = NULL, fp = bp->freelist; fp < dp; fpp = fp, fp = fp->next) - ; - - if (fp == dp) - aerror(ap, "freeing free object"); - - /* join object with next */ - if (dp + (dp-1)->size == fp-NOBJECT_FIELDS) { /* adjacent */ - (dp-1)->size += (fp-1)->size + NOBJECT_FIELDS; - dp->next = fp->next; - } else /* non-adjacent */ - dp->next = fp; - - /* join previous with object */ - if (fpp == NULL) - bp->freelist = dp; - else if (fpp + (fpp-1)->size == dp-NOBJECT_FIELDS) { /* adjacent */ - (fpp-1)->size += (dp-1)->size + NOBJECT_FIELDS; - fpp->next = dp->next; - } else /* non-adjacent */ - fpp->next = dp; + l = P2L(ptr); + lprev = l->prev; + lnext = l->next; - /* If whole block is free (and we have some other blocks - * around), release this block back to the system... - */ - if (bp->next != bp && bp->freelist == bp->cell + NOBJECT_FIELDS - && bp->freelist + (bp->freelist-1)->size == bp->last - /* XXX and the other block has some free memory? */ - ) - ablockfree(bp, ap); - ACHECK(ap); -} - -static void -ablockfree(bp, ap) - Block *bp; - Area *ap; -{ - /* NOTE: If this code changes, similar changes may be - * needed in alloc() (where realloc fails). - */ + l2 = realloc(l, sizeof(struct link) + size); + if (l2 == NULL) + internal_errorf(1, "unable to allocate memory"); + if (lprev) + lprev->next = l2; + else + ap->freelist = l2; + if (lnext) + lnext->prev = l2; - if (bp->next == bp) /* only block */ - ap->freelist = &aempty; - else { - bp->next->prev = bp->prev; - bp->prev->next = bp->next; - if (ap->freelist == bp) - ap->freelist = bp->next; - } - free((void*) bp); + return L2P(l2); } -# if DEBUG_ALLOC +/* coverity[+free : arg-0] */ void -acheck(ap) - Area *ap; +afree(void *ptr, Area *ap) { - Block *bp, *bpp; - Cell *dp, *dptmp, *fp; - int ok = 1; - int isfree; - static int disabled; - - if (disabled) - return; - - if (!ap) { - disabled = 1; - aerror(ap, "acheck: null area pointer"); - } + struct link *l; - bp = ap->freelist; - if (!bp) { - disabled = 1; - aerror(ap, "acheck: null area freelist"); - } - - /* Nothing to check... */ - if (bp == &aempty) + if (!ptr) return; - bpp = ap->freelist->prev; - while (1) { - if (bp->prev != bpp) { - shellf("acheck: bp->prev != previous\n"); - ok = 0; - } - fp = bp->freelist; - for (dp = &bp->cell[NOBJECT_FIELDS]; dp != bp->last; ) { - if ((dp-2)->block != bp) { - shellf("acheck: fragment's block is wrong\n"); - ok = 0; - } - isfree = dp == fp; - if ((dp-1)->size == 0 && isfree) { - shellf("acheck: 0 size frag\n"); - ok = 0; - } - if ((dp-1)->size > ICELLS - && !isfree - && (dp != &bp->cell[NOBJECT_FIELDS] - || dp + (dp-1)->size != bp->last)) - { - shellf("acheck: big cell doesn't make up whole block\n"); - ok = 0; - } - if (isfree) { - if (dp->next <= dp) { - shellf("acheck: free fragment's next <= self\n"); - ok = 0; - } - if (dp->next > bp->last) { - shellf("acheck: free fragment's next > last\n"); - ok = 0; - } - fp = dp->next; - } - dptmp = dp + (dp-1)->size; - if (dptmp > bp->last) { - shellf("acheck: next frag out of range\n"); - ok = 0; - break; - } else if (dptmp != bp->last) { - dptmp += NOBJECT_FIELDS; - if (dptmp > bp->last) { - shellf("acheck: next frag just out of range\n"); - ok = 0; - break; - } - } - if (isfree && dptmp == fp && dptmp != bp->last) { - shellf("acheck: adjacent free frags\n"); - ok = 0; - } else if (dptmp > fp) { - shellf("acheck: free frag list messed up\n"); - ok = 0; - } - dp = dptmp; - } - bpp = bp; - bp = bp->next; - if (bp == ap->freelist) - break; - } - if (!ok) { - disabled = 1; - aerror(ap, "acheck failed"); - } -} - -void -aprint(ap, ptr, size) - register Area *ap; - void *ptr; - size_t size; -{ - Block *bp; - - if (!ap) - shellf("aprint: null area pointer\n"); - else if (!(bp = ap->freelist)) - shellf("aprint: null area freelist\n"); - else if (bp == &aempty) - shellf("aprint: area is empty\n"); - else { - int i; - Cell *dp, *fp; - Block *bpp; + l = P2L(ptr); - bpp = ap->freelist->prev; - for (i = 0; ; i++) { - if (ptr) { - void *eptr = (void *) (((char *) ptr) + size); - /* print block only if it overlaps ptr/size */ - if (!((ptr >= (void *) bp - && ptr <= (void *) bp->last) - || (eptr >= (void *) bp - && eptr <= (void *) bp->last))) - continue; - shellf("aprint: overlap of 0x%p .. 0x%p\n", - ptr, eptr); - } - if (bp->prev != bpp || bp->next->prev != bp) - shellf( - "aprint: BAD prev pointer: bp %p, bp->prev %p, bp->next %p, bpp=%p\n", - bp, bp->prev, bp->next, bpp); - shellf("aprint: block %2d (p=%p,%p,n=%p): 0x%p .. 0x%p (%ld)\n", i, - bp->prev, bp, bp->next, - bp->cell, bp->last, - (long) ((char *) bp->last - (char *) bp->cell)); - fp = bp->freelist; - if (bp->last <= bp->cell + NOBJECT_FIELDS) - shellf( - "aprint: BAD bp->last too small: %p <= %p\n", - bp->last, bp->cell + NOBJECT_FIELDS); - if (bp->freelist < bp->cell + NOBJECT_FIELDS - || bp->freelist > bp->last) - shellf( - "aprint: BAD bp->freelist %p out of range: %p .. %p\n", - bp->freelist, - bp->cell + NOBJECT_FIELDS, bp->last); - for (dp = bp->cell; dp != bp->last ; ) { - dp += NOBJECT_FIELDS; - shellf( - "aprint: 0x%p .. 0x%p (%ld) %s\n", - (dp-NOBJECT_FIELDS), - (dp-NOBJECT_FIELDS) + (dp-1)->size - + NOBJECT_FIELDS, - (long) ((dp-1)->size + NOBJECT_FIELDS) - * sizeof(Cell), - dp == fp ? "free" : "allocated"); - if ((dp-2)->block != bp) - shellf( - "aprint: BAD dp->block %p != bp %p\n", - (dp-2)->block, bp); - if (dp > bp->last) - shellf( - "aprint: BAD dp gone past block: %p > %p\n", - dp, bp->last); - if (dp > fp) - shellf( - "aprint: BAD dp gone past free: %p > %p\n", - dp, fp); - if (dp == fp) { - fp = fp->next; - if (fp < dp || fp > bp->last) - shellf( - "aprint: BAD free object %p out of range: %p .. %p\n", - fp, - dp, bp->last); - } - dp += (dp-1)->size; - } - bpp = bp; - bp = bp->next; - if (bp == ap->freelist) - break; - } - } -} -# endif /* DEBUG_ALLOC */ - -# ifdef TEST_ALLOC - -Area a; -FILE *myout; - -int -main(int argc, char **argv) -{ - char buf[1024]; - struct info { - int size; - void *value; - }; - struct info info[1024 * 2]; - int size, ident; - int lineno = 0; - - myout = stdout; - ainit(&a); - while (fgets(buf, sizeof(buf), stdin)) { - lineno++; - if (buf[0] == '\n' || buf[0] == '#') - continue; - if (sscanf(buf, " alloc %d = i%d", &size, &ident) == 2) { - if (ident < 0 || ident > NELEM(info)) { - fprintf(stderr, "bad ident (%d) on line %d\n", - ident, lineno); - exit(1); - } - info[ident].value = alloc(info[ident].size = size, &a); - printf("%p = alloc(%d) [%d,i%d]\n", - info[ident].value, info[ident].size, - lineno, ident); - memset(info[ident].value, 1, size); - continue; - } - if (sscanf(buf, " afree i%d", &ident) == 1) { - if (ident < 0 || ident > NELEM(info)) { - fprintf(stderr, "bad ident (%d) on line %d\n", - ident, lineno); - exit(1); - } - afree(info[ident].value, &a); - printf("afree(%p) [%d,i%d]\n", info[ident].value, - lineno, ident); - continue; - } - if (sscanf(buf, " aresize i%d , %d", &ident, &size) == 2) { - void *value; - if (ident < 0 || ident > NELEM(info)) { - fprintf(stderr, "bad ident (%d) on line %d\n", - ident, lineno); - exit(1); - } - value = info[ident].value; - info[ident].value = aresize(value, - info[ident].size = size, - &a); - printf("%p = aresize(%p, %d) [%d,i%d]\n", - info[ident].value, value, info[ident].size, - lineno, ident); - memset(info[ident].value, 1, size); - continue; - } - if (sscanf(buf, " aprint i%d , %d", &ident, &size) == 2) { - if (ident < 0 || ident > NELEM(info)) { - fprintf(stderr, "bad ident (%d) on line %d\n", - ident, lineno); - exit(1); - } - printf("aprint(%p, %d) [%d,i%d]\n", - info[ident].value, size, lineno, ident); - aprint(&a, info[ident].value, size); - continue; - } - if (sscanf(buf, " aprint %d", &ident) == 1) { - if (ident < 0 || ident > NELEM(info)) { - fprintf(stderr, "bad ident (%d) on line %d\n", - ident, lineno); - exit(1); - } - printf("aprint(0, 0) [%d]\n", lineno); - aprint(&a, 0, 0); - continue; - } - if (sscanf(buf, " afreeall %d", &ident) == 1) { - printf("afreeall() [%d]\n", lineno); - afreeall(&a); - memset(info, 0, sizeof(info)); - continue; - } - fprintf(stderr, "unrecognized line (line %d)\n", - lineno); - exit(1); - } - return 0; -} + if (l->prev) + l->prev->next = l->next; + else + ap->freelist = l->next; + if (l->next) + l->next->prev = l->prev; -void -aerror(Area *ap, const char *msg) -{ - printf("aerror: %s\n", msg); - fflush(stdout); - abort(); + free(l); } - -# endif /* TEST_ALLOC */ - -#endif /* MEM_DEBUG */ diff --git a/shells/pdksh/files/c_ksh.c b/shells/pdksh/files/c_ksh.c index 95c25564ce9..afeff6f29be 100644 --- a/shells/pdksh/files/c_ksh.c +++ b/shells/pdksh/files/c_ksh.c @@ -1,6 +1,13 @@ +/* $NetBSD: c_ksh.c,v 1.2 2008/05/31 16:47:36 tnn Exp $ */ + /* * built-in Korn commands: c_* */ +#include <sys/cdefs.h> + +#ifndef lint +__RCSID("$NetBSD: c_ksh.c,v 1.2 2008/05/31 16:47:36 tnn Exp $"); +#endif #include "sh.h" #include "ksh_stat.h" @@ -25,6 +32,7 @@ c_cd(wp) char *dir, *try, *pwd; int phys_path; char *cdpath; + char *fdir = NULL; while ((optc = ksh_getopt(wp, &builtin_opt, "LP")) != EOF) switch (optc) { @@ -73,7 +81,7 @@ c_cd(wp) bi_errorf("don't know current directory"); return 1; } - /* substitue arg1 for arg2 in current path. + /* substitute arg1 for arg2 in current path. * if the first substitution fails because the cd fails * we could try to find another substitution. For now * we don't @@ -86,7 +94,7 @@ c_cd(wp) olen = strlen(wp[0]); nlen = strlen(wp[1]); elen = strlen(current_wd + ilen + olen) + 1; - dir = alloc(ilen + nlen + elen, ATEMP); + fdir = dir = alloc(ilen + nlen + elen, ATEMP); memcpy(dir, current_wd, ilen); memcpy(dir + ilen, wp[1], nlen); memcpy(dir + ilen + nlen, current_wd + ilen + olen, elen); @@ -121,6 +129,8 @@ c_cd(wp) bi_errorf("%s: bad directory", dir); else bi_errorf("%s - %s", try, strerror(errno)); + if (fdir) + afree(fdir, ATEMP); return 1; } @@ -169,6 +179,9 @@ c_cd(wp) if (printpath || cdnode) shprintf("%s\n", pwd); + if (fdir) + afree(fdir, ATEMP); + return 0; } @@ -178,7 +191,7 @@ c_pwd(wp) { int optc; int physical = Flag(FPHYSICAL); - char *p; + char *p, *freep = NULL; while ((optc = ksh_getopt(wp, &builtin_opt, "LP")) != EOF) switch (optc) { @@ -206,7 +219,7 @@ c_pwd(wp) if (p && eaccess(p, R_OK) < 0) p = (char *) 0; if (!p) { - p = ksh_get_wd((char *) 0, 0); + freep = p = ksh_get_wd((char *) 0, 0); if (!p) { bi_errorf("can't get current directory - %s", strerror(errno)); @@ -214,6 +227,8 @@ c_pwd(wp) } } shprintf("%s\n", p); + if (freep) + afree(freep, ATEMP); return 0; } @@ -333,7 +348,7 @@ c_print(wp) while ((c = *s++) != '\0') { Xcheck(xs, xp); #ifdef OS2 - if ((flags & PO_FSLASH) && c == '\\') + if ((flags & PO_FSLASH) && c == '\\') if (*s == '\\') *s++; else @@ -359,7 +374,7 @@ c_print(wp) case '0': /* Look for an octal number: can have * three digits (not counting the - * leading 0). Truely burnt. + * leading 0). Truly burnt. */ c = 0; for (i = 0; i < 3; i++) { @@ -390,8 +405,8 @@ c_print(wp) Xfree(xs, xp); } else { int n, len = Xlength(xs, xp); -#ifdef KSH int UNINITIALIZED(opipe); +#ifdef KSH /* Ensure we aren't killed by a SIGPIPE while writing to * a coprocess. at&t ksh doesn't seem to do this (seems @@ -582,7 +597,7 @@ c_typeset(wp) struct block *l = e->loc; struct tbl *vp, **p; Tflag fset = 0, fclr = 0; - int thing = 0, func = 0, local = 0; + int thing = 0, func = 0, localv = 0; const char *options = "L#R#UZ#fi#lprtux"; /* see comment below */ char *fieldstr, *basestr; int field, base; @@ -603,10 +618,10 @@ c_typeset(wp) /* called with 'typeset -' */ break; case 't': /* typeset */ - local = 1; + localv = 1; break; } - + fieldstr = basestr = (char *) 0; builtin_opt.flags |= GF_PLUSOPT; /* at&t ksh seems to have 0-9 as options, which are multiplied @@ -650,8 +665,8 @@ c_typeset(wp) flag = LCASEV; break; case 'p': /* posix export/readonly -p flag. - * typset -p is the same as typeset (in pdksh); - * here for compatability with ksh93. + * typeset -p is the same as typeset (in pdksh); + * here for compatibility with ksh93. */ pflag = 1; break; @@ -702,7 +717,7 @@ c_typeset(wp) return 1; } if (wp[builtin_opt.optind]) { - /* Take care of exclusions. + /* Take care of exclusions. * At this point, flags in fset are cleared in fclr and vise * versa. This property should be preserved. */ @@ -730,7 +745,7 @@ c_typeset(wp) int rval = 0; struct tbl *f; - if (local && !func) + if (localv && !func) fset |= LOCAL; for (i = builtin_opt.optind; wp[i]; i++) { if (func) { @@ -822,19 +837,19 @@ c_typeset(wp) shprintf("-x "); if ((vp->flag&RDONLY)) shprintf("-r "); - if ((vp->flag&TRACE)) + if ((vp->flag&TRACE)) shprintf("-t "); - if ((vp->flag&LJUST)) + if ((vp->flag&LJUST)) shprintf("-L%d ", vp->u2.field); - if ((vp->flag&RJUST)) + if ((vp->flag&RJUST)) shprintf("-R%d ", vp->u2.field); - if ((vp->flag&ZEROFIL)) + if ((vp->flag&ZEROFIL)) shprintf("-Z "); - if ((vp->flag&LCASEV)) + if ((vp->flag&LCASEV)) shprintf("-l "); - if ((vp->flag&UCASEV_AL)) + if ((vp->flag&UCASEV_AL)) shprintf("-u "); - if ((vp->flag&INT_U)) + if ((vp->flag&INT_U)) shprintf("-U "); shprintf("%s\n", vp->name); if (vp->flag&ARRAY) @@ -933,7 +948,7 @@ c_alias(wp) return 1; } ksh_getopt_reset(&builtin_opt, GF_ERROR); - return c_unalias((char **) args); + return c_unalias((char **)__UNCONST(args)); } @@ -1110,13 +1125,14 @@ c_jobs(wp) return 1; } wp += builtin_opt.optind; - if (!*wp) + if (!*wp) { if (j_jobs((char *) 0, flag, nflag)) rv = 1; - else + } else { for (; *wp; wp++) if (j_jobs(*wp, flag, nflag)) rv = 1; + } return rv; } @@ -1188,7 +1204,8 @@ c_kill(wp) int i, n, rv, sig; /* assume old style options if -digits or -UPPERCASE */ - if ((p = wp[1]) && *p == '-' && (digit(p[1]) || isupper(p[1]))) { + if ((p = wp[1]) && *p == '-' + && (digit(p[1]) || isupper((unsigned char)p[1]))) { if (!(t = gettrap(p + 1, TRUE))) { bi_errorf("bad signal `%s'", p + 1); return 1; @@ -1208,6 +1225,7 @@ c_kill(wp) builtin_opt.optarg); return 1; } + break; case '?': return 1; } @@ -1215,7 +1233,7 @@ c_kill(wp) } if ((lflag && t) || (!wp[i] && !lflag)) { shf_fprintf(shl_out, -"Usage: kill [ -s signame | -signum | -signame ] {pid|job}...\n\ +"usage: kill [ -s signame | -signum | -signame ] {pid|job}...\n\ kill -l [exit_status]\n" ); bi_errorf(null); @@ -1241,26 +1259,26 @@ c_kill(wp) shprintf("%s%s", p, sigtraps[i].name); shprintf(newline); } else { - int w, i; + int w, si; int mess_width; struct kill_info ki; - for (i = SIGNALS, ki.num_width = 1; i >= 10; i /= 10) + for (si = SIGNALS, ki.num_width = 1; si >= 10; si /= 10) ki.num_width++; ki.name_width = mess_width = 0; - for (i = 0; i < SIGNALS; i++) { - w = sigtraps[i].name ? strlen(sigtraps[i].name) - : ki.num_width; + for (si = 0; si < SIGNALS; si++) { + w = sigtraps[si].name ? + strlen(sigtraps[si].name) : ki.num_width; if (w > ki.name_width) ki.name_width = w; - w = strlen(sigtraps[i].mess); + w = strlen(sigtraps[si].mess); if (w > mess_width) mess_width = w; } print_columns(shl_stdout, SIGNALS - 1, kill_fmt_entry, (void *) &ki, - ki.num_width + ki.name_width + mess_width + 3); + ki.num_width + ki.name_width + mess_width + 3, 1); } return 0; } @@ -1271,7 +1289,7 @@ c_kill(wp) if (j_kill(p, sig)) rv = 1; } else if (!getn(p, &n)) { - bi_errorf("%s: arguments must be jobs or process ids", + bi_errorf("%s: arguments must be jobs or process IDs", p); rv = 1; } else { diff --git a/shells/pdksh/files/c_sh.c b/shells/pdksh/files/c_sh.c index 534e8232e38..a4cf3536ac7 100644 --- a/shells/pdksh/files/c_sh.c +++ b/shells/pdksh/files/c_sh.c @@ -1,6 +1,14 @@ +/* $NetBSD: c_sh.c,v 1.2 2008/05/31 16:47:36 tnn Exp $ */ + /* * built-in Bourne commands */ +#include <sys/cdefs.h> + +#ifndef lint +__RCSID("$NetBSD: c_sh.c,v 1.2 2008/05/31 16:47:36 tnn Exp $"); +#endif + #include "sh.h" #include "ksh_stat.h" /* umask() */ @@ -237,7 +245,7 @@ c_read(wp) char **wp; { register int c = 0; - int expand = 1, history = 0; + int expandv = 1, history = 0; int expanding; int ecode = 0; register char *cp; @@ -248,6 +256,7 @@ c_read(wp) XString cs, xs; struct tbl *vp; char UNINITIALIZED(*xp); + static char REPLY[] = "REPLY"; while ((optc = ksh_getopt(wp, &builtin_opt, "prsu,")) != EOF) switch (optc) { @@ -260,7 +269,7 @@ c_read(wp) break; #endif /* KSH */ case 'r': - expand = 0; + expandv = 0; break; case 's': history = 1; @@ -279,7 +288,7 @@ c_read(wp) wp += builtin_opt.optind; if (*wp == NULL) - *--wp = "REPLY"; + *--wp = REPLY; /* Since we can't necessarily seek backwards on non-regular files, * don't buffer them so we can't read too much. @@ -303,11 +312,11 @@ c_read(wp) * make sure the other side of the pipe is closed first. This allows * the detection of eof. * - * This is not compatiable with at&t ksh... the fd is kept so another - * coproc can be started with same ouput, however, this means eof + * This is not compatible with at&t ksh... the fd is kept so another + * coproc can be started with same output, however, this means eof * can't be detected... This is why it is closed here. * If this call is removed, remove the eof check below, too. - * coproc_readw_close(fd); + * coproc_readw_close(fd); */ #endif /* KSH */ @@ -364,7 +373,7 @@ c_read(wp) Xput(cs, cp, c); continue; } - if (expand && c == '\\') { + if (expandv && c == '\\') { expanding = 1; continue; } @@ -423,6 +432,7 @@ c_eval(wp) char **wp; { register struct source *s; + int rv; if (ksh_getopt(wp, &builtin_opt, null) == '?') return 1; @@ -456,7 +466,9 @@ c_eval(wp) exstat = subst_exstat; } - return shell(s, FALSE); + rv = shell(s, FALSE); + afree(s, ATEMP); + return rv; } int @@ -601,13 +613,14 @@ c_brkcont(wp) */ if (n == quit) { warningf(TRUE, "%s: cannot %s", wp[0], wp[0]); - return 0; + return 0; } /* POSIX says if n is too big, the last enclosing loop * shall be used. Doesn't say to print an error but we * do anyway 'cause the user messed up. */ - last_ep->flags &= ~EF_BRKCONT_PASS; + if (last_ep) + last_ep->flags &= ~EF_BRKCONT_PASS; warningf(TRUE, "%s: can only %s %d level(s)", wp[0], wp[0], n - quit); } @@ -626,7 +639,7 @@ c_set(wp) if (wp[1] == NULL) { static const char *const args [] = { "set", "-", NULL }; - return c_typeset((char **) args); + return c_typeset((char **)__UNCONST(args)); } argi = parse_args(wp, OF_SET, &setargs); @@ -848,7 +861,7 @@ c_exec(wp) fd_clexec(i); #endif /* KSH */ } - e->savefd = NULL; + e->savefd = NULL; } return 0; } diff --git a/shells/pdksh/files/c_test.c b/shells/pdksh/files/c_test.c index 63cfaf57ee2..66548790aea 100644 --- a/shells/pdksh/files/c_test.c +++ b/shells/pdksh/files/c_test.c @@ -1,3 +1,5 @@ +/* $NetBSD: c_test.c,v 1.2 2008/05/31 16:47:36 tnn Exp $ */ + /* * test(1); version 7-like -- author Erik Baalbergen * modified by Eric Gisin to be used as built-in. @@ -6,6 +8,12 @@ * modified by Michael Rendell to add Korn's [[ .. ]] expressions. * modified by J.T. Conklin to add POSIX compatibility. */ +#include <sys/cdefs.h> + +#ifndef lint +__RCSID("$NetBSD: c_test.c,v 1.2 2008/05/31 16:47:36 tnn Exp $"); +#endif + #include "sh.h" #include "ksh_stat.h" @@ -85,17 +93,17 @@ static const struct t_op b_ops [] = { {"", TO_NONOP } }; -static int test_stat ARGS((const char *path, struct stat *statb)); -static int test_eaccess ARGS((const char *path, int mode)); -static int test_oexpr ARGS((Test_env *te, int do_eval)); -static int test_aexpr ARGS((Test_env *te, int do_eval)); -static int test_nexpr ARGS((Test_env *te, int do_eval)); -static int test_primary ARGS((Test_env *te, int do_eval)); -static int ptest_isa ARGS((Test_env *te, Test_meta meta)); -static const char *ptest_getopnd ARGS((Test_env *te, Test_op op, int do_eval)); -static int ptest_eval ARGS((Test_env *te, Test_op op, const char *opnd1, - const char *opnd2, int do_eval)); -static void ptest_error ARGS((Test_env *te, int offset, const char *msg)); +static int test_stat ARGS((const char *, struct stat *)); +static int test_eaccess ARGS((const char *, int)); +static int test_oexpr ARGS((Test_env *, int)); +static int test_aexpr ARGS((Test_env *, int)); +static int test_nexpr ARGS((Test_env *, int)); +static int test_primary ARGS((Test_env *, int)); +static int ptest_isa ARGS((Test_env *, Test_meta)); +static const char *ptest_getopnd ARGS((Test_env *, Test_op, int)); +static int ptest_eval ARGS((Test_env *, Test_op, const char *, + const char *, int)); +static void ptest_error ARGS((Test_env *, int, const char *)); int c_test(wp) @@ -124,10 +132,10 @@ c_test(wp) te.pos.wp = wp + 1; te.wp_end = wp + argc; - /* + /* * Handle the special cases from POSIX.2, section 4.62.4. - * Implementation of all the rules isn't necessary since - * our parser does the right thing for the ommited steps. + * Implementation of all the rules isn't necessary since + * our parser does the right thing for the omitted steps. */ if (argc <= 5) { char **owp = wp; @@ -238,7 +246,7 @@ test_eval(te, op, opnd1, opnd2, do_eval) if (not) res = !res; } - return res; + return res; case TO_FILRD: /* -r */ return test_eaccess(opnd1, R_OK) == 0; case TO_FILWR: /* -w */ @@ -416,26 +424,26 @@ test_eval(te, op, opnd1, opnd2, do_eval) /* Nasty kludge to handle Korn's bizarre /dev/fd hack */ static int -test_stat(path, statb) - const char *path; +test_stat(pathx, statb) + const char *pathx; struct stat *statb; { #if !defined(HAVE_DEV_FD) int fd; - if (strncmp(path, "/dev/fd/", 8) == 0 && getn(path + 8, &fd)) + if (strncmp(pathx, "/dev/fd/", 8) == 0 && getn(pathx + 8, &fd)) return fstat(fd, statb); #endif /* !HAVE_DEV_FD */ - return stat(path, statb); + return stat(pathx, statb); } /* Routine to handle Korn's /dev/fd hack, and to deal with X_OK on * non-directories when running as root. */ static int -test_eaccess(path, mode) - const char *path; +test_eaccess(pathx, mode) + const char *pathx; int mode; { int res; @@ -444,7 +452,7 @@ test_eaccess(path, mode) int fd; /* Note: doesn't handle //dev/fd, etc.. (this is ok) */ - if (strncmp(path, "/dev/fd/", 8) == 0 && getn(path + 8, &fd)) { + if (strncmp(pathx, "/dev/fd/", 8) == 0 && getn(pathx + 8, &fd)) { int flags; if ((flags = fcntl(fd, F_GETFL, 0)) < 0 @@ -456,26 +464,22 @@ test_eaccess(path, mode) } #endif /* !HAVE_DEV_FD */ - /* On most (all?) unixes, access() says everything is executable for + res = eaccess(pathx, mode); + /* + * On most (all?) unixes, access() says everything is executable for * root - avoid this on files by using stat(). */ - if ((mode & X_OK) && ksheuid == 0) { + if (res == 0 && ksheuid == 0 && (mode & X_OK)) { struct stat statb; - if (stat(path, &statb) < 0) + if (stat(pathx, &statb) < 0) res = -1; else if (S_ISDIR(statb.st_mode)) res = 0; else res = (statb.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)) ? 0 : -1; - /* Need to check other permissions? If so, use access() as - * this will deal with root on NFS. - */ - if (res == 0 && (mode & (R_OK|W_OK))) - res = eaccess(path, mode); - } else - res = eaccess(path, mode); + } return res; } diff --git a/shells/pdksh/files/c_test.h b/shells/pdksh/files/c_test.h index 951dd9abd43..c7011f955b2 100644 --- a/shells/pdksh/files/c_test.h +++ b/shells/pdksh/files/c_test.h @@ -1,5 +1,7 @@ +/* $NetBSD: c_test.h,v 1.2 2008/05/31 16:47:36 tnn Exp $ */ + /* Various types of operations. Keeping things grouped nicely - * (unary,binary) makes switch() statements more efficeint. + * (unary,binary) makes switch() statements more efficient. */ enum Test_op { TO_NONOP = 0, /* non-operator */ diff --git a/shells/pdksh/files/c_ulimit.c b/shells/pdksh/files/c_ulimit.c index 5cd1ee06888..3f3ed19e9e0 100644 --- a/shells/pdksh/files/c_ulimit.c +++ b/shells/pdksh/files/c_ulimit.c @@ -1,8 +1,10 @@ +/* $NetBSD: c_ulimit.c,v 1.2 2008/05/31 16:47:36 tnn Exp $ */ + /* ulimit -- handle "ulimit" builtin Reworked to use getrusage() and ulimit() at once (as needed on - some schizophenic systems, eg, HP-UX 9.01), made argument parsing + some schizophrenic systems, eg, HP-UX 9.01), made argument parsing conform to at&t ksh, added autoconf support. Michael Rendell, May, '94 Eric Gisin, September 1988 @@ -15,6 +17,12 @@ the extended 4.nBSD resource limits. It now includes the code that was originally under case SYSULIMIT in source file "xec.c". */ +#include <sys/cdefs.h> + +#ifndef lint +__RCSID("$NetBSD: c_ulimit.c,v 1.2 2008/05/31 16:47:36 tnn Exp $"); +#endif + #include "sh.h" #include "ksh_time.h" @@ -109,9 +117,12 @@ c_ulimit(wp) # endif /* UL_GMEMLIM */ #endif /* RLIMIT_VMEM */ #ifdef RLIMIT_SWAP - { "swap(kbytes)", RLIMIT_SWAP, RLIMIT_SWAP, 1024, 'w' }, + { "swap(kbytes)", RLIMIT, RLIMIT_SWAP, RLIMIT_SWAP, 1024, 'w' }, +#endif +#ifdef RLIMIT_SBSIZE + { "sbsize(bytes)", RLIMIT, RLIMIT_SBSIZE, RLIMIT_SBSIZE, 1, 'b' }, #endif - { (char *) 0 } + { .name = NULL } }; static char options[3 + NELEM(limits)]; rlim_t UNINITIALIZED(val); @@ -194,7 +205,7 @@ c_ulimit(wp) val = limit.rlim_cur; else if (how & HARD) val = limit.rlim_max; - } else + } else #endif /* HAVE_SETRLIMIT */ #ifdef HAVE_ULIMIT { diff --git a/shells/pdksh/files/conf-end.h b/shells/pdksh/files/conf-end.h index c23cc07a2cb..f98aec06234 100644 --- a/shells/pdksh/files/conf-end.h +++ b/shells/pdksh/files/conf-end.h @@ -1,7 +1,9 @@ +/* $NetBSD: conf-end.h,v 1.2 2008/05/31 16:47:36 tnn Exp $ */ + /* * End of configuration stuff for PD ksh. * - * RCSid: $Id: conf-end.h,v 1.1.1.1 2008/05/23 17:15:16 tnn Exp $ + * RCSid: $NetBSD: conf-end.h,v 1.2 2008/05/31 16:47:36 tnn Exp $ */ #if defined(EMACS) || defined(VI) diff --git a/shells/pdksh/files/config.h.in b/shells/pdksh/files/config.h.in index bf16ac9dbca..46924574ee7 100644 --- a/shells/pdksh/files/config.h.in +++ b/shells/pdksh/files/config.h.in @@ -280,6 +280,11 @@ /* Define if you have the strerror function. */ #undef HAVE_STRERROR +/* Define if you have the strlcat function. */ +#undef HAVE_STRLCAT +/* Define if you have the strlcpy function. */ +#undef HAVE_STRLCPY + /* Define if you have the strstr function. */ #undef HAVE_STRSTR diff --git a/shells/pdksh/files/configure b/shells/pdksh/files/configure index ee34802a195..28e975fcacd 100755 --- a/shells/pdksh/files/configure +++ b/shells/pdksh/files/configure @@ -1985,12 +1985,12 @@ EOF fi echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6 -echo "configure:2057: checking return type of signal handlers" >&5 +echo "configure:1989: checking return type of signal handlers" >&5 if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 2062 "configure" +#line 1994 "configure" #include "confdefs.h" #include <sys/types.h> #include <signal.h> @@ -2007,7 +2007,7 @@ int main() { int i; ; return 0; } EOF -if { (eval echo configure:2079: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2011: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_type_signal=void else @@ -2036,7 +2036,7 @@ cat >> confdefs.h <<EOF EOF echo $ac_n "checking size of int""... $ac_c" 1>&6 -echo "configure:2108: checking size of int" >&5 +echo "configure:2040: checking size of int" >&5 if eval "test \"`echo '$''{'ac_cv_sizeof_int'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2044,7 +2044,7 @@ else { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } else cat > conftest.$ac_ext <<EOF -#line 2116 "configure" +#line 2048 "configure" #include "confdefs.h" #include <stdio.h> main() @@ -2071,7 +2071,7 @@ EOF echo $ac_n "checking size of long""... $ac_c" 1>&6 -echo "configure:2143: checking size of long" >&5 +echo "configure:2075: checking size of long" >&5 if eval "test \"`echo '$''{'ac_cv_sizeof_long'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2079,7 +2079,7 @@ else { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } else cat > conftest.$ac_ext <<EOF -#line 2151 "configure" +#line 2083 "configure" #include "confdefs.h" #include <stdio.h> main() @@ -2106,12 +2106,12 @@ EOF echo $ac_n "checking for clock_t in any of <sys/types.h>, <sys/times.h> and <sys/time.h>""... $ac_c" 1>&6 -echo "configure:2178: checking for clock_t in any of <sys/types.h>, <sys/times.h> and <sys/time.h>" >&5 +echo "configure:2110: checking for clock_t in any of <sys/types.h>, <sys/times.h> and <sys/time.h>" >&5 if eval "test \"`echo '$''{'ac_cv_type_clock_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 2183 "configure" +#line 2115 "configure" #include "confdefs.h" #include <sys/types.h> #if STDC_HEADERS @@ -2146,12 +2146,12 @@ EOF fi echo $ac_n "checking for sigset_t in <sys/types.h> and <signal.h>""... $ac_c" 1>&6 -echo "configure:2218: checking for sigset_t in <sys/types.h> and <signal.h>" >&5 +echo "configure:2150: checking for sigset_t in <sys/types.h> and <signal.h>" >&5 if eval "test \"`echo '$''{'ac_cv_type_sigset_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 2223 "configure" +#line 2155 "configure" #include "confdefs.h" #include <sys/types.h> #if STDC_HEADERS @@ -2181,12 +2181,12 @@ EOF fi echo $ac_n "checking for rlim_t in <sys/types.h> and <sys/resource.h>""... $ac_c" 1>&6 -echo "configure:2253: checking for rlim_t in <sys/types.h> and <sys/resource.h>" >&5 +echo "configure:2185: checking for rlim_t in <sys/types.h> and <sys/resource.h>" >&5 if eval "test \"`echo '$''{'ac_cv_type_rlim_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 2258 "configure" +#line 2190 "configure" #include "confdefs.h" #include <sys/types.h> #if STDC_HEADERS @@ -2212,7 +2212,7 @@ fi echo "$ac_t""$ac_cv_type_rlim_t" 1>&6 if test $ac_cv_type_rlim_t = no; then echo $ac_n "checking what to set rlim_t to""... $ac_c" 1>&6 -echo "configure:2284: checking what to set rlim_t to" >&5 +echo "configure:2216: checking what to set rlim_t to" >&5 if test $ac_cv_header_sys_resource_h = yes; then if eval "test \"`echo '$''{'ksh_cv_rlim_check'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -2222,7 +2222,7 @@ else else cat > conftest.$ac_ext <<EOF -#line 2294 "configure" +#line 2226 "configure" #include "confdefs.h" #include <sys/types.h> @@ -2257,7 +2257,7 @@ EOF fi echo $ac_n "checking for working memmove""... $ac_c" 1>&6 -echo "configure:2329: checking for working memmove" >&5 +echo "configure:2261: checking for working memmove" >&5 if eval "test \"`echo '$''{'ksh_cv_func_memmove'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2265,7 +2265,7 @@ else echo "configure: warning: assuming memmove broken" 1>&2; ksh_cv_func_memmove=no else cat > conftest.$ac_ext <<EOF -#line 2337 "configure" +#line 2269 "configure" #include "confdefs.h" #ifdef HAVE_STRING_H @@ -2309,7 +2309,7 @@ EOF else echo $ac_n "checking for working bcopy""... $ac_c" 1>&6 -echo "configure:2381: checking for working bcopy" >&5 +echo "configure:2313: checking for working bcopy" >&5 if eval "test \"`echo '$''{'ksh_cv_func_bcopy'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2317,7 +2317,7 @@ else echo "configure: warning: assuming bcopy broken" 1>&2; ksh_cv_func_bcopy=no else cat > conftest.$ac_ext <<EOF -#line 2389 "configure" +#line 2321 "configure" #include "confdefs.h" #ifdef HAVE_STRING_H @@ -2362,12 +2362,12 @@ EOF fi echo $ac_n "checking for memset""... $ac_c" 1>&6 -echo "configure:2434: checking for memset" >&5 +echo "configure:2366: checking for memset" >&5 if eval "test \"`echo '$''{'ksh_cv_func_memset'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 2439 "configure" +#line 2371 "configure" #include "confdefs.h" #ifdef HAVE_STRING_H @@ -2384,7 +2384,7 @@ int main() { char buf[16]; memset(buf, 'x', 7); printf("%7s", buf); ; return 0; } EOF -if { (eval echo configure:2456: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:2388: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* ksh_cv_func_memset=yes else @@ -2406,15 +2406,15 @@ EOF for ac_func in confstr dup2 flock getcwd getwd killpg nice \ setrlimit strerror strcasecmp strstr sysconf tcsetpgrp \ - ulimit waitpid wait3 + ulimit waitpid wait3 strlcpy strlcat do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:2481: checking for $ac_func" >&5 +echo "configure:2413: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 2486 "configure" +#line 2418 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -2437,7 +2437,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:2509: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:2441: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -2464,12 +2464,12 @@ done for ac_func in sigsetjmp _setjmp do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:2536: checking for $ac_func" >&5 +echo "configure:2468: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 2541 "configure" +#line 2473 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -2492,7 +2492,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:2564: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:2496: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -2519,12 +2519,12 @@ done for ac_func in valloc getpagesize do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:2591: checking for $ac_func" >&5 +echo "configure:2523: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 2596 "configure" +#line 2528 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -2547,7 +2547,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:2619: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:2551: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -2572,7 +2572,7 @@ fi done echo $ac_n "checking for working mmap""... $ac_c" 1>&6 -echo "configure:2644: checking for working mmap" >&5 +echo "configure:2576: checking for working mmap" >&5 if eval "test \"`echo '$''{'ac_cv_func_mmap'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2580,7 +2580,7 @@ else ac_cv_func_mmap=no else cat > conftest.$ac_ext <<EOF -#line 2652 "configure" +#line 2584 "configure" #include "confdefs.h" /* Thanks to Mike Haertel and Jim Avera for this test. */ @@ -2672,12 +2672,12 @@ EOF fi echo $ac_n "checking for lstat""... $ac_c" 1>&6 -echo "configure:2744: checking for lstat" >&5 +echo "configure:2676: checking for lstat" >&5 if eval "test \"`echo '$''{'ksh_cv_func_lstat'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 2749 "configure" +#line 2681 "configure" #include "confdefs.h" #include <sys/types.h> @@ -2690,7 +2690,7 @@ int main() { ; return 0; } EOF -if { (eval echo configure:2762: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:2694: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* ksh_cv_func_lstat=yes else @@ -2711,19 +2711,19 @@ EOF fi echo $ac_n "checking for sys_errlist declaration in errno.h""... $ac_c" 1>&6 -echo "configure:2783: checking for sys_errlist declaration in errno.h" >&5 +echo "configure:2715: checking for sys_errlist declaration in errno.h" >&5 if eval "test \"`echo '$''{'ksh_cv_decl_sys_errlist'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 2788 "configure" +#line 2720 "configure" #include "confdefs.h" #include <errno.h> int main() { char *msg = *(sys_errlist + 1); if (msg && *msg) return 12; ; return 0; } EOF -if { (eval echo configure:2795: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2727: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ksh_cv_decl_sys_errlist=yes else @@ -2747,12 +2747,12 @@ EOF else echo $ac_n "checking for sys_errlist in library""... $ac_c" 1>&6 -echo "configure:2819: checking for sys_errlist in library" >&5 +echo "configure:2751: checking for sys_errlist in library" >&5 if eval "test \"`echo '$''{'ksh_cv_var_sys_errlist'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 2824 "configure" +#line 2756 "configure" #include "confdefs.h" int main() { @@ -2765,7 +2765,7 @@ int main() { ; return 0; } EOF -if { (eval echo configure:2837: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:2769: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* ksh_cv_var_sys_errlist=yes else @@ -2787,12 +2787,12 @@ EOF fi echo $ac_n "checking for sys_siglist declaration in signal.h or unistd.h""... $ac_c" 1>&6 -echo "configure:2859: checking for sys_siglist declaration in signal.h or unistd.h" >&5 +echo "configure:2791: checking for sys_siglist declaration in signal.h or unistd.h" >&5 if eval "test \"`echo '$''{'ac_cv_decl_sys_siglist'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 2864 "configure" +#line 2796 "configure" #include "confdefs.h" #include <sys/types.h> #include <signal.h> @@ -2804,7 +2804,7 @@ int main() { char *msg = *(sys_siglist + 1); ; return 0; } EOF -if { (eval echo configure:2876: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2808: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_decl_sys_siglist=yes else @@ -2831,12 +2831,12 @@ EOF else echo $ac_n "checking for sys_siglist in library""... $ac_c" 1>&6 -echo "configure:2903: checking for sys_siglist in library" >&5 +echo "configure:2835: checking for sys_siglist in library" >&5 if eval "test \"`echo '$''{'ksh_cv_var_sys_siglist'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 2908 "configure" +#line 2840 "configure" #include "confdefs.h" int main() { @@ -2848,7 +2848,7 @@ int main() { ; return 0; } EOF -if { (eval echo configure:2920: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:2852: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* ksh_cv_var_sys_siglist=yes else @@ -2870,12 +2870,12 @@ EOF fi echo $ac_n "checking time() declaration in time.h""... $ac_c" 1>&6 -echo "configure:2942: checking time() declaration in time.h" >&5 +echo "configure:2874: checking time() declaration in time.h" >&5 if eval "test \"`echo '$''{'ksh_cv_time_delcared'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 2947 "configure" +#line 2879 "configure" #include "confdefs.h" #include <sys/types.h> #include <time.h> @@ -2883,7 +2883,7 @@ int main() { time_t (*f)() = time; if (f) return 12; ; return 0; } EOF -if { (eval echo configure:2955: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2887: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ksh_cv_time_delcared=yes else @@ -2904,7 +2904,7 @@ EOF fi echo $ac_n "checking if times() is present/working""... $ac_c" 1>&6 -echo "configure:2976: checking if times() is present/working" >&5 +echo "configure:2908: checking if times() is present/working" >&5 if eval "test \"`echo '$''{'ksh_cv_func_times_ok'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2913,7 +2913,7 @@ else else cat > conftest.$ac_ext <<EOF -#line 2985 "configure" +#line 2917 "configure" #include "confdefs.h" #include <sys/types.h> @@ -2959,12 +2959,12 @@ EOF for ac_func in getrusage do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:3031: checking for $ac_func" >&5 +echo "configure:2963: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 3036 "configure" +#line 2968 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -2987,7 +2987,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:3059: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:2991: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -3014,12 +3014,12 @@ done fi echo $ac_n "checking whether stat file-mode macros are broken""... $ac_c" 1>&6 -echo "configure:3086: checking whether stat file-mode macros are broken" >&5 +echo "configure:3018: checking whether stat file-mode macros are broken" >&5 if eval "test \"`echo '$''{'ac_cv_header_stat_broken'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 3091 "configure" +#line 3023 "configure" #include "confdefs.h" #include <sys/types.h> #include <sys/stat.h> @@ -3076,12 +3076,12 @@ EOF fi echo $ac_n "checking for st_rdev in struct stat""... $ac_c" 1>&6 -echo "configure:3148: checking for st_rdev in struct stat" >&5 +echo "configure:3080: checking for st_rdev in struct stat" >&5 if eval "test \"`echo '$''{'ac_cv_struct_st_rdev'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 3153 "configure" +#line 3085 "configure" #include "confdefs.h" #include <sys/types.h> #include <sys/stat.h> @@ -3089,7 +3089,7 @@ int main() { struct stat s; s.st_rdev; ; return 0; } EOF -if { (eval echo configure:3161: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3093: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_struct_st_rdev=yes else @@ -3110,12 +3110,12 @@ EOF fi echo $ac_n "checking for working const""... $ac_c" 1>&6 -echo "configure:3182: checking for working const" >&5 +echo "configure:3114: checking for working const" >&5 if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 3187 "configure" +#line 3119 "configure" #include "confdefs.h" int main() { @@ -3164,7 +3164,7 @@ ccp = (char const *const *) p; ; return 0; } EOF -if { (eval echo configure:3236: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3168: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_const=yes else @@ -3185,12 +3185,12 @@ EOF fi echo $ac_n "checking if compiler understands void""... $ac_c" 1>&6 -echo "configure:3257: checking if compiler understands void" >&5 +echo "configure:3189: checking if compiler understands void" >&5 if eval "test \"`echo '$''{'ksh_cv_c_void'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 3262 "configure" +#line 3194 "configure" #include "confdefs.h" void foo() { } @@ -3201,7 +3201,7 @@ int main() { ; return 0; } EOF -if { (eval echo configure:3273: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3205: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ksh_cv_c_void=yes else @@ -3224,12 +3224,12 @@ EOF fi echo $ac_n "checking if compiler understands volatile""... $ac_c" 1>&6 -echo "configure:3296: checking if compiler understands volatile" >&5 +echo "configure:3228: checking if compiler understands volatile" >&5 if eval "test \"`echo '$''{'ksh_cv_c_volatile'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 3301 "configure" +#line 3233 "configure" #include "confdefs.h" int x, y, z; int main() { @@ -3238,7 +3238,7 @@ volatile int a; int * volatile b = x ? &y : &z; *b = 0; ; return 0; } EOF -if { (eval echo configure:3310: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3242: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ksh_cv_c_volatile=yes else @@ -3261,12 +3261,12 @@ EOF fi echo $ac_n "checking if compiler understands prototypes""... $ac_c" 1>&6 -echo "configure:3333: checking if compiler understands prototypes" >&5 +echo "configure:3265: checking if compiler understands prototypes" >&5 if eval "test \"`echo '$''{'ksh_cv_c_prototypes'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 3338 "configure" +#line 3270 "configure" #include "confdefs.h" #include <stdarg.h> @@ -3280,7 +3280,7 @@ int main() { ; return 0; } EOF -if { (eval echo configure:3352: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3284: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ksh_cv_c_prototypes=yes else @@ -3301,12 +3301,12 @@ EOF fi echo $ac_n "checking if C compiler groks __attribute__(( .. ))""... $ac_c" 1>&6 -echo "configure:3373: checking if C compiler groks __attribute__(( .. ))" >&5 +echo "configure:3305: checking if C compiler groks __attribute__(( .. ))" >&5 if eval "test \"`echo '$''{'ksh_cv_c_func_attr'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 3378 "configure" +#line 3310 "configure" #include "confdefs.h" #include <stdarg.h> @@ -3323,7 +3323,7 @@ int main() { test_nr("%d", 10); test_cnst(2); test_uk(); test_nr(); ; return 0; } EOF -if { (eval echo configure:3395: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3327: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ksh_cv_c_func_attr=yes else @@ -3346,7 +3346,7 @@ EOF # Pull the hash mark out of the macro call to avoid m4 problems. ac_msg="whether #! works in shell scripts" echo $ac_n "checking $ac_msg""... $ac_c" 1>&6 -echo "configure:3418: checking $ac_msg" >&5 +echo "configure:3350: checking $ac_msg" >&5 if eval "test \"`echo '$''{'ac_cv_sys_interpreter'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3401,7 +3401,7 @@ ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 -echo "configure:3473: checking for a BSD compatible install" >&5 +echo "configure:3405: checking for a BSD compatible install" >&5 if test -z "$INSTALL"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -3451,7 +3451,7 @@ test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' echo $ac_n "checking if dup2() works (ie, resets the close-on-exec flag)""... $ac_c" 1>&6 -echo "configure:3523: checking if dup2() works (ie, resets the close-on-exec flag)" >&5 +echo "configure:3455: checking if dup2() works (ie, resets the close-on-exec flag)" >&5 if eval "test \"`echo '$''{'ksh_cv_dup2_clexec_ok'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3460,7 +3460,7 @@ else ksh_cv_dup2_clexec_ok=no else cat > conftest.$ac_ext <<EOF -#line 3532 "configure" +#line 3464 "configure" #include "confdefs.h" #include <sys/types.h> @@ -3510,12 +3510,12 @@ EOF fi echo $ac_n "checking flavour of signal routines""... $ac_c" 1>&6 -echo "configure:3582: checking flavour of signal routines" >&5 +echo "configure:3514: checking flavour of signal routines" >&5 if eval "test \"`echo '$''{'ksh_cv_signal_check'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 3587 "configure" +#line 3519 "configure" #include "confdefs.h" #include <signal.h> int main() { @@ -3528,7 +3528,7 @@ int main() { ; return 0; } EOF -if { (eval echo configure:3600: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:3532: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* ksh_cv_signal_check=posix else @@ -3536,7 +3536,7 @@ else cat conftest.$ac_ext >&5 rm -rf conftest* cat > conftest.$ac_ext <<EOF -#line 3608 "configure" +#line 3540 "configure" #include "confdefs.h" #include <signal.h> int main() { @@ -3546,7 +3546,7 @@ int main() { ; return 0; } EOF -if { (eval echo configure:3618: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:3550: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* ksh_cv_signal_check=bsd42 else @@ -3554,7 +3554,7 @@ else cat conftest.$ac_ext >&5 rm -rf conftest* cat > conftest.$ac_ext <<EOF -#line 3626 "configure" +#line 3558 "configure" #include "confdefs.h" #include <signal.h> RETSIGTYPE foo() { } @@ -3566,7 +3566,7 @@ int main() { ; return 0; } EOF -if { (eval echo configure:3638: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:3570: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* ksh_cv_signal_check=bsd41 else @@ -3604,7 +3604,7 @@ EOF EOF echo $ac_n "checking if signals interrupt read()""... $ac_c" 1>&6 -echo "configure:3676: checking if signals interrupt read()" >&5 +echo "configure:3608: checking if signals interrupt read()" >&5 if eval "test \"`echo '$''{'ksh_cv_signals_interrupt'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3613,7 +3613,7 @@ else else cat > conftest.$ac_ext <<EOF -#line 3685 "configure" +#line 3617 "configure" #include "confdefs.h" #include <errno.h> @@ -3736,7 +3736,7 @@ EOF fi echo $ac_n "checking flavour of pgrp routines""... $ac_c" 1>&6 -echo "configure:3808: checking flavour of pgrp routines" >&5 +echo "configure:3740: checking flavour of pgrp routines" >&5 if eval "test \"`echo '$''{'ksh_cv_pgrp_check'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3744,7 +3744,7 @@ else { echo "configure: error: cannot taste pgrp routines when cross compiling" 1>&2; exit 1; } else cat > conftest.$ac_ext <<EOF -#line 3816 "configure" +#line 3748 "configure" #include "confdefs.h" /* Check for BSD process groups */ @@ -3779,7 +3779,7 @@ else { echo "configure: error: cannot taste pgrp routines when cross compiling" 1>&2; exit 1; } else cat > conftest.$ac_ext <<EOF -#line 3851 "configure" +#line 3783 "configure" #include "confdefs.h" /* Check for POSIX process groups */ @@ -3820,7 +3820,7 @@ else { echo "configure: error: cannot taste pgrp routines when cross compiling" 1>&2; exit 1; } else cat > conftest.$ac_ext <<EOF -#line 3892 "configure" +#line 3824 "configure" #include "confdefs.h" /* Check for SYSV process groups */ @@ -3889,7 +3889,7 @@ EOF if test $ksh_cv_pgrp_check = bsd || test $ksh_cv_pgrp_check = posix ; then echo $ac_n "checking if process group synchronization is required""... $ac_c" 1>&6 -echo "configure:3961: checking if process group synchronization is required" >&5 +echo "configure:3893: checking if process group synchronization is required" >&5 if eval "test \"`echo '$''{'ksh_cv_need_pgrp_sync'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3898,7 +3898,7 @@ else ksh_cv_need_pgrp_sync=yes else cat > conftest.$ac_ext <<EOF -#line 3970 "configure" +#line 3902 "configure" #include "confdefs.h" main() @@ -3962,7 +3962,7 @@ EOF fi echo $ac_n "checking if opendir() fails to open non-directories""... $ac_c" 1>&6 -echo "configure:4034: checking if opendir() fails to open non-directories" >&5 +echo "configure:3966: checking if opendir() fails to open non-directories" >&5 if eval "test \"`echo '$''{'ksh_cv_opendir_ok'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3971,7 +3971,7 @@ else ksh_cv_opendir_ok=no else cat > conftest.$ac_ext <<EOF -#line 4043 "configure" +#line 3975 "configure" #include "confdefs.h" #include <stdio.h> @@ -4030,7 +4030,7 @@ EOF fi echo $ac_n "checking if you have /dev/fd/n""... $ac_c" 1>&6 -echo "configure:4102: checking if you have /dev/fd/n" >&5 +echo "configure:4034: checking if you have /dev/fd/n" >&5 if eval "test \"`echo '$''{'ksh_cv_dev_fd'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -4039,7 +4039,7 @@ else ksh_cv_dev_fd=no else cat > conftest.$ac_ext <<EOF -#line 4111 "configure" +#line 4043 "configure" #include "confdefs.h" #include <stdio.h> diff --git a/shells/pdksh/files/configure.in b/shells/pdksh/files/configure.in index 4cf1c710d98..aab11ef5f1b 100644 --- a/shells/pdksh/files/configure.in +++ b/shells/pdksh/files/configure.in @@ -276,7 +276,7 @@ KSH_MEMMOVE KSH_MEMSET AC_CHECK_FUNCS(confstr dup2 flock getcwd getwd killpg nice \ setrlimit strerror strcasecmp strstr sysconf tcsetpgrp \ - ulimit waitpid wait3) + ulimit waitpid wait3 strlcpy strlcat) AC_CHECK_FUNCS(sigsetjmp _setjmp, break) AC_FUNC_MMAP KSH_FUNC_LSTAT diff --git a/shells/pdksh/files/edit.c b/shells/pdksh/files/edit.c index 45446ef825f..4dcad724b27 100644 --- a/shells/pdksh/files/edit.c +++ b/shells/pdksh/files/edit.c @@ -1,7 +1,15 @@ +/* $NetBSD: edit.c,v 1.2 2008/05/31 16:47:36 tnn Exp $ */ + /* * Command line editing - common code * */ +#include <sys/cdefs.h> + +#ifndef lint +__RCSID("$NetBSD: edit.c,v 1.2 2008/05/31 16:47:36 tnn Exp $"); +#endif + #include "config.h" #ifdef EDIT @@ -15,6 +23,7 @@ # include <sys/stream.h> /* needed for <sys/ptem.h> */ # include <sys/ptem.h> /* needed for struct winsize */ #endif /* OS_SCO */ +#include <sys/ioctl.h> #include <ctype.h> #include "ksh_stat.h" @@ -126,11 +135,6 @@ x_read(buf, len) { int i; -#if defined(TIOCGWINSZ) - if (got_sigwinch) - check_sigwinch(); -#endif /* TIOCGWINSZ */ - x_mode(TRUE); #ifdef EMACS if (Flag(FEMACS) || Flag(FGMACS)) @@ -144,6 +148,11 @@ x_read(buf, len) #endif i = -1; /* internal error */ x_mode(FALSE); +#if defined(TIOCGWINSZ) + if (got_sigwinch) + check_sigwinch(); +#endif /* TIOCGWINSZ */ + return i; } @@ -320,7 +329,7 @@ x_mode(onoff) * * DESCRIPTION: * This function is based on a fix from guy@demon.co.uk - * It fixes a bug in that if PS1 contains '!', the length + * It fixes a bug in that if PS1 contains '!', the length * given by strlen() is probably wrong. * * RETURN VALUE: @@ -382,11 +391,11 @@ set_editmode(ed) }; char *rcp; int i; - + if ((rcp = ksh_strrchr_dirsep(ed))) ed = ++rcp; for (i = 0; i < NELEM(edit_flags); i++) - if (strstr(ed, options[(int) edit_flags[i]].name)) { + if (strstr(ed, goptions[(int) edit_flags[i]].name)) { change_flag(edit_flags[i], OF_SPECIAL, 1); return; } @@ -451,14 +460,12 @@ x_do_comment(buf, bsize, lenp) /* Common file/command completion code for vi/emacs */ -static char *add_glob ARGS((const char *str, int slen)); -static void glob_table ARGS((const char *pat, XPtrV *wp, struct table *tp)); -static void glob_path ARGS((int flags, const char *pat, XPtrV *wp, - const char *path)); +static char *add_glob ARGS((const char *, int)); +static void glob_table ARGS((const char *, XPtrV *, struct table *)); +static void glob_path ARGS((int, const char *, XPtrV *, const char *)); #if 0 /* not used... */ -int x_complete_word ARGS((const char *str, int slen, int is_command, - int *multiple, char **ret)); +int x_complete_word ARGS((const char *, int, int, int *, char **)); int x_complete_word(str, slen, is_command, nwordsp, ret) const char *str; @@ -496,8 +503,10 @@ x_print_expansions(nwords, words, is_command) int prefix_len; XPtrV l; + l.beg = NULL; + /* Check if all matches are in the same directory (in this - * case, we want to omitt the directory name) + * case, we want to omit the directory name) */ if (!is_command && (prefix_len = x_longest_prefix(nwords, words)) > 0) @@ -530,7 +539,7 @@ x_print_expansions(nwords, words, is_command) */ x_putc('\r'); x_putc('\n'); - pr_menu(use_copy ? (char **) XPptrv(l) : words); + pr_list(use_copy ? (char **) XPptrv(l) : words); if (use_copy) XPfree(l); /* not x_free_words() */ @@ -552,7 +561,7 @@ x_file_glob(flags, str, slen, wordsp) { char *toglob; char **words; - int nwords; + int nwords, i, idx, escaping; XPtrV w; struct source *s, *sold; @@ -561,6 +570,20 @@ x_file_glob(flags, str, slen, wordsp) toglob = add_glob(str, slen); + /* remove all escaping backward slashes */ + escaping = 0; + for(i = 0, idx = 0; toglob[i]; i++) { + if (toglob[i] == '\\' && !escaping) { + escaping = 1; + continue; + } + + toglob[idx] = toglob[i]; + idx++; + if (escaping) escaping = 0; + } + toglob[idx] = '\0'; + /* * Convert "foo*" (toglob) to an array of strings (words) */ @@ -596,13 +619,18 @@ x_file_glob(flags, str, slen, wordsp) || words[0][0] == '\0') { x_free_words(nwords, words); + words = NULL; nwords = 0; } } afree(toglob, ATEMP); - *wordsp = nwords ? words : (char **) 0; - + if (nwords) { + *wordsp = words; + } else if (words) { + x_free_words(nwords, words); + *wordsp = NULL; + } return nwords; } @@ -613,6 +641,8 @@ struct path_order_info { int path_order; }; +static int path_order_cmp(const void *aa, const void *bb); + /* Compare routine used in x_command_glob() */ static int path_order_cmp(aa, bb) @@ -722,7 +752,8 @@ x_command_glob(flags, str, slen, wordsp) return nwords; } -#define IS_WORDC(c) !(ctype(c, C_LEX1) || (c) == '\'' || (c) == '"') +#define IS_WORDC(c) !( ctype(c, C_LEX1) || (c) == '\'' || (c) == '"' \ + || (c) == '`' || (c) == '=' || (c) == ':' ) static int x_locate_word(buf, buflen, pos, startp, is_commandp) @@ -747,19 +778,22 @@ x_locate_word(buf, buflen, pos, startp, is_commandp) /* Keep going backwards to start of word (has effect of allowing * one blank after the end of a word) */ - for (; start > 0 && IS_WORDC(buf[start - 1]); start--) + for (; (start > 0 && IS_WORDC(buf[start - 1])) + || (start > 1 && buf[start-2] == '\\'); start--) ; /* Go forwards to end of word */ - for (end = start; end < buflen && IS_WORDC(buf[end]); end++) - ; + for (end = start; end < buflen && IS_WORDC(buf[end]); end++) { + if (buf[end] == '\\' && (end+1) < buflen) + end++; + } if (is_commandp) { int iscmd; /* Figure out if this is a command */ - for (p = start - 1; p >= 0 && isspace(buf[p]); p--) + for (p = start - 1; p >= 0 && isspace((unsigned char)buf[p]); p--) ; - iscmd = p < 0 || strchr(";|&()", buf[p]); + iscmd = p < 0 || strchr(";|&()`", buf[p]); if (iscmd) { /* If command has a /, path, etc. is not searched; * only current directory is searched, which is just @@ -846,7 +880,7 @@ add_glob(str, slen) for (s = toglob; *s; s++) { if (*s == '\\' && s[1]) s++; - else if (*s == '*' || *s == '[' || *s == '?' || *s == '$' + else if (*s == '*' || *s == '?' || *s == '$' || (s[1] == '(' /*)*/ && strchr("*+?@!", *s))) break; else if (ISDIRSEP(*s)) @@ -878,7 +912,8 @@ x_longest_prefix(nwords, words) prefix_len = strlen(words[0]); for (i = 1; i < nwords; i++) for (j = 0, p = words[i]; j < prefix_len; j++) - if (FILECHCONV(p[j]) != FILECHCONV(words[0][j])) { + if (FILECHCONV((unsigned char)p[j]) + != FILECHCONV((unsigned char)words[0][j])) { prefix_len = j; break; } @@ -953,14 +988,15 @@ glob_table(pat, wp, tp) } static void -glob_path(flags, pat, wp, path) +glob_path(flags, pat, wp, xpath) int flags; const char *pat; XPtrV *wp; - const char *path; + const char *xpath; { const char *sp, *p; char *xp; + int staterr; int pathlen; int patlen; int oldsize, newsize, i, j; @@ -968,7 +1004,7 @@ glob_path(flags, pat, wp, path) XString xs; patlen = strlen(pat) + 1; - sp = path; + sp = xpath; Xinit(xs, xp, patlen + 128, ATEMP); while (sp) { xp = Xstring(xs, xp); @@ -995,13 +1031,15 @@ glob_path(flags, pat, wp, path) memcpy(xp, pat, patlen); oldsize = XPsize(*wp); - glob_str(Xstring(xs, xp), wp, 0); + glob_str(Xstring(xs, xp), wp, 1); /* mark dirs */ newsize = XPsize(*wp); /* Check that each match is executable... */ words = (char **) XPptrv(*wp); for (i = j = oldsize; i < newsize; i++) { - if (search_access(words[i], X_OK, (int *) 0) >= 0) { + staterr = 0; + if ((search_access(words[i], X_OK, &staterr) >= 0) + || (staterr == EISDIR)) { words[j] = words[i]; if (!(flags & XCF_FULLPATH)) memmove(words[j], words[j] + pathlen, @@ -1018,4 +1056,40 @@ glob_path(flags, pat, wp, path) Xfree(xs, xp); } +/* + * if argument string contains any special characters, they will + * be escaped and the result will be put into edit buffer by + * keybinding-specific function + */ +int +x_escape(s, len, putbuf_func) + const char *s; + size_t len; + int putbuf_func ARGS((const char *s, size_t len)); +{ + size_t add, wlen; + const char *ifs = str_val(local("IFS", 0)); + int rval=0; + + for (add = 0, wlen = len; wlen - add > 0; add++) { + if (strchr("\\$(){}[]?*&;#|<>\"'`", s[add]) || strchr(ifs, s[add])) { + if (putbuf_func(s, add) != 0) { + rval = -1; + break; + } + + putbuf_func("\\", 1); + putbuf_func(&s[add], 1); + + add++; + wlen -= add; + s += add; + add = -1; /* after the increment it will go to 0 */ + } + } + if (wlen > 0 && rval == 0) + rval = putbuf_func(s, wlen); + + return (rval); +} #endif /* EDIT */ diff --git a/shells/pdksh/files/edit.h b/shells/pdksh/files/edit.h index a55ac5e0749..e3fd76930f6 100644 --- a/shells/pdksh/files/edit.h +++ b/shells/pdksh/files/edit.h @@ -1,3 +1,5 @@ +/* $NetBSD: edit.h,v 1.2 2008/05/31 16:47:36 tnn Exp $ */ + /* NAME: * edit.h - globals for edit modes * @@ -8,7 +10,7 @@ * * * RCSid: - * $Id: edit.h,v 1.1.1.1 2008/05/23 17:15:17 tnn Exp $ + * $NetBSD: edit.h,v 1.2 2008/05/31 16:47:36 tnn Exp $ * */ @@ -55,6 +57,7 @@ int x_cf_glob ARGS((int flags, const char *buf, int buflen, int pos, int *startp int x_longest_prefix ARGS((int nwords, char *const *words)); int x_basename ARGS((const char *s, const char *se)); void x_free_words ARGS((int nwords, char **words)); +int x_escape ARGS((const char *, size_t, int (*)(const char *s, size_t len))); /* emacs.c */ int x_emacs ARGS((char *buf, size_t len)); void x_init_emacs ARGS((void)); diff --git a/shells/pdksh/files/emacs-gen.sh b/shells/pdksh/files/emacs-gen.sh index c4a148e155e..67109e97504 100755 --- a/shells/pdksh/files/emacs-gen.sh +++ b/shells/pdksh/files/emacs-gen.sh @@ -1,4 +1,5 @@ #!/bin/sh +# $NetBSD: emacs-gen.sh,v 1.2 2008/05/31 16:47:36 tnn Exp $ case $# in 1) file=$1;; diff --git a/shells/pdksh/files/emacs.c b/shells/pdksh/files/emacs.c index 68faf1a2e6c..5acd8b8dd04 100644 --- a/shells/pdksh/files/emacs.c +++ b/shells/pdksh/files/emacs.c @@ -1,3 +1,5 @@ +/* $NetBSD: emacs.c,v 1.2 2008/05/31 16:47:36 tnn Exp $ */ + /* * Emacs-like command line editing and history * @@ -5,6 +7,12 @@ * modified by Doug Kingston, Doug Gwyn, and Lou Salkind * adapted to PD ksh by Eric Gisin */ +#include <sys/cdefs.h> + +#ifndef lint +__RCSID("$NetBSD: emacs.c,v 1.2 2008/05/31 16:47:36 tnn Exp $"); +#endif + #include "config.h" #ifdef EMACS @@ -13,6 +21,7 @@ #include "ksh_stat.h" #include "ksh_dir.h" #include <ctype.h> +#include <locale.h> #include "edit.h" static Area aedit; @@ -21,6 +30,8 @@ static Area aedit; #undef CTRL /* _BSD brain damage */ #define CTRL(x) ((x) == '?' ? 0x7F : (x) & 0x1F) /* ASCII */ #define UNCTRL(x) ((x) == 0x7F ? '?' : (x) | 0x40) /* ASCII */ +#define META(x) ((x) & 0x7f) +#define ISMETA(x) (Flag(FEMACSUSEMETA) && ((x) & 0x80)) /* values returned by keyboard functions */ @@ -49,7 +60,7 @@ struct x_defbindings { /* Separator for completion */ #define is_cfs(c) (c == ' ' || c == '\t' || c == '"' || c == '\'') -#define is_mfs(c) (!(isalnum(c) || c == '_' || c == '$')) /* Separator for motion */ +#define is_mfs(c) (!(isalnum((unsigned char)c) || c == '_' || c == '$')) /* Separator for motion */ #ifdef OS2 /* Deal with 8 bit chars & an extra prefix for function key (these two @@ -86,7 +97,7 @@ static char *xbp; /* start of visible portion of input buffer */ static char *xlp; /* last char visible on screen */ static int x_adj_ok; /* - * we use x_adj_done so that functions can tell + * we use x_adj_done so that functions can tell * whether x_adjust() has been called while they are active. */ static int x_adj_done; @@ -113,10 +124,11 @@ static char *killstack[KILLSIZE]; static int killsp, killtp; static int x_curprefix; static char *macroptr; +static int prompt_trunc; static int prompt_skip; static int x_ins ARGS((char *cp)); -static void x_delete ARGS((int nc, int force_push)); +static void x_delete ARGS((int nc, int push)); static int x_bword ARGS((void)); static int x_fword ARGS((void)); static void x_goto ARGS((char *cp)); @@ -130,7 +142,7 @@ static int x_search ARGS((char *pat, int sameline, int offset)); static int x_match ARGS((char *str, char *pat)); static void x_redraw ARGS((int limit)); static void x_push ARGS((int nchars)); -static char * x_mapin ARGS((const char *cp)); +static char * x_mapin ARGS((const char *cp, Area *area)); static char * x_mapout ARGS((int c)); static void x_print ARGS((int prefix, int key)); static void x_adjust ARGS((void)); @@ -138,9 +150,11 @@ static void x_e_ungetc ARGS((int c)); static int x_e_getc ARGS((void)); static void x_e_putc ARGS((int c)); static void x_e_puts ARGS((const char *s)); +static int x_comment ARGS((int c)); static int x_fold_case ARGS((int c)); static char *x_lastcp ARGS((void)); static void do_complete ARGS((int flags, Comp_type type)); +static int x_emacs_putbuf ARGS((const char *s, size_t len)); /* The lines between START-FUNC-TAB .. END-FUNC-TAB are run through a @@ -205,7 +219,7 @@ static const struct x_ftab x_ftab[] = { { x_yank, "yank", 0 }, { x_comp_list, "complete-list", 0 }, { x_expand, "expand-file", 0 }, - { x_fold_capitialize, "capitalize-word", XF_ARG }, + { x_fold_capitalize, "capitalize-word", XF_ARG }, { x_fold_lower, "downcase-word", XF_ARG }, { x_fold_upper, "upcase-word", XF_ARG }, { x_set_arg, "set-arg", XF_NOBIND }, @@ -269,6 +283,7 @@ static struct x_defbindings const x_defbindings[] = { { XFUNC_transpose, 0, CTRL('T') }, #endif { XFUNC_complete, 1, CTRL('[') }, + { XFUNC_comp_list, 0, CTRL('I') }, { XFUNC_comp_list, 1, '=' }, { XFUNC_enumerate, 1, '?' }, { XFUNC_expand, 1, '*' }, @@ -299,8 +314,8 @@ static struct x_defbindings const x_defbindings[] = { { XFUNC_fold_upper, 1, 'u' }, { XFUNC_fold_lower, 1, 'L' }, { XFUNC_fold_lower, 1, 'l' }, - { XFUNC_fold_capitialize, 1, 'C' }, - { XFUNC_fold_capitialize, 1, 'c' }, + { XFUNC_fold_capitalize, 1, 'C' }, + { XFUNC_fold_capitalize, 1, 'c' }, #ifdef OS2 { XFUNC_meta3, 0, 0xE0 }, { XFUNC_mv_back, 3, 'K' }, @@ -313,6 +328,7 @@ static struct x_defbindings const x_defbindings[] = { * entries. */ { XFUNC_meta2, 1, '[' }, + { XFUNC_meta2, 1, 'O' }, { XFUNC_prev_com, 2, 'A' }, { XFUNC_next_com, 2, 'B' }, { XFUNC_mv_forw, 2, 'C' }, @@ -342,15 +358,20 @@ x_emacs(buf, len) xx_cols = x_cols; x_col = promptlen(prompt, &p); prompt_skip = p - prompt; + prompt_trunc = x_col - (x_cols - 3 - MIN_EDIT_SPACE); + if (prompt_trunc > 0) + x_col -= prompt_trunc; + else + prompt_trunc = 0; x_adj_ok = 1; x_displen = xx_cols - 2 - x_col; x_adj_done = 0; - pprompt(prompt, 0); + pprompt(prompt, prompt_trunc); if (x_nextcmd >= 0) { int off = source->line - x_nextcmd; - if (histptr - history >= off) + if (histptr - histlist >= off) x_load_hist(histptr - off); x_nextcmd = -1; } @@ -360,8 +381,13 @@ x_emacs(buf, len) if ((c = x_e_getc()) < 0) return 0; + if (ISMETA(c)) { + c = META(c); + x_curprefix = 1; + } + f = x_curprefix == -1 ? XFUNC_insert - : x_tab[x_curprefix][c&CHARMASK]; + : x_tab[x_curprefix][c&CHARMASK]; if (!(x_ftab[f].xf_flags & XF_PREFIX) && x_last_command != XFUNC_set_arg) @@ -423,6 +449,8 @@ x_ins_string(c) return KSTD; } +static int x_do_ins(const char *cp, int len); + static int x_do_ins(cp, len) const char *cp; @@ -468,6 +496,21 @@ x_ins(s) return 0; } +/* + * this is used for x_escape() in do_complete() + */ +static int +x_emacs_putbuf(s, len) + const char *s; + size_t len; +{ + int rval; + + if ((rval = x_do_ins(s, len)) != 0) + return (rval); + return (rval); +} + static int x_del_back(c) int c; @@ -503,9 +546,9 @@ x_del_char(c) /* Delete nc chars to the right of the cursor (including cursor position) */ static void -x_delete(nc, force_push) +x_delete(nc, push) int nc; - int force_push; + int push; { int i,j; char *cp; @@ -522,7 +565,7 @@ x_delete(nc, force_push) /* * This lets us yank a word we have deleted. */ - if (nc > 1 || force_push) + if (push) x_push(nc); xep -= nc; @@ -540,7 +583,7 @@ x_delete(nc, force_push) * there is no need to ' ','\b'. * But if we must, make sure we do the minimum. */ - if ((i = xx_cols - 2 - x_col) > 0) + if ((i = x_displen) > 0) { j = (j < i) ? j : i; i = j; @@ -563,7 +606,7 @@ static int x_del_bword(c) int c; { - x_delete(x_bword(), FALSE); + x_delete(x_bword(), TRUE); return KSTD; } @@ -587,7 +630,7 @@ static int x_del_fword(c) int c; { - x_delete(x_fword(), FALSE); + x_delete(x_fword(), TRUE); return KSTD; } @@ -698,7 +741,7 @@ x_size(c) { if (c=='\t') return 4; /* Kludge, tabs are always four spaces. */ - if (iscntrl(c)) /* control char */ + if (iscntrl((unsigned char)c)) /* control char */ return 2; return 1; } @@ -721,7 +764,7 @@ x_zotc(c) if (c == '\t') { /* Kludge, tabs are always four spaces. */ x_e_puts(" "); - } else if (iscntrl(c)) { + } else if (iscntrl((unsigned char)c)) { x_e_putc('^'); x_e_putc(UNCTRL(c)); } else @@ -821,14 +864,14 @@ x_end_of_text(c) return KEOL; } -static int x_beg_hist(c) int c; { x_load_hist(history); return KSTD;} +static int x_beg_hist(c) int c; { x_load_hist(histlist); return KSTD;} static int x_end_hist(c) int c; { x_load_hist(histptr); return KSTD;} static int x_prev_com(c) int c; { x_load_hist(x_histp - x_arg); return KSTD;} static int x_next_com(c) int c; { x_load_hist(x_histp + x_arg); return KSTD;} - + /* Goto a particular history number obtained from argument. * If no argument is given history 1 is probably not what you * want so we'll simply go to the oldest one. @@ -838,7 +881,7 @@ x_goto_hist(c) int c; { if (x_arg_defaulted) - x_load_hist(history); + x_load_hist(histlist); else x_load_hist(histptr + x_arg - source->line); return KSTD; @@ -850,15 +893,15 @@ x_load_hist(hp) { int oldsize; - if (hp < history || hp > histptr) { + if (hp < histlist || hp > histptr) { x_e_putc(BEL); return; } x_histp = hp; oldsize = x_size_str(xbuf); - (void)strcpy(xbuf, *hp); + strlcpy(xbuf, *hp, xend - xbuf); xbp = xbuf; - xep = xcp = xbuf + strlen(*hp); + xep = xcp = xbuf + strlen(xbuf); xlp_valid = FALSE; if (xep > x_lastcp()) x_goto(xep); @@ -957,7 +1000,7 @@ x_search(pat, sameline, offset) register char **hp; int i; - for (hp = x_histp - (sameline ? 0 : 1) ; hp >= history; --hp) { + for (hp = x_histp - (sameline ? 0 : 1) ; hp >= histlist; --hp) { i = x_match(*hp, pat); if (i >= 0) { if (offset < 0) @@ -992,7 +1035,7 @@ x_del_line(c) int i, j; *xep = 0; - i = xep- xbuf; + i = xep - xbuf; j = x_size_str(xbuf); xcp = xbuf; x_push(i); @@ -1043,7 +1086,7 @@ x_redraw(limit) x_adj_ok = 0; if (limit == -1) x_e_putc('\n'); - else + else x_e_putc('\r'); x_flush(); if (xbp == xbuf) @@ -1097,14 +1140,14 @@ x_transpose(c) /* What transpose is meant to do seems to be up for debate. This * is a general summary of the options; the text is abcd with the - * upper case character or underscore indicating the cursor positiion: + * upper case character or underscore indicating the cursor position: * Who Before After Before After * at&t ksh in emacs mode: abCd abdC abcd_ (bell) * at&t ksh in gmacs mode: abCd baCd abcd_ abdc_ * gnu emacs: abCd acbD abcd_ abdc_ * Pdksh currently goes with GNU behavior since I believe this is the * most common version of emacs, unless in gmacs mode, in which case - * it does the at&t ksh gmacs mdoe. + * it does the at&t ksh gmacs mode. * This should really be broken up into 3 functions so users can bind * to the one they want. */ @@ -1216,7 +1259,7 @@ x_yank(c) killtp = KILLSIZE; else killtp = killsp; - killtp --; + killtp--; if (killstack[killtp] == 0) { x_e_puts("\nnothing to yank"); x_redraw(-1); @@ -1232,7 +1275,9 @@ x_meta_yank(c) int c; { int len; - if (x_last_command != XFUNC_yank && x_last_command != XFUNC_meta_yank) { + if ((x_last_command != XFUNC_yank && x_last_command != XFUNC_meta_yank) + || killstack[killtp] == 0) { + killtp = killsp; x_e_puts("\nyank something first"); x_redraw(-1); return KSTD; @@ -1302,12 +1347,13 @@ x_stuff(c) } static char * -x_mapin(cp) +x_mapin(cp, area) const char *cp; + Area *area; { char *new, *op; - op = new = str_save(cp, ATEMP); + op = new = str_save(cp, area); while (*cp) { /* XXX -- should handle \^ escape? */ if (*cp == '^') { @@ -1345,7 +1391,7 @@ x_mapout(c) *p++ = '0'; } else #endif /* OS2 */ - if (iscntrl(c)) { + if (iscntrl((unsigned char)c)) { *p++ = '^'; *p++ = UNCTRL(c); } else @@ -1410,7 +1456,7 @@ x_bind(a1, a2, macro, list) return 0; } - m1 = x_mapin(a1); + m2 = m1 = x_mapin(a1, ATEMP); prefix = key = 0; for (;; m1++) { key = *m1 & CHARMASK; @@ -1425,6 +1471,7 @@ x_bind(a1, a2, macro, list) else break; } + afree(m2, ATEMP); if (a2 == NULL) { x_print(prefix, key); @@ -1450,8 +1497,7 @@ x_bind(a1, a2, macro, list) #endif /* 0 */ } else { f = XFUNC_ins_string; - m2 = x_mapin(a2); - sp = str_save(m2, AEDIT); + sp = x_mapin(a2, AEDIT); } if (x_tab[prefix][key] == XFUNC_ins_string && x_atab[prefix][key]) @@ -1474,6 +1520,7 @@ void x_init_emacs() { register int i, j; + char *locale; ainit(AEDIT); x_nextcmd = -1; @@ -1485,15 +1532,25 @@ x_init_emacs() for (j = 0; j < X_TABSZ; j++) x_tab[i][j] = XFUNC_error; for (i = 0; i < NELEM(x_defbindings); i++) - x_tab[x_defbindings[i].xdb_tab][x_defbindings[i].xdb_char] + x_tab[(unsigned char)x_defbindings[i].xdb_tab][x_defbindings[i].xdb_char] = x_defbindings[i].xdb_func; x_atab = (char *(*)[X_TABSZ]) alloc(sizeofN(*x_atab, X_NTABS), AEDIT); for (i = 1; i < X_NTABS; i++) for (j = 0; j < X_TABSZ; j++) x_atab[i][j] = NULL; + + /* Determine if we can translate meta key or use 8-bit AscII + * XXX - It would be nice if there was a locale attribute to + * determine if the locale is 7-bit or not. + */ + locale = setlocale(LC_CTYPE, NULL); + if (locale == NULL || !strcmp(locale, "C") || !strcmp(locale, "POSIX")) + Flag(FEMACSUSEMETA) = 0; } +static void bind_if_not_bound(int p, int k, int func); + static void bind_if_not_bound(p, k, func) int p, k; @@ -1581,8 +1638,8 @@ x_version(c) char *o_xbp = xbp, *o_xep = xep, *o_xcp = xcp; int lim = x_lastcp() - xbp; - xbuf = xbp = xcp = (char *) ksh_version + 4; - xend = xep = (char *) ksh_version + 4 + strlen(ksh_version + 4); + xbuf = xbp = xcp = ksh_version + 4; + xend = xep = ksh_version + 4 + strlen(ksh_version + 4); x_redraw(lim); x_flush(); @@ -1738,12 +1795,15 @@ x_expand(c) x_goto(xbuf + start); x_delete(end - start, FALSE); - for (i = 0; i < nwords; i++) - if (x_ins(words[i]) < 0 || (i < nwords - 1 && x_ins(space) < 0)) + for (i = 0; i < nwords;) { + if (x_escape(words[i], strlen(words[i]), x_emacs_putbuf) < 0 || + (++i < nwords && x_ins(space) < 0)) { x_e_putc(BEL); return KSTD; } + } + x_adjust(); return KSTD; } @@ -1755,102 +1815,61 @@ do_complete(flags, type) Comp_type type; { char **words; - int nwords = 0; - int start, end; + int nwords; + int start, end, nlen, olen; int is_command; - int do_glob = 1; - Comp_type t = type; - char *comp_word = (char *) 0; - - if (type == CT_COMPLIST) { - do_glob = 0; - /* decide what we will do */ - nwords = x_cf_glob(flags, - xbuf, xep - xbuf, xcp - xbuf, - &start, &end, &words, &is_command); - if (nwords > 0) { - if (nwords > 1) { - int len = x_longest_prefix(nwords, words); - - t = CT_LIST; - /* Do completion if prefix matches original - * prefix (ie, no globbing chars), otherwise - * don't bother - */ - if (strncmp(words[0], xbuf + start, end - start) - == 0) - comp_word = str_nsave(words[0], len, - ATEMP); - else - type = CT_LIST; - /* Redo globing to show full paths if this - * is a command. - */ - if (is_command) { - do_glob = 1; - x_free_words(nwords, words); - } - } else - type = t = CT_COMPLETE; - } - } - if (do_glob) - nwords = x_cf_glob(flags | (t == CT_LIST ? XCF_FULLPATH : 0), - xbuf, xep - xbuf, xcp - xbuf, - &start, &end, &words, &is_command); + int completed = 0; + + nwords = x_cf_glob(flags, xbuf, xep - xbuf, xcp - xbuf, + &start, &end, &words, &is_command); + /* no match */ if (nwords == 0) { x_e_putc(BEL); return; } - switch (type) { - case CT_LIST: + + if (type == CT_LIST) { x_print_expansions(nwords, words, is_command); x_redraw(0); - break; - - case CT_COMPLIST: - /* Only get here if nwords > 1 && comp_word is set */ - { - int olen = end - start; - int nlen = strlen(comp_word); + x_free_words(nwords, words); + return; + } - x_print_expansions(nwords, words, is_command); - xcp = xbuf + end; - x_do_ins(comp_word + olen, nlen - olen); - x_redraw(0); - } - break; + olen = end - start; + nlen = x_longest_prefix(nwords, words); + /* complete */ + if (nwords == 1 || nlen > olen) { + x_goto(xbuf + start); + x_delete(olen, FALSE); + x_escape(words[0], nlen, x_emacs_putbuf); + x_adjust(); + completed = 1; + } + /* add space if single non-dir match */ + if ((nwords == 1) && (!ISDIRSEP(words[0][nlen - 1]))) { + x_ins(space); + completed = 1; + } - case CT_COMPLETE: - { - int nlen = x_longest_prefix(nwords, words); - - if (nlen > 0) { - x_goto(xbuf + start); - x_delete(end - start, FALSE); - words[0][nlen] = '\0'; - x_ins(words[0]); - /* If single match is not a directory, add a - * space to the end... - */ - if (nwords == 1 - && !ISDIRSEP(words[0][nlen - 1])) - x_ins(space); - } else - x_e_putc(BEL); - } - break; + if (type == CT_COMPLIST && !completed) { + x_print_expansions(nwords, words, is_command); + completed = 1; } + + if (completed) + x_redraw(0); + + x_free_words(nwords, words); } /* NAME: * x_adjust - redraw the line adjusting starting point etc. * * DESCRIPTION: - * This function is called when we have exceeded the bounds - * of the edit window. It increments x_adj_done so that - * functions like x_ins and x_delete know that we have been - * called and can skip the x_bs() stuff which has already + * This function is called when we have exceeded the bounds + * of the edit window. It increments x_adj_done so that + * functions like x_ins and x_delete know that we have been + * called and can skip the x_bs() stuff which has already * been done by x_redraw. * * RETURN VALUE: @@ -1890,7 +1909,7 @@ x_e_getc() unget_char = -1; } else { if (macroptr) { - c = *macroptr++; + c = (unsigned char) *macroptr++; if (!*macroptr) macroptr = (char *) 0; } else @@ -2019,11 +2038,11 @@ x_comment(c) * x_prev_histword - recover word from prev command * * DESCRIPTION: - * This function recovers the last word from the previous - * command and inserts it into the current edit line. If a - * numeric arg is supplied then the n'th word from the - * start of the previous command is used. - * + * This function recovers the last word from the previous + * command and inserts it into the current edit line. If a + * numeric arg is supplied then the n'th word from the + * start of the previous command is used. + * * Bound to M-. * * RETURN VALUE: @@ -2053,8 +2072,8 @@ x_prev_histword(c) rcp++; x_ins(rcp); } else { - int c; - + int i; + rcp = cp; /* * ignore white-space at start of line @@ -2071,10 +2090,10 @@ x_prev_histword(c) cp = rcp; while (*rcp && !is_cfs(*rcp)) rcp++; - c = *rcp; + i = *rcp; *rcp = '\0'; x_ins(cp); - *rcp = c; + *rcp = i; } return KSTD; } @@ -2097,14 +2116,14 @@ x_fold_lower(c) /* Lowercase N(1) words */ static int -x_fold_capitialize(c) +x_fold_capitalize(c) int c; { return x_fold_case('C'); } /* NAME: - * x_fold_case - convert word to UPPER/lower/Capitial case + * x_fold_case - convert word to UPPER/lower/Capital case * * DESCRIPTION: * This function is used to implement M-U,M-u,M-L,M-l,M-C and M-c @@ -2126,7 +2145,7 @@ x_fold_case(c) } while (x_arg--) { /* - * fisrt skip over any white-space + * first skip over any white-space */ while (cp != xep && is_mfs(*cp)) cp++; @@ -2136,24 +2155,24 @@ x_fold_case(c) */ if (cp != xep) { if (c == 'L') { /* lowercase */ - if (isupper(*cp)) - *cp = tolower(*cp); + if (isupper((unsigned char)*cp)) + *cp = tolower((unsigned char)*cp); } else { /* uppercase, capitialize */ - if (islower(*cp)) - *cp = toupper(*cp); + if (islower((unsigned char)*cp)) + *cp = toupper((unsigned char)*cp); } cp++; } /* * now for the rest of the word */ - while (cp != xep && !is_mfs(*cp)) { + while (cp != xep && !is_mfs((unsigned char)*cp)) { if (c == 'U') { /* uppercase */ - if (islower(*cp)) - *cp = toupper(*cp); + if (islower((unsigned char)*cp)) + *cp = toupper((unsigned char)*cp); } else { /* lowercase, capitialize */ - if (isupper(*cp)) - *cp = tolower(*cp); + if (isupper((unsigned char)*cp)) + *cp = tolower((unsigned char)*cp); } cp++; } @@ -2169,13 +2188,13 @@ x_fold_case(c) * x_lastcp() * * DESCRIPTION: - * This function returns a pointer to that char in the - * edit buffer that will be the last displayed on the + * This function returns a pointer to that char in the + * edit buffer that will be the last displayed on the * screen. The sequence: - * + * * for (cp = x_lastcp(); cp > xcp; cp) * x_bs(*--cp); - * + * * Will position the cursor correctly on the screen. * * RETURN VALUE: diff --git a/shells/pdksh/files/eval.c b/shells/pdksh/files/eval.c index 6415b028db0..a7a8edbde7e 100644 --- a/shells/pdksh/files/eval.c +++ b/shells/pdksh/files/eval.c @@ -1,6 +1,14 @@ +/* $NetBSD: eval.c,v 1.2 2008/05/31 16:47:36 tnn Exp $ */ + /* * Expansion - quoting, separation, substitution, globbing */ +#include <sys/cdefs.h> + +#ifndef lint +__RCSID("$NetBSD: eval.c,v 1.2 2008/05/31 16:47:36 tnn Exp $"); +#endif + #include "sh.h" #include <pwd.h> @@ -167,13 +175,16 @@ expand(cp, wp, f) XString ds; /* destination string */ register char *dp, *sp; /* dest., source */ int fdo, word; /* second pass flags; have word */ - int doblank; /* field spliting of parameter/command subst */ + int doblank; /* field splitting of parameter/command subst */ Expand x; /* expansion variables */ SubType st_head, *st; int UNINITIALIZED(newlines); /* For trailing newlines in COMSUB */ int saw_eq, tilde_ok; int make_magic; + size_t len; + x.split = 0; /* XXX gcc */ + x.str = NULL; /* XXX gcc */ if (cp == NULL) internal_errorf(1, "expand(NULL)"); /* for alias, readonly, set, typeset commands */ @@ -282,6 +293,7 @@ expand(cp, wp, f) int stype; int slen; + slen = -1; /* XXX gcc */ sp = strchr(sp, '\0') + 1; /* skip variable */ type = varsub(&x, varname, sp, &stype, &slen); if (type < 0) { @@ -413,10 +425,11 @@ expand(cp, wp, f) * fatal for special builtins (setstr * does readonly check). */ - setstr(st->var, debunk( - (char *) alloc(strlen(dp) + 1, - ATEMP), dp), - KSH_UNWIND_ERROR); + len = strlen(dp) + 1; + setstr(st->var, + debunk((char *) alloc(len, ATEMP), + dp, len), + KSH_UNWIND_ERROR); x.str = str_val(st->var); type = XSUB; if (f&DOBLANK) @@ -428,9 +441,9 @@ expand(cp, wp, f) char *s = Xrestpos(ds, dp, st->base); errorf("%s: %s", st->var->name, - dp == s ? + dp == s ? "parameter null or not set" - : (debunk(s, s), s)); + : (debunk(s, s, strlen(s) + 1), s)); } } st = st->prev; @@ -443,7 +456,7 @@ expand(cp, wp, f) c = *sp++ + 0x80; break; - case SPAT: /* pattern seperator (|) */ + case SPAT: /* pattern separator (|) */ make_magic = 1; c = '|'; break; @@ -574,7 +587,7 @@ expand(cp, wp, f) else if ((f & DOPAT) || !(fdo & DOMAGIC_)) XPput(*wp, p); else - XPput(*wp, debunk(p, p)); + XPput(*wp, debunk(p, p, strlen(p) + 1)); fdo = 0; saw_eq = 0; tilde_ok = (f & (DOTILDE|DOASNTILDE)) ? 1 : 0; @@ -592,6 +605,21 @@ expand(cp, wp, f) if (!quote) switch (c) { case '[': + { + const char *p = sp; + bool_t special = FALSE; + while (*p != EOS) { + if (p[0] == CHAR && + p[1] == ']') { + special = TRUE; + break; + } + + p += 2; + } + if (!special) + break; + } case NOT: case '-': case ']': @@ -847,6 +875,7 @@ comsub(xp, cp) s->start = s->str = cp; sold = source; t = compile(s); + afree(s, ATEMP); source = sold; if (t == NULL) @@ -870,8 +899,10 @@ comsub(xp, cp) openpipe(pv); shf = shf_fdopen(pv[0], SHF_RD, (struct shf *) 0); ofd1 = savefd(1, 0); /* fd 1 may be closed... */ - ksh_dup2(pv[1], 1, FALSE); - close(pv[1]); + if (pv[1] != 1) { + ksh_dup2(pv[1], 1, FALSE); + close(pv[1]); + } execute(t, XFORK|XXCOM|XPIPEO); restfd(1, ofd1); startlast(); @@ -896,7 +927,7 @@ trimsub(str, pat, how) register char *p, c; switch (how&0xff) { /* UCHAR_MAX maybe? */ - case '#': /* shortest at begining */ + case '#': /* shortest at beginning */ for (p = str; p <= end; p++) { c = *p; *p = '\0'; if (gmatch(str, pat, FALSE)) { @@ -906,7 +937,7 @@ trimsub(str, pat, how) *p = c; } break; - case '#'|0x80: /* longest match at begining */ + case '#'|0x80: /* longest match at beginning */ for (p = end; p >= str; p--) { c = *p; *p = '\0'; if (gmatch(str, pat, FALSE)) { @@ -948,14 +979,14 @@ glob(cp, wp, markdirs) int oldsize = XPsize(*wp); if (glob_str(cp, wp, markdirs) == 0) - XPput(*wp, debunk(cp, cp)); + XPput(*wp, debunk(cp, cp, strlen(cp) + 1)); else qsortp(XPptrv(*wp) + oldsize, (size_t)(XPsize(*wp) - oldsize), xstrcmp); } #define GF_NONE 0 -#define GF_EXCHECK BIT(0) /* do existance check on file */ +#define GF_EXCHECK BIT(0) /* do existence check on file */ #define GF_GLOBBED BIT(1) /* some globbing has been done */ #define GF_MARKDIR BIT(2) /* add trailing / to directories */ @@ -1083,7 +1114,7 @@ globit(xs, xpp, sp, wp, check) */ if (!has_globbing(sp, se)) { XcheckN(*xs, xp, se - sp + 1); - debunk(xp, sp); + debunk(xp, sp, Xnleft(*xs, xp)); xp += strlen(xp); *xpp = xp; globit(xs, xpp, np, wp, check); @@ -1102,9 +1133,6 @@ globit(xs, xpp, sp, wp, check) goto Nodir; while ((d = readdir(dirp)) != NULL) { name = d->d_name; - if (name[0] == '.' && - (name[1] == 0 || (name[1] == '.' && name[2] == 0))) - continue; /* always ignore . and .. */ if ((*name == '.' && *sp != '.') || !gmatch(name, sp, TRUE)) continue; @@ -1172,15 +1200,18 @@ copy_non_glob(xs, xpp, p) /* remove MAGIC from string */ char * -debunk(dp, sp) +debunk(dp, sp, dlen) char *dp; const char *sp; + size_t dlen; { char *d, *s; if ((s = strchr(sp, MAGIC))) { + if (s - sp >= dlen) + return dp; memcpy(dp, sp, s - sp); - for (d = dp + (s - sp); *s; s++) + for (d = dp + (s - sp); *s && (d - dp < dlen); s++) if (!ISMAGIC(*s) || !(*++s & 0x80) || !strchr("*+?@! ", *s & 0x7f)) *d++ = *s; @@ -1188,11 +1219,12 @@ debunk(dp, sp) /* extended pattern operators: *+?@! */ if ((*s & 0x7f) != ' ') *d++ = *s & 0x7f; - *d++ = '('; + if (d - dp < dlen) + *d++ = '('; } *d = '\0'; } else if (dp != sp) - strcpy(dp, sp); + strlcpy(dp, sp, dlen); return dp; } @@ -1282,11 +1314,19 @@ homedir(name) return NULL; #else /* OS2 */ struct passwd *pw; + size_t n; pw = getpwnam(name); if (pw == NULL) return NULL; - ap->val.s = str_save(pw->pw_dir, APERM); + n = strlen(pw->pw_dir); + if (n > 0 && '/' != pw->pw_dir[n - 1]) { + ap->val.s = str_nsave(pw->pw_dir, n + 1, APERM); + ap->val.s[n] = '/'; + ap->val.s[n + 1] = '\0'; + } else { + ap->val.s = str_save(pw->pw_dir, APERM); + } ap->flag |= DEFINED|ISSET|ALLOC; #endif /* OS2 */ } @@ -1335,7 +1375,7 @@ alt_expand(wp, start, exp_start, end, fdo) if (fdo & DOGLOB) glob(start, wp, fdo & DOMARKDIRS); else - XPput(*wp, debunk(start, start)); + XPput(*wp, debunk(start, start, end - start)); return; } brace_end = p; diff --git a/shells/pdksh/files/exec.c b/shells/pdksh/files/exec.c index f71404c50de..5ce28f3444c 100644 --- a/shells/pdksh/files/exec.c +++ b/shells/pdksh/files/exec.c @@ -1,6 +1,14 @@ +/* $NetBSD: exec.c,v 1.2 2008/05/31 16:47:36 tnn Exp $ */ + /* * execute command tree */ +#include <sys/cdefs.h> + +#ifndef lint +__RCSID("$NetBSD: exec.c,v 1.2 2008/05/31 16:47:36 tnn Exp $"); +#endif + #include "sh.h" #include "c_test.h" @@ -14,25 +22,24 @@ # define PS4_SUBSTITUTE(s) (s) #endif /* KSH */ -static int comexec ARGS((struct op *t, struct tbl *volatile tp, char **ap, - int volatile flags)); -static void scriptexec ARGS((struct op *tp, char **ap)); -static int call_builtin ARGS((struct tbl *tp, char **wp)); -static int iosetup ARGS((struct ioword *iop, struct tbl *tp)); -static int herein ARGS((const char *content, int sub)); +static int comexec ARGS((struct op *, struct tbl *volatile, char **, + int volatile)); +static void scriptexec ARGS((struct op *, char **)); +static int call_builtin ARGS((struct tbl *, char **)); +static int iosetup ARGS((struct ioword *, struct tbl *)); +static int herein ARGS((const char *, int)); #ifdef KSH -static char *do_selectargs ARGS((char **ap, bool_t print_menu)); +static char *do_selectargs ARGS((char **, bool_t)); #endif /* KSH */ #ifdef KSH -static int dbteste_isa ARGS((Test_env *te, Test_meta meta)); -static const char *dbteste_getopnd ARGS((Test_env *te, Test_op op, - int do_eval)); -static int dbteste_eval ARGS((Test_env *te, Test_op op, const char *opnd1, - const char *opnd2, int do_eval)); -static void dbteste_error ARGS((Test_env *te, int offset, const char *msg)); +static int dbteste_isa ARGS((Test_env *, Test_meta)); +static const char *dbteste_getopnd ARGS((Test_env *, Test_op, int)); +static int dbteste_eval ARGS((Test_env *, Test_op, const char *, + const char *, int)); +static void dbteste_error ARGS((Test_env *, int, const char *)); #endif /* KSH */ #ifdef OS2 -static int search_access1 ARGS((const char *path, int mode, int *errnop)); +static int search_access1 ARGS((const char *, int, int *)); #endif /* OS2 */ @@ -99,7 +106,7 @@ execute(t, flags) newenv(E_EXEC); if (trap) runtraps(0); - + if (t->type == TCOM) { /* Clear subst_exstat before argument expansion. Used by * null commands (see comexec() and c_eval()) and by c_set(). @@ -228,8 +235,10 @@ execute(t, flags) e->savefd[1] = savefd(1, 0); openpipe(pv); - ksh_dup2(pv[0], 0, FALSE); - close(pv[0]); + if (pv[0] != 0) { + ksh_dup2(pv[0], 0, FALSE); + close(pv[0]); + } coproc.write = pv[1]; coproc.job = (void *) 0; @@ -448,18 +457,19 @@ comexec(t, tp, ap, flags) int volatile flags; { int i; - int rv = 0; + volatile int rv = 0; register char *cp; register char **lastp; static struct op texec; /* Must be static (XXX but why?) */ int type_flags; int keepasn_ok; int fcflags = FC_BI|FC_FUNC|FC_PATH; + int bourne_function_call = 0; #ifdef KSH /* snag the last argument for $_ XXX not the same as at&t ksh, * which only seems to set $_ after a newline (but not in - * functions/dot scripts, but in interactive and scipt) - + * functions/dot scripts, but in interactive and script) - * perhaps save last arg here and set it in shell()?. */ if (Flag(FTALKING) && *(lastp = ap)) { @@ -544,9 +554,10 @@ comexec(t, tp, ap, flags) newblock(); /* ksh functions don't keep assignments, POSIX functions do. */ if (keepasn_ok && tp && tp->type == CFUNC - && !(tp->flag & FKSH)) + && !(tp->flag & FKSH)) { + bourne_function_call = 1; type_flags = 0; - else + } else type_flags = LOCAL|LOCAL_COPY|EXPORT; } if (Flag(FEXPORT)) @@ -563,6 +574,8 @@ comexec(t, tp, ap, flags) shf_flush(shl_out); } typeset(cp, type_flags, 0, 0, 0); + if (bourne_function_call && !(type_flags & EXPORT)) + typeset(cp, LOCAL|LOCAL_COPY|EXPORT, 0, 0, 0); } if ((cp = *ap) == NULL) { @@ -630,7 +643,7 @@ comexec(t, tp, ap, flags) if (tp->flag & FKSH) kshname = ap[0]; else - ap[0] = (char *) kshname; + ap[0] = (char *) __UNCONST(kshname); e->loc->argv = ap; for (i = 0; *ap++ != NULL; i++) ; @@ -712,8 +725,8 @@ comexec(t, tp, ap, flags) #ifdef KSH /* set $_ to program's full path */ /* setstr() can't fail here */ - setstr(typeset("_", LOCAL|EXPORT, 0, INTEGER, 0), tp->val.s, - KSH_RETURN_ERROR); + setstr(typeset("_", LOCAL|EXPORT, 0, INTEGER, 0), + tp->val.s, KSH_RETURN_ERROR); #endif /* KSH */ if (flags&XEXEC) { @@ -745,13 +758,13 @@ scriptexec(tp, ap) register struct op *tp; register char **ap; { - char *shell; + char *shellv; - shell = str_val(global(EXECSHELL_STR)); - if (shell && *shell) - shell = search(shell, path, X_OK, (int *) 0); - if (!shell || !*shell) - shell = EXECSHELL; + shellv = str_val(global(EXECSHELL_STR)); + if (shellv && *shellv) + shellv = search(shellv, path, X_OK, (int *) 0); + if (!shellv || !*shellv) + shellv = __UNCONST(EXECSHELL); *tp->args-- = tp->str; #ifdef SHARPBANG @@ -768,7 +781,7 @@ scriptexec(tp, ap) } if ((buf[0] == '#' && buf[1] == '!' && (cp = &buf[2])) # ifdef OS2 - || (strncmp(buf, "extproc", 7) == 0 && isspace(buf[7]) + || (strncmp(buf, "extproc", 7) == 0 && isspace((unsigned char)buf[7]) && (cp = &buf[7])) # endif /* OS2 */ ) @@ -821,22 +834,22 @@ scriptexec(tp, ap) afree(tmp_a0, ATEMP); } # endif /* OS2 */ - shell = a0; + shellv = a0; } } # ifdef OS2 } else { /* Use ksh documented shell default if present * else use OS2_SHELL which is assumed to need - * the /c option and '\' as dir separater. + * the /c option and '\' as dir separator. */ - char *p = shell; + char *p = shellv; - shell = str_val(global("EXECSHELL")); - if (shell && *shell) - shell = search(shell, path, X_OK, (int *) 0); - if (!shell || !*shell) { - shell = p; + shellv = str_val(global("EXECSHELL")); + if (shellv && *shellv) + shellv = search(shellv, path, X_OK, (int *) 0); + if (!shellv || !*shellv) { + shellv = p; *tp->args-- = "/c"; for (p = tp->str; *p; p++) if (*p == '/') @@ -846,12 +859,12 @@ scriptexec(tp, ap) } } #endif /* SHARPBANG */ - *tp->args = shell; + *tp->args = shellv; ksh_execve(tp->args[0], tp->args, ap, 0); /* report both the program that was run and the bogus shell */ - errorf("%s: %s: %s", tp->str, shell, strerror(errno)); + errorf("%s: %s: %s", tp->str, shellv, strerror(errno)); } int @@ -1048,7 +1061,12 @@ findcom(name, flags) npath = search(name, flags & FC_DEFPATH ? def_path : path, X_OK, &tp->u2.errno_); if (npath) { - tp->val.s = tp == &temp ? npath : str_save(npath, APERM); + if (tp == &temp) { + tp->val.s = npath; + } else { + tp->val.s = str_save(npath, APERM); + afree(npath, ATEMP); + } tp->flag |= ISSET|ALLOC; } else if ((flags & FC_FUNC) && (fpath = str_val(global("FPATH"))) != null @@ -1091,8 +1109,8 @@ flushcom(all) /* Check if path is something we want to find. Returns -1 for failure. */ int -search_access(path, mode, errnop) - const char *path; +search_access(pathx, mode, errnop) + const char *pathx; int mode; int *errnop; /* set if candidate found, but not suitable */ { @@ -1100,9 +1118,9 @@ search_access(path, mode, errnop) int ret, err = 0; struct stat statb; - if (stat(path, &statb) < 0) + if (stat(pathx, &statb) < 0) return -1; - ret = eaccess(path, mode); + ret = eaccess(pathx, mode); if (ret < 0) err = errno; /* File exists, but we can't access it */ else if (mode == X_OK @@ -1130,18 +1148,18 @@ search_access(path, mode, errnop) (char *) 0 }; int i; - char *mpath = (char *) path; + char *mpath = (char *) pathx; char *tp = mpath + strlen(mpath); char *p; char **sfx; - + /* If a suffix has been specified, check if it is one of the * suffixes that indicate the file is executable - if so, change * the access test to R_OK... * This code assumes OS/2 files can have only one suffix... */ if ((p = strrchr((p = ksh_strrchr_dirsep(mpath)) ? p : mpath, '.'))) { - if (mode == X_OK) + if (mode == X_OK) mode = R_OK; return search_access1(mpath, mode, errnop); } @@ -1161,17 +1179,17 @@ search_access(path, mode, errnop) #ifdef OS2 static int -search_access1(path, mode, errnop) - const char *path; +search_access1(pathx, mode, errnop) + const char *pathx; int mode; int *errnop; /* set if candidate found, but not suitable */ { int ret, err = 0; struct stat statb; - if (stat(path, &statb) < 0) + if (stat(pathx, &statb) < 0) return -1; - ret = eaccess(path, mode); + ret = eaccess(pathx, mode); if (ret < 0) err = errno; /* File exists, but we can't access it */ else if (!S_ISREG(statb.st_mode)) { @@ -1188,9 +1206,9 @@ search_access1(path, mode, errnop) * search for command with PATH */ char * -search(name, path, mode, errnop) +search(name, pathx, mode, errnop) const char *name; - const char *path; + const char *pathx; int mode; /* R_OK or X_OK */ int *errnop; /* set if candidate found, but not suitable */ { @@ -1217,12 +1235,12 @@ search(name, path, mode, errnop) } /* Look in current context always. (os2 style) */ - if (search_access(Xstring(xs, xp), mode, errnop) == 0) + if (search_access(Xstring(xs, xp), mode, errnop) == 0) return Xstring(xs, xp); /* not Xclose() - xp may be wrong */ #else /* OS2 */ if (ksh_strchr_dirsep(name)) { if (search_access(name, mode, errnop) == 0) - return (char *) name; + return (char *)__UNCONST(name); return NULL; } @@ -1230,7 +1248,7 @@ search(name, path, mode, errnop) Xinit(xs, xp, 128, ATEMP); #endif /* OS2 */ - sp = path; + sp = pathx; while (sp != NULL) { xp = Xstring(xs, xp); if (!(p = strchr(sp, PATHSEP))) @@ -1351,6 +1369,8 @@ iosetup(iop, tp) snptreef((char *) 0, 32, "%R", &iotmp), emsg); return -1; } + if (u == iop->unit) + return 0; /* "dup from" == "dup to" */ break; } } @@ -1375,13 +1395,19 @@ iosetup(iop, tp) return -1; } /* Do not save if it has already been redirected (i.e. "cat >x >y"). */ - if (e->savefd[iop->unit] == 0) - /* c_exec() assumes e->savefd[fd] set for any redirections. - * Ask savefd() not to close iop->unit - allows error messages - * to be seen if iop->unit is 2; also means we can't lose - * the fd (eg, both dup2 below and dup2 in restfd() failing). - */ - e->savefd[iop->unit] = savefd(iop->unit, 1); + if (e->savefd[iop->unit] == 0) { + /* If these are the same, it means unit was previously closed */ + if (u == iop->unit) + e->savefd[iop->unit] = -1; + else + /* c_exec() assumes e->savefd[fd] set for any + * redirections. Ask savefd() not to close iop->unit; + * this allows error messages to be seen if iop->unit + * is 2; also means we can't lose the fd (eg, both + * dup2 below and dup2 in restfd() failing). + */ + e->savefd[iop->unit] = savefd(iop->unit, 1); + } if (do_close) close(iop->unit); @@ -1463,7 +1489,7 @@ herein(content, sub) s = pushs(SSTRING, ATEMP); s->start = s->str = content; source = s; - if (yylex(ONEWORD) != LWORD) + if (yylex(ONEWORD|HEREDOC) != LWORD) internal_errorf(1, "herein: yylex"); source = osource; shf_puts(evalstr(yylval.cp, 0), shf); @@ -1509,7 +1535,8 @@ do_selectargs(ap, print_menu) if (print_menu || !*str_val(global("REPLY"))) pr_menu(ap); shellf("%s", str_val(global("PS3"))); - if (call_builtin(findcom("read", FC_BI), (char **) read_args)) + if (call_builtin(findcom("read", FC_BI), + (char **) __UNCONST(read_args))) return (char *) 0; s = str_val(global("REPLY")); if (*s) { @@ -1581,7 +1608,40 @@ pr_menu(ap) smi.arg_width = nwidth; smi.num_width = dwidth; print_columns(shl_out, n, select_fmt_entry, (void *) &smi, - dwidth + nwidth + 2); + dwidth + nwidth + 2, 1); + + return n; +} + +/* XXX: horrible kludge to fit within the framework */ + +static char *plain_fmt_entry ARGS((void *arg, int i, char *buf, int buflen)); + +static char * +plain_fmt_entry(arg, i, buf, buflen) + void *arg; + int i; + char *buf; + int buflen; +{ + shf_snprintf(buf, buflen, "%s", ((char *const *)arg)[i]); + return buf; +} + +int +pr_list(ap) + char *const *ap; +{ + char *const *pp; + int nwidth; + int i, n; + + for (n = 0, nwidth = 0, pp = ap; *pp; n++, pp++) { + i = strlen(*pp); + nwidth = (i > nwidth) ? i : nwidth; + } + print_columns(shl_out, n, plain_fmt_entry, (void *)__UNCONST(ap), + nwidth + 1, 0); return n; } diff --git a/shells/pdksh/files/expand.h b/shells/pdksh/files/expand.h index 73ac44c5777..2bf9df378f5 100644 --- a/shells/pdksh/files/expand.h +++ b/shells/pdksh/files/expand.h @@ -1,7 +1,9 @@ +/* $NetBSD: expand.h,v 1.2 2008/05/31 16:47:36 tnn Exp $ */ + /* * Expanding strings */ -/* $Id: expand.h,v 1.1.1.1 2008/05/23 17:15:18 tnn Exp $ */ +/* $Id: expand.h,v 1.2 2008/05/31 16:47:36 tnn Exp $ */ #define X_EXTRA 8 /* this many extra bytes in X string */ @@ -11,7 +13,7 @@ Xinit(xs, xp, 128, ATEMP); /* allocate initial string */ while ((c = generate()) { - Xcheck(xs, xp); /* expand string if neccessary */ + Xcheck(xs, xp); /* expand string if necessary */ Xput(xs, xp, c); /* add character */ } return Xclose(xs, xp); /* resize string */ diff --git a/shells/pdksh/files/expr.c b/shells/pdksh/files/expr.c index 48a1cc8f316..f5a0311ff61 100644 --- a/shells/pdksh/files/expr.c +++ b/shells/pdksh/files/expr.c @@ -1,9 +1,17 @@ +/* $NetBSD: expr.c,v 1.2 2008/05/31 16:47:36 tnn Exp $ */ + /* * Korn expression evaluation */ /* * todo: better error handling: if in builtin, should be builtin error, etc. */ +#include <sys/cdefs.h> + +#ifndef lint +__RCSID("$NetBSD: expr.c,v 1.2 2008/05/31 16:47:36 tnn Exp $"); +#endif + #include "sh.h" #include <ctype.h> @@ -61,7 +69,7 @@ enum prec { struct opinfo { char name[4]; int len; /* name length */ - enum prec prec; /* precidence: lower is higher */ + enum prec prec; /* precedence: lower is higher */ }; /* Tokens in this table must be ordered so the longest are first @@ -138,7 +146,7 @@ static struct tbl *tempvar ARGS((void)); static struct tbl *intvar ARGS((Expr_state *es, struct tbl *vp)); /* - * parse and evalute expression + * parse and evaluate expression */ int evaluate(expr, rval, error_ok) @@ -157,7 +165,7 @@ evaluate(expr, rval, error_ok) } /* - * parse and evalute expression, storing result in vp. + * parse and evaluate expression, storing result in vp. */ int v_evaluate(vp, expr, error_ok) @@ -206,7 +214,7 @@ v_evaluate(vp, expr, error_ok) if (vp->flag & INTEGER) setint_v(vp, v); else - /* can fail if readony */ + /* can fail if readonly */ setstr(vp, str_val(v), error_ok); quitenv(); @@ -417,21 +425,21 @@ evalexpr(es, prec) break; case O_TERN: { - int e = vl->val.i != 0; - if (!e) + int ex = vl->val.i != 0; + if (!ex) es->noassign++; vl = evalexpr(es, MAX_PREC); - if (!e) + if (!ex) es->noassign--; if (es->tok != CTERN) evalerr(es, ET_STR, "missing :"); token(es); - if (e) + if (ex) es->noassign++; vr = evalexpr(es, P_TERN); - if (e) + if (ex) es->noassign--; - vl = e ? vl : vr; + vl = ex ? vl : vr; } break; case O_ASN: @@ -463,7 +471,7 @@ token(es) char *tvar; /* skip white space */ - for (cp = es->tokp; (c = *cp), isspace(c); cp++) + for (cp = es->tokp; (c = *cp), isspace((unsigned char)c); cp++) ; es->tokp = cp; diff --git a/shells/pdksh/files/history.c b/shells/pdksh/files/history.c index 0c9329a052f..953316adbcc 100644 --- a/shells/pdksh/files/history.c +++ b/shells/pdksh/files/history.c @@ -1,3 +1,5 @@ +/* $NetBSD: history.c,v 1.2 2008/05/31 16:47:36 tnn Exp $ */ + /* * command history * @@ -14,6 +16,12 @@ * things. You need to have the mmap system call for this * to work on your system */ +#include <sys/cdefs.h> + +#ifndef lint +__RCSID("$NetBSD: history.c,v 1.2 2008/05/31 16:47:36 tnn Exp $"); +#endif + #include "sh.h" #include "ksh_stat.h" @@ -57,15 +65,14 @@ static int sprinkle ARGS((int)); # endif /* of EASY_HISTORY */ -static int hist_execute ARGS((char *cmd)); -static int hist_replace ARGS((char **hp, const char *pat, const char *rep, - int global)); -static char **hist_get ARGS((const char *str, int approx, int allow_cur)); -static char **hist_get_newest ARGS((int allow_cur)); -static char **hist_get_oldest ARGS(()); +static int hist_execute ARGS((char *)); +static int hist_replace ARGS((char **, const char *, const char *, int)); +static char **hist_get ARGS((const char *, int, int)); +static char **hist_get_newest ARGS((int)); +static char **hist_get_oldest ARGS((void)); static void histbackup ARGS((void)); -static char **current; /* current postition in history[] */ +static char **current; /* current position in history[] */ static int curpos; /* current index in history[] */ static char *hname; /* current name of history file */ static int hstarted; /* set after hist_init() called */ @@ -84,6 +91,11 @@ c_fc(wp) char *first = (char *) 0, *last = (char *) 0; char **hfirst, **hlast, **hp; + if (hist_source == NULL) { + bi_errorf("not interactive"); + return 1; + } + while ((optc = ksh_getopt(wp, &builtin_opt, "e:glnrs0,1,2,3,4,5,6,7,8,9,")) != EOF) switch (optc) { case 'e': @@ -91,8 +103,9 @@ c_fc(wp) if (strcmp(p, "-") == 0) sflag++; else { - editor = str_nsave(p, strlen(p) + 4, ATEMP); - strcat(editor, " $_"); + size_t len = strlen(p) + 4; + editor = str_nsave(p, len, ATEMP); + strlcat(editor, " $_", len); } break; case 'g': /* non-at&t ksh */ @@ -326,11 +339,11 @@ hist_execute(cmd) } static int -hist_replace(hp, pat, rep, global) +hist_replace(hp, pat, rep, globalv) char **hp; const char *pat; const char *rep; - int global; + int globalv; { char *line; @@ -347,7 +360,7 @@ hist_replace(hp, pat, rep, global) Xinit(xs, xp, 128, ATEMP); for (s = *hp; (s1 = strstr(s, pat)) - && (!any_subst || global) ; s = s1 + pat_len) + && (!any_subst || globalv) ; s = s1 + pat_len) { any_subst = 1; len = s1 - s; @@ -385,7 +398,7 @@ hist_get(str, approx, allow_cur) if (getn(str, &n)) { hp = histptr + (n < 0 ? n : (n - hist_source->line)); - if (hp < history) { + if (hp < histlist) { if (approx) hp = hist_get_oldest(); else { @@ -407,12 +420,12 @@ hist_get(str, approx, allow_cur) int anchored = *str == '?' ? (++str, 0) : 1; /* the -1 is to avoid the current fc command */ - n = findhist(histptr - history - 1, 0, str, anchored); + n = findhist(histptr - histlist - 1, 0, str, anchored); if (n < 0) { bi_errorf("%s: not in history", str); hp = (char **) 0; } else - hp = &history[n]; + hp = &histlist[n]; } return hp; } @@ -422,7 +435,7 @@ static char ** hist_get_newest(allow_cur) int allow_cur; { - if (histptr < history || (!allow_cur && histptr == history)) { + if (histptr < histlist || (!allow_cur && histptr == histlist)) { bi_errorf("no history (yet)"); return (char **) 0; } @@ -435,11 +448,11 @@ hist_get_newest(allow_cur) static char ** hist_get_oldest() { - if (histptr <= history) { + if (histptr <= histlist) { bi_errorf("no history (yet)"); return (char **) 0; } - return history; + return histlist; } /******************************/ @@ -450,7 +463,7 @@ histbackup() { static int last_line = -1; - if (histptr >= history && last_line != hist_source->line) { + if (histptr >= histlist && last_line != hist_source->line) { hist_source->line--; afree((void*)*histptr, APERM); histptr--; @@ -477,21 +490,21 @@ int histnum(n) int n; { - int last = histptr - history; + int last = histptr - histlist; if (n < 0 || n >= last) { current = histptr; curpos = last; return last; } else { - current = &history[n]; + current = &histlist[n]; curpos = n; return n; } } /* - * This will become unecessary if hist_get is modified to allow + * This will become unnecessary if hist_get is modified to allow * searching from positions other than the end, and in either * direction. */ @@ -503,18 +516,18 @@ findhist(start, fwd, str, anchored) int anchored; { char **hp; - int maxhist = histptr - history; + int maxhist = histptr - histlist; int incr = fwd ? 1 : -1; int len = strlen(str); if (start < 0 || start >= maxhist) start = maxhist; - hp = &history[start]; - for (; hp >= history && hp <= histptr; hp += incr) + hp = &histlist[start]; + for (; hp >= histlist && hp <= histptr; hp += incr) if ((anchored && strncmp(*hp, str, len) == 0) || (!anchored && strstr(*hp, str))) - return hp - history; + return hp - histlist; return -1; } @@ -528,18 +541,18 @@ sethistsize(n) int n; { if (n > 0 && n != histsize) { - int cursize = histptr - history; + int cursize = histptr - histlist; /* save most recent history */ if (n < cursize) { - memmove(history, histptr - n, n * sizeof(char *)); + memmove(histlist, histptr - n, n * sizeof(char *)); cursize = n; } - history = (char **)aresize(history, n*sizeof(char *), APERM); + histlist = (char **)aresize(histlist, n*sizeof(char *), APERM); histsize = n; - histptr = history + cursize; + histptr = histlist + cursize; } } @@ -577,7 +590,7 @@ sethistfile(name) afree(hname, APERM); hname = NULL; /* let's reset the history */ - histptr = history - 1; + histptr = histlist - 1; hist_source->line = 0; } # endif @@ -591,10 +604,10 @@ sethistfile(name) void init_histvec() { - if (history == (char **)NULL) { + if (histlist == (char **)NULL) { histsize = HISTORYSIZE; - history = (char **)alloc(histsize*sizeof (char *), APERM); - histptr = history - 1; + histlist = (char **)alloc(histsize*sizeof (char *), APERM); + histptr = histlist - 1; } } @@ -611,11 +624,11 @@ histsave(lno, cmd, dowrite) register char **hp = histptr; char *cp; - if (++hp >= history + histsize) { /* remove oldest command */ - afree((void*)history[0], APERM); - memmove(history, history + 1, - sizeof(history[0]) * (histsize - 1)); - hp = &history[histsize - 1]; + if (++hp >= histlist + histsize) { /* remove oldest command */ + afree((void*)histlist[0], APERM); + memmove(histlist, histlist + 1, + sizeof(histlist[0]) * (histsize - 1)); + hp = &histlist[histsize - 1]; } *hp = str_save(cmd, APERM); /* trash trailing newline but allow imbedded newlines */ @@ -734,11 +747,11 @@ hist_finish() if (once++) return; /* check how many we have */ - i = histptr - history; + i = histptr - histlist; if (i >= histsize) hp = &histptr[-histsize]; else - hp = history; + hp = histlist; if (hname && (fh = fopen(hname, "w"))) { for (i = 0; hp + i <= histptr && hp[i]; i++) @@ -779,9 +792,9 @@ histsave(lno, cmd, dowrite) hp = histptr; - if (++hp >= history + histsize) { /* remove oldest command */ - afree((void*)*history, APERM); - for (hp = history; hp < history + histsize - 1; hp++) + if (++hp >= histlist + histsize) { /* remove oldest command */ + afree((void*)*histlist, APERM); + for (hp = histlist; hp < histlist + histsize - 1; hp++) hp[0] = hp[1]; } *hp = c; @@ -858,8 +871,8 @@ hist_init(s) /* * check on its validity */ - if ((int)base == -1 || *base != HMAGIC1 || base[1] != HMAGIC2) { - if ((int)base != -1) + if (base == MAP_FAILED || *base != HMAGIC1 || base[1] != HMAGIC2) { + if (base != MAP_FAILED) munmap((caddr_t)base, hsize); hist_finish(); unlink(hname); @@ -887,7 +900,7 @@ typedef enum state { shdr, /* expecting a header */ sline, /* looking for a null byte to end the line */ sn1, /* bytes 1 to 4 of a line no */ - sn2, sn3, sn4, + sn2, sn3, sn4 } State; static int @@ -896,7 +909,7 @@ hist_count_lines(base, bytes) register int bytes; { State state = shdr; - register lines = 0; + int lines = 0; while (bytes--) { switch (state) @@ -1015,8 +1028,8 @@ histload(s, base, bytes) register int bytes; { State state; - int lno; - unsigned char *line; + int lno = 0; + unsigned char *line = NULL; for (state = shdr; bytes-- > 0; base++) { switch (state) { @@ -1044,7 +1057,7 @@ histload(s, base, bytes) case sline: if (*base == '\0') { /* worry about line numbers */ - if (histptr >= history && lno-1 != s->line) { + if (histptr >= histlist && lno-1 != s->line) { /* a replacement ? */ histinsert(s, lno, line); } @@ -1069,7 +1082,7 @@ histinsert(s, lno, line) { register char **hp; - if (lno >= s->line-(histptr-history) && lno <= s->line) { + if (lno >= s->line-(histptr-histlist) && lno <= s->line) { hp = &histptr[lno-s->line]; if (*hp) afree((void*)*hp, APERM); @@ -1093,7 +1106,7 @@ writehistfile(lno, cmd) unsigned char *base; unsigned char *new; int bytes; - char hdr[5]; + unsigned char hdr[5]; (void) flock(histfd, LOCK_EX); sizenow = lseek(histfd, 0L, SEEK_END); @@ -1105,7 +1118,7 @@ writehistfile(lno, cmd) /* someone has added some lines */ bytes = sizenow - hsize; base = (unsigned char *)mmap(0, sizenow, PROT_READ, MAP_FLAGS, histfd, 0); - if ((int)base == -1) + if (base == MAP_FAILED) goto bad; new = base + hsize; if (*new != COMMAND) { @@ -1157,7 +1170,7 @@ static int sprinkle(fd) int fd; { - static char mag[] = { HMAGIC1, HMAGIC2 }; + static unsigned char mag[] = { HMAGIC1, HMAGIC2 }; return(write(fd, mag, 2) != 2); } diff --git a/shells/pdksh/files/io.c b/shells/pdksh/files/io.c index a490aa8b5ba..ca3ca0f54ce 100644 --- a/shells/pdksh/files/io.c +++ b/shells/pdksh/files/io.c @@ -1,6 +1,14 @@ +/* $NetBSD: io.c,v 1.2 2008/05/31 16:47:36 tnn Exp $ */ + /* * shell buffered IO and formatted output */ +#include <sys/cdefs.h> + +#ifndef lint +__RCSID("$NetBSD: io.c,v 1.2 2008/05/31 16:47:36 tnn Exp $"); +#endif + #include <ctype.h> #include "sh.h" @@ -13,7 +21,7 @@ static int initio_done; */ -/* A shell error occured (eg, syntax error, etc.) */ +/* A shell error occurred (eg, syntax error, etc.) */ void #ifdef HAVE_PROTOTYPES errorf(const char *fmt, ...) @@ -297,11 +305,12 @@ savefd(fd, noclose) if (fd < FDBASE) { nfd = ksh_dupbase(fd, FDBASE); - if (nfd < 0) + if (nfd < 0) { if (errno == EBADF) return -1; else errorf("too many files open in shell"); + } if (!noclose) close(fd); } else @@ -318,7 +327,7 @@ restfd(fd, ofd) shf_flush(&shf_iob[fd]); if (ofd < 0) /* original fd closed */ close(fd); - else { + else if (fd != ofd) { ksh_dup2(ofd, fd, TRUE); /* XXX: what to do if this fails? */ close(ofd); } @@ -353,7 +362,7 @@ check_fd(name, mode, emsgp) { int fd, fl; - if (isdigit(name[0]) && !name[1]) { + if (isdigit((unsigned char)name[0]) && !name[1]) { fd = name[0] - '0'; if ((fl = fcntl(fd = name[0] - '0', F_GETFL, 0)) < 0) { if (emsgp) @@ -362,7 +371,7 @@ check_fd(name, mode, emsgp) } fl &= O_ACCMODE; #ifdef OS2 - if (mode == W_OK ) { + if (mode == W_OK ) { if (setmode(fd, O_TEXT) == -1) { if (emsgp) *emsgp = "couldn't set write mode"; @@ -372,7 +381,7 @@ check_fd(name, mode, emsgp) if (setmode(fd, O_BINARY) == -1) { if (emsgp) *emsgp = "couldn't set read mode"; - return -1; + return -1; } #else /* OS2 */ /* X_OK is a kludge to disable this check for dups (x<&1): @@ -449,7 +458,7 @@ coproc_write_close(fd) } } -/* Called to check for existance of/value of the co-process file descriptor. +/* Called to check for existence of/value of the co-process file descriptor. * (Used by check_fd() and by c_read/c_print to deal with -p option). */ int @@ -502,28 +511,36 @@ maketemp(ap, type, tlist) Temp_type type; struct temp **tlist; { +#ifndef __NetBSD__ static unsigned int inc; +#endif struct temp *tp; int len; int fd; - char *path; + char *pathx; const char *dir; dir = tmpdir ? tmpdir : "/tmp"; /* The 20 + 20 is a paranoid worst case for pid/inc */ len = strlen(dir) + 3 + 20 + 20 + 1; tp = (struct temp *) alloc(sizeof(struct temp) + len, ap); - tp->name = path = (char *) &tp[1]; + tp->name = pathx = (char *) &tp[1]; tp->shf = (struct shf *) 0; tp->type = type; +#ifdef __NetBSD__ + shf_snprintf(pathx, len, "%s/shXXXXXXXX", dir); + fd = mkstemp(pathx); + if (fd >= 0) + tp->shf = shf_fdopen(fd, SHF_WR, (struct shf *) 0); +#else while (1) { /* Note that temp files need to fit 8.3 DOS limits */ - shf_snprintf(path, len, "%s/sh%05u.%03x", + shf_snprintf(pathx, len, "%s/sh%05u.%03x", dir, (unsigned) procpid, inc++); /* Mode 0600 to be paranoid, O_TRUNC in case O_EXCL isn't * really there. */ - fd = open(path, O_RDWR|O_CREAT|O_EXCL|O_TRUNC, 0600); + fd = open(pathx, O_RDWR|O_CREAT|O_EXCL|O_TRUNC, 0600); if (fd >= 0) { tp->shf = shf_fdopen(fd, SHF_WR, (struct shf *) 0); break; @@ -541,7 +558,7 @@ maketemp(ap, type, tlist) */ break; } - tp->next = NULL; +#endif /* __NetBSD__ */ tp->pid = procpid; tp->next = *tlist; diff --git a/shells/pdksh/files/jobs.c b/shells/pdksh/files/jobs.c index 2b3a63b9e72..fd17dc153f0 100644 --- a/shells/pdksh/files/jobs.c +++ b/shells/pdksh/files/jobs.c @@ -1,3 +1,5 @@ +/* $NetBSD: jobs.c,v 1.2 2008/05/31 16:47:36 tnn Exp $ */ + /* * Process and job control */ @@ -13,7 +15,7 @@ * * Notes regarding the copious ifdefs: * - JOB_SIGS is independent of JOBS - it is defined if there are modern - * signal and wait routines available. This is prefered, even when + * signal and wait routines available. This is preferred, even when * JOBS is not defined, since the shell will not otherwise notice when * background jobs die until the shell waits for a foreground process * to die. @@ -21,6 +23,12 @@ * process groups * - NEED_PGRP_SYNC defined iff JOBS is defined - see comment below */ +#include <sys/cdefs.h> + +#ifndef lint +__RCSID("$NetBSD: jobs.c,v 1.2 2008/05/31 16:47:36 tnn Exp $"); +#endif + #include "sh.h" #include "ksh_stat.h" @@ -121,7 +129,7 @@ struct proc { #define JF_CHANGED 0x040 /* process has changed state */ #define JF_KNOWN 0x080 /* $! referenced */ #define JF_ZOMBIE 0x100 /* known, unwaited process */ -#define JF_REMOVE 0x200 /* flaged for removal (j_jobs()/j_noityf()) */ +#define JF_REMOVE 0x200 /* flagged for removal (j_jobs()/j_noityf()) */ #define JF_USETTYMODE 0x400 /* tty mode saved if process exits normally */ #define JF_SAVEDTTYPGRP 0x800 /* j->saved_ttypgrp is valid */ @@ -219,8 +227,7 @@ static Proc *new_proc ARGS((void)); static void check_job ARGS((Job *j)); static void put_job ARGS((Job *j, int where)); static void remove_job ARGS((Job *j, const char *where)); -static void kill_job ARGS((Job *j)); -static void fill_command ARGS((char *c, int len, struct op *t)); +static int kill_job ARGS((Job *j, int sig)); /* initialize job control */ void @@ -294,10 +301,17 @@ j_exit() && procpid == kshpid))))) { killed = 1; - killpg(j->pgrp, SIGHUP); + if (j->pgrp == 0) + kill_job(j, SIGHUP); + else + killpg(j->pgrp, SIGHUP); #ifdef JOBS - if (j->state == PSTOPPED) - killpg(j->pgrp, SIGCONT); + if (j->state == PSTOPPED) { + if (j->pgrp == 0) + kill_job(j, SIGCONT); + else + killpg(j->pgrp, SIGCONT); + } #endif /* JOBS */ } } @@ -497,7 +511,7 @@ exchild(t, flags, close_fd) put_job(j, PJ_PAST_STOPPED); } - fill_command(p->command, sizeof(p->command), t); + snptreef(p->command, sizeof(p->command), "%T", t); /* create child process */ forksleep = 1; @@ -508,7 +522,7 @@ exchild(t, flags, close_fd) forksleep <<= 1; } if (i < 0) { - kill_job(j); + kill_job(j, SIGKILL); remove_job(j, "fork failed"); #ifdef NEED_PGRP_SYNC if (j_sync_open) { @@ -621,8 +635,10 @@ exchild(t, flags, close_fd) SS_RESTORE_IGN|SS_FORCE); if (!(flags & (XPIPEI | XCOPROC))) { int fd = open("/dev/null", 0); - (void) ksh_dup2(fd, 0, TRUE); - close(fd); + if (fd != 0) { + (void) ksh_dup2(fd, 0, TRUE); + close(fd); + } } } remove_job(j, "child"); /* in case of `jobs` command */ @@ -805,7 +821,6 @@ j_kill(cp, sig) int sig; { Job *j; - Proc *p; int rv = 0; int ecode; #ifdef JOB_SIGS @@ -823,11 +838,10 @@ j_kill(cp, sig) } if (j->pgrp == 0) { /* started when !Flag(FMONITOR) */ - for (p=j->proc_list; p != (Proc *) 0; p = p->next) - if (kill(p->pid, sig) < 0) { - bi_errorf("%s: %s", cp, strerror(errno)); - rv = 1; - } + if (kill_job(j, sig) < 0) { + bi_errorf("%s: %s", cp, strerror(errno)); + rv = 1; + } } else { #ifdef JOBS if (j->state == PSTOPPED && (sig == SIGTERM || sig == SIGHUP)) @@ -1070,7 +1084,7 @@ j_notify() #endif /* JOB_SIGS */ } -/* Return pid of last process in last asynchornous job */ +/* Return pid of last process in last asynchronous job */ pid_t j_async() { @@ -1214,7 +1228,7 @@ j_waitj(j, flags, where) * a fork/exec instead of an exec (the fork means * the execed shell gets a different pid from its * pgrp, so naturally it sets its pgrp and gets hosed - * when it gets forgrounded by the parent shell, which + * when it gets foregrounded by the parent shell, which * has restored the tty's pgrp to that of the su * process). */ @@ -1282,7 +1296,7 @@ j_waitj(j, flags, where) j_systime = j->systime; rv = j->status; - if (!(flags & JW_ASYNCNOTIFY) + if (!(flags & JW_ASYNCNOTIFY) && (!Flag(FMONITOR) || j->state != PSTOPPED)) { j_print(j, JP_SHORT, shl_out); @@ -1423,12 +1437,12 @@ check_job(j) #ifdef KSH /* Note when co-process dies: can't be done in j_wait() nor - * remove_job() since neither may be called for non-interactive + * remove_job() since neither may be called for non-interactive * shells. */ if (j->state == PEXITED || j->state == PSIGNALLED) { /* No need to keep co-process input any more - * (at leasst, this is what ksh93d thinks) + * (at least, this is what ksh93d thinks) */ if (coproc.job == j) { coproc.job = (void *) 0; @@ -1530,16 +1544,17 @@ j_print(j, how, shf) coredumped = 0; switch (p->state) { case PRUNNING: - strcpy(buf, "Running"); + strlcpy(buf, "Running", sizeof buf); break; case PSTOPPED: - strcpy(buf, sigtraps[WSTOPSIG(p->status)].mess); + strlcpy(buf, sigtraps[WSTOPSIG(p->status)].mess, + sizeof buf); break; case PEXITED: if (how == JP_SHORT) buf[0] = '\0'; else if (WEXITSTATUS(p->status) == 0) - strcpy(buf, "Done"); + strlcpy(buf, "Done", sizeof buf); else shf_snprintf(buf, sizeof(buf), "Done (%d)", WEXITSTATUS(p->status)); @@ -1555,15 +1570,17 @@ j_print(j, how, shf) || WTERMSIG(p->status) == SIGPIPE)) { buf[0] = '\0'; } else - strcpy(buf, sigtraps[WTERMSIG(p->status)].mess); + strlcpy(buf, sigtraps[WTERMSIG(p->status)].mess, + sizeof buf); break; } - if (how != JP_SHORT) + if (how != JP_SHORT) { if (p == j->proc_list) shf_fprintf(shf, "[%d] %c ", j->job, jobchar); else shf_fprintf(shf, "%s", filler); + } if (how == JP_LONG) shf_fprintf(shf, "%5d ", p->pid); @@ -1635,27 +1652,27 @@ j_lookup(cp, ecodep) return (Job *) 0; } switch (*++cp) { - case '\0': /* non-standard */ - case '+': - case '%': + case '\0': /* non-standard */ + case '+': + case '%': if (job_list != (Job *) 0) return job_list; break; - case '-': + case '-': if (job_list != (Job *) 0 && job_list->next) return job_list->next; break; - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': job = atoi(cp); for (j = job_list; j != (Job *) 0; j = j->next) if (j->job == job) return j; break; - case '?': /* %?string */ + case '?': /* %?string */ last_match = (Job *) 0; for (j = job_list; j != (Job *) 0; j = j->next) for (p = j->proc_list; p != (Proc *) 0; p = p->next) @@ -1671,7 +1688,7 @@ j_lookup(cp, ecodep) return last_match; break; - default: /* %string */ + default: /* %string */ len = strlen(cp); last_match = (Job *) 0; for (j = job_list; j != (Job *) 0; j = j->next) @@ -1723,7 +1740,7 @@ new_job() return newj; } -/* Allocate new process strut +/* Allocate new process struct * * If jobs are compiled in then this routine expects sigchld to be blocked. */ @@ -1825,50 +1842,17 @@ put_job(j, where) * * If jobs are compiled in then this routine expects sigchld to be blocked. */ -static void -kill_job(j) +static int +kill_job(j, sig) Job *j; + int sig; { Proc *p; + int rval = 0; for (p = j->proc_list; p != (Proc *) 0; p = p->next) if (p->pid != 0) - (void) kill(p->pid, SIGKILL); -} - -/* put a more useful name on a process than snptreef does (in certain cases) */ -static void -fill_command(c, len, t) - char *c; - int len; - struct op *t; -{ - int alen; - char **ap; - - if (t->type == TEXEC || t->type == TCOM) { - /* Causes problems when set -u is in effect, can also - cause problems when array indices evaluated (may have - side effects, eg, assignment, incr, etc.) - if (t->type == TCOM) - ap = eval(t->args, DOBLANK|DONTRUNCOMMAND); - else - */ - ap = t->args; - --len; /* save room for the null */ - while (len > 0 && *ap != (char *) 0) { - alen = strlen(*ap); - if (alen > len) - alen = len; - memcpy(c, *ap, alen); - c += alen; - len -= alen; - if (len > 0) { - *c++ = ' '; len--; - } - ap++; - } - *c = '\0'; - } else - snptreef(c, len, "%T", t); + if (kill(p->pid, sig) < 0) + rval = -1; + return rval; } diff --git a/shells/pdksh/files/ksh.Man b/shells/pdksh/files/ksh.Man index f858ba31500..8c01c112145 100644 --- a/shells/pdksh/files/ksh.Man +++ b/shells/pdksh/files/ksh.Man @@ -1,4 +1,5 @@ '\" t +.\" $NetBSD: ksh.Man,v 1.2 2008/05/31 16:47:36 tnn Exp $ .\"{{{}}} .\"{{{ Notes about man page .\" - use the pseudo-macros .sh( and .sh) to begin and end sh-specific @@ -12,8 +13,8 @@ .\" name in built-in commands section?) .\" - need to be consistent about notation for `See section-name', ` .\" See description of foobar command', `See section section-name', etc. -.\" - need to use the term `external command' meaning `a command that is -.\" executed using execve(2)' (as opposed to a built-in command or +.\" - need to use the term `external command' meaning `a command that is +.\" executed using execve(2)' (as opposed to a built-in command or .\" function) for more clear description. .\"}}} .\"{{{ Title @@ -48,12 +49,12 @@ sh \- Public domain Bourne shell .\"{{{ Description .SH DESCRIPTION .ksh( -\fBksh\fP is a command interpreter that is intended for both -interactive and shell script use. Its command language is a superset -of the \fIsh\fP(1) shell language. +\fBksh\fP is a command interpreter that is intended for both +interactive and shell script use. +Its command language is a superset of the \fIsh\fP(1) shell language. .ksh) .sh( -\fBsh\fP is a reimplementation of the Bourne shell, a command +\fBsh\fP is a re-implementation of the Bourne shell, a command interpreter for both interactive and script use. .sh) .\"{{{ Shell Startup @@ -124,14 +125,14 @@ user-id (group-id) to its real user-id (group-id). If the basename of the name the shell is called with (\fIi.e.\fP, argv[0]) starts with \fB\-\fP or if the \fB\-l\fP option is used, the shell is assumed to be a login shell and the shell reads and executes the contents of -\fB/etc/profile\fP and \fB$HOME/.profile\fP if they exist and are readable. +\fB/etc/profile\fP, \fB$HOME/.profile\fP and \fB$ENV\fP if they exist and are +readable. .PP If the \fBENV\fP parameter is set when the shell starts (or, in the case of login shells, after any profiles are processed), its value is subjected to parameter, command, arithmetic and tilde substitution and the resulting file (if any) is read and executed. -If \fBENV\fP parameter is not set (and not null) and pdksh was compiled -with the \fBDEFAULT_ENV\fP macro defined, the file named in that macro +If the \fBENV\fP parameter is not set (and not null) the file \fB$HOME/.kshrc\fP is included (after the above mentioned substitutions have been performed). .PP The exit status of the shell is 127 if the command file specified @@ -292,7 +293,8 @@ are all valid, but is not. .\"{{{ ( list ) .IP "\fB(\fP \fIlist\fP \fB)\fP" -Execute \fIlist\fP in a subshell. There is no implicit way to pass +Execute \fIlist\fP in a subshell. +There is no implicit way to pass environment changes from a subshell back to its parent. .\"}}} .\"{{{ { list } @@ -304,12 +306,14 @@ Note that \fB{\fP and \fB}\fP are reserved words, not meta-characters. .IP "\fBcase\fP \fIword\fP \fBin\fP [ [\fB(\fP] \fIpattern\fP [\fB|\fP \fIpattern\fP] ... \fB)\fP \fIlist\fP \fB;;\fP ] ... \fBesac\fP" The \fBcase\fP statement attempts to match \fIword\fP against the specified \fIpattern\fPs; the \fIlist\fP associated with the first successfully matched -pattern is executed. Patterns used in \fBcase\fP statements are the same as +pattern is executed. +Patterns used in \fBcase\fP statements are the same as those used for file name patterns except that the restrictions regarding -\fB\&.\fP and \fB/\fP are dropped. Note that any unquoted space before and -after a pattern is stripped; any space with a pattern must be quoted. Both the -word and the patterns are subject to parameter, command, and arithmetic -substitution as well as tilde substitution. +\fB\&.\fP and \fB/\fP are dropped. +Note that any unquoted space before and +after a pattern is stripped; any space with a pattern must be quoted. +Both the word and the patterns are subject to parameter, command, and +arithmetic substitution as well as tilde substitution. For historical reasons, open and close braces may be used instead of \fBin\fP and \fBesac\fP (\fIe.g.\fP, \fBcase $foo { *) echo bar; }\fP). The exit status of a \fBcase\fP statement is that of the executed \fIlist\fP; @@ -319,7 +323,8 @@ if no \fIlist\fP is executed, the exit status is zero. .IP "\fBfor\fP \fIname\fP [ \fBin\fP \fIword\fP ... \fIterm\fP ] \fBdo\fP \fIlist\fP \fBdone\fP" where \fIterm\fP is either a newline or a \fB;\fP. For each \fIword\fP in the specified word list, the parameter \fIname\fP is -set to the word and \fIlist\fP is executed. If \fBin\fP is not used to +set to the word and \fIlist\fP is executed. +If \fBin\fP is not used to specify a word list, the positional parameters (\fB"$1"\fP, \fB"$2"\fP, \fIetc.\fP) are used instead. For historical reasons, open and close braces may be used instead @@ -331,7 +336,8 @@ of \fIlist\fP; if \fIlist\fP is never executed, the exit status is zero. .IP "\fBif\fP \fIlist\fP \fBthen\fP \fIlist\fP [\fBelif\fP \fIlist\fP \fBthen\fP \fIlist\fP] ... [\fBelse\fP \fIlist\fP] \fBfi\fP" If the exit status of the first \fIlist\fP is zero, the second \fIlist\fP is executed; otherwise the \fIlist\fP following the \fBelif\fP, if any, is -executed with similar consequences. If all the lists following the \fBif\fP +executed with similar consequences. +If all the lists following the \fBif\fP and \fBelif\fPs fail (\fIi.e.\fP, exit with non-zero status), the \fIlist\fP following the \fBelse\fP is executed. The exit status of an \fBif\fP statement is that @@ -372,7 +378,8 @@ exit status of the first \fIlist\fP is non-zero. .\"}}} .\"{{{ while list do list done .IP "\fBwhile\fP \fIlist\fP \fBdo\fP \fIlist\fP \fBdone\fP" -A \fBwhile\fP is a prechecked loop. Its body is executed as often +A \fBwhile\fP is a prechecked loop. +Its body is executed as often as the exit status of the first \fIlist\fP is zero. The exit status of a \fBwhile\fP statement is the last exit status of the \fIlist\fP in the body of the loop; if the body is not executed, @@ -432,7 +439,7 @@ or greater than, their second string operand, respectively. .IP \ \ \(bu The single argument form of \fBtest\fP, which tests if the argument has non-zero length, is not valid -- explicit operators must be always be used, \fIe.g.\fP, instead of +- explicit operators must always be used, \fIe.g.\fP, instead of .ce \fB[\fP \fIstr\fP \fB]\fP use @@ -477,13 +484,17 @@ of the form \fB"\fP...\fB`\fP...\fB\e"\fP...\fB`\fP..\fB"\fP. .\"}}} .\"{{{ Aliases .SS "Aliases" -There are two types of aliases: normal command aliases and tracked -aliases. Command aliases are normally used as a short hand for a long -or often used command. The shell expands command aliases (\fIi.e.\fP, +There are two types of aliases: normal command aliases and tracked aliases. +Command aliases are normally used as a short hand for a long +or often used command. +The shell expands command aliases (\fIi.e.\fP, substitutes the alias name for its value) when it reads the first word -of a command. An expanded alias is re-processed to check for more -aliases. If a command alias ends in a space or tab, the following word -is also checked for alias expansion. The alias expansion process stops +of a command. +An expanded alias is re-processed to check for more +aliases. +If a command alias ends in a space or tab, the following word +is also checked for alias expansion. +The alias expansion process stops when a word that is not an alias is found, when a quoted word is found or when an alias word that is currently being expanded is found. .PP @@ -506,8 +517,10 @@ integer='typeset \-i' local='typeset' .br login='exec login' -.br -newgrp='exec newgrp' +.\" ifndef __NetBSD__ +.\" .br +.\" newgrp='exec newgrp' +.\" endif .br nohup='nohup ' .br @@ -523,15 +536,17 @@ type='whence \-v' .ft P .PP Tracked aliases allow the shell to remember where it found a particular -command. The first time the shell does a path search for a command that +command. +The first time the shell does a path search for a command that is marked as a tracked alias, it saves the full path of the command. The next time the command is executed, the shell checks the saved path -to see that it is still valid, and if so, avoids repeating the path -search. Tracked aliases can be listed and created using \fBalias -\-t\fP. Note that changing the \fBPATH\fP parameter clears the saved -paths for all tracked aliases. If the \fBtrackall\fP option is set (\fIi.e.\fP, -\fBset \-o trackall\fP or \fBset \-h\fP), the shell tracks all -commands. This option is set automatically for non-interactive shells. +to see that it is still valid, and if so, avoids repeating the path search. +Tracked aliases can be listed and created using \fBalias \-t\fP. +Note that changing the \fBPATH\fP parameter clears the saved +paths for all tracked aliases. +If the \fBtrackall\fP option is set (\fIi.e.\fP, +\fBset \-o trackall\fP or \fBset \-h\fP), the shell tracks all commands. +This option is set automatically for non-interactive shells. For interactive shells, only the following commands are automatically tracked: \fBcat\fP, \fBcc\fP, \fBchmod\fP, \fBcp\fP, \fBdate\fP, \fBed\fP, \fBemacs\fP, \fBgrep\fP, \fBls\fP, \fBmail\fP, \fBmake\fP, \fBmv\fP, @@ -550,7 +565,7 @@ and arithmetic substitutions take the form \fB$((\fP\fIexpression\fP\fB))\fP. If a substitution appears outside of double quotes, the results of the substitution are generally subject to word or field splitting according to the current value of the \fBIFS\fP parameter. -The \fBIFS\fP parameter specifies a list of characters which +The \fBIFS\fP parameter specifies a list of characters which are used to break a string up into several words; any characters from the set space, tab and newline that appear in the IFS characters are called \fIIFS white space\fP. @@ -583,8 +598,8 @@ is carried out more efficiently because no process is started). .br .\"todo: fix this( $(..) parenthesis counting). NOTE: \fB$(\fP\fIcommand\fP\fB)\fP expressions are currently parsed by -finding the matching parenthesis, regardless of quoting. This will hopefully -be fixed soon. +finding the matching parenthesis, regardless of quoting. +This will hopefully be fixed soon. .PP Arithmetic substitutions are replaced by the value of the specified expression. @@ -601,7 +616,7 @@ letters or digits (`_' counts as a letter). The later form can be treated as arrays by appending an array index of the form: \fB[\fP\fIexpr\fP\fB]\fP where \fIexpr\fP is an arithmetic expression. -Array indicies are currently limited to the range 0 through 1023, inclusive. +Array indices are currently limited to the range 0 through 1023, inclusive. Parameter substitutions take the form \fB$\fP\fIname\fP, \fB${\fP\fIname\fP\fB}\fP or \fB${\fP\fIname\fP\fB[\fP\fIexpr\fP\fB]}\fP, where \fIname\fP is a @@ -639,7 +654,7 @@ of parameter substitution (see below). .\"{{{ environment Parameters with the export attribute (set using the \fBexport\fP or \fBtypeset \-x\fP commands, or by parameter assignments followed by simple -commands) are put in the environment (see \fIenviron\fP(5)) of commands +commands) are put in the environment (see \fIenviron\fP(7)) of commands run by the shell as \fIname\fP\fB=\fP\fIvalue\fP pairs. The order in which parameters appear in the environment of a command is unspecified. @@ -685,8 +700,8 @@ The number of elements in the array \fIname\fP. .\"{{{ ${name#pattern}, ${name##pattern} .IP "\fB${\fP\fIname\fP\fB#\fP\fIpattern\fP\fB}\fP, \fB${\fP\fIname\fP\fB##\fP\fIpattern\fP\fB}\fP" If \fIpattern\fP matches the beginning of the value of parameter \fIname\fP, -the matched text is deleted from the result of substitution. A single -\fB#\fP results in the shortest match, two \fB#\fP's results in the +the matched text is deleted from the result of substitution. +A single \fB#\fP results in the shortest match, two \fB#\fP's results in the longest match. .\"}}} .\"{{{ ${name%pattern}, ${name%%pattern} @@ -700,8 +715,8 @@ The following special parameters are implicitly set by the shell and cannot be set directly using assignments: .\"{{{ ! .IP \fB!\fP -Process id of the last background process started. If no background -processes have been started, the parameter is not set. +Process id of the last background process started. +If no background processes have been started, the parameter is not set. .\"}}} .\"{{{ # .IP \fB#\fP @@ -742,7 +757,7 @@ Further positional parameters may be accessed using .\"}}} .\"{{{ * .IP \fB*\fP -All positional parameters (except parameter 0), +All positional parameters (except parameter 0), \fIi.e.\fP, \fB$1 $2 $3\fP.... If used outside of double quotes, parameters are separate words (which are subjected to word splitting); if used within double quotes, @@ -754,7 +769,7 @@ parameters are separated by the first character of the \fBIFS\fP parameter Same as \fB$*\fP, unless it is used inside double quotes, in which case a separate word is generated for each positional parameter \- if there are no positional parameters, no word is generated ("$@" can be used -to access arguments, verbatim, without loosing null arguments or +to access arguments, verbatim, without losing null arguments or splitting arguments with spaces). .\"}}} .\"}}} @@ -775,7 +790,8 @@ the name of the file that changed (see \fBMAILPATH\fP parameter below). .\"}}} .\"{{{ CDPATH .IP \fBCDPATH\fP -Search path for the \fBcd\fP built-in command. Works the same way as +Search path for the \fBcd\fP built-in command. +Works the same way as \fBPATH\fP for those directories not beginning with \fB/\fP in \fBcd\fP commands. Note that if CDPATH is set and does not contain \fB.\fP nor an empty path, @@ -801,8 +817,8 @@ See \fBVISUAL\fP parameter below for how this works. .\"{{{ ENV .IP \fBENV\fP If this parameter is found to be set after any profile files are -executed, the expanded value is used as a shell start-up file. It -typically contains function and alias definitions. +executed, the expanded value is used as a shell start-up file. +It typically contains function and alias definitions. .\"}}} .\"{{{ ERRNO .IP \fBERRNO\fP @@ -838,7 +854,8 @@ Also, several invocations of the shell running on the same machine will share history if their \fBHISTFILE\fP parameters all point at the same file. .br -NOTE: if HISTFILE isn't set, no history file is used. This is +NOTE: if HISTFILE isn't set, no history file is used. +This is different from the original Korn shell, which uses \fB$HOME/.sh_history\fP; in future, pdksh may also use a default history file. .ksh) @@ -858,7 +875,8 @@ substituted for an unqualified \fB~\fP (see Tilde Expansion below). .IP \fBIFS\fP Internal field separator, used during substitution and by the \fBread\fP command, to split values into distinct arguments; normally set to -space, tab and newline. See Substitution above for details. +space, tab and newline. +See Substitution above for details. .br \fBNote:\fP this parameter is not imported from the environment when the shell is started. @@ -894,24 +912,27 @@ Not implemented yet. .\"{{{ MAIL .ksh( .IP \fBMAIL\fP -If set, the user will be informed of the arrival of mail in the named -file. This parameter is ignored if the \fBMAILPATH\fP parameter is set. +If set, the user will be informed of the arrival of mail in the named file. +This parameter is ignored if the \fBMAILPATH\fP parameter is set. .ksh) .\"}}} .\"{{{ MAILCHECK .ksh( .IP \fBMAILCHECK\fP How often, in seconds, the shell will check for mail in the file(s) -specified by \fBMAIL\fP or \fBMAILPATH\fP. If 0, the shell checks -before each prompt. The default is 600 (10 minutes). +specified by \fBMAIL\fP or \fBMAILPATH\fP. +If 0, the shell checks before each prompt. +The default is 600 (10 minutes). .ksh) .\"}}} .\"{{{ MAILPATH .ksh( .IP \fBMAILPATH\fP -A list of files to be checked for mail. The list is colon separated, +A list of files to be checked for mail. +The list is colon separated, and each file may be followed by a \fB?\fP and a message to be printed -if new mail has arrived. Command, parameter and arithmetic substitution is +if new mail has arrived. +Command, parameter and arithmetic substitution is performed on the message, and, during substitution, the parameter \fB$_\fP contains the name of the file. The default message is \fByou have mail in $_\fP. @@ -956,7 +977,8 @@ The process ID of the shell's parent (readonly). .ksh( Parameter, command and arithmetic substitutions are performed, and \fB!\fP is replaced with the current command number (see \fBfc\fP -command below). A literal ! can be put in the prompt by placing !! in PS1. +command below). +A literal ! can be put in the prompt by placing !! in PS1. Note that since the command line editors try to figure out how long the prompt is (so they know how far it is to edge of the screen), escape codes in the prompt tend to mess things up. @@ -999,13 +1021,14 @@ Default is `\fB+\ \fP'. .\"}}} .\"{{{ PWD .IP \fBPWD\fP -The current working directory. Maybe unset or null if shell doesn't -know where it is. +The current working directory. +Maybe unset or null if shell doesn't know where it is. .\"}}} .\"{{{ RANDOM .ksh( .IP \fBRANDOM\fP -A simple random number generator. Every time \fBRANDOM\fP is +A simple random number generator. +Every time \fBRANDOM\fP is referenced, it is assigned the next number in a random number series. The point in the series can be set by assigning a number to \fBRANDOM\fP (see \fIrand\fP(3)). @@ -1030,21 +1053,22 @@ the value that was assigned. .IP \fBTMOUT\fP If set to a positive integer in an interactive shell, it specifies the maximum number of seconds the shell will wait for input after -printing the primary prompt (\fBPS1\fP). If the time is exceeded, the -shell exits. +printing the primary prompt (\fBPS1\fP). +If the time is exceeded, the shell exits. .ksh) .\"}}} .\"{{{ TMPDIR .IP \fBTMPDIR\fP -The directory shell temporary files are created in. If this parameter -is not set, or does not contain the absolute path of a writable -directory, temporary files are created in \fB/tmp\fP. +The directory shell temporary files are created in. +If this parameter is not set, or does not contain the absolute path of a +writable directory, temporary files are created in \fB/tmp\fP. .\"}}} .\"{{{ VISUAL .ksh( .IP \fBVISUAL\fP If set, this parameter controls the command line editing mode for -interactive shells. If the last component of the path specified in this +interactive shells. +If the last component of the path specified in this parameter contains the string \fBvi\fP, \fBemacs\fP or \fBgmacs\fP, the vi, emacs or gmacs (Gosling emacs) editing mode is enabled, respectively. .ksh) @@ -1054,13 +1078,15 @@ vi, emacs or gmacs (Gosling emacs) editing mode is enabled, respectively. .\"{{{ Tilde Expansion .SS "Tilde Expansion" Tilde expansion, which is done in parallel with parameter substitution, -is done on words starting with an unquoted \fB~\fP. The characters -following the tilde, up to the first \fB/\fP, if any, are assumed to be -a login name. If the login name is empty, \fB+\fP or \fB\-\fP, the +is done on words starting with an unquoted \fB~\fP. +The characters following the tilde, up to the first \fB/\fP, if any, +are assumed to be a login name. +If the login name is empty, \fB+\fP or \fB\-\fP, the value of the \fBHOME\fP, \fBPWD\fP, or \fBOLDPWD\fP parameter is -substituted, respectively. Otherwise, the password file is searched for -the login name, and the tilde expression is substituted with the -user's home directory. If the login name is not found in the password +substituted, respectively. +Otherwise, the password file is searched for the login name, and the +tilde expression is substituted with the user's home directory. +If the login name is not found in the password file or if any quoting or parameter substitution occurs in the login name, no substitution is performed. .PP @@ -1070,7 +1096,8 @@ and \fBtypeset\fP), tilde expansion is done after any unquoted colon (\fB:\fP), and login names are also delimited by colons. .PP The home directory of previously expanded login names are cached and -re-used. The \fBalias \-d\fP command may be used to list, change and +re-used. +The \fBalias \-d\fP command may be used to list, change and add to this cache (\fIe.g.\fP, `alias \-d fac=/usr/local/facilities; cd ~fac/bin'). .\"}}} @@ -1096,34 +1123,39 @@ file name generation. .SS "File Name Patterns" .PP A file name pattern is a word containing one or more unquoted \fB?\fP or -\fB*\fP characters or \fB[\fP..\fB]\fP sequences. Once brace expansion has +\fB*\fP characters or \fB[\fP..\fB]\fP sequences. +Once brace expansion has been performed, the shell replaces file name patterns with the sorted names of all the files that match the pattern (if no files match, the word is -left unchanged). The pattern elements have the following meaning: +left unchanged). +The pattern elements have the following meaning: .IP \fB?\fP matches any single character. .IP \fB*\fP matches any sequence of characters. .IP \fB[\fP..\fB]\fP -matches any of the characters inside the brackets. Ranges of characters +matches any of the characters inside the brackets. +Ranges of characters can be specified by separating two characters by a \fB\-\fP, \fIe.g.\fP, \fB[a0\-9]\fP matches the letter \fBa\fP or any digit. In order to represent itself, a \fB\-\fP must either be quoted or the first or last character in the character -list. Similarly, a \fB]\fP must be quoted or the first character in the list -if it is represent itself instead of the end of the list. Also, a \fB!\fP +list. +Similarly, a \fB]\fP must be quoted or the first character in the list +if it is represent itself instead of the end of the list. +Also, a \fB!\fP appearing at the start of the list has special meaning (see below), so to represent itself it must be quoted or appear later in the list. .IP \fB[!\fP..\fB]\fP like \fB[\fP..\fB]\fP, except it matches any character not inside the brackets. .ksh( .IP "\fB*(\fP\fIpattern\fP\fB|\fP ... \fP|\fP\fIpattern\fP\fB)\fP" -matches any string of characters that matches zero or more occurances +matches any string of characters that matches zero or more occurrences of the specified patterns. Example: the pattern \fB*(foo|bar)\fP matches the strings `', `foo', `bar', `foobarfoo', \fIetc.\fP. .IP "\fB+(\fP\fIpattern\fP\fB|\fP ... \fP|\fP\fIpattern\fP\fB)\fP" -matches any string of characters that matches one or more occurances +matches any string of characters that matches one or more occurrences of the specified patterns. Example: the pattern \fB+(foo|bar)\fP matches the strings `foo', `bar', `foobarfoo', \fIetc.\fP. @@ -1172,7 +1204,8 @@ created when job control is disabled, for which standard input is initially set to be from \fB/dev/null\fP, and commands for which any of the following redirections have been specified: .IP "\fB>\fP \fIfile\fP" -standard output is redirected to \fIfile\fP. If \fIfile\fP does not exist, +standard output is redirected to \fIfile\fP. +If \fIfile\fP does not exist, it is created; if it does exist, is a regular file and the \fBnoclobber\fP option is set, an error occurs, otherwise the file is truncated. Note that this means the command \fIcmd < foo > foo\fP will open @@ -1183,7 +1216,8 @@ same as \fB>\fP, except the file is truncated, even if the \fBnoclobber\fP option is set. .IP "\fB>>\fP \fIfile\fP" same as \fB>\fP, except the file an existing file is appended to instead -of being truncated. Also, the file is opened in append mode, so writes +of being truncated. +Also, the file is opened in append mode, so writes always go to the end of the file (see \fIopen\fP(2)). .IP "\fB<\fP \fIfile\fP" standard input is redirected from \fIfile\fP, which is opened for reading. @@ -1305,11 +1339,12 @@ expression) - the parameter is incremented by 1. When used as a prefix operator, the result is the incremented value of the parameter, when used as a postfix operator, the result is the original value of the parameter. -.IP "\fB++\fP" -similar to \fB++\fP, except the paramter is decremented by 1. +.IP "\fB--\fP" +similar to \fB++\fP, except the parameter is decremented by 1. .IP "\fB,\fP" separates two arithmetic expressions; the left hand side is evaluated first, -then the right. The result is value of the expression on the right hand side. +then the right. +The result is value of the expression on the right hand side. .IP "\fB=\fP" assignment; variable on the left is set to the value on the right. .IP "\fB*= /= %= += \-= <<= >>= &= ^= |=\fP" @@ -1335,7 +1370,8 @@ not equal; the result is 0 if both arguments are equal, 1 if not. less than; the result is 1 if the left argument is less than the right, 0 if not. .IP "\fB<= >= >\fP" -less than or equal, greater than or equal, greater than. See <. +less than or equal, greater than or equal, greater than. +See <. .IP "\fB<< >>\fP" shift left (right); the result is the left argument with its bits shifted left (right) by the amount given in the right argument. @@ -1343,8 +1379,8 @@ left (right) by the amount given in the right argument. addition, subtraction, multiplication, and division. .IP "\fB%\fP" remainder; the result is the remainder of the division of the left argument -by the right. The sign of the result is unspecified if either argument -is negative. +by the right. +The sign of the result is unspecified if either argument is negative. .IP "\fI<arg1>\fP \fB?\fP \fI<arg2>\fP \fB:\fP \fI<arg3>\fP" if \fI<arg1>\fP is non-zero, the result is \fI<arg2>\fP, otherwise \fI<arg3>\fP. @@ -1361,7 +1397,7 @@ using \fB>&p\fP and \fB<&p\fP redirections, respectively. Once a co-process has been started, another can't be started until the co-process exits, or until the co-process input has been redirected using an \fBexec \fP\fIn\fP\fB>&p\fP redirection. -If a co-process's input is redirected in this way, the next +If a co-process's input is redirected in this way, the next co-process to be started will share the output with the first co-process, unless the output of the initial co-process has been redirected using an \fBexec \fP\fIn\fP\fB<&p\fP redirection. @@ -1382,7 +1418,7 @@ closes its copy of the pipe). This can be avoided by redirecting the output to a numbered file descriptor (as this also causes the shell to close its copy). Note that this behaviour is slightly different from the original Korn shell -which closes its copy of the write portion of the co-processs output when the +which closes its copy of the write portion of the co-processes' output when the most recently started co-process (instead of when all sharing co-processes) exits. .IP \ \ \(bu @@ -1425,7 +1461,8 @@ Functions can have two attributes, trace and export, which can be set with \fBtypeset \-ft\fP and \fBtypeset \-fx\fP, respectively. When a traced function is executed, the shell's \fBxtrace\fP option is turned on for the functions duration, otherwise the \fBxtrace\fP option is turned off. -The export attribute of functions is currently not used. In the original +The export attribute of functions is currently not used. +In the original Korn shell, exported functions are visible to shell scripts that are executed. .PP Since functions are executed in the current shell environment, parameter @@ -1449,7 +1486,7 @@ the \fB()\fP notation: the \fB$0\fP parameter is set to the name of the function (Bourne-style functions leave \fB$0\fP untouched). .IP \ \ \(bu -parameter assignments preceeding function calls are not kept in +parameter assignments preceding function calls are not kept in the shell environment (executing Bourne-style functions will keep assignments). .IP \ \ \(bu @@ -1498,8 +1535,10 @@ is not expanded and included when the shell starts. \fB\e"\fP inside double quoted \fB`\fP..\fB`\fP command substitutions: in posix mode, the \fB\e"\fP is interpreted when the command is interpreted; in non-posix mode, the backslash is stripped before the command substitution -is interpreted. For example, \fBecho "`echo \e"hi\e"`"\fP produces `"hi"' in -posix mode, `hi' in non-posix mode. To avoid problems, use the \fB$(...\fP) +is interpreted. +For example, \fBecho "`echo \e"hi\e"`"\fP produces `"hi"' in +posix mode, `hi' in non-posix mode. +To avoid problems, use the \fB$(...\fP) form of command substitution. .IP \ \ \(bu \fBkill \-l\fP output: in posix mode, signal names are listed one a single line; @@ -1533,7 +1572,8 @@ explicitly turned on later. if there are no errors; in non-posix mode, the exit status is that of any command substitutions performed in generating the set command. For example, `\fBset \-\- `false`; echo $?\fP' prints 0 in posix mode, -1 in non-posix mode. This construct is used in most shell scripts that +1 in non-posix mode. +This construct is used in most shell scripts that use the old \fIgetopt\fP(1) command. .IP \ \ \(bu argument expansion of \fBalias\fP, \fBexport\fP, \fBreadonly\fP, and @@ -1572,7 +1612,7 @@ assignments, the type of command is determined: a special built-in, a function, a regular built-in or the name of a file to execute found using the \fBPATH\fP parameter. The checks are made in the above order. -Special built-in commands differ from other commands in that +Special built-in commands differ from other commands in that the \fBPATH\fP parameter is not used to find them, an error during their execution can cause a non-interactive shell to exit and parameter assignments that are specified before the command are @@ -1580,7 +1620,7 @@ kept after the command completes. Just to confuse things, if the posix option is turned off (see \fBset\fP command below) some special commands are very special in that no field splitting, file globing, brace expansion nor tilde expansion -is preformed on arguments that look like assignments. +is performed on arguments that look like assignments. Regular built-in commands are different only in that the \fBPATH\fP parameter is not used to find them. .PP @@ -1596,12 +1636,12 @@ break exec readonly shift .IP "Additional ksh special commands" .TS lw(8m)fB lw(8m)fB lw(8m)fB lw(8m)fB lw(8m)fB . -builtin times typeset +builtin times typeset .TE .IP "Very special commands (non-posix mode)" .TS lw(8m)fB lw(8m)fB lw(8m)fB lw(8m)fB lw(8m)fB . -alias readonly set typeset +alias readonly set typeset .TE .IP "POSIX regular commands" .TS @@ -1613,8 +1653,8 @@ cd fc jobs true wait .IP "Additional ksh regular commands" .TS lw(8m)fB lw(8m)fB lw(8m)fB lw(8m)fB lw(8m)fB . -[ let pwd ulimit -echo print test whence +[ let pwd ulimit +echo print test whence .TE .PP In the future, the additional ksh special and regular commands may @@ -1644,9 +1684,9 @@ Without arguments, \fBalias\fP lists all aliases. For any name without a value, the existing alias is listed. Any name with a value defines an alias (see Aliases above). .sp -When listing aliases, one of two formats is used: +When listing aliases, one of two formats is used: normally, aliases are listed as \fIname\fP\fB=\fP\fIvalue\fP, where -\fIvalue\fP is quoted; if options were preceded with \fB+\fP +\fIvalue\fP is quoted; if options were preceded with \fB+\fP or a lone \fB+\fP is given on the command line, only \fIname\fP is printed. In addition, if the \fB\-p\fP option is used, each alias @@ -1687,14 +1727,15 @@ Execute the built-in command \fIcommand\fP. .\"}}} .\"{{{ cd [-LP] [dir] .IP "\fBcd\fP [\fB\-LP\fP] [\fIdir\fP]" -Set the working directory to \fIdir\fP. If the parameter \fBCDPATH\fP +Set the working directory to \fIdir\fP. +If the parameter \fBCDPATH\fP is set, it lists directories to search in for \fIdir\fP. -\fIdir\fP. An empty entry in the \fBCDPATH\fP entry means the current -directory. +An empty entry in the \fBCDPATH\fP entry means the current directory. If a non-empty directory from \fBCDPATH\fP is used, the resulting full path is printed to standard output. If \fIdir\fP is -missing, the home directory \fB$HOME\fP is used. If \fIdir\fP is +missing, the home directory \fB$HOME\fP is used. +If \fIdir\fP is \fB\-\fP, the previous working directory is used (see OLDPWD parameter). If \fB\-L\fP option (logical path) is used or if the \fBphysical\fP option (see \fBset\fP command below) isn't set, references to \fB..\fP in \fIdir\fP @@ -1739,7 +1780,7 @@ their names are simply printed, for aliases, a command that defines them is printed, and for commands found by searching the \fBPATH\fP parameter, the full path of the command is printed. -If no command is be found, (\fIi.e.\fP, the path search fails), nothing +If no command is found, (\fIi.e.\fP, the path search fails), nothing is printed and \fBcommand\fP exits with a non-zero status. The \fB\-V\fP option is like the \fB\-v\fP option, except it is more verbose. .ksh) @@ -1761,7 +1802,7 @@ that are recognized. .sp The options are provided for compatibility with BSD shell scripts: \fB\-n\fP suppresses the trailing newline, \fB\-e\fP enables backslash -interpretation (a no-op, since this is normally done), and \fB\-E\fP which +interpretation (a no-op, since this is normally done), and \fB\-E\fP suppresses backslash interpretation. .\"}}} .\"{{{ eval command ... @@ -1818,9 +1859,11 @@ A command that exits with a non-zero status. \fIfirst\fP and \fIlast\fP select commands from the history. Commands can be selected by history number, or a string specifying the most recent command starting -with that string. The \fB\-l\fP option lists the command on stdout, -and \fB\-n\fP inhibits the default command numbers. The \fB\-r\fP -option reverses the order of the list. Without \fB\-l\fP, the selected +with that string. +The \fB\-l\fP option lists the command on stdout, +and \fB\-n\fP inhibits the default command numbers. +The \fB\-r\fP option reverses the order of the list. +Without \fB\-l\fP, the selected commands are edited by the editor specified with the \fB\-e\fP option, or if no \fB\-e\fP is specified, the editor specified by the \fBFCEDIT\fP parameter (if this parameter is not set, \fB/bin/ed\fP is used), @@ -1830,9 +1873,10 @@ and then executed by the shell. .\"{{{ fc [-e - | -s] [-g] [old=new] [prefix] .IP "\fBfc\fP [\fB\-e \-\fP | \fB\-s\fP] [\fB\-g\fP] [\fIold\fP\fB=\fP\fInew\fP] [\fIprefix\fP]" Re-execute the selected command (the previous command by default) after -performing the optional substitution of \fIold\fP with \fInew\fP. If -\fB\-g\fP is specified, all occurrences of \fIold\fP are replaced with -\fInew\fP. This command is usually accessed with the predefined alias +performing the optional substitution of \fIold\fP with \fInew\fP. +If \fB\-g\fP is specified, all occurrences of \fIold\fP are replaced with +\fInew\fP. +This command is usually accessed with the predefined alias \fBr='fc \-e \-'\fP. .\"}}} .\"{{{ fg [job ...] @@ -1848,8 +1892,8 @@ See Job Control below for more information. (or positional parameters, if no arguments are given) and to check for legal options. \fIoptstring\fP contains the option letters that -\fBgetopts\fP is to recognize. If a letter is followed by a colon, the -option is expected to have an argument. +\fBgetopts\fP is to recognize. +If a letter is followed by a colon, the option is expected to have an argument. Options that do not take arguments may be grouped in a single argument. If an option takes an argument and the option character is not the last character of the argument it is found in, the remainder of the argument @@ -1872,7 +1916,7 @@ does not begin with a colon. .sp When the end of the options is encountered, \fBgetopts\fP exits with a non-zero exit status. -Options end at the first (non-option argument) argument that does not +Options end at the first (non-option) argument that does not start with a \-, or when a \fB\-\-\fP argument is encountered. .sp Option parsing can be reset by setting \fBOPTIND\fP to 1 (this is done @@ -1931,12 +1975,13 @@ quoted, \fB((\fP \fIexpr\fP \fB))\fP is syntactic sugar for \fBlet .\"{{{ print [-nprsun | -R [-en]] [argument ...] .IP "\fBprint\fP [\fB\-nprsu\fP\fIn\fP | \fB\-R\fP [\fB\-en\fP]] [\fIargument ...\fP]" \fBPrint\fP prints its arguments on the standard output, separated by -spaces, and terminated with a newline. The \fB\-n\fP option suppresses -the newline. By default, certain C escapes are translated. These -include \eb, \ef, \en, \er, \et, \ev, and \e0### (# is an octal digit, of -which there may be 0 to 3). -\ec is equivalent to using the \fB\-n\fP option. \e expansion may be -inhibited with the \fB\-r\fP option. +spaces, and terminated with a newline. +The \fB\-n\fP option suppresses the newline. +By default, certain C escapes are translated. +These include \eb, \ef, \en, \er, \et, \ev, and \e0### (# is an octal digit, +of which there may be 0 to 3). +\ec is equivalent to using the \fB\-n\fP option. +\e expansion may be inhibited with the \fB\-r\fP option. The \fB\-s\fP option prints to the history file instead of standard output, the \fB\-u\fP option prints to file descriptor \fIn\fP (\fIn\fP defaults to 1 if omitted), and the \fB\-p\fP option prints to the co-process @@ -1982,7 +2027,8 @@ If the \fB\-s\fP option is used, input is saved to the history file. .\"}}} .\"{{{ readonly [-p] [parameter[=value] ...] .IP "\fBreadonly\fP [\fB\-p\fP] [\fIparameter\fP[\fB=\fP\fIvalue\fP]] ..." -Sets the readonly attribute of the named parameters. If values are given, +Sets the readonly attribute of the named parameters. +If values are given, parameters are set to them before setting the attribute. Once a parameter is made readonly, it cannot be unset and its value cannot be changed. @@ -2067,14 +2113,14 @@ Do not execute any commands \- useful for checking the syntax of scripts (ignored if interactive). T} \-p privileged T{ -Set automatically if, when the shell starts, the read uid or gid does not +Set automatically if, when the shell starts, the real uid or gid does not match the effective uid or gid, respectively. -See Shell Startup above for a description of what this -means. +See Shell Startup above for a description of what this means. T} -r restricted T{ Enable restricted mode \(em this option can only be used when the shell is -invoked. See Shell Startup above for a description of what this +invoked. +See Shell Startup above for a description of what this means. T} \-s stdin T{ @@ -2112,6 +2158,12 @@ T} Enable BRL emacs-like command line editing (interactive shells only); see Emacs Editing Mode. T} + emacs-usemeta T{ +In emacs command-line editing, use the 8th bit +as meta (^[) prefix. This is the default if +LC_CTYPE is unset or POSIX respectively C. +8 +T} gmacs T{ Enable gmacs-like (Gosling emacs) command line editing (interactive shells only); @@ -2139,14 +2191,16 @@ T} Causes the \fBcd\fP and \fBpwd\fP commands to use `physical' (\fIi.e.\fP, the filesystem's) \fB..\fP directories instead of `logical' directories (\fIi.e.\fP, the shell handles \fB..\fP, which allows the user -to be obliveous of symlink links to directories). -Clear by default. Note that setting +to be oblivious of symlink links to directories). +Clear by default. +Note that setting this option does not effect the current value of the \fBPWD\fP parameter; only the \fBcd\fP command changes \fBPWD\fP. See the \fBcd\fP and \fBpwd\fP commands above for more details. T} posix T{ -Enable posix mode. See POSIX Mode above. +Enable posix mode. +See POSIX Mode above. T} vi T{ Enable vi-like command line editing (interactive shells only). @@ -2167,12 +2221,12 @@ If this option is not set, characters in the range T} vi-tabcomplete T{ In vi command line editing, do command / file name completion when -tab (^I) is entered in insert mode. +tab (^I) is entered in insert mode. This is the default. T} .TE .sp -These options can also be used upon invocation of the shell. The current -set of options (with single letter names) can be found in the +These options can also be used upon invocation of the shell. +The current set of options (with single letter names) can be found in the parameter \fB\-\fP. \fBset -o\fP with no option name will list all the options and whether each is on or off; \fBset +o\fP will print the long names of all options that @@ -2197,20 +2251,20 @@ renamed to \fB1\fP, \fB2\fP, \fIetc.\fP .IP "\fBtest\fP \fIexpression\fP" .IP "\fB[\fP \fIexpression\fP \fB]\fP" \fBtest\fP evaluates the \fIexpression\fP and returns zero status if -true, and 1 status if false and greater than 1 if there was an error. +true, 1 if false, and greater than 1 if there was an error. It is normally used as the condition command of \fBif\fP and \fBwhile\fP statements. The following basic expressions are available: .sp .TS -afB ltw(2.8i). +afB ltw(3.2i). \fIstr\fP T{ -\fIstr\fP has non-zero length. Note that there is the potential +\fIstr\fP has non-zero length. +Note that there is the potential for problems if \fIstr\fP turns out to be an operator (\fIe.g.\fP, \fB-r\fP) - it is generally better to use a test like -.RS +.ce \fB[ X"\fP\fIstr\fP\fB" != X ]\fP -.RE instead (double quotes are used in case \fIstr\fP contains spaces or file globing characters). T} @@ -2278,17 +2332,16 @@ T} shell \fIoption\fP is set (see \fBset\fP command above for list of options). As a non-standard extension, if the option starts with a \fB!\fP, the test is negated; the test always fails if option doesn't exist (thus -.RS +.ce \fB[ -o \fP\fIfoo\fP \fB-o -o !\fP\fIfoo\fP \fB]\fP -.RE returns true if and only if option \fIfoo\fP exists). T} \fIfile\fP \-nt \fIfile\fP T{ -first \fIfile\fP is newer than second \fIfile\fP or first +first \fIfile\fP is newer than second \fIfile\fP or first \fIfile\fP exists and the second \fIfile\fP does not. T} \fIfile\fP \-ot \fIfile\fP T{ -first \fIfile\fP is older than second \fIfile\fP or second \fIfile\fP +first \fIfile\fP is older than second \fIfile\fP or second \fIfile\fP exists and the first \fIfile\fP does not. T} \fIfile\fP \-ef \fIfile\fP T{ @@ -2371,7 +2424,8 @@ operator, including an unstripped \fB!\fP). \fBNote:\fP A common mistake is to use \fBif [ $foo = bar ]\fP which fails if parameter \fBfoo\fP is null or unset, if it has embedded spaces (\fIi.e.\fP, \fBIFS\fP characters), or if it is a unary operator like \fB!\fP or -\fB\-n\fP. Use tests like \fBif [ "X$foo" = Xbar ]\fP instead. +\fB\-n\fP. +Use tests like \fBif [ "X$foo" = Xbar ]\fP instead. .\"}}} .\"{{{ time [-p] [pipeline] .IP "\fBtime\fP [\fB-p\fP] [ \fIpipeline\fP ]" @@ -2380,8 +2434,8 @@ If no pipeline is given, then the user and system time used by the shell itself, and all the commands it has run since it was started, are reported. The times reported are the real time (elapsed time from start to finish), -the user cpu time (time spent running in user mode) -and the system cpu time (time spent running in kernel mode). +the user CPU time (time spent running in user mode) +and the system CPU time (time spent running in kernel mode). Times are reported to standard error; the format of the output is: .nf 0.00s real 0.00s user 0.00s system @@ -2414,7 +2468,7 @@ Sets trap handler that is to be executed when any of the specified signals are received. \fBHandler\fP is either a null string, indicating the signals are to be ignored, a minus (\fB\-\fP), indicating that the default action is to -be taken for the signals (see signal(2 or 3)), or a string containing shell +be taken for the signals (see signal(3)), or a string containing shell commands to be evaluated and executed at the first opportunity (\fIi.e.\fP, when the current command completes, or before printing the next \fBPS1\fP prompt) after receipt of one of the signals. @@ -2512,7 +2566,7 @@ T} \-p T{ Print complete typeset commands that can be used to re-create the attributes (but not the values) of parameters. -This is the default action (option exists for ksh93 compatability). +This is the default action (option exists for ksh93 compatibility). T} \-r T{ Readonly attribute: parameters with the this attribute may not be assigned to @@ -2530,19 +2584,21 @@ Upper case attribute: all lower case characters in values are converted to upper case. (In the original Korn shell, this parameter meant `unsigned integer' when used with the \fB\-i\fP option, which meant upper case letters would never be used -for bases greater than 10. See the \fB\-U\fP option). +for bases greater than 10. +See the \fB\-U\fP option). .sp -For functions, \fB\-u\fP is the undefined attribute. See Functions above -for the implications of this. +For functions, \fB\-u\fP is the undefined attribute. +See Functions above for the implications of this. T} \-x T{ Export attribute: parameters (or functions) are placed in the environment of -any executed commands. Exported functions are not implemented yet. +any executed commands. +Exported functions are not implemented yet. T} .TE .\"}}} -.\"{{{ ulimit [-acdfHlmnpsStvw] [value] -.IP "\fBulimit\fP [\fB\-acdfHlmnpsStvw\fP] [\fIvalue\fP]" +.\"{{{ ulimit [-abcdfHlmnpsStvw] [value] +.IP "\fBulimit\fP [\fB\-abcdfHlmnpsStvw\fP] [\fIvalue\fP]" Display or set process limits. If no options are used, the file size limit (\fB\-f\fP) is assumed. \fBvalue\fP, if specified, may be either be an arithmetic expression or the @@ -2560,6 +2616,8 @@ Displays all limits; unless \fB\-H\fP is used, soft limits are displayed. Set the hard limit only (default is to set both hard and soft limits). .IP \fB\-S\fP Set the soft limit only (default is to set both hard and soft limits). +.IP \fB\-b\fP +Impose a size limit of \fIn\fP bytes on the size of socket buffers. .IP \fB\-c\fP Impose a size limit of \fIn\fP blocks on the size of core dumps. .IP \fB\-d\fP @@ -2580,7 +2638,7 @@ time. .IP \fB\-s\fP Impose a size limit of \fIn\fP kbytes on the size of the stack area. .IP \fB\-t\fP -Impose a time limit of \fIn\fP cpu seconds to be used by each process. +Impose a time limit of \fIn\fP CPU seconds to be used by each process. .IP \fB\-v\fP Impose a limit of \fIn\fP kbytes on the amount of virtual memory used; on some systems this is the maximum allowable virtual address (in bytes, @@ -2767,7 +2825,8 @@ the job has neither stopped or exited (note that running does not necessarily mean consuming CPU time \(em the process could be blocked waiting for some event). .IP "\fBDone\fP [\fB(\fP\fInumber\fP\fB)\fP]" -the job exited. \fInumber\fP is the exit status of the job, which is +the job exited. +\fInumber\fP is the exit status of the job, which is omitted if the status is zero. .IP "\fBStopped\fP [\fB(\fP\fIsignal\fP\fB)\fP]" the job was stopped by the indicated \fIsignal\fP (if no signal is given, @@ -2801,7 +2860,7 @@ jobs are sent a \fBHUP\fP signal and the shell exits. .SS "Interactive Input Line Editing" The shell supports three modes of reading command lines from a tty in an interactive session. -Which is used is controlled by the \fBemacs\fP, \fBgmacs\fP and \fBvi\fP +Which is used is controlled by the \fBemacs\fP, \fBgmacs\fP and \fBvi\fP \fBset\fP options (at most one of these can be set at once). If none of these options is enabled, the shell simply reads lines using the normal tty driver. @@ -2822,11 +2881,13 @@ The line is scrolled horizontally as necessary. .\"{{{ Emacs Editing Mode .SS "Emacs Editing Mode" When the \fBemacs\fP option is set, interactive input line editing is -enabled. \fBWarning\fP: This mode is slightly different from the emacs +enabled. +\fBWarning\fP: This mode is slightly different from the emacs mode in the original Korn shell and the 8th bit is stripped in emacs mode. In this mode various editing commands (typically bound to one or more control characters) cause immediate actions without waiting for a -new-line. Several editing commands are bound to particular control +new-line. +Several editing commands are bound to particular control characters when the shell is invoked; these bindings can be changed using the following commands: .\"{{{ bind @@ -2838,12 +2899,15 @@ The current bindings are listed. The specified editing command is bound to the given \fBstring\fP, which should consist of a control character (which may be written using caret notation \fB^\fP\fIX\fP), optionally preceded by one of the two prefix -characters. Future input of the \fIstring\fP will cause the editing -command to be immediately invoked. Note that although only two prefix +characters. +Future input of the \fIstring\fP will cause the editing +command to be immediately invoked. +Note that although only two prefix characters (usually ESC and ^X) are supported, some multi-character -sequences can be supported. The following binds the arrow keys on -an ANSI terminal, or xterm (these are in the default bindings). Of course -some escape sequences won't work out quite this nicely: +sequences can be supported. +The following binds the arrow keys on +an ANSI terminal, or xterm (these are in the default bindings). +Of course some escape sequences won't work out quite this nicely: .sp .RS \fBbind '^[['=prefix\-2 @@ -2877,10 +2941,12 @@ A count prefix for a command is entered using the sequence \fB^[\fP\fIn\fP, where \fIn\fP is a sequence of 1 or more digits; unless otherwise specified, if a count is omitted, it defaults to 1. Note that editing command names are -used only with the \fBbind\fP command. Furthermore, many editing -commands are useful only on terminals with a visible cursor. The -default bindings were chosen to resemble corresponding EMACS key -bindings. The users tty characters (\fIe.g.\fP, ERASE) are bound to +used only with the \fBbind\fP command. +Furthermore, many editing +commands are useful only on terminals with a visible cursor. +The default bindings were chosen to resemble corresponding EMACS key +bindings. +The users tty characters (\fIe.g.\fP, ERASE) are bound to reasonable substitutes and override the default bindings. .\"{{{ abort ^G .IP "\fBabort ^G\fP" @@ -2889,8 +2955,8 @@ order to abort the search. .\"}}} .\"{{{ auto-insert n .IP "\fBauto-insert\fP \fIn\fP" -Simply causes the character to appear as literal input. Most ordinary -characters are bound to this. +Simply causes the character to appear as literal input. +Most ordinary characters are bound to this. .\"}}} .\"{{{ backward-char n ^B .IP "\fBbackward-char\fP \fIn\fP \fB^B\fP" @@ -2922,11 +2988,13 @@ are removed and the cursor is placed at the beginning of the line. .\"}}} .\"{{{ complete ^[^[ .IP "\fBcomplete ^[^[\fP" +.IP "\fBcomplete ^I\fP" Automatically completes as much as is unique of the command name -or the file name containing the cursor. If the entire remaining command +or the file name containing the cursor. +If the entire remaining command or file name is unique a space is printed after its completion, unless -it is a directory name in which case \fB/\fP is appended. If there is -no command or file name with the current partial word as its +it is a directory name in which case \fB/\fP is appended. +If there is no command or file name with the current partial word as its prefix, a bell character is output (usually causing a audio beep). .\"}}} .\"{{{ complete-command ^X^[ @@ -2963,7 +3031,8 @@ Deletes characters after the cursor up to the end of \fIn\fP words. .\"}}} .\"{{{ down-history n ^N .IP "\fBdown-history\fP \fIn\fP \fB^N\fP" -Scrolls the history buffer forward \fIn\fP lines (later). Each input line +Scrolls the history buffer forward \fIn\fP lines (later). +Each input line originally starts just after the last entry in the history buffer, so \fBdown-history\fP is not useful until either \fBsearch-history\fP or \fBup-history\fP has been performed. @@ -3044,19 +3113,20 @@ can complete the partial word containing the cursor. .\"{{{ list-file ^X^Y .IP "\fBlist-file ^X^Y\fP" Prints a sorted, columnated list of file names (if any) that can -complete the partial word containing the cursor. File type indicators +complete the partial word containing the cursor. +File type indicators are appended as described under \fBlist\fP above. .\"}}} .\"{{{ newline ^J and ^M .IP "\fBnewline ^J\fP, \fB^M\fP" -Causes the current input line to be processed by the shell. The -current cursor position may be anywhere on the line. +Causes the current input line to be processed by the shell. +The current cursor position may be anywhere on the line. .\"}}} .\"{{{ newline-and-next ^O .IP "\fBnewline-and-next ^O\fP" Causes the current input line to be processed by the shell, and -the next line from history becomes the current line. This is -only useful after an up-history or search-history. +the next line from history becomes the current line. +This is only useful after an up-history or search-history. .\"}}} .\"{{{ no-op QUIT .IP "\fBno-op QUIT\fP" @@ -3086,22 +3156,25 @@ Reprints the prompt string and the current input line. .\"}}} .\"{{{ search-character-backward n ^[^] .IP "\fBsearch-character-backward\fP \fIn\fP \fB^[^]\fP" -Search backward in the current line for the \fIn\fPth occurance of the +Search backward in the current line for the \fIn\fPth occurrence of the next character typed. .\"}}} .\"{{{ search-character-forward n ^] .IP "\fBsearch-character-forward\fP \fIn\fP \fB^]\fP" -Search forward in the current line for the \fIn\fPth occurance of the +Search forward in the current line for the \fIn\fPth occurrence of the next character typed. .\"}}} .\"{{{ search-history ^R .IP "\fBsearch-history ^R\fP" -Enter incremental search mode. The internal history list is searched -backwards for commands matching the input. An initial \fB^\fP in the -search string anchors the search. The abort key will leave search mode. -Other commands will be executed after leaving search mode. Successive -\fBsearch-history\fP commands continue searching backward to the next -previous occurrence of the pattern. The history buffer retains only a +Enter incremental search mode. +The internal history list is searched +backwards for commands matching the input. +An initial \fB^\fP in the search string anchors the search. +The abort key will leave search mode. +Other commands will be executed after leaving search mode. +Successive \fBsearch-history\fP commands continue searching backward to +the next previous occurrence of the pattern. +The history buffer retains only a finite number of lines; the oldest are discarded as necessary. .\"}}} .\"{{{ set-mark-command ^[<space> @@ -3112,8 +3185,8 @@ Set the mark at the cursor position. .IP "\fBstuff\fP" On systems supporting it, pushes the bound character back onto the terminal input where it may receive special processing by the terminal -handler. This is useful for the BRL \fB^T\fP mini-systat feature, for -example. +handler. +This is useful for the BRL \fB^T\fP mini-systat feature, for example. .\"}}} .\"{{{ stuff-reset .IP "\fBstuff-reset\fP" @@ -3121,7 +3194,7 @@ Acts like \fBstuff\fP, then aborts input the same as an interrupt. .\"}}} .\"{{{ transport-chars ^T .IP "\fBtranspose-chars ^T\fP" -If at the end of line, or if the \fBgmacs\fP option is set, +If at the end of line, or if the \fBgmacs\fP option is set, this exchanges the two previous characters; otherwise, it exchanges the previous and current characters and moves the cursor one character to the right. @@ -3136,7 +3209,8 @@ Uppercases the next \fIn\fP words. .\"}}} .\"{{{ version ^V .IP "\fBversion ^V\fP" -Display the version of ksh. The current edit buffer is restored as soon +Display the version of ksh. +The current edit buffer is restored as soon as any key is pressed (the key is then processed, unless it is a space). .\"}}} .\"{{{ yank ^Y @@ -3249,10 +3323,10 @@ specified, the last word is inserted. insert the comment character (\fB#\fP) at the start of the current line and return the line to the shell (equivalent to \fBI#^J\fP). .IP "\fIn\fP\fBg\fP" -like \fBG\fP, except if \fIn\fP is not specified, it goes to the most recent +like \fBG\fP, except if \fIn\fP is not specified, it goes to the most recent remembered line. .IP "\fIn\fP\fBv\fP" -edit line \fIn\fP using the vi editor; +edit line \fIn\fP using the vi editor; if \fIn\fP is not specified, the current line is edited. The actual command executed is `\fBfc \-e ${VISUAL:-${EDITOR:-vi}}\fP \fIn\fP'. @@ -3272,7 +3346,7 @@ current directory. After expansion, the cursor is placed just past the last word and the editor is in insert mode. .IP "\fIn\fP\fB\e\fP, \fIn\fP\fB^F\fP, \fIn\fP\fB<tab>\fP and \fIn\fP\fB<esc>\fP" -command/file name completion: +command/file name completion: replace the current big-word with the longest unique match obtained after performing command/file name expansion. \fB<tab>\fP is only recognized if the \fBvi-tabcomplete\fP option is set, @@ -3348,7 +3422,7 @@ move to the \fIn\fPth previous line in the history. move to line \fIn\fP in the history; if \fIn\fP is not specified, the number first remembered line is used. .IP "\fIn\fP\fBg\fP" -like \fBG\fP, except if \fIn\fP is not specified, it goes to the most recent +like \fBG\fP, except if \fIn\fP is not specified, it goes to the most recent remembered line. .IP "\fIn\fP\fB/\fP\fIstring\fP" search backward through the history for the \fIn\fPth line containing @@ -3412,8 +3486,8 @@ the current line is deleted. replace the next \fIn\fP characters with the character \fIc\fP. .IP "\fIn\fP\fBR\fP" replace: enter insert mode but overwrite existing characters instead of -inserting before existing characters. The replacement is repeated \fIn\fP -times. +inserting before existing characters. +The replacement is repeated \fIn\fP times. .IP "\fIn\fP\fB~\fP" change the case of the next \fIn\fP characters. .IP "\fIn\fP\fBy\fP\fImove-cmd\fP" @@ -3449,7 +3523,7 @@ be deleted and a new prompt to be printed. .\"Has all vi commands except: .\" movement: { } [[ ]] ^E ^Y ^U ^D ^F ^B H L M () .\" tag commands: ^T ^] -.\" mark commands: m ` ' +.\" mark commands: m ` ' .\" named-buffer commands: " @ .\" file/shell/ex-commands: Q ZZ ^^ : ! & .\" multi-line change commands: o O J @@ -3463,6 +3537,8 @@ be deleted and a new prompt to be printed. .\"}}} .\"{{{ Files .SH FILES +~/.kshrc +.br ~/.profile .br /etc/profile @@ -3471,14 +3547,17 @@ be deleted and a new prompt to be printed. .\"}}} .\"{{{ Bugs .SH BUGS -Any bugs in pdksh should be reported to pdksh@cs.mun.ca. Please +Any bugs in pdksh should be reported to pdksh@cs.mun.ca. +Please include the version of pdksh (echo $KSH_VERSION shows it), the machine, operating system and compiler you are using and a description of how to repeat the bug (a small shell script that demonstrates the bug is -best). The following, if relevant (if you are not sure, include them), +best). +The following, if relevant (if you are not sure, include them), can also helpful: options you are using (both options.h options and set \-o options) and a copy of your config.h (the file generated by the -configure script). New versions of pdksh can be obtained from +configure script). +New versions of pdksh can be obtained from ftp://ftp.cs.mun.ca/pub/pdksh/. .PP BTW, the most frequently reported bug is @@ -3498,17 +3577,18 @@ of the public domain korn shell. .SH AUTHORS This shell is based on the public domain 7th edition Bourne shell clone by Charles Forsyth and parts of the BRL shell by Doug A.\& Gwyn, Doug Kingston, -Ron Natalie, Arnold Robbins, Lou Salkind and others. The first release +Ron Natalie, Arnold Robbins, Lou Salkind and others. +The first release of pdksh was created by Eric Gisin, and it was subsequently maintained by John R.\& MacMillan (chance!john@sq.sq.com), and -Simon J.\& Gerraty (sjg@zen.void.oz.au). The current maintainer is -Michael Rendell (michael@cs.mun.ca). +Simon J.\& Gerraty (sjg@zen.void.oz.au). +The current maintainer is Michael Rendell (michael@cs.mun.ca). The CONTRIBUTORS file in the source distribution contains a more complete list of people and their part in the shell's development. .\"}}} .\"{{{ See also .SH "SEE ALSO" -awk(1), +awk(1), .ksh( sh(1), .ksh) @@ -3518,7 +3598,7 @@ ksh(1), csh(1), ed(1), getconf(1), getopt(1), sed(1), stty(1), vi(1), dup(2), execve(2), getgid(2), getuid(2), open(2), pipe(2), wait(2), getopt(3), rand(3), signal(3), system(3), -environ(5) +environ(7) .PP .IR "The KornShell Command and Programming Language" , Morris Bolsky and David Korn, 1989, ISBN 0-13-516972-0. diff --git a/shells/pdksh/files/ksh_dir.h b/shells/pdksh/files/ksh_dir.h index f08be16c790..5f5acb4bc94 100644 --- a/shells/pdksh/files/ksh_dir.h +++ b/shells/pdksh/files/ksh_dir.h @@ -1,5 +1,7 @@ +/* $NetBSD: ksh_dir.h,v 1.2 2008/05/31 16:47:36 tnn Exp $ */ + /* Wrapper around the ugly dir includes/ifdefs */ -/* $Id: ksh_dir.h,v 1.1.1.1 2008/05/23 17:15:20 tnn Exp $ */ +/* $NetBSD: ksh_dir.h,v 1.2 2008/05/31 16:47:36 tnn Exp $ */ #if defined(HAVE_DIRENT_H) # include <dirent.h> diff --git a/shells/pdksh/files/ksh_limval.h b/shells/pdksh/files/ksh_limval.h index 77219f04a17..1e9189b4ac7 100644 --- a/shells/pdksh/files/ksh_limval.h +++ b/shells/pdksh/files/ksh_limval.h @@ -1,5 +1,7 @@ +/* $NetBSD: ksh_limval.h,v 1.2 2008/05/31 16:47:36 tnn Exp $ */ + /* Wrapper around the values.h/limits.h includes/ifdefs */ -/* $Id: ksh_limval.h,v 1.1.1.1 2008/05/23 17:15:20 tnn Exp $ */ +/* $NetBSD: ksh_limval.h,v 1.2 2008/05/31 16:47:36 tnn Exp $ */ #ifdef HAVE_VALUES_H # include <values.h> diff --git a/shells/pdksh/files/ksh_stat.h b/shells/pdksh/files/ksh_stat.h index 77eb5f924d2..3fd8021db25 100644 --- a/shells/pdksh/files/ksh_stat.h +++ b/shells/pdksh/files/ksh_stat.h @@ -1,5 +1,7 @@ +/* $NetBSD: ksh_stat.h,v 1.2 2008/05/31 16:47:36 tnn Exp $ */ + /* Wrapper around the ugly sys/stat includes/ifdefs */ -/* $Id: ksh_stat.h,v 1.1.1.1 2008/05/23 17:15:20 tnn Exp $ */ +/* $NetBSD: ksh_stat.h,v 1.2 2008/05/31 16:47:36 tnn Exp $ */ /* assumes <sys/types.h> already included */ #include <sys/stat.h> diff --git a/shells/pdksh/files/ksh_time.h b/shells/pdksh/files/ksh_time.h index 9f5e63b13ba..19d60ceebd9 100644 --- a/shells/pdksh/files/ksh_time.h +++ b/shells/pdksh/files/ksh_time.h @@ -1,8 +1,10 @@ +/* $NetBSD: ksh_time.h,v 1.2 2008/05/31 16:47:36 tnn Exp $ */ + #ifndef KSH_TIME_H # define KSH_TIME_H /* Wrapper around the ugly time.h,sys/time.h includes/ifdefs */ -/* $Id: ksh_time.h,v 1.1.1.1 2008/05/23 17:15:20 tnn Exp $ */ +/* $NetBSD: ksh_time.h,v 1.2 2008/05/31 16:47:36 tnn Exp $ */ #ifdef TIME_WITH_SYS_TIME # include <sys/time.h> diff --git a/shells/pdksh/files/ksh_times.h b/shells/pdksh/files/ksh_times.h index 7a38b2bc8a7..f1686171812 100644 --- a/shells/pdksh/files/ksh_times.h +++ b/shells/pdksh/files/ksh_times.h @@ -1,3 +1,5 @@ +/* $NetBSD: ksh_times.h,v 1.2 2008/05/31 16:47:36 tnn Exp $ */ + #ifndef KSH_TIMES_H # define KSH_TIMES_H diff --git a/shells/pdksh/files/ksh_wait.h b/shells/pdksh/files/ksh_wait.h index 5676fb2b5d4..0a94d1b1111 100644 --- a/shells/pdksh/files/ksh_wait.h +++ b/shells/pdksh/files/ksh_wait.h @@ -1,5 +1,7 @@ +/* $NetBSD: ksh_wait.h,v 1.2 2008/05/31 16:47:37 tnn Exp $ */ + /* Wrapper around the ugly sys/wait includes/ifdefs */ -/* $Id: ksh_wait.h,v 1.1.1.1 2008/05/23 17:15:20 tnn Exp $ */ +/* $NetBSD: ksh_wait.h,v 1.2 2008/05/31 16:47:37 tnn Exp $ */ #ifdef HAVE_SYS_WAIT_H # include <sys/wait.h> diff --git a/shells/pdksh/files/lex.c b/shells/pdksh/files/lex.c index df840e872a6..4d9fbc8d1a9 100644 --- a/shells/pdksh/files/lex.c +++ b/shells/pdksh/files/lex.c @@ -1,6 +1,14 @@ +/* $NetBSD: lex.c,v 1.2 2008/05/31 16:47:37 tnn Exp $ */ + /* * lexical analysis and source input */ +#include <sys/cdefs.h> + +#ifndef lint +__RCSID("$NetBSD: lex.c,v 1.2 2008/05/31 16:47:37 tnn Exp $"); +#endif + #include "sh.h" #include <ctype.h> @@ -213,10 +221,10 @@ yylex(cf) case '\\': c = getsc(); #ifdef OS2 - if (isalnum(c)) { + if (isalnum((unsigned char)c)) { *wp++ = CHAR, *wp++ = '\\'; *wp++ = CHAR, *wp++ = c; - } else + } else #endif if (c) /* trailing \ is lost */ *wp++ = QCHAR, *wp++ = c; @@ -240,10 +248,16 @@ yylex(cf) case '\\': c = getsc(); switch (c) { - case '"': case '\\': + case '\\': case '$': case '`': *wp++ = QCHAR, *wp++ = c; break; + case '"': + if ((cf & HEREDOC) == 0) { + *wp++ = QCHAR, *wp++ = c; + break; + } + /* FALLTROUGH */ default: Xcheck(ws, wp); if (c) { /* trailing \ is lost */ @@ -645,11 +659,13 @@ Done: if (c == c2 || (c == '<' && c2 == '>')) { iop->flag = c == c2 ? (c == '>' ? IOCAT : IOHERE) : IORDWR; - if (iop->flag == IOHERE) - if ((c2 = getsc()) == '-') + if (iop->flag == IOHERE) { + if ((c2 = getsc()) == '-') { iop->flag |= IOSKIP; - else + } else { ungetsc(c2); + } + } } else if (c2 == '&') iop->flag = IODUP | (c == '<' ? IORDUP : 0); else { @@ -725,7 +741,7 @@ Done: /* copy word to unprefixed string ident */ for (sp = yylval.cp, dp = ident; dp < ident+IDENT && (c = *sp++) == CHAR; ) *dp++ = *sp++; - /* Make sure the ident array stays '\0' paded */ + /* Make sure the ident array stays '\0' padded */ memset(dp, 0, (ident+IDENT) - dp + 1); if (c != EOS) *ident = '\0'; /* word is not unquoted */ @@ -934,7 +950,7 @@ getsc__() source->flags |= s->flags & SF_ALIAS; s = source; } else if (*s->u.tblp->val.s - && isspace(strchr(s->u.tblp->val.s, 0)[-1])) + && isspace((unsigned char)strchr(s->u.tblp->val.s, 0)[-1])) { source = s = s->next; /* pop source stack */ /* Note that this alias ended with a space, @@ -1119,7 +1135,7 @@ set_prompt(to, s) */ { struct shf *shf; - char *ps1; + char * volatile ps1; Area *saved_atemp; ps1 = str_val(global("PS1")); @@ -1389,5 +1405,5 @@ pop_state_(si, old_end) afree(old_base, ATEMP); - return si->base + STATE_BSIZE - 1;; + return si->base + STATE_BSIZE - 1; } diff --git a/shells/pdksh/files/lex.h b/shells/pdksh/files/lex.h index 461254edd5a..eae06f6c503 100644 --- a/shells/pdksh/files/lex.h +++ b/shells/pdksh/files/lex.h @@ -1,8 +1,10 @@ +/* $NetBSD: lex.h,v 1.2 2008/05/31 16:47:37 tnn Exp $ */ + /* * Source input, lexer and parser */ -/* $Id: lex.h,v 1.1.1.1 2008/05/23 17:15:20 tnn Exp $ */ +/* $Id: lex.h,v 1.2 2008/05/31 16:47:37 tnn Exp $ */ #define IDENT 64 @@ -20,7 +22,7 @@ struct source { char ugbuf[2]; /* buffer for ungetsc() (SREREAD) and * alias (SALIAS) */ int line; /* line number */ - int errline; /* line the error occured on (0 if not set) */ + int errline; /* line the error occurred on (0 if not set) */ const char *file; /* input file name */ int flags; /* SF_* */ Area *areap; @@ -35,7 +37,7 @@ struct source { #define SSTRING 3 /* string */ #define SWSTR 4 /* string without \n */ #define SWORDS 5 /* string[] */ -#define SWORDSEP 6 /* string[] seperator */ +#define SWORDSEP 6 /* string[] separator */ #define SALIAS 7 /* alias expansion */ #define SREREAD 8 /* read ahead to be re-scanned */ @@ -113,6 +115,7 @@ typedef union { #define ESACONLY BIT(7) /* only accept esac keyword */ #define CMDWORD BIT(8) /* parsing simple command (alias related) */ #define HEREDELIM BIT(9) /* parsing <<,<<- delimiter */ +#define HEREDOC BIT(10) /* parsing heredoc */ #define HERES 10 /* max << in line */ @@ -124,7 +127,7 @@ EXTERN char ident [IDENT+1]; #ifdef HISTORY # define HISTORYSIZE 128 /* size of saved history */ -EXTERN char **history; /* saved commands */ +EXTERN char **histlist; /* saved commands */ EXTERN char **histptr; /* last history item */ EXTERN int histsize; /* history size */ #endif /* HISTORY */ diff --git a/shells/pdksh/files/mail.c b/shells/pdksh/files/mail.c index 2ef0b2b385d..2ee5eed5ac7 100644 --- a/shells/pdksh/files/mail.c +++ b/shells/pdksh/files/mail.c @@ -1,7 +1,15 @@ +/* $NetBSD: mail.c,v 1.2 2008/05/31 16:47:37 tnn Exp $ */ + /* * Mailbox checking code by Robert J. Gibson, adapted for PD ksh by * John R. MacMillan */ +#include <sys/cdefs.h> + +#ifndef lint +__RCSID("$NetBSD: mail.c,v 1.2 2008/05/31 16:47:37 tnn Exp $"); +#endif + #include "config.h" @@ -10,7 +18,7 @@ #include "ksh_stat.h" #include "ksh_time.h" -#define MBMESSAGE "you have mail in $_" +#define MBMESSAGE "You have mail in $_" typedef struct mbox { struct mbox *mb_next; /* next mbox in list */ diff --git a/shells/pdksh/files/main.c b/shells/pdksh/files/main.c index f63583f5511..8aaa07d94ad 100644 --- a/shells/pdksh/files/main.c +++ b/shells/pdksh/files/main.c @@ -1,6 +1,15 @@ +/* $NetBSD: main.c,v 1.2 2008/05/31 16:47:37 tnn Exp $ */ + /* - * startup, main loop, enviroments and error handling + * startup, main loop, environments and error handling */ +#include <sys/cdefs.h> +#include <locale.h> + +#ifndef lint +__RCSID("$NetBSD: main.c,v 1.2 2008/05/31 16:47:37 tnn Exp $"); +#endif + #define EXTERN /* define EXTERNs in sh.h */ @@ -64,7 +73,9 @@ static const char *const initcoms [] = { #ifdef KSH /* Aliases that are builtin commands in at&t */ "login=exec login", +#ifndef __NetBSD__ "newgrp=exec newgrp", +#endif /* __NetBSD__ */ #endif /* KSH */ NULL, /* this is what at&t ksh seems to track, with the addition of emacs */ @@ -79,9 +90,7 @@ static const char *const initcoms [] = { }; int -main(argc, argv) - int argc; - register char **argv; +main(int argc, char *argv[]) { register int i; int argi; @@ -108,14 +117,14 @@ main(argc, argv) "pdksh", (char *) 0 }; - argv = (char **) empty_argv; + argv = (char **)__UNCONST(empty_argv); argc = 1; } kshname = *argv; ainit(&aperm); /* initialize permanent Area */ - /* set up base enviroment */ + /* set up base environment */ memset(&env, 0, sizeof(env)); env.type = E_NONE; ainit(&env.area); @@ -175,8 +184,8 @@ main(argc, argv) } - /* Turn on nohup by default for how - will change to off - * by default once people are aware of its existance + /* Turn on nohup by default for now - will change to off + * by default once people are aware of its existence * (at&t ksh does not have a nohup option - it always sends * the hup). */ @@ -201,7 +210,17 @@ main(argc, argv) change_flag(FPOSIX, OF_SPECIAL, 1); #endif /* POSIXLY_CORRECT */ - /* import enviroment */ + /* Set edit mode to emacs by default, may be overridden + * by the environment or the user. Also, we want tab completion + * on in vi by default. */ +#if defined(EDIT) && defined(EMACS) + change_flag(FEMACS, OF_SPECIAL, 1); +#endif /* EDIT && EMACS */ +#if defined(EDIT) && defined(VI) + Flag(FVITABCOMPLETE) = 1; +#endif /* EDIT && VI */ + + /* import environment */ if (environ != NULL) for (wp = environ; *wp != NULL; wp++) typeset(*wp, IMPORT|EXPORT, 0, 0, 0); @@ -244,7 +263,7 @@ main(argc, argv) setstr(global(version_param), ksh_version, KSH_RETURN_ERROR); /* execute initialization statements */ - for (wp = (char**) initcoms; *wp != NULL; wp++) { + for (wp = (char**)__UNCONST(initcoms); *wp != NULL; wp++) { shcomexec(wp); for (; *wp != NULL; wp++) ; @@ -271,8 +290,10 @@ main(argc, argv) /* this to note if monitor is set on command line (see below) */ Flag(FMONITOR) = 127; argi = parse_args(argv, OF_CMDLINE, (int *) 0); - if (argi < 0) + if (argi < 0) { exit(1); + /* NOTREACHED */ + } if (Flag(FCOMMAND)) { s = pushs(SSTRING, ATEMP); @@ -319,7 +340,8 @@ main(argc, argv) { struct stat s_stdin; - if (fstat(0, &s_stdin) >= 0 && S_ISCHR(s_stdin.st_mode)) + if (fstat(0, &s_stdin) >= 0 && S_ISCHR(s_stdin.st_mode) && + Flag(FTALKING)) reset_nonblock(0); } @@ -336,7 +358,7 @@ main(argc, argv) l = e->loc; l->argv = &argv[argi - 1]; l->argc = argc - argi; - l->argv[0] = (char *) kshname; + l->argv[0] = (char *)__UNCONST(kshname); getopts_reset(1); /* Disable during .profile/ENV reading */ @@ -391,7 +413,7 @@ main(argc, argv) #ifdef DEFAULT_ENV /* If env isn't set, include default environment */ if (env_file == null) - env_file = DEFAULT_ENV; + env_file = __UNCONST(DEFAULT_ENV); #endif /* DEFAULT_ENV */ env_file = substitute(env_file, DOTILDE); if (*env_file != '\0') @@ -411,7 +433,7 @@ main(argc, argv) "ENV", "SHELL", (char *) 0 }; - shcomexec((char **) restr_com); + shcomexec((char **)__UNCONST(restr_com)); /* After typeset command... */ Flag(FRESTRICTED) = 1; } @@ -426,6 +448,7 @@ main(argc, argv) } else Flag(FTRACKALL) = 1; /* set after ENV */ + setlocale(LC_CTYPE, ""); shell(s, TRUE); /* doesn't return */ return 0; } @@ -438,7 +461,6 @@ include(name, argc, argv, intr_ok) int intr_ok; { register Source *volatile s = NULL; - Source *volatile sold; struct shf *shf; char **volatile old_argv; volatile int old_argc; @@ -455,11 +477,9 @@ include(name, argc, argv, intr_ok) old_argv = (char **) 0; old_argc = 0; } - sold = source; newenv(E_INCL); i = ksh_sigsetjmp(e->jbuf, 0); if (i) { - source = sold; if (s) /* Do this before quitenv(), which frees the memory */ shf_close(s->u.shf); quitenv(); @@ -496,7 +516,6 @@ include(name, argc, argv, intr_ok) s->u.shf = shf; s->file = str_save(name, ATEMP); i = shell(s, FALSE); - source = sold; shf_close(s->u.shf); quitenv(); if (old_argv) { @@ -511,10 +530,13 @@ command(comm) const char *comm; { register Source *s; + int r; s = pushs(SSTRING, ATEMP); s->start = s->str = comm; - return shell(s, FALSE); + r = shell(s, FALSE); + afree(s, ATEMP); + return r; } /* @@ -529,6 +551,7 @@ shell(s, toplevel) volatile int wastty = s->flags & SF_TTY; volatile int attempts = 13; volatile int interactive = Flag(FTALKING) && toplevel; + Source *volatile old_source = source; int i; newenv(E_PARSE); @@ -536,7 +559,6 @@ shell(s, toplevel) really_exit = 0; i = ksh_sigsetjmp(e->jbuf, 0); if (i) { - s->start = s->str = null; switch (i) { case LINTR: /* we get here if SIGINT not caught or ignored */ case LERROR: @@ -556,16 +578,20 @@ shell(s, toplevel) * a tty, but to have stopped jobs, one only * needs FMONITOR set (not FTALKING/SF_TTY)... */ + /* toss any input we have so far */ + s->start = s->str = null; break; } /* fall through... */ case LEXIT: case LLEAVE: case LRETURN: + source = old_source; quitenv(); unwind(i); /* keep on going */ /*NOREACHED*/ default: + source = old_source; quitenv(); internal_errorf(1, "shell: %d", i); /*NOREACHED*/ @@ -576,11 +602,12 @@ shell(s, toplevel) if (trap) runtraps(0); - if (s->next == NULL) + if (s->next == NULL) { if (Flag(FVERBOSE)) s->flags |= SF_ECHO; else s->flags &= ~SF_ECHO; + } if (interactive) { j_notify(); @@ -621,6 +648,7 @@ shell(s, toplevel) reclaim(); } quitenv(); + source = old_source; return exstat; } @@ -737,7 +765,7 @@ cleanup_parents_env() /* Don't clean up temporary files - parent will probably need them. * Also, can't easily reclaim memory since variables, etc. could be - * anywyere. + * anywhere. */ /* close all file descriptors hiding in savefd */ @@ -807,7 +835,7 @@ remove_temps(tp) APERM); memset(t, 0, sizeof(struct temp)); t->name = (char *) &t[1]; - strcpy(t->name, tp->name); + strlcpy(t->name, tp->name, strlen(tp->name) + 1); t->next = delayed_remove; delayed_remove = t; } diff --git a/shells/pdksh/files/misc.c b/shells/pdksh/files/misc.c index 97dfd238330..5bb7b8caa60 100644 --- a/shells/pdksh/files/misc.c +++ b/shells/pdksh/files/misc.c @@ -1,6 +1,14 @@ +/* $NetBSD: misc.c,v 1.2 2008/05/31 16:47:37 tnn Exp $ */ + /* * Miscellaneous functions */ +#include <sys/cdefs.h> + +#ifndef lint +__RCSID("$NetBSD: misc.c,v 1.2 2008/05/31 16:47:37 tnn Exp $"); +#endif + #include "sh.h" #include <ctype.h> /* for FILECHCONV */ @@ -81,7 +89,15 @@ str_save(s, ap) register const char *s; Area *ap; { - return s ? strcpy((char*) alloc((size_t)strlen(s)+1, ap), s) : NULL; + size_t len; + char *p; + + if (!s) + return NULL; + len = strlen(s)+1; + p = alloc(len, ap); + strlcpy(p, s, len+1); + return (p); } /* Allocate a string of size n+1 and copy upto n characters from the possibly @@ -118,7 +134,7 @@ Xcheck_grow_(xsp, xp, more) return xsp->beg + (xp - old_beg); } -const struct option options[] = { +const struct option goptions[] = { /* Special cases (see parse_args()): -A, -o, -s. * Options are sorted by their longnames - the order of these * entries MUST match the order of sh_flag F* enumerations in sh.h. @@ -131,6 +147,7 @@ const struct option options[] = { { (char *) 0, 'c', OF_CMDLINE }, #ifdef EMACS { "emacs", 0, OF_ANY }, + { "emacs-usemeta", 0, OF_ANY }, /* non-standard */ #endif { "errexit", 'e', OF_ANY }, #ifdef EMACS @@ -171,7 +188,7 @@ const struct option options[] = { #endif { "xtrace", 'x', OF_ANY }, /* Anonymous flags: used internally by shell only - * (not visable to user) + * (not visible to user) */ { (char *) 0, 0, OF_INTERNAL }, /* FTALKING_I */ }; @@ -185,8 +202,8 @@ option(n) { int i; - for (i = 0; i < NELEM(options); i++) - if (options[i].name && strcmp(options[i].name, n) == 0) + for (i = 0; i < NELEM(goptions); i++) + if (goptions[i].name && strcmp(goptions[i].name, n) == 0) return i; return -1; @@ -197,7 +214,7 @@ struct options_info { struct { const char *name; int flag; - } opts[NELEM(options)]; + } opts[NELEM(goptions)]; }; static char *options_fmt_entry ARGS((void *arg, int i, char *buf, int buflen)); @@ -232,22 +249,22 @@ printoptions(verbose) /* verbose version */ shprintf("Current option settings\n"); - for (i = n = oi.opt_width = 0; i < NELEM(options); i++) - if (options[i].name) { - len = strlen(options[i].name); - oi.opts[n].name = options[i].name; + for (i = n = oi.opt_width = 0; i < NELEM(goptions); i++) + if (goptions[i].name) { + len = strlen(goptions[i].name); + oi.opts[n].name = goptions[i].name; oi.opts[n++].flag = i; if (len > oi.opt_width) oi.opt_width = len; } print_columns(shl_stdout, n, options_fmt_entry, &oi, - oi.opt_width + 5); + oi.opt_width + 5, 1); } else { /* short version ala ksh93 */ shprintf("set"); - for (i = 0; i < NELEM(options); i++) - if (Flag(i) && options[i].name) - shprintf(" -o %s", options[i].name); + for (i = 0; i < NELEM(goptions); i++) + if (Flag(i) && goptions[i].name) + shprintf(" -o %s", goptions[i].name); shprintf(newline); } } @@ -259,9 +276,9 @@ getoptions() char m[(int) FNFLAGS + 1]; register char *cp = m; - for (i = 0; i < NELEM(options); i++) - if (options[i].c && Flag(i)) - *cp++ = options[i].c; + for (i = 0; i < NELEM(goptions); i++) + if (goptions[i].c && Flag(i)) + *cp++ = goptions[i].c; *cp = 0; return str_save(m, ATEMP); } @@ -309,7 +326,9 @@ change_flag(f, what, newval) #ifdef OS2 ; #else /* OS2 */ - setuid(ksheuid = getuid()); + seteuid(ksheuid = getuid()); + setuid(ksheuid); + setegid(getgid()); setgid(getgid()); #endif /* OS2 */ } else if (f == FPOSIX && newval) { @@ -334,8 +353,8 @@ parse_args(argv, what, setargsp) int what; /* OF_CMDLINE or OF_SET */ int *setargsp; { - static char cmd_opts[NELEM(options) + 3]; /* o:\0 */ - static char set_opts[NELEM(options) + 5]; /* Ao;s\0 */ + static char cmd_opts[NELEM(goptions) + 3]; /* o:\0 */ + static char set_opts[NELEM(goptions) + 5]; /* Ao;s\0 */ char *opts; char *array = (char *) 0; Getopt go; @@ -345,16 +364,18 @@ parse_args(argv, what, setargsp) if (cmd_opts[0] == '\0') { char *p, *q; - strcpy(cmd_opts, "o:"); /* see cmd_opts[] declaration */ + /* see cmd_opts[] declaration */ + strlcpy(cmd_opts, "o:", sizeof cmd_opts); p = cmd_opts + strlen(cmd_opts); - strcpy(set_opts, "A:o;s"); /* see set_opts[] declaration */ + /* see set_opts[] declaration */ + strlcpy(set_opts, "A:o;s", sizeof set_opts); q = set_opts + strlen(set_opts); - for (i = 0; i < NELEM(options); i++) { - if (options[i].c) { - if (options[i].flags & OF_CMDLINE) - *p++ = options[i].c; - if (options[i].flags & OF_SET) - *q++ = options[i].c; + for (i = 0; i < NELEM(goptions); i++) { + if (goptions[i].c) { + if (goptions[i].flags & OF_CMDLINE) + *p++ = goptions[i].c; + if (goptions[i].flags & OF_SET) + *q++ = goptions[i].c; } } *p = '\0'; @@ -400,7 +421,7 @@ parse_args(argv, what, setargsp) * if the output of "set +o" is to be used. */ ; - else if (i >= 0 && (options[i].flags & what)) + else if (i >= 0 && (goptions[i].flags & what)) change_flag((enum sh_flag) i, what, set); else { bi_errorf("%s: bad option", go.optarg); @@ -417,15 +438,15 @@ parse_args(argv, what, setargsp) sortargs = 1; break; } - for (i = 0; i < NELEM(options); i++) - if (optc == options[i].c - && (what & options[i].flags)) + for (i = 0; i < NELEM(goptions); i++) + if (optc == goptions[i].c + && (what & goptions[i].flags)) { change_flag((enum sh_flag) i, what, set); break; } - if (i == NELEM(options)) { + if (i == NELEM(goptions)) { internal_errorf(1, "parse_args: `%c'", optc); return -1; /* not reached */ } @@ -471,18 +492,15 @@ getn(as, ai) const char *as; int *ai; { - const char *s; - register int n; - int sawdigit = 0; + char *p; + long n; - s = as; - if (*s == '-' || *s == '+') - s++; - for (n = 0; digit(*s); s++, sawdigit = 1) - n = n * 10 + (*s - '0'); - *ai = (*as == '-') ? -n : n; - if (*s || !sawdigit) + n = strtol(as, &p, 10); + + if (!*as || *p || INT_MIN >= n || n >= INT_MAX) return 0; + + *ai = (int)n; return 1; } @@ -528,7 +546,7 @@ gmatch(s, p, isfile) char tbuf[64]; char *t = len <= sizeof(tbuf) ? tbuf : (char *) alloc(len, ATEMP); - debunk(t, p); + debunk(t, p, len); return !strcmp(t, s); } return do_gmatch((const unsigned char *) s, (const unsigned char *) se, @@ -540,7 +558,7 @@ gmatch(s, p, isfile) * if it contains no pattern characters or if there is a syntax error. * Syntax errors are: * - [ with no closing ] - * - imballenced $(...) expression + * - imbalanced $(...) expression * - [...] and *(...) not nested (eg, [a$(b|]c), *(a[b|c]d)) */ /*XXX @@ -624,8 +642,8 @@ do_gmatch(s, se, p, pe, isfile) sc = s < se ? *s : '\0'; s++; if (isfile) { - sc = FILECHCONV(sc); - pc = FILECHCONV(pc); + sc = FILECHCONV((unsigned char)sc); + pc = FILECHCONV((unsigned char)pc); } if (!ISMAGIC(pc)) { if (sc != pc) @@ -854,7 +872,7 @@ qsort1(base, lim, f) for (;;) { if (i < lptr) { if ((c = (*f)(*i, *lptr)) == 0) { - lptr --; + lptr--; swap2(i, lptr); continue; } @@ -867,13 +885,13 @@ qsort1(base, lim, f) begin: if (j > hptr) { if ((c = (*f)(*hptr, *j)) == 0) { - hptr ++; + hptr++; swap2(hptr, j); goto begin; } if (c > 0) { if (i == lptr) { - hptr ++; + hptr++; swap3(i, hptr, j); i = lptr += 1; goto begin; @@ -1024,11 +1042,11 @@ ksh_getopt(argv, go, options) } go->p = 0; } else if (*o == ',') { - /* argument is attatched to option character, even if null */ + /* argument is attached to option character, even if null */ go->optarg = argv[go->optind - 1] + go->p; go->p = 0; } else if (*o == '#') { - /* argument is optional and may be attatched or unattatched + /* argument is optional and may be attached or unattached * but must start with a digit. optarg is set to 0 if the * argument is missing. */ @@ -1037,13 +1055,13 @@ ksh_getopt(argv, go, options) go->optarg = argv[go->optind - 1] + go->p; go->p = 0; } else - go->optarg = (char *) 0;; + go->optarg = (char *) 0; } else { if (argv[go->optind] && digit(argv[go->optind][0])) { go->optarg = argv[go->optind++]; go->p = 0; } else - go->optarg = (char *) 0;; + go->optarg = (char *) 0; } } return c; @@ -1088,12 +1106,13 @@ print_value_quoted(s) * element */ void -print_columns(shf, n, func, arg, max_width) +print_columns(shf, n, func, arg, max_width, prefcol) struct shf *shf; int n; char *(*func) ARGS((void *, int, char *, int)); void *arg; int max_width; + int prefcol; { char *str = (char *) alloc(max_width + 1, ATEMP); int i; @@ -1109,7 +1128,7 @@ print_columns(shf, n, func, arg, max_width) if (!cols) cols = 1; rows = (n + cols - 1) / cols; - if (n && cols > rows) { + if (prefcol && n && cols > rows) { int tmp = rows; rows = cols; @@ -1321,7 +1340,7 @@ ksh_get_wd(buf, bsize) b = buf; else b = alloc(MAXPATHLEN + 1, ATEMP); - if (!getwd(b)) { + if (!getcwd(b, MAXPATHLEN)) { errno = EACCES; if (b != buf) afree(b, ATEMP); diff --git a/shells/pdksh/files/missing.c b/shells/pdksh/files/missing.c index 6ce3c553e5a..d90f4d0c706 100644 --- a/shells/pdksh/files/missing.c +++ b/shells/pdksh/files/missing.c @@ -291,3 +291,80 @@ dup2(oldd, newd) return fcntl(oldd, F_DUPFD, newd); } #endif /* !HAVE_MEMSET */ + + +/* XXX tnn note: The below copyright applies to strlcpy and strlcat */ +/* taken from libnbcompat */ + +/* + * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE + * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef HAVE_STRLCPY +size_t +strlcpy(char *dst, const char *src, size_t siz) +{ + char *d = dst; + const char *s = src; + size_t n = siz; + + /* Copy as many bytes as will fit */ + if (n != 0 && --n != 0) { + do { + if ((*d++ = *s++) == 0) + break; + } while (--n != 0); + } + + /* Not enough room in dst, add NUL and traverse rest of src */ + if (n == 0) { + if (siz != 0) + *d = '\0'; /* NUL-terminate dst */ + while (*s++) + ; + } + + return(s - src - 1); /* count does not include NUL */ +} +#endif + +#ifndef HAVE_STRLCAT +size_t +strlcat(char *dst, const char *src, size_t siz) { + char *d = dst; + const char *s = src; + size_t n = siz; + size_t dlen; + + /* Find the end of dst and adjust bytes left but don't go past end */ + while (n-- != 0 && *d != '\0') + d++; + dlen = d - dst; + n = siz - dlen; + + if (n == 0) + return(dlen + strlen(s)); + while (*s != '\0') { + if (n != 1) { + *d++ = *s; + n--; + } + s++; + } + *d = '\0'; + + return(dlen + (s - src)); /* count does not include NUL */ +} +#endif diff --git a/shells/pdksh/files/mkman b/shells/pdksh/files/mkman index 04666607aa1..6b18b207920 100755 --- a/shells/pdksh/files/mkman +++ b/shells/pdksh/files/mkman @@ -7,7 +7,7 @@ if [ X"$1" = X-v ] ; then shift fi if [ $# != 2 ] ; then - echo "Usage: $0 [-v] which-shell ksh.Man-file" 1>&2 + echo "usage: $0 [-v] which-shell ksh.Man-file" 1>&2 exit 1; fi shell=$1 diff --git a/shells/pdksh/files/path.c b/shells/pdksh/files/path.c index f73c2abc27a..525b2d52974 100644 --- a/shells/pdksh/files/path.c +++ b/shells/pdksh/files/path.c @@ -1,55 +1,25 @@ +/* $NetBSD: path.c,v 1.2 2008/05/31 16:47:37 tnn Exp $ */ +#include <sys/cdefs.h> + +#ifndef lint +__RCSID("$NetBSD: path.c,v 1.2 2008/05/31 16:47:37 tnn Exp $"); +#endif + + #include "sh.h" #include "ksh_stat.h" /* * Contains a routine to search a : separated list of - * paths (a la CDPATH) and make appropiate file names. + * paths (a la CDPATH) and make appropriate file names. * Also contains a routine to simplify .'s and ..'s out of * a path name. * * Larry Bouzane (larry@cs.mun.ca) */ -/* - * $Log: path.c,v $ - * Revision 1.1.1.1 2008/05/23 17:15:20 tnn - * Import subset of pdksh-5.2.14 distribution. - * Only the files required to build it, for pkgsrc bootstrap purposes. - * - * Revision 1.2 1994/05/19 18:32:40 michael - * Merge complete, stdio replaced, various fixes. (pre autoconf) - * - * Revision 1.1 1994/04/06 13:14:03 michael - * Initial revision - * - * Revision 4.2 1990/12/06 18:05:24 larry - * Updated test code to reflect parameter change. - * Fixed problem with /a/./.dir being simplified to /a and not /a/.dir due - * to *(cur+2) == *f test instead of the correct cur+2 == f - * - * Revision 4.1 90/10/29 14:42:19 larry - * base MUN version - * - * Revision 3.1.0.4 89/02/16 20:28:36 larry - * Forgot to set *pathlist to NULL when last changed make_path(). - * - * Revision 3.1.0.3 89/02/13 20:29:55 larry - * Fixed up cd so that it knew when a node from CDPATH was used and would - * print a message only when really necessary. - * - * Revision 3.1.0.2 89/02/13 17:51:22 larry - * Merged with Eric Gisin's version. - * - * Revision 3.1.0.1 89/02/13 17:50:58 larry - * *** empty log message *** - * - * Revision 3.1 89/02/13 17:49:28 larry - * *** empty log message *** - * - */ - #ifdef S_ISLNK -static char *do_phys_path ARGS((XString *xsp, char *xp, const char *path)); +static char *do_phys_path ARGS((XString *, char *, const char *)); #endif /* S_ISLNK */ /* @@ -65,7 +35,7 @@ static char *do_phys_path ARGS((XString *xsp, char *xp, const char *path)); * - cdpathp is set to the start of the next element in cdpathp (or NULL * if there are no more elements. * The return value indicates whether a non-null element from cdpathp - * was appened to result. + * was appended to result. */ int make_path(cwd, file, cdpathp, xsp, phys_pathp) @@ -146,22 +116,22 @@ make_path(cwd, file, cdpathp, xsp, phys_pathp) * ie, simplify_path("/a/b/c/./../d/..") returns "/a/b" */ void -simplify_path(path) - char *path; +simplify_path(pathx) + char *pathx; { char *cur; char *t; int isrooted; - char *very_start = path; + char *very_start = pathx; char *start; - if (!*path) + if (!*pathx) return; - if ((isrooted = ISROOTEDPATH(path))) + if ((isrooted = ISROOTEDPATH(pathx))) very_start++; #if defined (OS2) || defined (__CYGWIN__) - if (path[0] && path[1] == ':') /* skip a: */ + if (pathx[0] && pathx[1] == ':') /* skip a: */ very_start += 2; #endif /* OS2 || __CYGWIN__ */ @@ -182,7 +152,7 @@ simplify_path(path) #ifdef __CYGWIN__ /* preserve leading double-slash on pathnames (for UNC paths) */ - if (path[0] && ISDIRSEP(path[0]) && path[1] && ISDIRSEP(path[1])) + if (pathx[0] && ISDIRSEP(pathx[0]) && pathx[1] && ISDIRSEP(pathx[1])) very_start++; #endif /* __CYGWIN__ */ @@ -192,7 +162,7 @@ simplify_path(path) t++; if (*t == '\0') { - if (cur == path) + if (cur == pathx) /* convert empty path to dot */ *cur++ = '.'; *cur = '\0'; @@ -229,11 +199,11 @@ simplify_path(path) void -set_current_wd(path) - char *path; +set_current_wd(pathx) + char *pathx; { int len; - char *p = path; + char *p = pathx; if (!p && !(p = ksh_get_wd((char *) 0, 0))) p = null; @@ -243,21 +213,21 @@ set_current_wd(path) if (len > current_wd_size) current_wd = aresize(current_wd, current_wd_size = len, APERM); memcpy(current_wd, p, len); - if (p != path && p != null) + if (p != pathx && p != null) afree(p, ATEMP); } #ifdef S_ISLNK char * -get_phys_path(path) - const char *path; +get_phys_path(pathx) + const char *pathx; { XString xs; char *xp; - Xinit(xs, xp, strlen(path) + 1, ATEMP); + Xinit(xs, xp, strlen(pathx) + 1, ATEMP); - xp = do_phys_path(&xs, xp, path); + xp = do_phys_path(&xs, xp, pathx); if (!xp) return (char *) 0; @@ -270,10 +240,10 @@ get_phys_path(path) } static char * -do_phys_path(xsp, xp, path) +do_phys_path(xsp, xp, pathx) XString *xsp; char *xp; - const char *path; + const char *pathx; { const char *p, *q; int len, llen; @@ -281,7 +251,7 @@ do_phys_path(xsp, xp, path) char lbuf[PATH]; Xcheck(*xsp, xp); - for (p = path; p; p = q) { + for (p = pathx; p; p = q) { while (ISDIRSEP(*p)) p++; if (!*p) diff --git a/shells/pdksh/files/proto.h b/shells/pdksh/files/proto.h index e78930d4bca..69c985452e6 100644 --- a/shells/pdksh/files/proto.h +++ b/shells/pdksh/files/proto.h @@ -1,300 +1,298 @@ +/* $NetBSD: proto.h,v 1.2 2008/05/31 16:47:37 tnn Exp $ */ + /* * prototypes for PD-KSH * originally generated using "cproto.c 3.5 92/04/11 19:28:01 cthuang " - * $Id: proto.h,v 1.1.1.1 2008/05/23 17:15:20 tnn Exp $ + * $Id: proto.h,v 1.2 2008/05/31 16:47:37 tnn Exp $ */ /* alloc.c */ -Area * ainit ARGS((Area *ap)); -void afreeall ARGS((Area *ap)); -void * alloc ARGS((size_t size, Area *ap)); -void * aresize ARGS((void *ptr, size_t size, Area *ap)); -void afree ARGS((void *ptr, Area *ap)); +Area * ainit ARGS((Area *)); +void afreeall ARGS((Area *)); +void * alloc ARGS((size_t, Area *)); +void * aresize ARGS((void *, size_t, Area *)); +void afree ARGS((void *, Area *)); /* c_ksh.c */ -int c_hash ARGS((char **wp)); -int c_cd ARGS((char **wp)); -int c_pwd ARGS((char **wp)); -int c_print ARGS((char **wp)); -int c_whence ARGS((char **wp)); -int c_command ARGS((char **wp)); -int c_typeset ARGS((char **wp)); -int c_alias ARGS((char **wp)); -int c_unalias ARGS((char **wp)); -int c_let ARGS((char **wp)); -int c_jobs ARGS((char **wp)); -int c_fgbg ARGS((char **wp)); -int c_kill ARGS((char **wp)); -void getopts_reset ARGS((int val)); -int c_getopts ARGS((char **wp)); -int c_bind ARGS((char **wp)); +int c_hash ARGS((char **)); +int c_cd ARGS((char **)); +int c_pwd ARGS((char **)); +int c_print ARGS((char **)); +int c_whence ARGS((char **)); +int c_command ARGS((char **)); +int c_typeset ARGS((char **)); +int c_alias ARGS((char **)); +int c_unalias ARGS((char **)); +int c_let ARGS((char **)); +int c_jobs ARGS((char **)); +int c_fgbg ARGS((char **)); +int c_kill ARGS((char **)); +void getopts_reset ARGS((int)); +int c_getopts ARGS((char **)); +int c_bind ARGS((char **)); /* c_sh.c */ -int c_label ARGS((char **wp)); -int c_shift ARGS((char **wp)); -int c_umask ARGS((char **wp)); -int c_dot ARGS((char **wp)); -int c_wait ARGS((char **wp)); -int c_read ARGS((char **wp)); -int c_eval ARGS((char **wp)); -int c_trap ARGS((char **wp)); -int c_brkcont ARGS((char **wp)); -int c_exitreturn ARGS((char **wp)); -int c_set ARGS((char **wp)); -int c_unset ARGS((char **wp)); -int c_ulimit ARGS((char **wp)); -int c_times ARGS((char **wp)); -int timex ARGS((struct op *t, int f)); -void timex_hook ARGS((struct op *t, char ** volatile *app)); -int c_exec ARGS((char **wp)); -int c_builtin ARGS((char **wp)); +int c_label ARGS((char **)); +int c_shift ARGS((char **)); +int c_umask ARGS((char **)); +int c_dot ARGS((char **)); +int c_wait ARGS((char **)); +int c_read ARGS((char **)); +int c_eval ARGS((char **)); +int c_trap ARGS((char **)); +int c_brkcont ARGS((char **)); +int c_exitreturn ARGS((char **)); +int c_set ARGS((char **)); +int c_unset ARGS((char **)); +int c_ulimit ARGS((char **)); +int c_times ARGS((char **)); +int timex ARGS((struct op *, int)); +void timex_hook ARGS((struct op *, char ** volatile *)); +int c_exec ARGS((char **)); +int c_builtin ARGS((char **)); /* c_test.c */ -int c_test ARGS((char **wp)); +int c_test ARGS((char **)); /* edit.c: most prototypes in edit.h */ void x_init ARGS((void)); -int x_read ARGS((char *buf, size_t len)); -void set_editmode ARGS((const char *ed)); +int x_read ARGS((char *, size_t)); +void set_editmode ARGS((const char *)); /* emacs.c: most prototypes in edit.h */ -int x_bind ARGS((const char *a1, const char *a2, int macro, - int list)); +int x_bind ARGS((const char *, const char *, int, int)); /* eval.c */ -char * substitute ARGS((const char *cp, int f)); -char ** eval ARGS((char **ap, int f)); -char * evalstr ARGS((char *cp, int f)); -char * evalonestr ARGS((char *cp, int f)); -char *debunk ARGS((char *dp, const char *sp)); -void expand ARGS((char *cp, XPtrV *wp, int f)); -int glob_str ARGS((char *cp, XPtrV *wp, int markdirs)); +char * substitute ARGS((const char *, int)); +char ** eval ARGS((char **, int)); +char * evalstr ARGS((char *, int)); +char * evalonestr ARGS((char *, int)); +char *debunk ARGS((char *, const char *, size_t)); +void expand ARGS((char *, XPtrV *, int)); +int glob_str ARGS((char *, XPtrV *, int)); /* exec.c */ -int fd_clexec ARGS((int fd)); -int execute ARGS((struct op * volatile t, volatile int flags)); -int shcomexec ARGS((char **wp)); -struct tbl * findfunc ARGS((const char *name, unsigned int h, int create)); -int define ARGS((const char *name, struct op *t)); -void builtin ARGS((const char *name, int (*func)(char **))); -struct tbl * findcom ARGS((const char *name, int flags)); +int fd_clexec ARGS((int)); +int execute ARGS((struct op * volatile, volatile int)); +int shcomexec ARGS((char **)); +struct tbl * findfunc ARGS((const char *, unsigned int, int)); +int define ARGS((const char *, struct op *)); +void builtin ARGS((const char *, int (*)(char **))); +struct tbl * findcom ARGS((const char *, int)); void flushcom ARGS((int all)); -char * search ARGS((const char *name, const char *path, int mode, - int *errnop)); -int search_access ARGS((const char *path, int mode, int *errnop)); -int pr_menu ARGS((char *const *ap)); +char * search ARGS((const char *, const char *, int, int *)); +int search_access ARGS((const char *, int, int *)); +int pr_menu ARGS((char *const *)); +int pr_list ARGS((char *const *)); /* expr.c */ -int evaluate ARGS((const char *expr, long *rval, int error_ok)); -int v_evaluate ARGS((struct tbl *vp, const char *expr, volatile int error_ok)); +int evaluate ARGS((const char *, long *, int)); +int v_evaluate ARGS((struct tbl *, const char *, volatile int)); /* history.c */ void init_histvec ARGS((void)); -void hist_init ARGS((Source *s)); +void hist_init ARGS((Source *)); void hist_finish ARGS((void)); -void histsave ARGS((int lno, const char *cmd, int dowrite)); +void histsave ARGS((int, const char *, int)); #ifdef HISTORY -int c_fc ARGS((register char **wp)); -void sethistsize ARGS((int n)); -void sethistfile ARGS((const char *name)); +int c_fc ARGS((char **)); +void sethistsize ARGS((int)); +void sethistfile ARGS((const char *)); # ifdef EASY_HISTORY -void histappend ARGS((const char *cmd, int nl_separate)); +void histappend ARGS((const char *, int)); # endif char ** histpos ARGS((void)); int histN ARGS((void)); -int histnum ARGS((int n)); -int findhist ARGS((int start, int fwd, const char *str, - int anchored)); +int histnum ARGS((int)); +int findhist ARGS((int, int, const char *, int)); #endif /* HISTORY */ /* io.c */ -void errorf ARGS((const char *fmt, ...)) +void errorf ARGS((const char *, ...)) GCC_FUNC_ATTR2(noreturn, format(printf, 1, 2)); -void warningf ARGS((int fileline, const char *fmt, ...)) +void warningf ARGS((int, const char *, ...)) GCC_FUNC_ATTR(format(printf, 2, 3)); -void bi_errorf ARGS((const char *fmt, ...)) +void bi_errorf ARGS((const char *, ...)) GCC_FUNC_ATTR(format(printf, 1, 2)); -void internal_errorf ARGS((int jump, const char *fmt, ...)) +void internal_errorf ARGS((int, const char *, ...)) GCC_FUNC_ATTR(format(printf, 2, 3)); -void error_prefix ARGS((int fileline)); -void shellf ARGS((const char *fmt, ...)) +void error_prefix ARGS((int)); +void shellf ARGS((const char *, ...)) GCC_FUNC_ATTR(format(printf, 1, 2)); -void shprintf ARGS((const char *fmt, ...)) +void shprintf ARGS((const char *, ...)) GCC_FUNC_ATTR(format(printf, 1, 2)); #ifdef KSH_DEBUG void kshdebug_init_ ARGS((void)); -void kshdebug_printf_ ARGS((const char *fmt, ...)) +void kshdebug_printf_ ARGS((const char *, ...)) GCC_FUNC_ATTR(format(printf, 1, 2)); -void kshdebug_dump_ ARGS((const char *str, const void *mem, int nbytes)); +void kshdebug_dump_ ARGS((const char *, const void *, int)); #endif /* KSH_DEBUG */ -int can_seek ARGS((int fd)); +int can_seek ARGS((int)); void initio ARGS((void)); -int ksh_dup2 ARGS((int ofd, int nfd, int errok)); -int savefd ARGS((int fd, int noclose)); -void restfd ARGS((int fd, int ofd)); -void openpipe ARGS((int *pv)); -void closepipe ARGS((int *pv)); -int check_fd ARGS((char *name, int mode, const char **emsgp)); +int ksh_dup2 ARGS((int, int, int)); +int savefd ARGS((int, int)); +void restfd ARGS((int, int)); +void openpipe ARGS((int *)); +void closepipe ARGS((int *)); +int check_fd ARGS((char *, int, const char **)); #ifdef KSH void coproc_init ARGS((void)); -void coproc_read_close ARGS((int fd)); -void coproc_readw_close ARGS((int fd)); -void coproc_write_close ARGS((int fd)); -int coproc_getfd ARGS((int mode, const char **emsgp)); -void coproc_cleanup ARGS((int reuse)); +void coproc_read_close ARGS((int)); +void coproc_readw_close ARGS((int)); +void coproc_write_close ARGS((int)); +int coproc_getfd ARGS((int, const char **)); +void coproc_cleanup ARGS((int)); #endif /* KSH */ -struct temp *maketemp ARGS((Area *ap, Temp_type type, struct temp **tlist)); +struct temp *maketemp ARGS((Area *, Temp_type, struct temp **)); /* jobs.c */ -void j_init ARGS((int mflagset)); +void j_init ARGS((int)); void j_exit ARGS((void)); void j_change ARGS((void)); -int exchild ARGS((struct op *t, int flags, int close_fd)); +int exchild ARGS((struct op *, int, int)); void startlast ARGS((void)); int waitlast ARGS((void)); -int waitfor ARGS((const char *cp, int *sigp)); -int j_kill ARGS((const char *cp, int sig)); -int j_resume ARGS((const char *cp, int bg)); -int j_jobs ARGS((const char *cp, int slp, int nflag)); +int waitfor ARGS((const char *, int *)); +int j_kill ARGS((const char *, int)); +int j_resume ARGS((const char *, int)); +int j_jobs ARGS((const char *, int, int)); void j_notify ARGS((void)); pid_t j_async ARGS((void)); int j_stopped_running ARGS((void)); /* lex.c */ -int yylex ARGS((int cf)); -void yyerror ARGS((const char *fmt, ...)) +int yylex ARGS((int)); +void yyerror ARGS((const char *, ...)) GCC_FUNC_ATTR2(noreturn, format(printf, 1, 2)); -Source * pushs ARGS((int type, Area *areap)); -void set_prompt ARGS((int to, Source *s)); -void pprompt ARGS((const char *cp, int ntruncate)); +Source * pushs ARGS((int, Area *)); +void set_prompt ARGS((int, Source *)); +void pprompt ARGS((const char *, int)); /* mail.c */ #ifdef KSH void mcheck ARGS((void)); -void mcset ARGS((long interval)); -void mbset ARGS((char *p)); -void mpset ARGS((char *mptoparse)); +void mcset ARGS((long)); +void mbset ARGS((char *)); +void mpset ARGS((char *)); #endif /* KSH */ /* main.c */ -int include ARGS((const char *name, int argc, char **argv, - int intr_ok)); -int command ARGS((const char *comm)); -int shell ARGS((Source *volatile s, int volatile toplevel)); -void unwind ARGS((int i)) GCC_FUNC_ATTR(noreturn); -void newenv ARGS((int type)); +int include ARGS((const char *, int, char **, int)); +int command ARGS((const char *)); +int shell ARGS((Source *volatile, int volatile)); +void unwind ARGS((int)) GCC_FUNC_ATTR(noreturn); +void newenv ARGS((int)); void quitenv ARGS((void)); void cleanup_parents_env ARGS((void)); void cleanup_proc_env ARGS((void)); -void aerror ARGS((Area *ap, const char *msg)) +void aerror ARGS((Area *, const char *)) GCC_FUNC_ATTR(noreturn); /* misc.c */ -void setctypes ARGS((const char *s, int t)); +void setctypes ARGS((const char *, int)); void initctypes ARGS((void)); -char * ulton ARGS((unsigned long n, int base)); -char * str_save ARGS((const char *s, Area *ap)); -char * str_nsave ARGS((const char *s, int n, Area *ap)); -int option ARGS((const char *n)); +char * ulton ARGS((unsigned long, int)); +char * str_save ARGS((const char *, Area *)); +char * str_nsave ARGS((const char *, int, Area *)); +int option ARGS((const char *)); char * getoptions ARGS((void)); -void change_flag ARGS((enum sh_flag f, int what, int newval)); -int parse_args ARGS((char **argv, int what, int *setargsp)); -int getn ARGS((const char *as, int *ai)); -int bi_getn ARGS((const char *as, int *ai)); -char * strerror ARGS((int i)); -int gmatch ARGS((const char *s, const char *p, int isfile)); -int has_globbing ARGS((const char *xp, const char *xpe)); -const unsigned char *pat_scan ARGS((const unsigned char *p, - const unsigned char *pe, int match_sep)); -void qsortp ARGS((void **base, size_t n, int (*f)(void *, void *))); -int xstrcmp ARGS((void *p1, void *p2)); -void ksh_getopt_reset ARGS((Getopt *go, int)); -int ksh_getopt ARGS((char **argv, Getopt *go, const char *options)); -void print_value_quoted ARGS((const char *s)); -void print_columns ARGS((struct shf *shf, int n, - char *(*func)(void *, int, char *, int), - void *arg, int max_width)); -int strip_nuls ARGS((char *buf, int nbytes)); -char *str_zcpy ARGS((char *dst, const char *src, int dsize)); -int blocking_read ARGS((int fd, char *buf, int nbytes)); -int reset_nonblock ARGS((int fd)); -char *ksh_get_wd ARGS((char *buf, int bsize)); +void change_flag ARGS((enum sh_flag, int, int)); +int parse_args ARGS((char **v, int what, int *)); +int getn ARGS((const char *, int *)); +int bi_getn ARGS((const char *, int *)); +int gmatch ARGS((const char *, const char *, int)); +int has_globbing ARGS((const char *, const char *)); +const unsigned char *pat_scan ARGS((const unsigned char *, + const unsigned char *, int)); +void qsortp ARGS((void **, size_t, int (*)(void *, void *))); +int xstrcmp ARGS((void *, void *)); +void ksh_getopt_reset ARGS((Getopt *, int)); +int ksh_getopt ARGS((char **, Getopt *, const char *)); +void print_value_quoted ARGS((const char *)); +void print_columns ARGS((struct shf *, int, + char *(*)(void *, int, char *, int), + void *, int, int)); +int strip_nuls ARGS((char *, int)); +char *str_zcpy ARGS((char *, const char *, int)); +int blocking_read ARGS((int, char *, int)); +int reset_nonblock ARGS((int)); +char *ksh_get_wd ARGS((char *, int)); /* path.c */ -int make_path ARGS((const char *cwd, const char *file, - char **pathlist, XString *xsp, int *phys_pathp)); -void simplify_path ARGS((char *path)); -char *get_phys_path ARGS((const char *path)); -void set_current_wd ARGS((char *path)); +int make_path ARGS((const char *, const char *, + char **, XString *, int *)); +void simplify_path ARGS((char *)); +char *get_phys_path ARGS((const char *)); +void set_current_wd ARGS((char *)); /* syn.c */ void initkeywords ARGS((void)); -struct op * compile ARGS((Source *s)); +struct op * compile ARGS((Source *)); /* table.c */ -unsigned int hash ARGS((const char *n)); -void tinit ARGS((struct table *tp, Area *ap, int tsize)); -struct tbl * tsearch ARGS((struct table *tp, const char *n, unsigned int h)); -struct tbl * tenter ARGS((struct table *tp, const char *n, unsigned int h)); -void tdelete ARGS((struct tbl *p)); -void twalk ARGS((struct tstate *ts, struct table *tp)); -struct tbl * tnext ARGS((struct tstate *ts)); -struct tbl ** tsort ARGS((struct table *tp)); +unsigned int hash ARGS((const char *)); +void tinit ARGS((struct table *, Area *, int)); +struct tbl * tsearch ARGS((struct table *, const char *, unsigned int)); +struct tbl * tenter ARGS((struct table *, const char *, unsigned int)); +void tdelete ARGS((struct tbl *)); +void twalk ARGS((struct tstate *, struct table *)); +struct tbl * tnext ARGS((struct tstate *)); +struct tbl ** tsort ARGS((struct table *)); /* trace.c */ /* trap.c */ void inittraps ARGS((void)); #ifdef KSH void alarm_init ARGS((void)); #endif /* KSH */ -Trap * gettrap ARGS((const char *name, int igncase)); -RETSIGTYPE trapsig ARGS((int i)); +Trap * gettrap ARGS((const char *, int)); +RETSIGTYPE trapsig ARGS((int)); void intrcheck ARGS((void)); int fatal_trap_check ARGS((void)); int trap_pending ARGS((void)); -void runtraps ARGS((int intr)); -void runtrap ARGS((Trap *p)); +void runtraps ARGS((int)); +void runtrap ARGS((Trap *)); void cleartraps ARGS((void)); void restoresigs ARGS((void)); -void settrap ARGS((Trap *p, char *s)); +void settrap ARGS((Trap *, char *)); int block_pipe ARGS((void)); -void restore_pipe ARGS((int restore_dfl)); -int setsig ARGS((Trap *p, handler_t f, int flags)); -void setexecsig ARGS((Trap *p, int restore)); +void restore_pipe ARGS((int)); +int setsig ARGS((Trap *, handler_t, int)); +void setexecsig ARGS((Trap *, int)); /* tree.c */ -int fptreef ARGS((struct shf *f, int indent, const char *fmt, ...)); -char * snptreef ARGS((char *s, int n, const char *fmt, ...)); -struct op * tcopy ARGS((struct op *t, Area *ap)); -char * wdcopy ARGS((const char *wp, Area *ap)); -char * wdscan ARGS((const char *wp, int c)); -char * wdstrip ARGS((const char *wp)); -void tfree ARGS((struct op *t, Area *ap)); +int fptreef ARGS((struct shf *, int, const char *, ...)); +char * snptreef ARGS((char *, int, const char *, ...)); +struct op * tcopy ARGS((struct op *, Area *)); +char * wdcopy ARGS((const char *, Area *)); +char * wdscan ARGS((const char *, int)); +char * wdstrip ARGS((const char *)); +void tfree ARGS((struct op *, Area *)); /* var.c */ void newblock ARGS((void)); void popblock ARGS((void)); void initvar ARGS((void)); -struct tbl * global ARGS((const char *n)); -struct tbl * local ARGS((const char *n, bool_t copy)); -char * str_val ARGS((struct tbl *vp)); -long intval ARGS((struct tbl *vp)); -int setstr ARGS((struct tbl *vq, const char *s, int error_ok)); -struct tbl *setint_v ARGS((struct tbl *vq, struct tbl *vp)); -void setint ARGS((struct tbl *vq, long n)); -int getint ARGS((struct tbl *vp, long *nump)); -struct tbl * typeset ARGS((const char *var, Tflag set, Tflag clr, int field, int base)); -void unset ARGS((struct tbl *vp, int array_ref)); -char * skip_varname ARGS((const char *s, int aok)); -char *skip_wdvarname ARGS((const char *s, int aok)); -int is_wdvarname ARGS((const char *s, int aok)); -int is_wdvarassign ARGS((const char *s)); +struct tbl * global ARGS((const char *)); +struct tbl * local ARGS((const char *, bool_t)); +char * str_val ARGS((struct tbl *)); +long intval ARGS((struct tbl *)); +int setstr ARGS((struct tbl *, const char *, int)); +struct tbl *setint_v ARGS((struct tbl *, struct tbl *)); +void setint ARGS((struct tbl *, long)); +int getint ARGS((struct tbl *, long *)); +struct tbl * typeset ARGS((const char *, Tflag, Tflag, int, int)); +void unset ARGS((struct tbl *, int)); +char * skip_varname ARGS((const char *, int)); +char *skip_wdvarname ARGS((const char *, int)); +int is_wdvarname ARGS((const char *, int)); +int is_wdvarassign ARGS((const char *)); char ** makenv ARGS((void)); void change_random ARGS((void)); -int array_ref_len ARGS((const char *cp)); -char * arrayname ARGS((const char *str)); -void set_array ARGS((const char *var, int reset, char **vals)); +int array_ref_len ARGS((const char *)); +char * arrayname ARGS((const char *)); +void set_array ARGS((const char *, int, char **)); /* version.c */ /* vi.c: see edit.h */ /* Hack to avoid billions of compile warnings on SunOS 4.1.x */ #if defined(MUN) && defined(sun) && !defined(__svr4__) -extern void bcopy ARGS((const void *src, void *dst, size_t size)); -extern int fclose ARGS((FILE *fp)); -extern int fprintf ARGS((FILE *fp, const char *fmt, ...)); -extern int fread ARGS((void *buf, int size, int num, FILE *fp)); -extern int ioctl ARGS((int fd, int request, void *arg)); -extern int killpg ARGS((int pgrp, int sig)); -extern int nice ARGS((int n)); -extern int readlink ARGS((const char *path, char *buf, int bufsize)); -extern int setpgrp ARGS((int pid, int pgrp)); -extern int strcasecmp ARGS((const char *s1, const char *s2)); +extern void bcopy ARGS((const void *, void *, size_t)); +extern intclose ARGS((FILE *)); +extern intprintf ARGS((FILE *, const char *, ...)); +extern intread ARGS((void *, int, int, FILE *)); +extern int ioctl ARGS((int, int, void *)); +extern int killpg ARGS((int, int)); +extern int nice ARGS((int)); +extern int readlink ARGS((const char *, char *, int)); +extern int setpgrp ARGS((int, int)); +extern int strcasecmp ARGS((const char *, const char *)); extern int tolower ARGS((int)); extern int toupper ARGS((int)); /* Include files aren't included yet */ -extern int getrlimit ARGS(( /* int resource, struct rlimit *rpl */ )); -extern int getrusage ARGS(( /* int who, struct rusage *rusage */ )); -extern int gettimeofday ARGS(( /* struct timeval *tv, struct timezone *tz */ )); -extern int setrlimit ARGS(( /* int resource, struct rlimit *rlp */ )); -extern int lstat ARGS(( /* const char *path, struct stat *buf */ )); +extern int getrlimit ARGS(( /* int, struct rlimit * */ )); +extern int getrusage ARGS(( /* int, struct rusage * */ )); +extern int gettimeofday ARGS(( /* struct timeval *, struct timezone * */ )); +extern int setrlimit ARGS(( /* int, struct rlimit * */ )); +extern int lstat ARGS(( /* const char *, struct stat * */ )); #endif diff --git a/shells/pdksh/files/sh.h b/shells/pdksh/files/sh.h index f19b45ba218..77c0338de5e 100644 --- a/shells/pdksh/files/sh.h +++ b/shells/pdksh/files/sh.h @@ -1,8 +1,10 @@ +/* $NetBSD: sh.h,v 1.3 2008/05/31 16:47:37 tnn Exp $ */ + /* * Public Domain Bourne/Korn shell */ -/* $Id: sh.h,v 1.2 2008/05/23 17:19:49 tnn Exp $ */ +/* $Id: sh.h,v 1.3 2008/05/31 16:47:37 tnn Exp $ */ #include "config.h" /* system and option configuration info */ @@ -12,7 +14,6 @@ # define ARGS(args) () /* K&R declaration */ #endif - /* Start of common headers */ #include <stdio.h> @@ -349,7 +350,7 @@ typedef int bool_t; /* Table flag type - needs > 16 and < 32 bits */ typedef INT32 Tflag; -#define NUFILE 10 /* Number of user-accessible files */ +#define NUFILE 32 /* Number of user-accessible files */ #define FDBASE 10 /* First file usable by Shell */ /* you're not going to run setuid shell scripts, are you? */ @@ -359,7 +360,7 @@ typedef INT32 Tflag; * not a char that is used often. Also, can't use the high bit as it causes * portability problems (calling strchr(x, 0x80|'x') is error prone). */ -#define MAGIC (7)/* prefix for *?[!{,} during expand */ +#define MAGIC (7) /* prefix for *?[!{,} during expand */ #define ISMAGIC(c) ((unsigned char)(c) == MAGIC) #define NOT '!' /* might use ^ (ie, [!...] vs [^..]) */ @@ -370,18 +371,16 @@ typedef INT32 Tflag; EXTERN const char *kshname; /* $0 */ EXTERN pid_t kshpid; /* $$, shell pid */ EXTERN pid_t procpid; /* pid of executing process */ -EXTERN int ksheuid; /* effective uid of shell */ +EXTERN uid_t ksheuid; /* effective uid of shell */ EXTERN int exstat; /* exit status */ EXTERN int subst_exstat; /* exit status of last $(..)/`..` */ EXTERN const char *safe_prompt; /* safe prompt if PS1 substitution fails */ - /* * Area-based allocation built on malloc/free */ - typedef struct Area { - struct Block *freelist; /* free list */ + struct link *freelist; /* free list */ } Area; EXTERN Area aperm; /* permanent object space */ @@ -402,23 +401,22 @@ EXTERN Area aperm; /* permanent object space */ # define kshdebug_dump(a) #endif /* KSH_DEBUG */ - /* * parsing & execution environment */ EXTERN struct env { - short type; /* enviroment type - see below */ + short type; /* environment type - see below */ short flags; /* EF_* */ Area area; /* temporary allocation area */ struct block *loc; /* local variables and functions */ short *savefd; /* original redirected fd's */ - struct env *oenv; /* link to previous enviroment */ + struct env *oenv; /* link to previous environment */ ksh_jmp_buf jbuf; /* long jump back to env creator */ struct temp *temps; /* temp files */ } *e; /* struct env.type values */ -#define E_NONE 0 /* dummy enviroment */ +#define E_NONE 0 /* dummy environment */ #define E_PARSE 1 /* parsing command # */ #define E_FUNC 2 /* executing function # */ #define E_INCL 3 /* including a file via . # */ @@ -449,7 +447,6 @@ EXTERN struct env { #define LSHELL 8 /* return to interactive shell() */ #define LAEXPR 9 /* error in arithmetic expression */ - /* option processing */ #define OF_CMDLINE 0x01 /* command line */ #define OF_SET 0x02 /* set builtin */ @@ -462,7 +459,7 @@ struct option { char c; /* character flag (if any) */ short flags; /* OF_* */ }; -extern const struct option options[]; +extern const struct option goptions[]; /* * flags (the order of these enums MUST match the order in misc.c(options[])) @@ -476,6 +473,7 @@ enum sh_flag { FCOMMAND, /* -c: (invocation) execute specified command */ #ifdef EMACS FEMACS, /* emacs command editing */ + FEMACSUSEMETA, /* use 8th bit as meta */ #endif FERREXIT, /* -e: quit on error */ #ifdef EMACS @@ -483,7 +481,7 @@ enum sh_flag { #endif FIGNOREEOF, /* eof does not exit */ FTALKING, /* -i: interactive */ - FKEYWORD, /* -k: name=value anywere */ + FKEYWORD, /* -k: name=value anywhere */ FLOGIN, /* -l: a login shell */ FMARKDIRS, /* mark dirs with / in file name completion */ FMONITOR, /* -m: job control monitoring */ @@ -594,7 +592,6 @@ EXTERN int volatile fatal_trap;/* received a fatal signal */ extern Trap sigtraps[SIGNALS+1]; #endif /* !FROM_TRAP_C */ - #ifdef KSH /* * TMOUT support @@ -609,11 +606,9 @@ EXTERN unsigned int ksh_tmout; EXTERN enum tmout_enum ksh_tmout_state I__(TMOUT_EXECUTING); #endif /* KSH */ - /* For "You have stopped jobs" message */ EXTERN int really_exit; - /* * fast character classes */ @@ -636,7 +631,6 @@ extern short ctypes []; EXTERN int ifs0 I__(' '); /* for "$*" */ - /* Argument parsing for built-in commands and getopts command */ /* Values for Getopt.flags */ @@ -662,7 +656,6 @@ typedef struct { EXTERN Getopt builtin_opt; /* for shell builtin commands */ EXTERN Getopt user_opt; /* parsing state for getopts builtin command */ - #ifdef KSH /* This for co-processes */ @@ -683,7 +676,7 @@ EXTERN struct coproc coproc; EXTERN sigset_t sm_default, sm_sigchld; #endif /* JOB_SIGS */ -extern const char ksh_version[]; +extern char ksh_version[]; /* name of called builtin function (used by error functions) */ EXTERN char *builtin_argv0; @@ -694,11 +687,11 @@ EXTERN char *current_wd; EXTERN int current_wd_size; #ifdef EDIT -/* Minimium required space to work with on a line - if the prompt leaves less +/* Minimum required space to work with on a line - if the prompt leaves less * space than this on a line, the prompt is truncated. */ # define MIN_EDIT_SPACE 7 -/* Minimium allowed value for x_cols: 2 for prompt, 3 for " < " at end of line +/* Minimum allowed value for x_cols: 2 for prompt, 3 for " < " at end of line */ # define MIN_COLS (2 + MIN_EDIT_SPACE + 3) EXTERN int x_cols I__(80); /* tty columns */ @@ -706,7 +699,6 @@ EXTERN int x_cols I__(80); /* tty columns */ # define x_cols 80 /* for pr_menu(exec.c) */ #endif - /* These to avoid bracket matching problems */ #define OPAREN '(' #define CPAREN ')' diff --git a/shells/pdksh/files/shf.c b/shells/pdksh/files/shf.c index 3d2cc17b265..ecfbebfa595 100644 --- a/shells/pdksh/files/shf.c +++ b/shells/pdksh/files/shf.c @@ -1,6 +1,14 @@ +/* $NetBSD: shf.c,v 1.2 2008/05/31 16:47:37 tnn Exp $ */ + /* * Shell file I/O routines */ +#include <sys/cdefs.h> + +#ifndef lint +__RCSID("$NetBSD: shf.c,v 1.2 2008/05/31 16:47:37 tnn Exp $"); +#endif + #include "sh.h" #include "ksh_stat.h" @@ -355,7 +363,6 @@ shf_emptybuf(shf, flags) shf->rp = nbuf + (shf->rp - shf->buf); shf->wp = nbuf + (shf->wp - shf->buf); shf->rbsize += shf->wbsize; - shf->wbsize += shf->wbsize; shf->wnleft += shf->wbsize; shf->wbsize *= 2; shf->buf = nbuf; @@ -838,7 +845,7 @@ shf_smprintf(fmt, va_alist) * this out... * * For shorts, we want sign extend for %d but not for %[oxu] - on 16 bit - * machines it don't matter. Assmumes C compiler has converted shorts to + * machines it don't matter. Assumes C compiler has converted shorts to * ints before pushing them. */ #define POP_INT(f, s, a) (((f) & FL_LONG) ? \ @@ -896,6 +903,7 @@ shf_vfprintf(shf, fmt, args) char numbuf[(BITS(long) + 2) / 3 + 1]; /* this stuff for dealing with the buffer */ int nwritten = 0; + static char nulls[] = "(null %s)"; #ifdef FP /* should be in <math.h> * extern double frexp(); @@ -921,7 +929,7 @@ shf_vfprintf(shf, fmt, args) * This will accept flags/fields in any order - not * just the order specified in printf(3), but this is * the way _doprnt() seems to work (on bsd and sysV). - * The only resriction is that the format character must + * The only restriction is that the format character must * come last :-). */ flags = field = precision = 0; @@ -1082,7 +1090,7 @@ shf_vfprintf(shf, fmt, args) char *p; /* - * This could proabably be done better, + * This could probably be done better, * but it seems to work. Note that gcvt() * is not used, as you cannot tell it to * not strip the zeros. @@ -1102,7 +1110,7 @@ shf_vfprintf(shf, fmt, args) * This is the same as * expo = ceil(log10(fpnum)) * but doesn't need -lm. This is an - * aproximation as expo is rounded up. + * approximation as expo is rounded up. */ (void) frexp(fpnum, &expo); expo = my_ceil(expo / LOG2_10); @@ -1214,7 +1222,7 @@ shf_vfprintf(shf, fmt, args) case 's': if (!(s = va_arg(args, char *))) - s = "(null %s)"; + s = nulls; len = strlen(s); break; diff --git a/shells/pdksh/files/shf.h b/shells/pdksh/files/shf.h index 8be727f73d3..7f249162bb9 100644 --- a/shells/pdksh/files/shf.h +++ b/shells/pdksh/files/shf.h @@ -1,10 +1,12 @@ +/* $NetBSD: shf.h,v 1.2 2008/05/31 16:47:37 tnn Exp $ */ + #ifndef SHF_H # define SHF_H /* * Shell file I/O routines */ -/* $Id: shf.h,v 1.1.1.1 2008/05/23 17:15:21 tnn Exp $ */ +/* $Id: shf.h,v 1.2 2008/05/31 16:47:37 tnn Exp $ */ #define SHF_BSIZE 512 diff --git a/shells/pdksh/files/sigact.c b/shells/pdksh/files/sigact.c index 8e12af0b95a..5dfcd8b117d 100644 --- a/shells/pdksh/files/sigact.c +++ b/shells/pdksh/files/sigact.c @@ -1,3 +1,5 @@ +/* $NetBSD: sigact.c,v 1.2 2008/05/31 16:47:37 tnn Exp $ */ + /* NAME: * sigact.c - fake sigaction(2) * @@ -136,6 +138,12 @@ * - sigaction(),sigsuspend(),Signal(),signal(): use handler_t typedef * instead of explicit type. */ +#include <sys/cdefs.h> + +#ifndef lint +__RCSID("$NetBSD: sigact.c,v 1.2 2008/05/31 16:47:37 tnn Exp $"); +#endif + /* #include <signal.h> @@ -145,11 +153,7 @@ /* #ifndef __P - # if defined(__STDC__) || defined(__cplusplus) - # define __P(p) p - # else - # define __P(p) () - # endif + # define __P(p) p #endif */ diff --git a/shells/pdksh/files/sigact.h b/shells/pdksh/files/sigact.h index 538af9b63c0..92749c1e0a9 100644 --- a/shells/pdksh/files/sigact.h +++ b/shells/pdksh/files/sigact.h @@ -1,3 +1,5 @@ +/* $NetBSD: sigact.h,v 1.2 2008/05/31 16:47:37 tnn Exp $ */ + /* NAME: * sigact.h - sigaction et al * @@ -20,7 +22,7 @@ */ /* * RCSid: - * $Id: sigact.h,v 1.1.1.1 2008/05/23 17:15:21 tnn Exp $ + * $NetBSD: sigact.h,v 1.2 2008/05/31 16:47:37 tnn Exp $ */ /* Changes to sigact.h for pdksh, Michael Rendell <michael@cs.mun.ca>: * - changed SIG_HDLR to RETSIGTYPE for use with GNU autoconf @@ -44,13 +46,7 @@ #if 0 /* ARGS(), volatile and const are already set up in config*.h -mhr */ #undef ARGS -#if defined(__STDC__) || defined(__cplusplus) -# define ARGS(p) p -#else -# define ARGS(p) () -# define volatile /* don't optimize please */ -# define const /* read only */ -#endif +#define ARGS(p) p #endif #ifndef IS_KSH diff --git a/shells/pdksh/files/siglist.in b/shells/pdksh/files/siglist.in index 70c549d4228..e106ce50f0a 100644 --- a/shells/pdksh/files/siglist.in +++ b/shells/pdksh/files/siglist.in @@ -1,3 +1,4 @@ +# $NetBSD: siglist.in,v 1.2 2008/05/31 16:47:37 tnn Exp $ # # List of signals used to initialize ksh's signal table (see trap.c # and siglist.sh). diff --git a/shells/pdksh/files/siglist.sh b/shells/pdksh/files/siglist.sh index 952edc40be8..e863a8a497d 100755 --- a/shells/pdksh/files/siglist.sh +++ b/shells/pdksh/files/siglist.sh @@ -1,5 +1,5 @@ #!/bin/sh - +# $NetBSD: siglist.sh,v 1.2 2008/05/31 16:47:37 tnn Exp $ # # Script to generate a sorted, complete list of signals, suitable # for inclusion in trap.c as array initializer. @@ -20,18 +20,18 @@ CPP="${1-cc -E}" echo '#include "sh.h"'; echo ' { QwErTy SIGNALS , "DUMMY" , "hook for number of signals" },'; sed -e '/^[ ]*#/d' -e 's/^[ ]*\([^ ][^ ]*\)[ ][ ]*\(.*[^ ]\)[ ]*$/#ifdef SIG\1\ - { QwErTy SIG\1 , "\1", "\2" },\ + { QwErTy .signal = SIG\1 , .name = "\1", .mess = "\2" },\ #endif/') > $in $CPP $in > $out -sed -n 's/{ QwErTy/{/p' < $out | awk '{print NR, $0}' | sort +2n +0n | +sed -n 's/{ QwErTy/{/p' < $out | awk '{print NR, $0}' | sort -k5n -k1n | sed 's/^[0-9]* //' | awk 'BEGIN { last=0; nsigs=0; } { - if ($2 ~ /^[0-9][0-9]*$/ && $3 == ",") { - n = $2; + if ($4 ~ /^[0-9][0-9]*$/ && $5 == ",") { + n = $4; if (n > 0 && n != last) { while (++last < n) { - printf "\t{ %d , (char *) 0, `Signal %d` } ,\n", last, last; + printf "\t{ .signal = %d , .name = NULL, .mess = `Signal %d` } ,\n", last, last; } print; } diff --git a/shells/pdksh/files/syn.c b/shells/pdksh/files/syn.c index 6c8dddeb569..109ca1b145a 100644 --- a/shells/pdksh/files/syn.c +++ b/shells/pdksh/files/syn.c @@ -1,9 +1,18 @@ +/* $NetBSD: syn.c,v 1.2 2008/05/31 16:47:37 tnn Exp $ */ + /* * shell parser (C version) */ +#include <sys/cdefs.h> + +#ifndef lint +__RCSID("$NetBSD: syn.c,v 1.2 2008/05/31 16:47:37 tnn Exp $"); +#endif + #include "sh.h" #include "c_test.h" +#include <assert.h> struct nesting_state { int start_token; /* token than began nesting (eg, FOR) */ @@ -569,7 +578,7 @@ function_body(name, ksh_func) /* * Probably something like foo() followed by eof or ;. * This is accepted by sh and ksh88. - * To make "typset -f foo" work reliably (so its output can + * To make "typeset -f foo" work reliably (so its output can * be used as input), we pretend there is a colon here. */ t->left = newtp(TCOM); @@ -674,7 +683,7 @@ const struct tokeninfo { #endif /* KSH */ /* and some special cases... */ { "newline", '\n', FALSE }, - { 0 } + { .name = NULL } }; void @@ -800,7 +809,7 @@ compile(s) * a=[ab] * $ x=typeset; $x a=[ab]; echo "$a" * a=a - * $ + * $ */ static int assign_command(s) @@ -889,8 +898,12 @@ dbtestp_isa(te, meta) if (ret) { ACCEPT; if (meta != TM_END) { - if (!save) + if (!save) { + assert(/* meta >= 0 && */ + meta < sizeof(dbtest_tokens) / + sizeof(dbtest_tokens[0])); save = wdcopy(dbtest_tokens[(int) meta], ATEMP); + } XPput(*te->pos.av, save); } } diff --git a/shells/pdksh/files/table.c b/shells/pdksh/files/table.c index 848546c32ac..b390986519e 100644 --- a/shells/pdksh/files/table.c +++ b/shells/pdksh/files/table.c @@ -1,6 +1,14 @@ +/* $NetBSD: table.c,v 1.2 2008/05/31 16:47:37 tnn Exp $ */ + /* * dynamic hashed associative table for commands and variables */ +#include <sys/cdefs.h> + +#ifndef lint +__RCSID("$NetBSD: table.c,v 1.2 2008/05/31 16:47:37 tnn Exp $"); +#endif + #include "sh.h" @@ -52,8 +60,8 @@ texpand(tp, nsize) tp->tbls = ntblp; if (otblp == NULL) return; - for (i = 0; i < osize; i++) - if ((tblp = otblp[i]) != NULL) + for (i = 0; i < osize; i++) { + if ((tblp = otblp[i]) != NULL) { if ((tblp->flag&DEFINED)) { for (p = &ntblp[hash(tblp->name) & (tp->size-1)]; @@ -65,6 +73,8 @@ texpand(tp, nsize) } else if (!(tblp->flag & FINUSE)) { afree((void*)tblp, tp->areap); } + } + } afree((void*)otblp, tp->areap); } diff --git a/shells/pdksh/files/table.h b/shells/pdksh/files/table.h index ac8581d593f..637d1c82b22 100644 --- a/shells/pdksh/files/table.h +++ b/shells/pdksh/files/table.h @@ -1,4 +1,4 @@ -/* $Id: table.h,v 1.1.1.1 2008/05/23 17:15:21 tnn Exp $ */ +/* $NetBSD: table.h,v 1.2 2008/05/31 16:47:37 tnn Exp $ */ /* * generic hashed associative table for commands and variables. diff --git a/shells/pdksh/files/trap.c b/shells/pdksh/files/trap.c index 3adee9e8311..8f646ad8866 100644 --- a/shells/pdksh/files/trap.c +++ b/shells/pdksh/files/trap.c @@ -1,6 +1,14 @@ +/* $NetBSD: trap.c,v 1.2 2008/05/31 16:47:37 tnn Exp $ */ + /* * signal handling */ +#include <sys/cdefs.h> + +#ifndef lint +__RCSID("$NetBSD: trap.c,v 1.2 2008/05/31 16:47:37 tnn Exp $"); +#endif + /* Kludge to avoid bogus re-declaration of sigtraps[] error on AIX 3.2.5 */ #define FROM_TRAP_C @@ -12,9 +20,9 @@ * list of signals */ Trap sigtraps[SIGNALS+1] = { - { SIGEXIT_, "EXIT", "Signal 0" }, + { .signal = SIGEXIT_, .name = "EXIT", .mess = "Signal 0" }, #include "siglist.out" /* generated by siglist.sh */ - { SIGERR_, "ERR", "Error handler" }, + { .signal = SIGERR_, .name = "ERR", .mess = "Error handler" }, }; static struct sigaction Sigact_ign, Sigact_trap; @@ -46,7 +54,7 @@ inittraps() sigtraps[SIGHUP].flags |= TF_FATAL; sigtraps[SIGCHLD].flags |= TF_SHELL_USES; - /* these are always caught so we can clean up any temproary files. */ + /* these are always caught so we can clean up any temporary files. */ setsig(&sigtraps[SIGINT], trapsig, SS_RESTORE_ORIG); setsig(&sigtraps[SIGQUIT], trapsig, SS_RESTORE_ORIG); setsig(&sigtraps[SIGTERM], trapsig, SS_RESTORE_ORIG); @@ -68,6 +76,8 @@ static RETSIGTYPE alarm_catcher(sig) int sig; { + int errno_ = errno; + if (ksh_tmout_state == TMOUT_READING) { int left = alarm(0); @@ -77,6 +87,7 @@ alarm_catcher(sig) } else alarm(left); } + errno = errno_; return RETSIGVAL; } #endif /* KSH */ @@ -97,9 +108,20 @@ gettrap(name, igncase) return NULL; } for (p = sigtraps, i = SIGNALS+1; --i >= 0; p++) - if (p->name && (igncase ? strcasecmp(p->name, name) == 0 - : strcmp(p->name, name) == 0)) - return p; + if (p->name) { + if (igncase) { + if (p->name && (!strcasecmp(p->name, name) || + (strlen(name) > 3 && !strncasecmp("SIG", + p->name, 3) && + !strcasecmp(p->name, name + 3)))) + return p; + } else { + if (p->name && (!strcmp(p->name, name) || + (strlen(name) > 3 && !strncmp("SIG", + p->name, 3) && !strcmp(p->name, name + 3)))) + return p; + } + } return NULL; } @@ -111,6 +133,7 @@ trapsig(i) int i; { Trap *p = &sigtraps[i]; + int errno_ = errno; trap = p->set = 1; if (p->flags & TF_DFL_INTR) @@ -125,6 +148,7 @@ trapsig(i) if (sigtraps[i].cursig == trapsig) /* this for SIGCHLD,SIGALRM */ sigaction(i, &Sigact_trap, (struct sigaction *) 0); #endif /* V7_SIGNALS */ + errno = errno_; return RETSIGVAL; } @@ -156,7 +180,7 @@ fatal_trap_check() } /* Returns the signal number of any pending traps: ie, a signal which has - * occured for which a trap has been set or for which the TF_DFL_INTR flag + * occurred for which a trap has been set or for which the TF_DFL_INTR flag * is set. */ int @@ -252,7 +276,7 @@ runtrap(p) p->flags |= old_changed; } } - + /* clear pending traps and reset user's trap handlers; used after fork(2) */ void cleartraps() @@ -292,11 +316,14 @@ settrap(p, s) if (p->trap) afree(p->trap, APERM); - p->trap = str_save(s, APERM); /* handles s == 0 */ - p->flags |= TF_CHANGED; - f = !s ? SIG_DFL : s[0] ? trapsig : SIG_IGN; - - p->flags |= TF_USER_SET; + p->flags |= TF_CHANGED|TF_USER_SET; + if (s) { + p->trap = str_save(s, APERM); + f = s[0] ? trapsig : SIG_IGN; + } else { + p->trap = NULL; + f = SIG_DFL; + } if ((p->flags & (TF_DFL_INTR|TF_FATAL)) && f == SIG_DFL) f = trapsig; else if (p->flags & TF_SHELL_USES) { diff --git a/shells/pdksh/files/tree.c b/shells/pdksh/files/tree.c index c8e1a2f2e00..67b5237d91c 100644 --- a/shells/pdksh/files/tree.c +++ b/shells/pdksh/files/tree.c @@ -1,6 +1,14 @@ +/* $NetBSD: tree.c,v 1.2 2008/05/31 16:47:37 tnn Exp $ */ + /* * command tree climbing */ +#include <sys/cdefs.h> + +#ifndef lint +__RCSID("$NetBSD: tree.c,v 1.2 2008/05/31 16:47:37 tnn Exp $"); +#endif + #include "sh.h" @@ -370,7 +378,7 @@ int #ifdef HAVE_PROTOTYPES fptreef(struct shf *shf, int indent, const char *fmt, ...) #else -fptreef(shf, indent, fmt, va_alist) +fptreef(shf, indent, fmt, va_alist) struct shf *shf; int indent; const char *fmt; @@ -380,7 +388,7 @@ fptreef(shf, indent, fmt, va_alist) va_list va; SH_VA_START(va, fmt); - + vfptreef(shf, indent, fmt, va); va_end(va); return 0; @@ -506,7 +514,7 @@ tcopy(t, ap) for (tw = t->vars; *tw++ != NULL; ) ; rw = r->vars = (char **) - alloc((int)(tw - t->vars) * sizeof(*tw), ap); + alloc((tw - t->vars + 1) * sizeof(*tw), ap); for (tw = t->vars; *tw != NULL; ) *rw++ = wdcopy(*tw++, ap); *rw = NULL; @@ -518,7 +526,7 @@ tcopy(t, ap) for (tw = t->args; *tw++ != NULL; ) ; rw = r->args = (char **) - alloc((int)(tw - t->args) * sizeof(*tw), ap); + alloc((tw - t->args + 1) * sizeof(*tw), ap); for (tw = t->args; *tw != NULL; ) *rw++ = wdcopy(*tw++, ap); *rw = NULL; @@ -553,7 +561,7 @@ wdscan(wp, c) while (1) switch (*wp++) { case EOS: - return (char *) wp; + return (char *) __UNCONST(wp); case CHAR: case QCHAR: wp++; @@ -574,7 +582,7 @@ wdscan(wp, c) case CSUBST: wp++; if (c == CSUBST && nest == 0) - return (char *) wp; + return (char *) __UNCONST(wp); nest--; break; #ifdef KSH @@ -585,7 +593,7 @@ wdscan(wp, c) case SPAT: case CPAT: if (c == wp[-1] && nest == 0) - return (char *) wp; + return (char *) __UNCONST(wp); if (wp[-1] == CPAT) nest--; break; @@ -679,7 +687,7 @@ iocopy(iow, ap) for (ior = iow; *ior++ != NULL; ) ; - ior = (struct ioword **) alloc((int)(ior - iow) * sizeof(*ior), ap); + ior = (struct ioword **) alloc((ior - iow + 1) * sizeof(*ior), ap); for (i = 0; iow[i] != NULL; i++) { register struct ioword *p, *q; diff --git a/shells/pdksh/files/tree.h b/shells/pdksh/files/tree.h index a2c007dfe1b..de3b9ce6da5 100644 --- a/shells/pdksh/files/tree.h +++ b/shells/pdksh/files/tree.h @@ -1,8 +1,10 @@ +/* $NetBSD: tree.h,v 1.2 2008/05/31 16:47:37 tnn Exp $ */ + /* * command trees for compile/execute */ -/* $Id: tree.h,v 1.1.1.1 2008/05/23 17:15:21 tnn Exp $ */ +/* $Id: tree.h,v 1.2 2008/05/31 16:47:37 tnn Exp $ */ #define NOBLOCK ((struct op *)NULL) #define NOWORD ((char *)NULL) @@ -107,7 +109,7 @@ struct ioword { #define XCCLOSE BIT(7) /* exchild: close close_fd in child */ #define XERROK BIT(8) /* non-zero exit ok (for set -e) */ #define XCOPROC BIT(9) /* starting a co-process */ -#define XTIME BIT(10) /* timeing TCOM command */ +#define XTIME BIT(10) /* timing TCOM command */ #define XINTACT BIT(11) /* OS2: proc started from interactive session */ /* diff --git a/shells/pdksh/files/tty.c b/shells/pdksh/files/tty.c index d3023d4a019..285c6c9a365 100644 --- a/shells/pdksh/files/tty.c +++ b/shells/pdksh/files/tty.c @@ -1,3 +1,12 @@ +/* $NetBSD: tty.c,v 1.2 2008/05/31 16:47:37 tnn Exp $ */ + +#include <sys/cdefs.h> + +#ifndef lint +__RCSID("$NetBSD: tty.c,v 1.2 2008/05/31 16:47:37 tnn Exp $"); +#endif + + #include "sh.h" #include "ksh_stat.h" #define EXTERN @@ -102,6 +111,10 @@ tty_init(init_ttystate) { int do_close = 1; int tfd; +#ifndef _PATH_TTY +#define _PATH_TTY "/dev/tty" +#endif + const char *devtty = _PATH_TTY; if (tty_fd >= 0) { close(tty_fd); @@ -111,7 +124,7 @@ tty_init(init_ttystate) /* SCO can't job control on /dev/tty, so don't try... */ #if !defined(__SCO__) - if ((tfd = open("/dev/tty", O_RDWR, 0)) < 0) { + if ((tfd = open(devtty, O_RDWR, 0)) < 0) { #ifdef __NeXT /* rlogin on NeXT boxes does not set up the controlling tty, * so force it to be done here... @@ -123,7 +136,7 @@ tty_init(init_ttystate) if (s && (fd = open(s, O_RDWR, 0)) >= 0) { close(fd); - tfd = open("/dev/tty", O_RDWR, 0); + tfd = open(devtty, O_RDWR, 0); } } #endif /* __NeXT */ @@ -133,8 +146,8 @@ tty_init(init_ttystate) if (tfd < 0) { tty_devtty = 0; warningf(FALSE, - "No controlling tty (open /dev/tty: %s)", - strerror(errno)); + "No controlling tty (open %s: %s)", + devtty, strerror(errno)); } # endif /* __mips */ } diff --git a/shells/pdksh/files/tty.h b/shells/pdksh/files/tty.h index a9e1a4a2850..d5014b088e7 100644 --- a/shells/pdksh/files/tty.h +++ b/shells/pdksh/files/tty.h @@ -1,3 +1,5 @@ +/* $NetBSD: tty.h,v 1.2 2008/05/31 16:47:37 tnn Exp $ */ + /* tty.h -- centralized definitions for a variety of terminal interfaces @@ -8,7 +10,7 @@ last edit: 30-Jul-1987 D A Gwyn */ -/* $Id: tty.h,v 1.1.1.1 2008/05/23 17:15:21 tnn Exp $ */ +/* $NetBSD: tty.h,v 1.2 2008/05/31 16:47:37 tnn Exp $ */ /* some useful #defines */ #ifdef EXTERN diff --git a/shells/pdksh/files/var.c b/shells/pdksh/files/var.c index 6b4aab0275f..ae81dd135d2 100644 --- a/shells/pdksh/files/var.c +++ b/shells/pdksh/files/var.c @@ -1,3 +1,12 @@ +/* $NetBSD: var.c,v 1.2 2008/05/31 16:47:37 tnn Exp $ */ + +#include <sys/cdefs.h> + +#ifndef lint +__RCSID("$NetBSD: var.c,v 1.2 2008/05/31 16:47:37 tnn Exp $"); +#endif + + #include "sh.h" #include "ksh_time.h" #include "ksh_limval.h" @@ -39,7 +48,7 @@ newblock() ainit(&l->area); /* todo: could use e->area (l->area => l->areap) */ if (!e->loc) { l->argc = 0; - l->argv = (char **) empty; + l->argv = (char **) __UNCONST(empty); } else { l->argc = e->loc->argc; l->argv = e->loc->argv; @@ -62,12 +71,14 @@ popblock() register int i; e->loc = l->next; /* pop block */ - for (i = l->vars.size; --i >= 0; ) - if ((vp = *vpp++) != NULL && (vp->flag&SPECIAL)) + for (i = l->vars.size; --i >= 0; ) { + if ((vp = *vpp++) != NULL && (vp->flag&SPECIAL)) { if ((vq = global(vp->name))->flag & ISSET) setspec(vq); else unsetspec(vq); + } + } if (l->flags & BF_DOGETOPTS) user_opt = l->getopts_state; afreeall(&l->area); @@ -122,6 +133,8 @@ initvar() * non-zero if this is an array, sets *valp to the array index, returns * the basename of the array. */ +const char *array_index_calc(const char *n, bool_t *arrayp, int *valp); + const char * array_index_calc(n, arrayp, valp) const char *n; @@ -162,7 +175,7 @@ global(n) register struct block *l = e->loc; register struct tbl *vp; register int c; - unsigned h; + unsigned h; bool_t array; int val; @@ -217,11 +230,12 @@ global(n) } for (l = e->loc; ; l = l->next) { vp = tsearch(&l->vars, n, h); - if (vp != NULL) + if (vp != NULL) { if (array) return arraysearch(vp, val); else return vp; + } if (l->next == NULL) break; } @@ -325,8 +339,12 @@ str_val(vp) } if (!(vp->flag & INT_U) && vp->val.i < 0) *--s = '-'; - if (vp->flag & (RJUST|LJUST)) /* case already dealt with */ + if (vp->flag & (RJUST|LJUST)) { /* case already dealt with */ s = formatstr(vp, s); + (void)strlcpy(strbuf, s, sizeof(strbuf)); + afree(s, ATEMP); + s = strbuf; + } } return s; } @@ -353,7 +371,10 @@ setstr(vq, s, error_ok) const char *s; int error_ok; { - if (vq->flag & RDONLY) { + char *fs = NULL; + int no_ro_check = error_ok & 0x4; + error_ok &= ~0x4; + if ((vq->flag & RDONLY) && !no_ro_check) { warningf(TRUE, "%s: is read only", vq->name); if (!error_ok) errorf(null); @@ -372,13 +393,12 @@ setstr(vq, s, error_ok) vq->flag &= ~(ISSET|ALLOC); vq->type = 0; if (s && (vq->flag & (UCASEV_AL|LCASEV|LJUST|RJUST))) - s = formatstr(vq, s); + s = fs = formatstr(vq, s); if ((vq->flag&EXPORT)) export(vq, s); else { vq->val.s = str_save(s, vq->areap); - if (vq->val.s) /* <sjg> don't lie */ - vq->flag |= ALLOC; + vq->flag |= ALLOC; } } else /* integer dest */ if (!v_evaluate(vq, s, error_ok)) @@ -386,6 +406,8 @@ setstr(vq, s, error_ok) vq->flag |= ISSET; if ((vq->flag&SPECIAL)) setspec(vq); + if (fs) + afree(fs, ATEMP); return 1; } @@ -420,7 +442,7 @@ getint(vp, nump) int base, neg; int have_base = 0; long num; - + if (vp->flag&SPECIAL) getspec(vp); /* XXX is it possible for ISSET to be set and val.s to be 0? */ @@ -431,12 +453,12 @@ getint(vp, nump) return vp->type; } s = vp->val.s + vp->type; - if (s == NULL) /* redundent given initial test */ + if (s == NULL) /* redundant given initial test */ s = null; base = 10; num = 0; neg = 0; - for (c = *s++; c ; c = *s++) { + for (c = (unsigned char)*s++; c ; c = (unsigned char)*s++) { if (c == '-') { neg++; } else if (c == '#') { @@ -475,7 +497,7 @@ setint_v(vq, vp) { int base; long num; - + if ((base = getint(vp, &num)) == -1) return NULL; if (!(vq->flag & INTEGER) && (vq->flag & ALLOC)) { @@ -513,11 +535,11 @@ formatstr(vp, s) int slen; if (vp->flag & RJUST) { - const char *q = s + olen; + const char *r = s + olen; /* strip trailing spaces (at&t ksh uses q[-1] == ' ') */ - while (q > s && isspace(q[-1])) - --q; - slen = q - s; + while (r > s && isspace((unsigned char)r[-1])) + --r; + slen = r - s; if (slen > vp->u2.field) { s += slen - vp->u2.field; slen = vp->u2.field; @@ -528,7 +550,7 @@ formatstr(vp, s) vp->u2.field - slen, null, slen, s); } else { /* strip leading spaces/zeros */ - while (isspace(*s)) + while (isspace((unsigned char)*s)) s++; if (vp->flag & ZEROFIL) while (*s == '0') @@ -541,12 +563,12 @@ formatstr(vp, s) if (vp->flag & UCASEV_AL) { for (q = p; *q; q++) - if (islower(*q)) - *q = toupper(*q); + if (islower((unsigned char)*q)) + *q = toupper((unsigned char)*q); } else if (vp->flag & LCASEV) { for (q = p; *q; q++) - if (isupper(*q)) - *q = tolower(*q); + if (isupper((unsigned char)*q)) + *q = tolower((unsigned char)*q); } return p; @@ -598,7 +620,7 @@ typeset(var, set, clr, field, base) return NULL; if (*val == '[') { int len; - + len = array_ref_len(val); if (len == 0) return NULL; @@ -619,10 +641,10 @@ typeset(var, set, clr, field, base) if (*val == '=') tvar = str_nsave(var, val++ - var, ATEMP); else { - /* Importing from original envirnment: must have an = */ + /* Importing from original environment: must have an = */ if (set & IMPORT) return NULL; - tvar = (char *) var; + tvar = (char *) __UNCONST(var); val = NULL; } @@ -690,7 +712,7 @@ typeset(var, set, clr, field, base) if (fake_assign) { if (!setstr(t, s, KSH_RETURN_ERROR)) { /* Somewhat arbitrary action here: - * zap contents of varibale, but keep + * zap contents of variable, but keep * the flag settings. */ ok = 0; @@ -715,13 +737,13 @@ typeset(var, set, clr, field, base) if (val != NULL) { if (vp->flag&INTEGER) { /* do not zero base before assignment */ - setstr(vp, val, KSH_UNWIND_ERROR); + setstr(vp, val, KSH_UNWIND_ERROR | 0x4); /* Done after assignment to override default */ if (base > 0) vp->type = base; } else /* setstr can't fail (readonly check already done) */ - setstr(vp, val, KSH_RETURN_ERROR); + setstr(vp, val, KSH_RETURN_ERROR | 0x4); } /* only x[0] is ever exported, so use vpbase */ @@ -778,7 +800,7 @@ skip_varname(s, aok) if (aok && *s == '[' && (alen = array_ref_len(s))) s += alen; } - return (char *) s; + return (char *) __UNCONST(s); } /* Return a pointer to the first character past any legal variable name. */ @@ -811,7 +833,7 @@ skip_wdvarname(s, aok) } } } - return (char *) s; + return (char *) __UNCONST(s); } /* Check if coded string s is a variable name */ @@ -1126,6 +1148,7 @@ arraysearch(vp, val) int val; { struct tbl *prev, *curr, *new; + size_t namelen = strlen(vp->name) + 1; vp->flag |= ARRAY|DEFINED; @@ -1146,8 +1169,9 @@ arraysearch(vp, val) else new = curr; } else - new = (struct tbl *)alloc(sizeof(struct tbl)+strlen(vp->name)+1, vp->areap); - strcpy(new->name, vp->name); + new = (struct tbl *)alloc(sizeof(struct tbl) + namelen, + vp->areap); + strlcpy(new->name, vp->name, namelen); new->flag = vp->flag & ~(ALLOC|DEFINED|ISSET|SPECIAL); new->type = vp->type; new->areap = vp->areap; @@ -1191,7 +1215,7 @@ arrayname(str) if ((p = strchr(str, '[')) == 0) /* Shouldn't happen, but why worry? */ - return (char *) str; + return (char *) __UNCONST(str); return str_nsave(str, p - str, ATEMP); } diff --git a/shells/pdksh/files/version.c b/shells/pdksh/files/version.c index bdb5a614deb..f18b18ac4bd 100644 --- a/shells/pdksh/files/version.c +++ b/shells/pdksh/files/version.c @@ -1,8 +1,16 @@ +/* $NetBSD: version.c,v 1.2 2008/05/31 16:47:37 tnn Exp $ */ + /* * value of $KSH_VERSION (or $SH_VERSION) */ +#include <sys/cdefs.h> + +#ifndef lint +__RCSID("$NetBSD: version.c,v 1.2 2008/05/31 16:47:37 tnn Exp $"); +#endif + #include "sh.h" -const char ksh_version [] = +char ksh_version [] = "@(#)PD KSH v5.2.14 99/07/13.2"; diff --git a/shells/pdksh/files/vi.c b/shells/pdksh/files/vi.c index b9408ceb490..dbde10b9e05 100644 --- a/shells/pdksh/files/vi.c +++ b/shells/pdksh/files/vi.c @@ -1,9 +1,17 @@ +/* $NetBSD: vi.c,v 1.2 2008/05/31 16:47:37 tnn Exp $ */ + /* * vi command editing * written by John Rochester (initially for nsh) * bludgeoned to fit pdksh by Larry Bouzane, Jeff Sparkes & Eric Gisin * */ +#include <sys/cdefs.h> + +#ifndef lint +__RCSID("$NetBSD: vi.c,v 1.2 2008/05/31 16:47:37 tnn Exp $"); +#endif + #include "config.h" #ifdef VI @@ -25,44 +33,45 @@ struct edstate { }; -static int vi_hook ARGS((int ch)); -static void vi_reset ARGS((char *buf, size_t len)); -static int nextstate ARGS((int ch)); -static int vi_insert ARGS((int ch)); -static int vi_cmd ARGS((int argcnt, const char *cmd)); -static int domove ARGS((int argcnt, const char *cmd, int sub)); -static int redo_insert ARGS((int count)); -static void yank_range ARGS((int a, int b)); -static int bracktype ARGS((int ch)); +static int vi_hook ARGS((int)); +static void vi_reset ARGS((char *, size_t)); +static int nextstate ARGS((int)); +static int vi_insert ARGS((int)); +static int vi_cmd ARGS((int, const char *)); +static int domove ARGS((int, const char *, int)); +static int redo_insert ARGS((int)); +static void yank_range ARGS((int, int)); +static int bracktype ARGS((int)); static void save_cbuf ARGS((void)); static void restore_cbuf ARGS((void)); -static void edit_reset ARGS((char *buf, size_t len)); -static int putbuf ARGS((const char *buf, int len, int repl)); -static void del_range ARGS((int a, int b)); -static int findch ARGS((int ch, int cnt, int forw, int incl)); -static int forwword ARGS((int argcnt)); -static int backword ARGS((int argcnt)); -static int endword ARGS((int argcnt)); -static int Forwword ARGS((int argcnt)); -static int Backword ARGS((int argcnt)); -static int Endword ARGS((int argcnt)); -static int grabhist ARGS((int save, int n)); -static int grabsearch ARGS((int save, int start, int fwd, char *pat)); -static void redraw_line ARGS((int newline)); -static void refresh ARGS((int leftside)); +static void edit_reset ARGS((char *, size_t)); +static int putbuf ARGS((const char *, int, int)); +static void del_range ARGS((int, int)); +static int findch ARGS((int, int, int, int)); +static int forwword ARGS((int)); +static int backword ARGS((int)); +static int endword ARGS((int)); +static int Forwword ARGS((int)); +static int Backword ARGS((int)); +static int Endword ARGS((int)); +static int grabhist ARGS((int, int)); +static int grabsearch ARGS((int, int, int, char *)); +static void redraw_line ARGS((int)); +static void refresh ARGS((int)); static int outofwin ARGS((void)); static void rewindow ARGS((void)); -static int newcol ARGS((int ch, int col)); -static void display ARGS((char *wb1, char *wb2, int leftside)); -static void ed_mov_opt ARGS((int col, char *wb)); -static int expand_word ARGS((int command)); -static int complete_word ARGS((int command, int count)); -static int print_expansions ARGS((struct edstate *e, int command)); -static int char_len ARGS((int c)); -static void x_vi_zotc ARGS((int c)); -static void vi_pprompt ARGS((int full)); +static int newcol ARGS((int, int)); +static void display ARGS((char *, char *, int)); +static void ed_mov_opt ARGS((int, char *)); +static int expand_word ARGS((int)); +static int complete_word ARGS((int, int)); +static int print_expansions ARGS((struct edstate *, int)); +static int char_len ARGS((int)); +static void x_vi_zotc ARGS((int)); +static void vi_pprompt ARGS((int)); static void vi_error ARGS((void)); static void vi_macro_reset ARGS((void)); +static int x_vi_putbuf ARGS((const char *, size_t)); #define C_ 0x1 /* a valid command that isn't a M_, E_, U_ */ #define M_ 0x2 /* movement command (h, l, etc.) */ @@ -235,7 +244,7 @@ x_vi(buf, len) x_putc('\r'); x_putc('\n'); x_flush(); - if (c == -1) + if (c == -1 || len <= es->linelen) return -1; if (es->cbuf != buf) @@ -419,7 +428,7 @@ vi_hook(ch) } } else { locpat[srchlen] = '\0'; - (void) strcpy(srchpat, locpat); + (void) strlcpy(srchpat, locpat, sizeof srchpat); } state = VCMD; } else if (ch == edchars.erase || ch == Ctrl('h')) { @@ -443,9 +452,9 @@ vi_hook(ch) int i; int n = srchlen; - while (n > 0 && isspace(locpat[n - 1])) + while (n > 0 && isspace((unsigned char)locpat[n - 1])) n--; - while (n > 0 && !isspace(locpat[n - 1])) + while (n > 0 && !isspace((unsigned char)locpat[n - 1])) n--; for (i = srchlen; --i >= n; ) es->linelen -= char_len((unsigned char) locpat[i]); @@ -459,15 +468,22 @@ vi_hook(ch) else { locpat[srchlen++] = ch; if ((ch & 0x80) && Flag(FVISHOW8)) { + if (es->linelen + 2 > es->cbufsize) + vi_error(); es->cbuf[es->linelen++] = 'M'; es->cbuf[es->linelen++] = '-'; ch &= 0x7f; } if (ch < ' ' || ch == 0x7f) { + if (es->linelen + 2 > es->cbufsize) + vi_error(); es->cbuf[es->linelen++] = '^'; es->cbuf[es->linelen++] = ch ^ '@'; - } else + } else { + if (es->linelen >= es->cbufsize) + vi_error(); es->cbuf[es->linelen++] = ch; + } es->cursor = es->linelen; refresh(0); } @@ -690,7 +706,7 @@ vi_insert(ch) /* End nonstandard vi commands } */ default: - if (es->linelen == es->cbufsize - 1) + if (es->linelen >= es->cbufsize - 1) return -1; ibuf[inslen++] = ch; if (insert == INSERT) { @@ -817,8 +833,8 @@ vi_cmd(argcnt, cmd) return -1; if (*cmd == 'c' && (cmd[1]=='w' || cmd[1]=='W') && - !isspace(es->cbuf[es->cursor])) { - while (isspace(es->cbuf[--ncursor])) + !isspace((unsigned char)es->cbuf[es->cursor])) { + while (isspace((unsigned char)es->cbuf[--ncursor])) ; ncursor++; } @@ -1050,7 +1066,7 @@ vi_cmd(argcnt, cmd) if (histnum(-1) < 0) return -1; p = *histpos(); -#define issp(c) (isspace((c)) || (c) == '\n') +#define issp(c) (isspace((unsigned char)(c)) || (c) == '\n') if (argcnt) { while (*p && issp(*p)) p++; @@ -1105,12 +1121,12 @@ vi_cmd(argcnt, cmd) return -1; for (i = 0; i < argcnt; i++) { p = &es->cbuf[es->cursor]; - if (islower(*p)) { + if (islower((unsigned char)*p)) { modified = 1; hnum = hlast; - *p = toupper(*p); - } else if (isupper(*p)) { + *p = toupper((unsigned char)*p); + } else if (isupper((unsigned char)*p)) { modified = 1; hnum = hlast; - *p = tolower(*p); + *p = tolower((unsigned char)*p); } if (es->cursor < es->linelen - 1) es->cursor++; @@ -1258,7 +1274,7 @@ domove(argcnt, cmd, sub) case '^': ncursor = 0; - while (ncursor < es->linelen - 1 && isspace(es->cbuf[ncursor])) + while (ncursor < es->linelen - 1 && isspace((unsigned char)es->cbuf[ncursor])) ncursor++; break; @@ -1402,8 +1418,8 @@ save_edstate(old) new = (struct edstate *)alloc(sizeof(struct edstate), APERM); new->cbuf = alloc(old->cbufsize, APERM); + memcpy(new->cbuf, old->cbuf, old->linelen); new->cbufsize = old->cbufsize; - strcpy(new->cbuf, old->cbuf); new->linelen = old->linelen; new->cursor = old->cursor; new->winleft = old->winleft; @@ -1414,7 +1430,7 @@ static void restore_edstate(new, old) struct edstate *old, *new; { - strncpy(new->cbuf, old->cbuf, old->linelen); + memcpy(new->cbuf, old->cbuf, old->linelen); new->linelen = old->linelen; new->cursor = old->cursor; new->winleft = old->winleft; @@ -1470,6 +1486,17 @@ edit_reset(buf, len) holdlen = 0; } +/* + * this is used for calling x_escape() in complete_word() + */ +static int +x_vi_putbuf(s, len) + const char *s; + size_t len; +{ + return putbuf(s, len, 0); +} + static int putbuf(buf, len, repl) const char *buf; @@ -1548,12 +1575,12 @@ forwword(argcnt) while (is_wordch(es->cbuf[ncursor]) && ncursor < es->linelen) ncursor++; - else if (!isspace(es->cbuf[ncursor])) + else if (!isspace((unsigned char)es->cbuf[ncursor])) while (!is_wordch(es->cbuf[ncursor]) && - !isspace(es->cbuf[ncursor]) && + !isspace((unsigned char)es->cbuf[ncursor]) && ncursor < es->linelen) ncursor++; - while (isspace(es->cbuf[ncursor]) && ncursor < es->linelen) + while (isspace((unsigned char)es->cbuf[ncursor]) && ncursor < es->linelen) ncursor++; } return ncursor; @@ -1567,7 +1594,7 @@ backword(argcnt) ncursor = es->cursor; while (ncursor > 0 && argcnt--) { - while (--ncursor > 0 && isspace(es->cbuf[ncursor])) + while (--ncursor > 0 && isspace((unsigned char)es->cbuf[ncursor])) ; if (ncursor > 0) { if (is_wordch(es->cbuf[ncursor])) @@ -1577,7 +1604,7 @@ backword(argcnt) else while (--ncursor >= 0 && !is_wordch(es->cbuf[ncursor]) && - !isspace(es->cbuf[ncursor])) + !isspace((unsigned char)es->cbuf[ncursor])) ; ncursor++; } @@ -1594,7 +1621,7 @@ endword(argcnt) ncursor = es->cursor; while (ncursor < es->linelen && argcnt--) { while (++ncursor < es->linelen - 1 && - isspace(es->cbuf[ncursor])) + isspace((unsigned char)es->cbuf[ncursor])) ; if (ncursor < es->linelen - 1) { if (is_wordch(es->cbuf[ncursor])) @@ -1604,7 +1631,7 @@ endword(argcnt) else while (++ncursor < es->linelen && !is_wordch(es->cbuf[ncursor]) && - !isspace(es->cbuf[ncursor])) + !isspace((unsigned char)es->cbuf[ncursor])) ; ncursor--; } @@ -1620,9 +1647,9 @@ Forwword(argcnt) ncursor = es->cursor; while (ncursor < es->linelen && argcnt--) { - while (!isspace(es->cbuf[ncursor]) && ncursor < es->linelen) + while (!isspace((unsigned char)es->cbuf[ncursor]) && ncursor < es->linelen) ncursor++; - while (isspace(es->cbuf[ncursor]) && ncursor < es->linelen) + while (isspace((unsigned char)es->cbuf[ncursor]) && ncursor < es->linelen) ncursor++; } return ncursor; @@ -1636,9 +1663,9 @@ Backword(argcnt) ncursor = es->cursor; while (ncursor > 0 && argcnt--) { - while (--ncursor >= 0 && isspace(es->cbuf[ncursor])) + while (--ncursor >= 0 && isspace((unsigned char)es->cbuf[ncursor])) ; - while (ncursor >= 0 && !isspace(es->cbuf[ncursor])) + while (ncursor >= 0 && !isspace((unsigned char)es->cbuf[ncursor])) ncursor--; ncursor++; } @@ -1654,11 +1681,11 @@ Endword(argcnt) ncursor = es->cursor; while (ncursor < es->linelen - 1 && argcnt--) { while (++ncursor < es->linelen - 1 && - isspace(es->cbuf[ncursor])) + isspace((unsigned char)es->cbuf[ncursor])) ; if (ncursor < es->linelen - 1) { while (++ncursor < es->linelen && - !isspace(es->cbuf[ncursor])) + !isspace((unsigned char)es->cbuf[ncursor])) ; ncursor--; } @@ -1732,8 +1759,8 @@ grabsearch(save, start, fwd, pat) } static void -redraw_line(newline) - int newline; +redraw_line(newlinex) + int newlinex; { (void) memset(wbuf[win], ' ', wbuf_len); if (newline) { @@ -1930,8 +1957,8 @@ ed_mov_opt(col, wb) /* replace word with all expansions (ie, expand word*) */ static int -expand_word(command) - int command; +expand_word(commandx) + int commandx; { static struct edstate *buf; int rval = 0; @@ -1941,7 +1968,7 @@ expand_word(command) int i; /* Undo previous expansion */ - if (command == 0 && expanded == EXPAND && buf) { + if (commandx == 0 && expanded == EXPAND && buf) { restore_edstate(es, buf); buf = 0; expanded = NONE; @@ -1965,7 +1992,7 @@ expand_word(command) del_range(start, end); es->cursor = start; for (i = 0; i < nwords; ) { - if (putbuf(words[i], (int) strlen(words[i]), 0) != 0) { + if (x_escape(words[i], strlen(words[i]), x_vi_putbuf) != 0) { rval = -1; break; } @@ -1985,8 +2012,8 @@ expand_word(command) } static int -complete_word(command, count) - int command; +complete_word(commandx, count) + int commandx; int count; { static struct edstate *buf; @@ -2000,12 +2027,12 @@ complete_word(command, count) int is_command; /* Undo previous completion */ - if (command == 0 && expanded == COMPLETE && buf) { + if (commandx == 0 && expanded == COMPLETE && buf) { print_expansions(buf, 0); expanded = PRINT; return 0; } - if (command == 0 && expanded == PRINT && buf) { + if (commandx == 0 && expanded == PRINT && buf) { restore_edstate(es, buf); buf = 0; expanded = NONE; @@ -2068,9 +2095,12 @@ complete_word(command, count) buf = save_edstate(es); del_range(start, end); es->cursor = start; - if (putbuf(match, match_len, 0) != 0) - rval = -1; - else if (is_unique) { + + /* escape all shell-sensitive characters and put the result into + * command buffer */ + rval = x_escape(match, match_len, x_vi_putbuf); + + if (rval == 0 && is_unique) { /* If exact match, don't undo. Allows directory completions * to be used (ie, complete the next portion of the path). */ @@ -2091,9 +2121,9 @@ complete_word(command, count) } static int -print_expansions(e, command) - struct edstate *e; - int command; +print_expansions(ex, commandx) + struct edstate *ex; + int commandx; { int nwords; int start, end; @@ -2101,7 +2131,7 @@ print_expansions(e, command) int is_command; nwords = x_cf_glob(XCF_COMMAND_FILE|XCF_FULLPATH, - e->cbuf, e->linelen, e->cursor, + ex->cbuf, ex->linelen, ex->cursor, &start, &end, &words, &is_command); if (nwords == 0) { vi_error(); @@ -2129,7 +2159,7 @@ char_len(c) return len; } -/* Similar to x_zotc(emacs.c), but no tab wierdness */ +/* Similar to x_zotc(emacs.c), but no tab weirdness */ static void x_vi_zotc(c) int c; |