diff options
author | Erik Andersen <andersen@codepoet.org> | 2000-05-14 04:16:35 +0000 |
---|---|---|
committer | Erik Andersen <andersen@codepoet.org> | 2000-05-14 04:16:35 +0000 |
commit | 64bc6412188b141c010ac3b8e813b837dd991e80 (patch) | |
tree | ffa12b79ea4b13191754f54b872eb1a4f9e3a04b /libc/stdlib |
Initial revision
Diffstat (limited to 'libc/stdlib')
-rw-r--r-- | libc/stdlib/Makefile | 64 | ||||
-rw-r--r-- | libc/stdlib/atexit.c | 117 | ||||
-rw-r--r-- | libc/stdlib/bsearch.c | 46 | ||||
-rw-r--r-- | libc/stdlib/getenv.c | 31 | ||||
-rw-r--r-- | libc/stdlib/malloc/Makefile | 33 | ||||
-rw-r--r-- | libc/stdlib/malloc/alloc.c | 82 | ||||
-rw-r--r-- | libc/stdlib/mkstemp.c | 43 | ||||
-rw-r--r-- | libc/stdlib/mktemp.c | 40 | ||||
-rw-r--r-- | libc/stdlib/putenv.c | 62 | ||||
-rw-r--r-- | libc/stdlib/qsort.c | 166 | ||||
-rw-r--r-- | libc/stdlib/rand.c | 61 | ||||
-rw-r--r-- | libc/stdlib/setenv.c | 73 | ||||
-rw-r--r-- | libc/stdlib/strtod.c | 96 | ||||
-rw-r--r-- | libc/stdlib/system.c | 48 |
14 files changed, 962 insertions, 0 deletions
diff --git a/libc/stdlib/Makefile b/libc/stdlib/Makefile new file mode 100644 index 000000000..da8053f1d --- /dev/null +++ b/libc/stdlib/Makefile @@ -0,0 +1,64 @@ +# Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk> +# This file is part of the Linux-8086 C library and is distributed +# under the GNU Library General Public License. + +LIBC=../libc.a + +CC=m68k-pic-coff-gcc +AR=m68k-pic-coff-ar +RANLIB=m68k-pic-coff-ranlib + +CCFLAGS= -O2 -m68000 -msoft-float -fno-builtin -I../include + +MSRC=aliases.c +MOBJ=abs.o remove.o creat.o bcopy.o bzero.o +# raise.o bcmp.o index.o rindex.o + + +ESRC=atexit.c +EOBJ=on_exit.o atexit.o __do_exit.o exit.o + +GOBJ=atoi.o atol.o ltoa.o ltostr.o \ + ctype.o qsort.o bsearch.o rand.o lsearch.o getopt.o \ + itoa.o strtol.o crypt.o sleep.o mkstemp.o mktemp.o + +UOBJ=getenv.o putenv.o popen.o system.o getcwd.o setenv.o \ + execl.o execv.o execlp.o execvp.o execvep.o + + +OBJ=$(MOBJ) $(EOBJ) $(GOBJ) $(UOBJ) + +## No ELKS strtod() until BCC does 16 bit FP... +#ifneq ($(LIB_CPU),i86) +#OBJ+=strtod.o +#endif + +CFLAGS=$(ARCH) $(CCFLAGS) $(DEFS) + +all: $(LIBC) + @$(RM) $(OBJ) + +$(LIBC): $(LIBC)($(OBJ)) + +$(LIBC)($(MOBJ)): $(MSRC) + $(CC) $(CFLAGS) -DL_$* $< -c -o $*.o + $(AR) $(ARFLAGS) $@ $*.o + +$(LIBC)($(EOBJ)): $(ESRC) + $(CC) $(CFLAGS) -DL_$* $< -c -o $*.o + $(AR) $(ARFLAGS) $@ $*.o + +clean: + rm -f *.o libc.a + +$(LIBC)(strtol.o): strtol.c + $(CC) -c -ansi $(ARCH) $(CCFLAGS) $(DEFS) $*.c + $(AR) $(ARFLAGS) $@ $*.o + +$(LIBC)(strtod.o): strtod.c + $(CC) -c -ansi $(ARCH) $(CCFLAGS) $(DEFS) $*.c + $(AR) $(ARFLAGS) $@ $*.o + +$(LIBC)(crypt.o): crypt.c + $(CC) -c -ansi $(ARCH) $(CCFLAGS) $(DEFS) $*.c + $(AR) $(ARFLAGS) $@ $*.o diff --git a/libc/stdlib/atexit.c b/libc/stdlib/atexit.c new file mode 100644 index 000000000..2a82c6edb --- /dev/null +++ b/libc/stdlib/atexit.c @@ -0,0 +1,117 @@ +/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk> + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +/* + * This deals with both the atexit and on_exit function calls + * + * Note calls installed with atexit are called with the same args as on_exit + * fuctions; the void* is given the NULL value. + * + */ + +#include <errno.h> + +/* ATEXIT.H */ +#define MAXONEXIT 20 /* AIUI Posix requires 10 */ + +typedef void (*vfuncp) (); + +extern vfuncp __cleanup; +extern void __do_exit(); + +extern struct exit_table +{ + vfuncp called; + void *argument; +} +__on_exit_table[MAXONEXIT]; + +extern int __on_exit_count; + +/* End ATEXIT.H */ + +#ifdef L_atexit +vfuncp __cleanup; + +int +atexit(ptr) +vfuncp ptr; +{ + if( __on_exit_count < 0 || __on_exit_count >= MAXONEXIT) + { + errno = ENOMEM; + return -1; + } + __cleanup = __do_exit; + if( ptr ) + { + __on_exit_table[__on_exit_count].called = ptr; + __on_exit_table[__on_exit_count].argument = 0; + __on_exit_count++; + } + return 0; +} + +#endif + +#ifdef L_on_exit +int +on_exit(ptr, arg) +vfuncp ptr; +void *arg; +{ + if( __on_exit_count < 0 || __on_exit_count >= MAXONEXIT) + { + errno = ENOMEM; + return -1; + } + __cleanup = __do_exit; + if( ptr ) + { + __on_exit_table[__on_exit_count].called = ptr; + __on_exit_table[__on_exit_count].argument = arg; + __on_exit_count++; + } + return 0; +} + +#endif + +#ifdef L___do_exit + +int __on_exit_count = 0; +struct exit_table __on_exit_table[MAXONEXIT]; + +void +__do_exit(rv) +int rv; +{ + register int count = __on_exit_count-1; + register vfuncp ptr; + __on_exit_count = -1; /* ensure no more will be added */ + __cleanup = 0; /* Calling exit won't re-do this */ + + /* In reverse order */ + for (; count >= 0; count--) + { + ptr = __on_exit_table[count].called; + (*ptr) (rv, __on_exit_table[count].argument); + } +} + +#endif + +#ifdef L_exit + +void +exit(rv) +int rv; +{ + if (__cleanup) + __cleanup(); + _exit(rv); +} + +#endif diff --git a/libc/stdlib/bsearch.c b/libc/stdlib/bsearch.c new file mode 100644 index 000000000..989866743 --- /dev/null +++ b/libc/stdlib/bsearch.c @@ -0,0 +1,46 @@ + +/* + * This file lifted in toto from 'Dlibs' on the atari ST (RdeBath) + * + * + * Dale Schumacher 399 Beacon Ave. + * (alias: Dalnefre') St. Paul, MN 55104 + * dal@syntel.UUCP United States of America + * "It's not reality that's important, but how you perceive things." + */ +#include <stdio.h> + +static int _bsearch; /* index of element found, or where to + * insert */ + +char * +bsearch(key, base, num, size, cmp) +register char *key; /* item to search for */ +register char *base; /* base address */ +int num; /* number of elements */ +register int size; /* element size in bytes */ +register int (*cmp) (); /* comparison function */ +{ + register int a, b, c, dir; + + a = 0; + b = num - 1; + while (a <= b) + { + c = (a + b) >> 1; /* == ((a + b) / 2) */ + if (dir = (*cmp) ((base + (c * size)), key)) + { + if (dir > 0) + b = c - 1; + else /* (dir < 0) */ + a = c + 1; + } + else + { + _bsearch = c; + return (base + (c * size)); + } + } + _bsearch = b; + return (NULL); +} diff --git a/libc/stdlib/getenv.c b/libc/stdlib/getenv.c new file mode 100644 index 000000000..1ed83a622 --- /dev/null +++ b/libc/stdlib/getenv.c @@ -0,0 +1,31 @@ +/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk> + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ +#include <string.h> +#include <stdlib.h> +#include <malloc.h> + +extern char ** environ; + +char * +getenv(var) +const char * var; +{ + char **p; + int len; + + len = strlen(var); + + if (!environ) + return 0; + + for(p=environ; *p; p++) + { + if( memcmp(var, *p, len) == 0 && (*p)[len] == '=' ) + return *p + len + 1; + } + return 0; +} + + diff --git a/libc/stdlib/malloc/Makefile b/libc/stdlib/malloc/Makefile new file mode 100644 index 000000000..36872c301 --- /dev/null +++ b/libc/stdlib/malloc/Makefile @@ -0,0 +1,33 @@ +# Copyright (C) 1996 Robert de Bath <robert@mayday.compulink.co.uk> +# This file is part of the Linux-8086 C library and is distributed +# under the GNU Library General Public License. + +LIBC=../libc.a + +CC=m68k-pic-coff-gcc +AR=m68k-pic-coff-ar +RANLIB=m68k-pic-coff-ranlib + +CCFLAGS= -O2 -m68000 -msoft-float -I../include + + +MSRC=alloc.c +MOBJ=malloc.o free.o calloc.o malloc_dbg.o free_dbg.o calloc_dbg.o + +OBJ=$(MOBJ) + +CFLAGS=$(ARCH) $(CCFLAGS) $(DEFS) + +all: $(LIBC) + @$(RM) $(OBJ) + +$(LIBC): $(LIBC)($(OBJ)) + +$(LIBC)($(MOBJ)): $(MSRC) + $(CC) $(CFLAGS) -DL_$* $< -c -o $*.o + $(AR) $(ARFLAGS) $@ $*.o + +clean: + rm -f *.o libc.a + + diff --git a/libc/stdlib/malloc/alloc.c b/libc/stdlib/malloc/alloc.c new file mode 100644 index 000000000..b92cb7c69 --- /dev/null +++ b/libc/stdlib/malloc/alloc.c @@ -0,0 +1,82 @@ +#include <unistd.h> +#include <sys/mman.h> +#include <stdio.h> +#include <stdlib.h> + +#ifdef L_calloc_dbg + +void * +calloc_dbg(size_t num, size_t size, char * function, char * file, int line) +{ + void * ptr; + fprintf(stderr, "calloc of %d bytes at %s @%s:%d = ", num*size, function, file, line); + ptr = calloc(num,size); + fprtinf(stderr, "%p\n", ptr); + return ptr; +} + +#endif + +#ifdef L_malloc_dbg + +void * +malloc_dbg(size_t len, char * function, char * file, int line) +{ + void * result; + fprintf(stderr, "malloc of %d bytes at %s @%s:%d = ", len, function, file, line); + result = malloc(len); + fprintf(stderr, "%p\n", result); + return result; +} + +#endif + +#ifdef L_free_dbg + +void +free_dbg(void * ptr, char * function, char * file, int line) +{ + fprintf(stderr, "free of %p at %s @%s:%d\n", ptr, function, file, line); + free(ptr); +} + +#endif + + +#ifdef L_calloc + +void * +calloc(size_t num, size_t size) +{ + void * ptr = malloc(num*size); + if (ptr) + memset(ptr, 0, num*size); + return ptr; +} + +#endif + +#ifdef L_malloc + +void * +malloc(size_t len) +{ + void * result = mmap((void *)0, len, PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_ANONYMOUS, 0, 0); + if (result == (void*)-1) + return 0; + + return result; +} + +#endif + +#ifdef L_free + +void +free(void * ptr) +{ + munmap(ptr, 0); +} + +#endif diff --git a/libc/stdlib/mkstemp.c b/libc/stdlib/mkstemp.c new file mode 100644 index 000000000..d65ada4f7 --- /dev/null +++ b/libc/stdlib/mkstemp.c @@ -0,0 +1,43 @@ + +#include <features.h> +#include <unistd.h> +#include <fcntl.h> + +int mkstemp(template) +char * template; +{ + int i; + int num; /* UNINITIALIZED */ + int n2; + int l = strlen(template); + + if (l<6) { + errno = EINVAL; + return -1; + } + + for(i=l-6;i<l;i++) + if (template[i] != 'X') { + errno = EINVAL; + return -1; + } + +again: + n2 = num; + for(i=l-1;i>=l-6;i--) { + template[i] = '0' + n2 % 10; + n2 /= 10; + } + + i = open(template, O_RDWR|O_EXCL|O_CREAT, 0666); + + if (i==-1) { + if (errno == EEXIST) { + num++; + goto again; + } else + return -1; + } + + return i; +} diff --git a/libc/stdlib/mktemp.c b/libc/stdlib/mktemp.c new file mode 100644 index 000000000..08b356710 --- /dev/null +++ b/libc/stdlib/mktemp.c @@ -0,0 +1,40 @@ + +#include <features.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/stat.h> + +char * mktemp(template) +char * template; +{ + int i; + int num; /* UNINITIALIZED */ + int n2; + int l = strlen(template); + struct stat stbuf; + + if (l<6) { + errno = EINVAL; + return 0; + } + + for(i=l-6;i<l;i++) + if (template[i] != 'X') { + errno = EINVAL; + return 0; + } + +again: + n2 = num; + for(i=l-1;i>=l-6;i--) { + template[i] = '0' + n2 % 10; + n2 /= 10; + } + + if (stat(template, &stbuf) == 0) { + num++; + goto again; + } + + return template; +} diff --git a/libc/stdlib/putenv.c b/libc/stdlib/putenv.c new file mode 100644 index 000000000..a7a453d5f --- /dev/null +++ b/libc/stdlib/putenv.c @@ -0,0 +1,62 @@ +/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk> + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ +#include <string.h> +#include <stdlib.h> +#include <malloc.h> + +extern char ** environ; +#define ADD_NUM 4 + +int +putenv(var) +const char * var; +{ +static char ** mall_env = 0; +static int extras = 0; + char **p, **d; + char * r; + int len; + + r = strchr(var, '='); + if( r == 0 ) len = strlen(var); + else len = r-var; + + if (!environ) { + environ = (char**)malloc(ADD_NUM * sizeof(char*)); + memset(environ, 0, sizeof(char*)*ADD_NUM); + extras = ADD_NUM; + } + + for(p=environ; *p; p++) + { + if( memcmp(var, *p, len) == 0 && (*p)[len] == '=' ) + { + while( p[0] = p[1] ) p++; + extras++; + break; + } + } + if( r == 0 ) return 0; + if( extras <= 0 ) /* Need more space */ + { + d = malloc((p-environ+1+ADD_NUM)*sizeof(char*)); + if( d == 0 ) return -1; + + memcpy((void*) d, (void*) environ, (p-environ+1)*sizeof(char*)); + p = d + (p-environ); + extras=ADD_NUM; + + if( mall_env ) free(mall_env); + environ = d; + mall_env = d; + } + *p++ = strdup((char*)var); + *p = '\0'; + extras--; + + return 0; +} + + diff --git a/libc/stdlib/qsort.c b/libc/stdlib/qsort.c new file mode 100644 index 000000000..cee53c398 --- /dev/null +++ b/libc/stdlib/qsort.c @@ -0,0 +1,166 @@ +/* + * This file lifted in toto from 'Dlibs' on the atari ST (RdeBath) + * + * + * Dale Schumacher 399 Beacon Ave. + * (alias: Dalnefre') St. Paul, MN 55104 + * dal@syntel.UUCP United States of America + * "It's not reality that's important, but how you perceive things." + */ +#include <string.h> + +char *_qbuf = 0; /* pointer to storage for qsort() */ + +#define PIVOT ((i+j)>>1) +#define moveitem(dst,src,size) if(dst != src) memcpy(dst, src, size) + +static +_wqsort(base, lo, hi, cmp) +register int *base; +register int lo; +register int hi; +register int (*cmp) (); +{ + int k; + register int i, j, t; + register int *p = &k; + + while (hi > lo) + { + i = lo; + j = hi; + t = PIVOT; + *p = base[t]; + base[t] = base[i]; + base[i] = *p; + while (i < j) + { + while (((*cmp) ((base + j), p)) > 0) + --j; + base[i] = base[j]; + while ((i < j) && (((*cmp) ((base + i), p)) <= 0)) + ++i; + base[j] = base[i]; + } + base[i] = *p; + if ((i - lo) < (hi - i)) + { + _wqsort(base, lo, (i - 1), cmp); + lo = i + 1; + } + else + { + _wqsort(base, (i + 1), hi, cmp); + hi = i - 1; + } + } +} + +static +_lqsort(base, lo, hi, cmp) +register long *base; +register int lo; +register int hi; +register int (*cmp) (); +{ + long k; + register int i, j, t; + register long *p = &k; + + while (hi > lo) + { + i = lo; + j = hi; + t = PIVOT; + *p = base[t]; + base[t] = base[i]; + base[i] = *p; + while (i < j) + { + while (((*cmp) ((base + j), p)) > 0) + --j; + base[i] = base[j]; + while ((i < j) && (((*cmp) ((base + i), p)) <= 0)) + ++i; + base[j] = base[i]; + } + base[i] = *p; + if ((i - lo) < (hi - i)) + { + _lqsort(base, lo, (i - 1), cmp); + lo = i + 1; + } + else + { + _lqsort(base, (i + 1), hi, cmp); + hi = i - 1; + } + } +} + +static +_nqsort(base, lo, hi, size, cmp) +register char *base; +register int lo; +register int hi; +register int size; +register int (*cmp) (); +{ + register int i, j; + register char *p = _qbuf; + + while (hi > lo) + { + i = lo; + j = hi; + p = (base + size * PIVOT); + moveitem(_qbuf, p, size); + moveitem(p, (base + size * i), size); + moveitem((base + size * i), _qbuf, size); + p = _qbuf; + while (i < j) + { + while (((*cmp) ((base + size * j), p)) > 0) + --j; + moveitem((base + size * i), (base + size * j), size); + while ((i < j) && (((*cmp) ((base + size * i), p)) <= 0)) + ++i; + moveitem((base + size * j), (base + size * i), size); + } + moveitem((base + size * i), p, size); + if ((i - lo) < (hi - i)) + { + _nqsort(base, lo, (i - 1), size, cmp); + lo = i + 1; + } + else + { + _nqsort(base, (i + 1), hi, size, cmp); + hi = i - 1; + } + } +} + +qsort(base, num, size, cmp) +char *base; +int num; +int size; +int (*cmp) (); +{ + char _qtemp[128]; + + if (_qbuf == 0) + { + if (size > sizeof(_qtemp))/* records too large! */ + return; + _qbuf = _qtemp; + } + if (size == 2) + _wqsort(base, 0, num - 1, cmp); + else if (size == 4) + _lqsort(base, 0, num - 1, cmp); + else + _nqsort(base, 0, num - 1, size, cmp); + if (_qbuf == _qtemp) + _qbuf = 0; +} diff --git a/libc/stdlib/rand.c b/libc/stdlib/rand.c new file mode 100644 index 000000000..4eb07894b --- /dev/null +++ b/libc/stdlib/rand.c @@ -0,0 +1,61 @@ +#ifdef ZX81_RNG +/* + * This is my favorite tiny RNG, If you had a ZX81 you may recognise it :-) + * (RdeBath) + */ + +#include <stdlib.h> + +#define MAXINT (((unsigned)-1)>>1) + +static unsigned int sseed = 0; + +int rand() +{ + return ( sseed = (((sseed+1L)*75L)%65537L)-1 ) & MAXINT; +} + +void srand(seed) +unsigned int seed; +{ + sseed=seed; +} + +#else + +/* + * This generator is a combination of three linear congruential generators + * with periods or 2^15-405, 2^15-1041 and 2^15-1111. It has a period that + * is the product of these three numbers. + */ + +static int seed1 = 1; +static int seed2 = 1; +static int seed3 = 1; +#define MAXINT (((unsigned)-1)>>1) + +#define CRANK(a,b,c,m,s) \ + q = s/a; \ + s = b*(s-a*q) - c*q; \ + if(s<0) s+=m; + +int rand() +{ + register int q, z; + CRANK(206, 157, 31, 32363, seed1); + CRANK(217, 146, 45, 31727, seed2); + CRANK(222, 142, 133, 31657, seed3); + + return seed1^seed2^seed3; +} + +void srand(seed) +unsigned int seed; +{ + seed &= MAXINT; + seed1= seed%32362 + 1; + seed2= seed%31726 + 1; + seed3= seed%31656 + 1; +} + +#endif diff --git a/libc/stdlib/setenv.c b/libc/stdlib/setenv.c new file mode 100644 index 000000000..0990fdec2 --- /dev/null +++ b/libc/stdlib/setenv.c @@ -0,0 +1,73 @@ +/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk> + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ +#include <string.h> +#include <stdlib.h> +#include <malloc.h> + +extern char ** environ; +#define ADD_NUM 4 + +int +setenv(var, value, overwrite) +const char * var; +const char * value; +int overwrite; +{ +static char ** mall_env = 0; +static int extras = 0; + char **p, **d; + char * t; + int len; + + len = strlen(var); + + if (!environ) { + environ = (char**)malloc(ADD_NUM * sizeof(char*)); + memset(environ, 0, sizeof(char*)*ADD_NUM); + extras = ADD_NUM; + } + + for(p=environ; *p; p++) + { + if( memcmp(var, *p, len) == 0 && (*p)[len] == '=' ) + { + if (!overwrite) + return -1; + while( p[0] = p[1] ) p++; + extras++; + break; + } + } + + if( extras <= 0 ) /* Need more space */ + { + d = malloc((p-environ+1+ADD_NUM)*sizeof(char*)); + if( d == 0 ) return -1; + + memcpy((void*) d, (void*) environ, (p-environ+1)*sizeof(char*)); + p = d + (p-environ); + extras=ADD_NUM; + + if( mall_env ) free(mall_env); + environ = d; + mall_env = d; + } + + t = malloc(len + 1 + strlen(value) + 1); + if (!t) + return -1; + + strcpy(t, var); + strcat(t, "="); + strcat(t, value); + + *p++ = (char*)t; + *p = '\0'; + extras--; + + return 0; +} + + diff --git a/libc/stdlib/strtod.c b/libc/stdlib/strtod.c new file mode 100644 index 000000000..0d3bb790a --- /dev/null +++ b/libc/stdlib/strtod.c @@ -0,0 +1,96 @@ +/* + * strtod.c - This file is part of the libc-8086 package for ELKS, + * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ +#include <stdlib.h> +#include <ctype.h> + +float +strtod(const char *nptr, char ** endptr) +{ + unsigned short negative; + float number; + float fp_part; + int exponent; + unsigned short exp_negative; + + /* advance beyond any leading whitespace */ + while (isspace(*nptr)) + nptr++; + + /* check for optional '+' or '-' */ + negative=0; + if (*nptr=='-') + { + negative=1; + nptr++; + } + else + if (*nptr=='+') + nptr++; + + number=0; + while (isdigit(*nptr)) + { + number=number*10+(*nptr-'0'); + nptr++; + } + + if (*nptr=='.') + { + nptr++; + fp_part=0; + while (isdigit(*nptr)) + { + fp_part=fp_part/10.0 + (*nptr-'0')/10.0; + nptr++; + } + number+=fp_part; + } + + if (*nptr=='e' || *nptr=='E') + { + nptr++; + exp_negative=0; + if (*nptr=='-') + { + exp_negative=1; + nptr++; + } + else + if (*nptr=='+') + nptr++; + + exponent=0; + while (isdigit(*nptr)) + { + exponent=exponent*10+(*nptr-'0'); + exponent++; + } + } + + while (exponent) + { + if (exp_negative) + number/=10; + else + number*=10; + exponent--; + } + return (negative ? -number:number); +} diff --git a/libc/stdlib/system.c b/libc/stdlib/system.c new file mode 100644 index 000000000..b764613be --- /dev/null +++ b/libc/stdlib/system.c @@ -0,0 +1,48 @@ + +#include <stddef.h> +#include <signal.h> +#include <unistd.h> + +int +system(command) +char * command; +{ + int wait_val, wait_ret, pid; + __sighandler_t save_quit, save_int, save_chld; + + if( command == 0 ) return 1; + + save_quit = signal(SIGQUIT, SIG_IGN); + save_int = signal(SIGINT, SIG_IGN); + save_chld = signal(SIGCHLD, SIG_DFL); + + if( (pid=vfork()) < 0 ) + { + signal(SIGQUIT, save_quit); + signal(SIGINT, save_int); + signal(SIGCHLD, save_chld); + return -1; + } + if( pid == 0 ) + { + signal(SIGQUIT, SIG_DFL); + signal(SIGINT, SIG_DFL); + signal(SIGCHLD, SIG_DFL); + + execl("/bin/sh", "sh", "-c", command, (char*)0); + _exit(127); + } + /* Signals are not absolutly guarenteed with vfork */ + signal(SIGQUIT, SIG_IGN); + signal(SIGINT, SIG_IGN); + + printf("Waiting for child %d\n", pid); + + if (wait4(pid, &wait_val, 0, 0) == -1) + wait_val = -1; + + signal(SIGQUIT, save_quit); + signal(SIGINT, save_int); + signal(SIGCHLD, save_chld); + return wait_val; +} |