diff options
Diffstat (limited to 'mdk-stage1/dietlibc/lib')
109 files changed, 1441 insertions, 440 deletions
diff --git a/mdk-stage1/dietlibc/lib/__dtostr.c b/mdk-stage1/dietlibc/lib/__dtostr.c index def091f16..e9a8a83d3 100644 --- a/mdk-stage1/dietlibc/lib/__dtostr.c +++ b/mdk-stage1/dietlibc/lib/__dtostr.c @@ -1,3 +1,4 @@ +#include <stdio.h> /* convert double to string. Helper for sprintf. */ int __dtostr(double d,char *buf,int maxlen,int prec) { @@ -14,8 +15,14 @@ int __dtostr(double d,char *buf,int maxlen,int prec) { char *oldbuf=buf; int initial=1; + if (d==0.0) { + *buf='0'; ++buf; + goto done; + } if (s) { d=-d; *buf='-'; --maxlen; buf++; } - if ((i=e10)>=0) { +/* printf("e=%d e10=%d prec=%d\n",e,e10,prec); */ + if (e10>=0) { + i=e10; while (i>10) { tmp=tmp*1e10; i-=10; } while (i>1) { tmp=tmp*10; --i; } } else { @@ -52,6 +59,20 @@ int __dtostr(double d,char *buf,int maxlen,int prec) { } /* step 5: loop through the digits, inserting the decimal point when * appropriate */ + if (d<1.0) { + double x=1.0; + int first=1; + do { + if (--maxlen<0) return buf-oldbuf; + *buf='0'; ++buf; + if (first) { + first=0; + *buf='.'; ++buf; + if (--maxlen<0) return buf-oldbuf; + } + x/=10.0; + } while (x>d); + } for (; prec>0; ) { double tmp2=d/tmp; char c; @@ -77,6 +98,7 @@ int __dtostr(double d,char *buf,int maxlen,int prec) { } else tmp/=10.0; } +done: *buf=0; return buf-oldbuf; } diff --git a/mdk-stage1/dietlibc/lib/__fstat64.c b/mdk-stage1/dietlibc/lib/__fstat64.c new file mode 100644 index 000000000..6f9fcb2c5 --- /dev/null +++ b/mdk-stage1/dietlibc/lib/__fstat64.c @@ -0,0 +1,25 @@ +#include "dietfeatures.h" + +#ifdef WANT_LARGEFILE_BACKCOMPAT +#include <sys/stat.h> +#ifndef __NO_STAT64 +#include <errno.h> + +extern int __dietlibc_fstat64(int __fd, struct stat64 *__buf); +extern void __stat64_cvt(const struct stat *src,struct stat64 *dest); + +int fstat64(int __fd, struct stat64 *__buf) { + if (__dietlibc_fstat64(__fd,__buf)) { + struct stat temp; +#ifdef WANT_THREAD_SAFE + if (*__errno_location()!=ENOSYS) return -1; +#else + if (errno!=ENOSYS) return -1; +#endif + if (fstat(__fd,&temp)) return -1; + __stat64_cvt(&temp,__buf); + } + return 0; +} +#endif +#endif diff --git a/mdk-stage1/dietlibc/lib/__getcwd.c b/mdk-stage1/dietlibc/lib/__getcwd.c new file mode 100644 index 000000000..e97fc4520 --- /dev/null +++ b/mdk-stage1/dietlibc/lib/__getcwd.c @@ -0,0 +1,10 @@ +#include <stdlib.h> + +extern int __syscall_getcwd(char* buf, size_t size); + +char *getcwd(char *buf, size_t size) { + int tmp; + if ((tmp=__syscall_getcwd(buf,size))<0) return 0; + buf[tmp]=0; + return buf; +} diff --git a/mdk-stage1/dietlibc/lib/__isnan.c b/mdk-stage1/dietlibc/lib/__isnan.c new file mode 100644 index 000000000..9d21e9824 --- /dev/null +++ b/mdk-stage1/dietlibc/lib/__isnan.c @@ -0,0 +1,14 @@ +#include <stdio.h> + +int __isnan(double d) { + unsigned long long *x=(unsigned long long *)&d; + return (*x==0x7FF8002000000000ll || *x==0x7FF0002000000000); +} + +#if 0 +TestFromIeeeExtended("7FFF0000000000000000"); /* +infinity */ +TestFromIeeeExtended("FFFF0000000000000000"); /* -infinity */ +TestFromIeeeExtended("7FFF8001000000000000"); /* Quiet NaN(1) */ +TestFromIeeeExtended("7FFF0001000000000000"); /* Signalling NaN(1) */ +TestFromIeeeExtended("3FFFFEDCBA9876543210"); /* accuracy test */ +#endif diff --git a/mdk-stage1/dietlibc/lib/__lltostr.c b/mdk-stage1/dietlibc/lib/__lltostr.c index f53dcfb80..eb4a27cef 100644 --- a/mdk-stage1/dietlibc/lib/__lltostr.c +++ b/mdk-stage1/dietlibc/lib/__lltostr.c @@ -1,7 +1,5 @@ #include <string.h> -static char *num="0123456789abcdefghijklmnopqrstuvwxyz"; - int __lltostr(char *s, int size, unsigned long long i, int base, char UpCase) { char *tmp; @@ -23,8 +21,7 @@ int __lltostr(char *s, int size, unsigned long long i, int base, char UpCase) while((tmp>s)&&(i)) { tmp--; - *tmp=num[i%base]; - if ((UpCase)&&(*tmp>96)) (*tmp)-=' '; + if ((*tmp=i%base+'0')>'9') *tmp+=(UpCase?'A':'a')-'9'-1; i=i/base; j++; } diff --git a/mdk-stage1/dietlibc/lib/__lstat64.c b/mdk-stage1/dietlibc/lib/__lstat64.c new file mode 100644 index 000000000..a871f3917 --- /dev/null +++ b/mdk-stage1/dietlibc/lib/__lstat64.c @@ -0,0 +1,25 @@ +#include "dietfeatures.h" + +#ifdef WANT_LARGEFILE_BACKCOMPAT +#include <sys/stat.h> +#ifndef __NO_STAT64 +#include <errno.h> + +extern int __dietlibc_lstat64(const char *__file, struct stat64 *__buf); +extern void __stat64_cvt(const struct stat *src,struct stat64 *dest); + +int lstat64(const char *__file, struct stat64 *__buf) { + if (__dietlibc_lstat64(__file,__buf)) { + struct stat temp; +#ifdef WANT_THREAD_SAFE + if (*__errno_location()!=ENOSYS) return -1; +#else + if (errno!=ENOSYS) return -1; +#endif + if (lstat(__file,&temp)) return -1; + __stat64_cvt(&temp,__buf); + } + return 0; +} +#endif +#endif diff --git a/mdk-stage1/dietlibc/lib/__ltostr.c b/mdk-stage1/dietlibc/lib/__ltostr.c index b2ebeb074..57e0690d2 100644 --- a/mdk-stage1/dietlibc/lib/__ltostr.c +++ b/mdk-stage1/dietlibc/lib/__ltostr.c @@ -1,7 +1,5 @@ #include <string.h> -static char *num="0123456789abcdefghijklmnopqrstuvwxyz"; - int __ltostr(char *s, int size, unsigned long i, int base, char UpCase) { char *tmp; @@ -23,8 +21,7 @@ int __ltostr(char *s, int size, unsigned long i, int base, char UpCase) while((tmp>s)&&(i)) { tmp--; - *tmp=num[i%base]; - if ((UpCase)&&(*tmp>96)) (*tmp)-=' '; + if ((*tmp=i%base+'0')>'9') *tmp+=(UpCase?'A':'a')-'9'-1; i=i/base; j++; } diff --git a/mdk-stage1/dietlibc/lib/__stat64.c b/mdk-stage1/dietlibc/lib/__stat64.c new file mode 100644 index 000000000..dfb0d4315 --- /dev/null +++ b/mdk-stage1/dietlibc/lib/__stat64.c @@ -0,0 +1,25 @@ +#include "dietfeatures.h" + +#ifdef WANT_LARGEFILE_BACKCOMPAT +#include <sys/stat.h> +#ifndef __NO_STAT64 +#include <errno.h> + +extern int __dietlibc_stat64(const char *__file, struct stat64 *__buf); +extern void __stat64_cvt(const struct stat *src,struct stat64 *dest); + +int stat64(const char *__file, struct stat64 *__buf) { + if (__dietlibc_stat64(__file,__buf)) { + struct stat temp; +#ifdef WANT_THREAD_SAFE + if (*__errno_location()!=ENOSYS) return -1; +#else + if (errno!=ENOSYS) return -1; +#endif + if (stat(__file,&temp)) return -1; + __stat64_cvt(&temp,__buf); + } + return 0; +} +#endif +#endif diff --git a/mdk-stage1/dietlibc/lib/__stat64_cvt.c b/mdk-stage1/dietlibc/lib/__stat64_cvt.c new file mode 100644 index 000000000..dced352a4 --- /dev/null +++ b/mdk-stage1/dietlibc/lib/__stat64_cvt.c @@ -0,0 +1,18 @@ +#include <sys/stat.h> +#ifndef __NO_STAT64 + +void __stat64_cvt(const struct stat *src,struct stat64 *dest) { + dest->st_dev=src->st_dev; + dest->st_ino=src->st_ino; + dest->st_mode=src->st_mode; + dest->st_nlink=src->st_nlink; + dest->st_uid=src->st_gid; + dest->st_rdev=src->st_rdev; + dest->st_size=src->st_size; + dest->st_blksize=src->st_blksize; + dest->st_blocks=src->st_blocks; + dest->st_atime=src->st_atime; + dest->st_mtime=src->st_mtime; + dest->st_ctime=src->st_ctime; +} +#endif diff --git a/mdk-stage1/dietlibc/lib/abort.c b/mdk-stage1/dietlibc/lib/abort.c index e6374c5ac..55bfb8f0f 100644 --- a/mdk-stage1/dietlibc/lib/abort.c +++ b/mdk-stage1/dietlibc/lib/abort.c @@ -1,8 +1,7 @@ #include <linux/types.h> #include <linux/signal.h> #include <signal.h> - -extern int exit(int code) __attribute__ ((noreturn)); +#include <stdlib.h> void abort() { sigset_t t; diff --git a/mdk-stage1/dietlibc/lib/accept.c b/mdk-stage1/dietlibc/lib/accept.c index a7ae824eb..c7e8254ca 100644 --- a/mdk-stage1/dietlibc/lib/accept.c +++ b/mdk-stage1/dietlibc/lib/accept.c @@ -2,7 +2,7 @@ extern int socketcall(int callno,long* args); -int accept(int a, void * addr, void * addr2) { +int __libc_accept(int a, void * addr, void * addr2) { #ifdef __i386__ return socketcall(SYS_ACCEPT, (long*)&a); #else @@ -11,4 +11,4 @@ int accept(int a, void * addr, void * addr2) { #endif } -int __libc_accept(int a, void * addr, void * addr2) __attribute__((weak,alias("accept"))); +int accept(int a, void * addr, void * addr2) __attribute__((weak,alias("__libc_accept"))); diff --git a/mdk-stage1/dietlibc/lib/alloc.c b/mdk-stage1/dietlibc/lib/alloc.c index 27b6838df..8cb87a69b 100644 --- a/mdk-stage1/dietlibc/lib/alloc.c +++ b/mdk-stage1/dietlibc/lib/alloc.c @@ -5,6 +5,7 @@ #include <linux/unistd.h> #include <asm/mman.h> #include <linux/errno.h> +#include "dietfeatures.h" #if 0 #include <sys/mman.h> @@ -31,8 +32,10 @@ extern void *memset(void *s, int c, size_t n); extern void *memcpy(void *dest, const void *src, size_t n); typedef struct t_alloc_head { + unsigned int magic1; struct t_alloc_head *ptr; unsigned long size; + unsigned int magic2; } alloc_head; /* guess what ? the virtual block size */ @@ -49,22 +52,28 @@ typedef struct t_alloc_head { #define PAGE_ALIGN(s) (((s)+MEM_BLOCK_SIZE-1)&(~(MEM_BLOCK_SIZE-1))) #define PAGE_ALIGNP(p) ((char*)PAGE_ALIGN((size_t)(p))) -#define END_OF_BLOCK(p) ((alloc_head*)(((char*)(p))+((p)->size))) -#define START_BLOCK(p) ((alloc_head*)(((char*)(p))-sizeof(alloc_head))) -#define START_DATA(p) (((char*)(p))+sizeof(alloc_head)) -#define MIN_ALLOC(s) (((((s)+sizeof(alloc_head)-1)/MEM_ALLOC_MIN)+1)*MEM_ALLOC_MIN) +#define END_OF_BLOCK(p) ((alloc_head*)(((char*)(p))+((p)->size))) +#define START_BLOCK(p) ((alloc_head*)(((char*)(p))-sizeof(alloc_head))) +#define START_DATA(p) (((char*)(p))+sizeof(alloc_head)) +#define MIN_ALLOC(s) (((((s)+sizeof(alloc_head)-1)/MEM_ALLOC_MIN)+1)*MEM_ALLOC_MIN) + +#define ALLOC_MAGIC1 0xbad2f7ee +#define ALLOC_MAGIC2 0xf7ee2bad /* freelist handler */ -static alloc_head base = {&base,0}; +static alloc_head base = {ALLOC_MAGIC1,&base,0,ALLOC_MAGIC2}; static char *alloc_get_end = MEM_ALLOC_START; -void free(void *ptr) +void __libc_free(void *ptr) { alloc_head *prev,*p,*block; if (ptr==NULL) return; block=START_BLOCK(ptr); + if (block->magic1 != ALLOC_MAGIC1) return; + if (block->magic2 != ALLOC_MAGIC2) return; + prev=&base; for (p=prev->ptr ; ; prev=p, p=p->ptr) { @@ -91,6 +100,7 @@ void free(void *ptr) prev->ptr = block->ptr; } } +void free(void *ptr) __attribute__((weak,alias("__libc_free"))); static void *alloc_get_mem(unsigned long size) { @@ -119,16 +129,18 @@ static void *alloc_get_mem(unsigned long size) /* make a header */ ah=(alloc_head*)tmp; + ah->magic1=ALLOC_MAGIC1; + ah->magic2=ALLOC_MAGIC2; ah->ptr=ah; ah->size=size; /* link new free maped pages in freelist */ - free(START_DATA(tmp)); + __libc_free(START_DATA(tmp)); return &base; } -void *malloc(size_t size) +void *__libc_malloc(size_t size) { alloc_head *p, *prev; size_t need; @@ -157,6 +169,8 @@ void *malloc(size_t size) else { prev->ptr=tmp; + tmp->magic1=ALLOC_MAGIC1; + tmp->magic2=ALLOC_MAGIC2; tmp->ptr=p->ptr; tmp->size=p->size-need; /* remaining size */ } @@ -169,11 +183,13 @@ void *malloc(size_t size) } else if (p==&base) { - if ((p=alloc_get_mem(need))==NULL) return NULL; + if ((p=alloc_get_mem(need))==NULL) goto err_out; } } +err_out: return NULL; } +void *malloc(size_t size) __attribute__((weak,alias("__libc_malloc"))); void *calloc(size_t nmemb,size_t size) { @@ -206,10 +222,12 @@ void *realloc(void *ptr,size_t size) } return NULL; } - if (diff>0) + if (diff>=sizeof(alloc_head)) { tmp->size=need; tf=END_OF_BLOCK(tmp); + tf->magic1=ALLOC_MAGIC1; + tf->magic2=ALLOC_MAGIC2; tf->ptr=tf; tf->size=diff; free(START_DATA(tf)); diff --git a/mdk-stage1/dietlibc/lib/assert_fail.c b/mdk-stage1/dietlibc/lib/assert_fail.c index caa70ef5b..3d6ba65c1 100644 --- a/mdk-stage1/dietlibc/lib/assert_fail.c +++ b/mdk-stage1/dietlibc/lib/assert_fail.c @@ -1,6 +1,7 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> +#include "dietwarning.h" extern int __ltostr(char *s, int size, unsigned long i, int base, char UpCase); @@ -25,3 +26,5 @@ void __assert_fail (const char *assertion, const char *file, unsigned int line, } abort(); } + +link_warning("__assert_fail","warning: your code still has assertions enabled!") diff --git a/mdk-stage1/dietlibc/lib/atexit.c b/mdk-stage1/dietlibc/lib/atexit.c index 2b644bf49..8204af06c 100644 --- a/mdk-stage1/dietlibc/lib/atexit.c +++ b/mdk-stage1/dietlibc/lib/atexit.c @@ -15,9 +15,9 @@ int atexit(function t) { extern void _exit(int code) __attribute__((noreturn)); void exit(int code) { - if (__atexitlist[0]) __atexitlist[0](); - if (__atexitlist[1]) __atexitlist[1](); - if (__atexitlist[2]) __atexitlist[2](); if (__atexitlist[3]) __atexitlist[3](); + if (__atexitlist[2]) __atexitlist[2](); + if (__atexitlist[1]) __atexitlist[1](); + if (__atexitlist[0]) __atexitlist[0](); _exit(code); } diff --git a/mdk-stage1/dietlibc/lib/atof.c b/mdk-stage1/dietlibc/lib/atof.c index 4839e5152..54221390e 100644 --- a/mdk-stage1/dietlibc/lib/atof.c +++ b/mdk-stage1/dietlibc/lib/atof.c @@ -1,5 +1,10 @@ #include <stdlib.h> double atof(const char *nptr) { +#if 0 return strtod(nptr,0); +#else + double tmp=strtod(nptr,0); + return tmp; +#endif } diff --git a/mdk-stage1/dietlibc/lib/bsearch.c b/mdk-stage1/dietlibc/lib/bsearch.c new file mode 100644 index 000000000..d2f5c74b2 --- /dev/null +++ b/mdk-stage1/dietlibc/lib/bsearch.c @@ -0,0 +1,20 @@ +#include <stdlib.h> + +void *bsearch(const void *key, const void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)) { + const char *v, *r; + int res; + r=base+(nmemb-1)*size; + do { + register int num=nmemb/2; + v=base+num*size; + if ((res=compar(key,v))<0) { + r=v-size; + nmemb=num; + } else { + if (res==0) return (void*)v; + base=v+size; + nmemb-=num; + } + } while ((char*)base<=r); + return 0; +} diff --git a/mdk-stage1/dietlibc/lib/cfgetospeed.c b/mdk-stage1/dietlibc/lib/cfgetospeed.c index 4e392a239..4d70888f7 100644 --- a/mdk-stage1/dietlibc/lib/cfgetospeed.c +++ b/mdk-stage1/dietlibc/lib/cfgetospeed.c @@ -2,5 +2,5 @@ #include <sys/types.h> speed_t cfgetospeed(struct termios *termios_p) { - return termios_p->c_ospeed; + return ((termios_p->c_iflag & (CBAUD|CBAUDEX))); } diff --git a/mdk-stage1/dietlibc/lib/cfmakeraw.c b/mdk-stage1/dietlibc/lib/cfmakeraw.c new file mode 100644 index 000000000..7f6df9913 --- /dev/null +++ b/mdk-stage1/dietlibc/lib/cfmakeraw.c @@ -0,0 +1,14 @@ +#include <termios.h> +#include <sys/ioctl.h> + +void cfmakeraw(struct termios *t) +{ + t->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON); + t->c_oflag &= ~OPOST; + t->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); + t->c_cflag &= ~(CSIZE|PARENB); + t->c_cflag |= CS8; + t->c_cc[VMIN] = 1; + t->c_cc[VTIME] = 0; +} + diff --git a/mdk-stage1/dietlibc/lib/closedir.c b/mdk-stage1/dietlibc/lib/closedir.c index c8d834f3b..e73025eb1 100644 --- a/mdk-stage1/dietlibc/lib/closedir.c +++ b/mdk-stage1/dietlibc/lib/closedir.c @@ -1,28 +1,10 @@ -#include <stdlib.h> +#include "dietdirent.h" #include <unistd.h> -#include <errno.h> -#undef _POSIX_PTHREADS -#include "dirstream.h" - -#undef closedir -int closedir(DIR * dir) -{ - int fd; - - if (!dir) { - errno = EBADF; - return -1; - } +#include <dirent.h> +#include <stdlib.h> - /* We need to check dd_fd. */ - if (dir->dd_fd == -1) - { - errno = EBADF; - return -1; - } - fd = dir->dd_fd; - dir->dd_fd = -1; - free(dir->dd_buf); - free(dir); - return close(fd); +int closedir (DIR* d) { + int res=close(d->fd); + free(d); + return res; } diff --git a/mdk-stage1/dietlibc/lib/connect.c b/mdk-stage1/dietlibc/lib/connect.c index f7f4f1ed7..01fd61a6c 100644 --- a/mdk-stage1/dietlibc/lib/connect.c +++ b/mdk-stage1/dietlibc/lib/connect.c @@ -2,7 +2,7 @@ extern int socketcall(int callno,long* args); -int connect(int a, void * b, int c) { +int __libc_connect(int a, void * b, int c) { #ifdef __i386__ return socketcall(SYS_CONNECT, (long*)&a); #else @@ -11,4 +11,4 @@ int connect(int a, void * b, int c) { #endif } -int __libc_connect(int a, void * b, int c) __attribute__((weak,alias("connect"))); +int connect(int a, void * b, int c) __attribute__((weak,alias("__libc_connect"))); diff --git a/mdk-stage1/dietlibc/lib/creat.c b/mdk-stage1/dietlibc/lib/creat.c new file mode 100644 index 000000000..82145b515 --- /dev/null +++ b/mdk-stage1/dietlibc/lib/creat.c @@ -0,0 +1,5 @@ +#include <fcntl.h> + +int creat(const char *file,mode_t mode) { + return open(file,O_WRONLY|O_CREAT|O_TRUNC,mode); +} diff --git a/mdk-stage1/dietlibc/lib/creat64.c b/mdk-stage1/dietlibc/lib/creat64.c index 923c1baaa..8cf897b57 100644 --- a/mdk-stage1/dietlibc/lib/creat64.c +++ b/mdk-stage1/dietlibc/lib/creat64.c @@ -1,5 +1,9 @@ #include <fcntl.h> +#ifndef O_LARGEFILE +#define O_LARGEFILE 0 +#endif + int creat64(const char *file,mode_t mode) { - return open64(file,O_WRONLY|O_CREAT|O_TRUNC,mode); + return open(file,O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE,mode); } diff --git a/mdk-stage1/dietlibc/lib/exec_lib.c b/mdk-stage1/dietlibc/lib/exec_lib.c new file mode 100644 index 000000000..3129224a0 --- /dev/null +++ b/mdk-stage1/dietlibc/lib/exec_lib.c @@ -0,0 +1,20 @@ +#include <unistd.h> +#include <paths.h> + +extern char **environ; + +int __exec_shell(const char *file, char *const argv[]) { + int i; + + for (i = 0; argv[i]; i++); + + { + char *shell_argv[i + 1]; + shell_argv[0] = _PATH_BSHELL; + shell_argv[1] = (char *) file; + for (; i > 1; i--) + shell_argv[i] = argv[i - 1]; + return execve(_PATH_BSHELL, shell_argv, environ); + } +} + diff --git a/mdk-stage1/dietlibc/lib/exec_lib.h b/mdk-stage1/dietlibc/lib/exec_lib.h new file mode 100644 index 000000000..0971bd1fb --- /dev/null +++ b/mdk-stage1/dietlibc/lib/exec_lib.h @@ -0,0 +1,9 @@ +#ifndef __EXEC_LIB_H +#define __EXEC_LIB_H + +#include <paths.h> + +extern int __exec_shell(const char *file, char *const argv[]); + +#endif /* __EXEC_LIB_H */ + diff --git a/mdk-stage1/dietlibc/lib/execl.c b/mdk-stage1/dietlibc/lib/execl.c index ae28fb850..71459e71f 100644 --- a/mdk-stage1/dietlibc/lib/execl.c +++ b/mdk-stage1/dietlibc/lib/execl.c @@ -3,7 +3,7 @@ #include <errno.h> #include <stdlib.h> -int execl( const char *path, ...) { +int execl( const char *path,...) { va_list ap; int n,i; char **argv,*tmp; diff --git a/mdk-stage1/dietlibc/lib/execlp.c b/mdk-stage1/dietlibc/lib/execlp.c new file mode 100644 index 000000000..3aea1e960 --- /dev/null +++ b/mdk-stage1/dietlibc/lib/execlp.c @@ -0,0 +1,26 @@ +#include <stdarg.h> +#include <unistd.h> +#include <errno.h> +#include <stdlib.h> +#include "dietstdarg.h" + +int execlp(const char* file, const char *arg,...) { + va_list ap,bak; + int n,i; + char **argv,*tmp; + va_start(ap, arg); + va_copy(bak,ap); + n=2; + while ((tmp=va_arg(ap,char *))) + ++n; + va_end (ap); + if ((argv=(char **)alloca(n*sizeof(char*)))) { + argv[0]=arg; + for (i=0; i<n; ++i) + argv[i+1]=va_arg(bak,char *); + va_end (bak); + return execvp(file,argv); + } + __set_errno(ENOMEM); + return -1; +} diff --git a/mdk-stage1/dietlibc/lib/execv.c b/mdk-stage1/dietlibc/lib/execv.c new file mode 100644 index 000000000..efd760253 --- /dev/null +++ b/mdk-stage1/dietlibc/lib/execv.c @@ -0,0 +1,13 @@ +#include <limits.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <errno.h> +#include "exec_lib.h" + +int execv(const char *file, char *const argv[]) { + if (execve(file,argv,environ)==-1) { + if (errno==ENOEXEC) __exec_shell(file,argv); + } + return -1; +} diff --git a/mdk-stage1/dietlibc/lib/execvp.c b/mdk-stage1/dietlibc/lib/execvp.c index 809252990..20521d69f 100644 --- a/mdk-stage1/dietlibc/lib/execvp.c +++ b/mdk-stage1/dietlibc/lib/execvp.c @@ -2,25 +2,8 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> -#include <paths.h> #include <errno.h> - -extern char **environ; - -static int exec_shell(const char *file, char *const argv[]) { - int i; - - for (i = 0; argv[i]; i++); - - if (1) { - char *shell_argv[i + 1]; - shell_argv[0] = _PATH_BSHELL; - shell_argv[1] = (char *) file; - for (; i > 1; i--) - shell_argv[i] = argv[i - 1]; - return execve(_PATH_BSHELL, shell_argv, environ); - } -} +#include "exec_lib.h" int execvp(const char *file, char *const argv[]) { char *path=getenv("PATH"); @@ -28,7 +11,7 @@ int execvp(const char *file, char *const argv[]) { char buf[PATH_MAX]; if (strchr((char*)file,'/')) { if (execve(file,argv,environ)==-1) { - if (errno==ENOEXEC) exec_shell(file,argv); + if (errno==ENOEXEC) __exec_shell(file,argv); return -1; } } @@ -45,7 +28,7 @@ int execvp(const char *file, char *const argv[]) { buf[next-cur]='/'; memmove(&buf[next-cur+1],file,strlen(file)+1); if (execve(buf,argv,environ)==-1) { - if (errno==ENOEXEC) return exec_shell(buf,argv); + if (errno==ENOEXEC) return __exec_shell(buf,argv); if ((errno!=EACCES) && (errno!=ENOENT)) return -1; } if (*next==0) break; diff --git a/mdk-stage1/dietlibc/lib/getopt.c b/mdk-stage1/dietlibc/lib/getopt.c new file mode 100644 index 000000000..93097122f --- /dev/null +++ b/mdk-stage1/dietlibc/lib/getopt.c @@ -0,0 +1,118 @@ +#include "getopt.h" +#include <string.h> + +/* + * by Olaf Dreesen + */ + +int opterr; + +int optind=1; +char *optarg; + +static int opt_unknown=1,opt_unknown_len; + +static int getopt_check(int c,char*o,int ol) +{ + int i; + if (c==':') return 2; + for (i=0;i<ol;i++) + { + if (o[i]==c) + { + if (o[i+1]==':') return 1; + return 0; + } + } + return 2; +} + +static void getopt_sort(char*v[],int oi) +{ + int i; + char *tmp, *tmp2=0; + + if (opt_unknown_len) + { + tmp=v[optind-(1+oi)]; + if (oi) tmp2=v[optind-1]; + + for (i=opt_unknown+opt_unknown_len;i>opt_unknown;i--) v[i+oi]=v[i-1]; + + v[opt_unknown++]=tmp; + if (oi) v[opt_unknown++]=tmp2; + } +} + +static char* nextchar; +int getopt(int c,char*v[],char*o) +{ + int ol=strlen(o); + int ret=0; + int oi=0; + + optarg=0; + + while (nextchar || (optind<c)) + { + if (nextchar) + { + if ((ret=(*(++nextchar)))) + { + switch (getopt_check(ret,o,ol)) + { + case 1: + if (*(++nextchar)) + optarg=nextchar; + else + { + if (optind<c) + { + oi=1; + optarg=v[optind++]; + } + else + ret='?'; + } + nextchar=0; + case 0: + if (!nextchar) + getopt_sort(v,oi); + else + if (!(*(nextchar+1))) + getopt_sort(v,oi); + return ret; + break; + default: + return '?'; + break; + } + } + else + nextchar=0; + } + else + { + if ((v[optind][0]=='-')&&((v[optind][1]!=0))) + { + if ((v[optind][1]=='-')&&(v[optind][2]==0)) + { + getopt_sort(v,oi); + optind=opt_unknown; + return -1; + } + else + { + nextchar=v[optind]; + } + } + else + { + ++opt_unknown_len; + } + ++optind; + } + } + optind=opt_unknown; + return -1; +} diff --git a/mdk-stage1/dietlibc/lib/getpgrp.c b/mdk-stage1/dietlibc/lib/getpgrp.c new file mode 100644 index 000000000..ee2ab0257 --- /dev/null +++ b/mdk-stage1/dietlibc/lib/getpgrp.c @@ -0,0 +1,6 @@ +#include <unistd.h> + +int getpgrp() +{ + return getpgid(0); +} diff --git a/mdk-stage1/dietlibc/lib/getservent.c b/mdk-stage1/dietlibc/lib/getservent.c index ee6a77c21..bf25d046b 100644 --- a/mdk-stage1/dietlibc/lib/getservent.c +++ b/mdk-stage1/dietlibc/lib/getservent.c @@ -5,6 +5,7 @@ #include <errno.h> #include <netinet/in.h> #include <string.h> +#include <ctype.h> static int servicesfd=-1; static char* servicesmap; @@ -14,29 +15,13 @@ static char* aliases[10]; static char *cur; -static inline int isalpha(char c) { - return (c>='a' && c<='z') || (c>='A' && c<='Z'); -} - -static inline int isdigit(char c) { - return (c>='0' && c<='9'); -} - -static inline int isalnum(char c) { - return isalpha(c) || isdigit(c); -} - -static inline int isblank(char c) { - return (c==' ' || c=='\t'); -} - /* nameserver 42/tcp name # IEN 116 */ struct servent *getservent(void) { static struct servent se; char *last; int aliasidx; if (servicesfd<0) { - servicesfd=open("/etc/services",O_RDONLY); + servicesfd=open(_PATH_SERVICES,O_RDONLY); if (servicesfd<0) return 0; serviceslen=lseek(servicesfd,0,SEEK_END); servicesmap=mmap(0,serviceslen,PROT_READ|PROT_WRITE,MAP_PRIVATE,servicesfd,0); @@ -71,17 +56,17 @@ again: if (*cur!='/') goto parseerror; cur++; se.s_proto=cur; - while (cur<last && isalpha(*cur)) cur++; + while (cur<last && isalpha(*cur)) ++cur; if (cur>=last) return 0; if (*cur=='\n') { *cur++=0; return &se; } *cur=0; cur++; /* now the aliases */ - for (aliasidx=0;aliasidx<10;aliasidx++) { - while (cur<last && isblank(*cur)) cur++; + for (aliasidx=0;aliasidx<10;++aliasidx) { + while (cur<last && isblank(*cur)) ++cur; aliases[aliasidx]=cur; - while (cur<last && isalpha(*cur)) cur++; + while (cur<last && isalpha(*cur)) ++cur; + if (*cur=='\n') { *cur++=0; ++aliasidx; break; } if (cur>=last || !isblank(*cur)) break; - if (*cur=='\n') { *cur++=0; break; } *cur++=0; } aliases[aliasidx]=0; @@ -99,8 +84,13 @@ error: return 0; } +void setservent(int stayopen) { + cur=servicesmap; +} + struct servent *getservbyname(const char *name, const char *proto) { struct servent *s; + setservent(0); for (s=getservent(); s; s=getservent()) { char **tmp; #if 0 @@ -109,6 +99,16 @@ struct servent *getservbyname(const char *name, const char *proto) { write(1,"/",1); write(1,s->s_proto,strlen(s->s_proto)); write(1,"\n",1); + if (!strcmp(name,"auth")) { + tmp=s->s_aliases; + write(1," aka ",5); + while (*tmp) { + write(1,*tmp,strlen(*tmp)); + write(1,", ",2); + ++tmp; + } + write(1,"\n",1); + } #endif if (!strcmp(name,s->s_name) && !strcmp(proto,s->s_proto)) return s; @@ -128,10 +128,6 @@ struct servent *getservbyport(int port, const char *proto) { return 0; } -void setservent(int stayopen) { - cur=servicesmap; -} - void endservent(void) { if (servicesmap!=(char*)-1) munmap(servicesmap,serviceslen); if (servicesfd!=-1) close(servicesfd); diff --git a/mdk-stage1/dietlibc/lib/htonl.c b/mdk-stage1/dietlibc/lib/htonl.c new file mode 100644 index 000000000..490de42c4 --- /dev/null +++ b/mdk-stage1/dietlibc/lib/htonl.c @@ -0,0 +1,12 @@ +#include <endian.h> + +unsigned long int htonl(unsigned long int hostlong) { +#if __BYTE_ORDER==__LITTLE_ENDIAN + return (hostlong>>24) | ((hostlong&0xff0000)>>8) | + ((hostlong&0xff00)<<8) | (hostlong<<24); +#else + return hostlong; +#endif +} + +unsigned long int ntohl(unsigned long int hostlong) __attribute__((weak,alias("htonl"))); diff --git a/mdk-stage1/dietlibc/lib/htons.c b/mdk-stage1/dietlibc/lib/htons.c index 92a43f937..765d3bbc5 100644 --- a/mdk-stage1/dietlibc/lib/htons.c +++ b/mdk-stage1/dietlibc/lib/htons.c @@ -1,12 +1,11 @@ -#include <asm/byteorder.h> +#include <endian.h> -#undef htons -#ifdef __i386__ -unsigned short int htons(unsigned short int netshort) { - return ___arch__swab16(netshort); -} +unsigned short int htons(unsigned short int hostshort) { +#if __BYTE_ORDER==__LITTLE_ENDIAN + return ((hostshort>>8)&0xff) | (hostshort<<8); #else -unsigned short int htons(unsigned short int netshort) { - return netshort; -} + return hostshort; #endif +} + +unsigned short int ntohs(unsigned short int hostshort) __attribute__((weak,alias("htons"))); diff --git a/mdk-stage1/dietlibc/lib/isalnum.c b/mdk-stage1/dietlibc/lib/isalnum.c index 19e5151d5..4d363fab9 100644 --- a/mdk-stage1/dietlibc/lib/isalnum.c +++ b/mdk-stage1/dietlibc/lib/isalnum.c @@ -1,6 +1,7 @@ #include <ctype.h> -int isalnum(int c) { +int __isalnum_ascii(int c) { return isalpha(c) || isdigit(c); } +int isalnum(int c) __attribute__((weak,alias("__isalnum_ascii"))); diff --git a/mdk-stage1/dietlibc/lib/isalpha.c b/mdk-stage1/dietlibc/lib/isalpha.c index db04c3fae..07ea69696 100644 --- a/mdk-stage1/dietlibc/lib/isalpha.c +++ b/mdk-stage1/dietlibc/lib/isalpha.c @@ -1,6 +1,7 @@ #include <ctype.h> -inline int isalpha(int c) { +int __isalpha_ascii(int c) { return (c>='a' && c<='z') || (c>='A' && c<='Z'); } +int isalpha(int c) __attribute__((weak,alias("__isalpha_ascii"))); diff --git a/mdk-stage1/dietlibc/lib/isascii.c b/mdk-stage1/dietlibc/lib/isascii.c index e627efb41..e06994783 100644 --- a/mdk-stage1/dietlibc/lib/isascii.c +++ b/mdk-stage1/dietlibc/lib/isascii.c @@ -1,6 +1,6 @@ #include <ctype.h> -inline int isascii(int c) { +int isascii(int c) { return (c & 0x80) == 0; } diff --git a/mdk-stage1/dietlibc/lib/iscntrl.c b/mdk-stage1/dietlibc/lib/iscntrl.c new file mode 100644 index 000000000..a183a54f1 --- /dev/null +++ b/mdk-stage1/dietlibc/lib/iscntrl.c @@ -0,0 +1,7 @@ +#include <ctype.h> + +int __iscntrl_ascii(int c) { + return (c<32) || (c==127); +} + +int iscntrl(int c) __attribute__((weak,alias("__iscntrl_ascii"))); diff --git a/mdk-stage1/dietlibc/lib/isdigit.c b/mdk-stage1/dietlibc/lib/isdigit.c index 734eb5197..8a7c3e801 100644 --- a/mdk-stage1/dietlibc/lib/isdigit.c +++ b/mdk-stage1/dietlibc/lib/isdigit.c @@ -1,6 +1,7 @@ #include <ctype.h> -inline int isdigit(int c) { +int __isdigit_ascii(int c) { return (c>='0' && c<='9'); } +int isdigit(int c) __attribute__((weak,alias("__isdigit_ascii"))); diff --git a/mdk-stage1/dietlibc/lib/isgraph.c b/mdk-stage1/dietlibc/lib/isgraph.c new file mode 100644 index 000000000..807f90ff0 --- /dev/null +++ b/mdk-stage1/dietlibc/lib/isgraph.c @@ -0,0 +1,5 @@ +int __isgraph_ascii(int c) { + return (c>=33 && c<=126); +} + +int isgraph(int c) __attribute__((weak,alias("__isgraph_ascii"))); diff --git a/mdk-stage1/dietlibc/lib/islower.c b/mdk-stage1/dietlibc/lib/islower.c new file mode 100644 index 000000000..6a9afa519 --- /dev/null +++ b/mdk-stage1/dietlibc/lib/islower.c @@ -0,0 +1,7 @@ +#include <ctype.h> + +int __islower_ascii(int c) { + return (c>='a' && c<='z'); +} + +int islower(int c) __attribute__((weak,alias("__islower_ascii"))); diff --git a/mdk-stage1/dietlibc/lib/isprint.c b/mdk-stage1/dietlibc/lib/isprint.c new file mode 100644 index 000000000..e980658a5 --- /dev/null +++ b/mdk-stage1/dietlibc/lib/isprint.c @@ -0,0 +1,6 @@ + +int __isprint_ascii(int c) { + return (c>=32 && c<=126); +} + +int isprint(int c) __attribute__((weak,alias("__isprint_ascii"))); diff --git a/mdk-stage1/dietlibc/lib/ispunct.c b/mdk-stage1/dietlibc/lib/ispunct.c new file mode 100644 index 000000000..2fd1183b1 --- /dev/null +++ b/mdk-stage1/dietlibc/lib/ispunct.c @@ -0,0 +1,7 @@ +#include <ctype.h> + +int __ispunct_ascii(int c) { + return isprint(c) && !( isalnum(c) || isspace(c) ); +} + +int ispunct(int c) __attribute__((weak,alias("__ispunct_ascii"))); diff --git a/mdk-stage1/dietlibc/lib/isspace.c b/mdk-stage1/dietlibc/lib/isspace.c index ab39e81bc..916f784ab 100644 --- a/mdk-stage1/dietlibc/lib/isspace.c +++ b/mdk-stage1/dietlibc/lib/isspace.c @@ -1,6 +1,8 @@ #include <ctype.h> -int isspace(int ch) +int __isspace_ascii(int ch) { return ((ch==' ')||(ch=='\f')||(ch=='\t')||(ch=='\v')||(ch=='\r')||(ch=='\n')); } + +int isspace(int c) __attribute__((weak,alias("__isspace_ascii"))); diff --git a/mdk-stage1/dietlibc/lib/isupper.c b/mdk-stage1/dietlibc/lib/isupper.c new file mode 100644 index 000000000..933dfc169 --- /dev/null +++ b/mdk-stage1/dietlibc/lib/isupper.c @@ -0,0 +1,7 @@ +#include <ctype.h> + +int __isupper_ascii(int c) { + return (c>='A' && c<='Z'); +} + +int isupper(int c) __attribute__((weak,alias("__isupper_ascii"))); diff --git a/mdk-stage1/dietlibc/lib/isxdigit.c b/mdk-stage1/dietlibc/lib/isxdigit.c new file mode 100644 index 000000000..22a711f2d --- /dev/null +++ b/mdk-stage1/dietlibc/lib/isxdigit.c @@ -0,0 +1,5 @@ +int __isxdigit_ascii(int c) { + return ((c>='0'&&c<='9') || (c>='A'&&c<='F') || (c>='a'&&c<='f')); +} + +int isxdigit(int c) __attribute__((weak,alias("__isxdigit_ascii"))); diff --git a/mdk-stage1/dietlibc/lib/lseek64.c b/mdk-stage1/dietlibc/lib/lseek64.c new file mode 100644 index 000000000..f39e779f9 --- /dev/null +++ b/mdk-stage1/dietlibc/lib/lseek64.c @@ -0,0 +1,22 @@ +#include "dietfeatures.h" + +#ifdef WANT_LARGEFILE_BACKCOMPAT +#include <sys/stat.h> +#ifndef __NO_STAT64 +#include <errno.h> +#include <unistd.h> + +loff_t lseek64(int fildes, loff_t offset, int whence) { + loff_t tmp; + if (llseek(fildes,offset>>32,offset&0xffffffff,&tmp,whence)) { +#ifdef WANT_THREAD_SAFE + if (*__errno_location()!=ENOSYS) return -1; +#else + if (errno!=ENOSYS) return -1; +#endif + return (loff_t)lseek(fildes,(off_t)offset,whence); + } + return tmp; +} +#endif +#endif diff --git a/mdk-stage1/dietlibc/lib/memcmp.c b/mdk-stage1/dietlibc/lib/memcmp.c index 8bce6c975..c05a46863 100644 --- a/mdk-stage1/dietlibc/lib/memcmp.c +++ b/mdk-stage1/dietlibc/lib/memcmp.c @@ -12,3 +12,5 @@ int memcmp(const void *dst, const void *src, size_t count) { } return 0; } + +int bcmp(const char *a,const char *b,size_t c) __attribute__((weak,alias("memcmp"))); diff --git a/mdk-stage1/dietlibc/lib/mkfifo.c b/mdk-stage1/dietlibc/lib/mkfifo.c index 97659490c..596efbe27 100644 --- a/mdk-stage1/dietlibc/lib/mkfifo.c +++ b/mdk-stage1/dietlibc/lib/mkfifo.c @@ -1,6 +1,6 @@ #include <linux/stat.h> #include <unistd.h> -int mkfifo(char *fn,int mode) { +int mkfifo(const char *fn,mode_t mode) { return mknod(fn,S_IFIFO|mode,0); } diff --git a/mdk-stage1/dietlibc/lib/msgctl.c b/mdk-stage1/dietlibc/lib/msgctl.c new file mode 100644 index 000000000..19ea6d8cf --- /dev/null +++ b/mdk-stage1/dietlibc/lib/msgctl.c @@ -0,0 +1,10 @@ +#include <sys/types.h> +#include <sys/ipc.h> +#include <sys/msg.h> +#include <asm/ipc.h> + +extern int __ipc(); + +int msgctl(int msqid, int cmd, struct msqid_ds *buf) { + return __ipc(MSGCTL,msqid,cmd,0,buf); +} diff --git a/mdk-stage1/dietlibc/lib/msgget.c b/mdk-stage1/dietlibc/lib/msgget.c new file mode 100644 index 000000000..9bca09ebe --- /dev/null +++ b/mdk-stage1/dietlibc/lib/msgget.c @@ -0,0 +1,10 @@ +#include <sys/types.h> +#include <sys/ipc.h> +#include <sys/msg.h> +#include <asm/ipc.h> + +extern int __ipc(); + +int msgget(key_t key,int flag) { + return __ipc(MSGGET,key,flag,0,0); +} diff --git a/mdk-stage1/dietlibc/lib/msgrcv.c b/mdk-stage1/dietlibc/lib/msgrcv.c new file mode 100644 index 000000000..b4ae9cc6c --- /dev/null +++ b/mdk-stage1/dietlibc/lib/msgrcv.c @@ -0,0 +1,13 @@ +#include <sys/types.h> +#include <sys/ipc.h> +#include <sys/msg.h> +#include <asm/ipc.h> + +extern int __ipc(); + +int msgrcv(int msqid, void *msgp, size_t msgsz, long int msgtyp, int msgflg) { + struct ipc_kludge tmp; + tmp.msgp = msgp; + tmp.msgtyp = msgtyp; + return __ipc(MSGRCV,msqid, msgsz, msgflg, &tmp); +} diff --git a/mdk-stage1/dietlibc/lib/msgsnd.c b/mdk-stage1/dietlibc/lib/msgsnd.c new file mode 100644 index 000000000..6203053f0 --- /dev/null +++ b/mdk-stage1/dietlibc/lib/msgsnd.c @@ -0,0 +1,10 @@ +#include <sys/types.h> +#include <sys/ipc.h> +#include <sys/msg.h> +#include <asm/ipc.h> + +extern int __ipc(); + +int msgsnd (int msqid, const void *msgp, size_t msgsz, int msgflg) { + return __ipc(MSGSND,msqid, msgsz, msgflg, msgp); +} diff --git a/mdk-stage1/dietlibc/lib/nop.c b/mdk-stage1/dietlibc/lib/nop.c index 623278dee..c05bea813 100644 --- a/mdk-stage1/dietlibc/lib/nop.c +++ b/mdk-stage1/dietlibc/lib/nop.c @@ -1,7 +1,7 @@ -int __fflush_stdin() __attribute__((weak,alias("__nop"))); -int __fflush_stdout() __attribute__((weak,alias("__nop"))); -int __fflush_stderr() __attribute__((weak,alias("__nop"))); +int __fflush_stdin() __attribute__((weak,alias("__return0"))); +int __fflush_stdout() __attribute__((weak,alias("__return0"))); +int __fflush_stderr() __attribute__((weak,alias("__return0"))); /* used for weak aliases */ -int __nop() { return 0; } +int __return0() { return 0; } diff --git a/mdk-stage1/dietlibc/lib/open64.c b/mdk-stage1/dietlibc/lib/open64.c index cab7e992e..f1499d017 100644 --- a/mdk-stage1/dietlibc/lib/open64.c +++ b/mdk-stage1/dietlibc/lib/open64.c @@ -1,11 +1,14 @@ #include <linux/types.h> #include <linux/fcntl.h> -#include <unistd.h> -#ifdef O_LARGEFILE -int open64(const char* file,int oflag,int mode) { +#ifndef O_LARGEFILE +#define O_LARGEFILE 0 +#endif + +extern int open(const char* file,int oflag,int mode); + +int __libc_open64(const char* file,int oflag,int mode) { return open(file,oflag|O_LARGEFILE,mode); } -int __libc_open64(const char* file,int oflag,int mode) __attribute__((weak,alias("open64"))); -#endif +int open64(const char* file,int oflag,int mode) __attribute__((weak,alias("__libc_open64"))); diff --git a/mdk-stage1/dietlibc/lib/opendir.c b/mdk-stage1/dietlibc/lib/opendir.c index 05c0b9bc8..5c0c4a305 100644 --- a/mdk-stage1/dietlibc/lib/opendir.c +++ b/mdk-stage1/dietlibc/lib/opendir.c @@ -1,63 +1,18 @@ -#include <sys/stat.h> +#include "dietdirent.h" +#include <unistd.h> +#include <dirent.h> #include <stdlib.h> -#include <string.h> #include <fcntl.h> -#include <unistd.h> -#undef _POSIX_PTHREADS -#include <errno.h> - -#include "dirstream.h" - -#ifndef O_DIRECTORY -#define O_DIRECTORY 0200000 /* must be a directory */ -#endif - -/* - * opendir just makes an open() call - it return NULL if it fails - * (open sets errno), otherwise it returns a DIR * pointer. - */ -#undef opendir -DIR * -opendir(const char * name) -{ - int fd; - struct stat statbuf; - struct dirent *buf; - DIR *ptr; - - /* - if (stat(name,&statbuf)) return NULL; - if (!S_ISDIR(statbuf.st_mode)) { - errno = ENOTDIR; - return NULL; - } - */ - if ((fd = open(name,O_RDONLY|O_DIRECTORY)) < 0) - return NULL; - /* According to POSIX, directory streams should be closed when - * exec. From "Anna Pluzhnikov" <besp@midway.uchicago.edu>. - */ - if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0) - return NULL; - if (!(ptr=malloc(sizeof(*ptr)))) { - close(fd); - errno = ENOMEM; - return NULL; - } - - ptr->dd_max = statbuf.st_blksize; - if (ptr->dd_max < 512) - ptr->dd_max = 512; - if (!(buf=malloc(ptr->dd_max))) { - close(fd); - free(ptr); - errno = ENOMEM; - return NULL; +DIR *opendir (const char *name) { + DIR *t=(DIR*)malloc(sizeof(DIR)); + if (t) { + if ((t->fd=open(name,O_RDONLY|O_DIRECTORY))>=0) { + t->num=t->cur=0; + } else { + free(t); + t=0; + } } - ptr->dd_fd = fd; - ptr->dd_nextoff = ptr->dd_nextloc = ptr->dd_size = 0; - ptr->dd_buf = buf; - ptr->dd_getdents = unknown; - return ptr; + return t; } diff --git a/mdk-stage1/dietlibc/lib/perror.c b/mdk-stage1/dietlibc/lib/perror.c index 5476d76a1..ecab7250b 100644 --- a/mdk-stage1/dietlibc/lib/perror.c +++ b/mdk-stage1/dietlibc/lib/perror.c @@ -1,5 +1,7 @@ +#include "dietfeatures.h" #include <unistd.h> #include <string.h> +#include <errno.h> extern char *sys_errlist[]; extern int sys_nerr; @@ -10,7 +12,11 @@ void perror(const char *s) { write(2,s,strlen(s)); write(2,": ",2); if (errno>=0 && errno<sys_nerr) +#ifdef WANT_THREAD_SAFE + message=sys_errlist[*__errno_location()]; +#else message=sys_errlist[errno]; +#endif write(2,message,strlen(message)); write(2,"\n",1); } diff --git a/mdk-stage1/dietlibc/lib/puts.c b/mdk-stage1/dietlibc/lib/puts.c index 01f6e50c4..54415151d 100644 --- a/mdk-stage1/dietlibc/lib/puts.c +++ b/mdk-stage1/dietlibc/lib/puts.c @@ -1,6 +1,12 @@ #include <unistd.h> #include <string.h> +#include "dietstdio.h" +#include "dietfeatures.h" int puts(const char *s) { +#ifdef WANT_BUFFERED_STDIO + return fwrite(s,1,strlen(s),stdout) && fputc('\n',stdout); +#else return write(1,s,strlen(s)) && write(1,"\n",1); +#endif } diff --git a/mdk-stage1/dietlibc/lib/qsort.c b/mdk-stage1/dietlibc/lib/qsort.c new file mode 100644 index 000000000..2a8824bf3 --- /dev/null +++ b/mdk-stage1/dietlibc/lib/qsort.c @@ -0,0 +1,125 @@ +#include <stdlib.h> +#include <assert.h> + +/* comments: + 1. insertion sort sofort, nicht nachträglich + 2. threshold = 16 + */ + +static inline void iswap(void *a,void *b,size_t size) { + register char *x=a; + register char *y=b; + register char *z=x+size; + while (x<z) { + register char tmp=*x; + *x=*y; + *y=tmp; + ++x; ++y; + } +} + +static inline void swap(void *base,size_t size,size_t a,size_t b) { + iswap(base+a*size,base+b*size,size); +} + +#if 0 +extern int array[]; + +void dumparray() { + printf("array now {%d,%d,%d,%d,%d}\n",array[0],array[1],array[2],array[3],array[4]); +} +#endif + +void isort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)) { + int i; + while (nmemb>1) { + char *min=base; + char *tmp=min+size; + for (i=1; i<nmemb; ++i) { + if (compar(tmp,min)<0) + min=tmp; + tmp+=size; + } + iswap(min,base,size); + base+=size; + nmemb-=1; + } +} + +void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)) { +#ifdef DEBUG + char *dbase=base; + char *dmax=base+(nmemb-1)*size; + char dmemb=nmemb; +#endif + static int level=0; + char* v; /* pivot */ + char* mid, *max, *min; + int lmemb; + +#if 0 + int left,right; + left=(int*)base-array; + right=left+nmemb-1; + ++level; + { int i; for (i=0; i<level; ++i) printf(" "); } + printf("qsort: level %d; base=%p, %dx%d; array[%d..%d]\n",level,base,nmemb,size,left,right); + assert(left>=0 && right<=1000); +#endif + if (nmemb<=8) { + --level; + return isort(base,nmemb,size,compar); + } + { + mid=base+(nmemb/2)*size; + max=base+(nmemb-1)*size; + + if (compar(base,max)<0) /* a[left] < a[right] */ + if (compar(base,mid)<0) /* a[left] < a[med] */ + if (compar(max,mid)<0) /* a[left] < a[right] < a[med] */ + v=max; + else /* a[left] < a[med] < a[right] */ + v=mid; + else /* a[med] < a[left] < a[right] */ + v=base; + else /* a[right] < a[left] */ + if (compar(base,mid)<0) /* a[right] < a[left] < a[med] */ + v=base; + else /* a[right] < a[left] && a[med] < a[left] */ + if (compar(max,mid)<0) /* a[right] < a[med] < a[left] */ + v=mid; + else + v=max; +// printf("%d %d %d -> median %d\n",*(int*)base,*(int*)mid,*(int*)max,*(int*)v); + } + if (v != max) + iswap(v,max,size); + v=max; + min=base; lmemb=0; + for (;;) { + while (compar(min,v)<0) { min+=size; ++lmemb; } + while (compar(max-=size,v)>0) ; + if (min>=max) break; + iswap(min,max,size); + } + iswap(min,v,size); +#ifdef DEBUG +// { int i; for (i=0; i<level; ++i) printf(" "); } +// printf("-=< base=%p, min=%p, nmemb=%d, lmemb=%d (%d)\n",base,min,nmemb,lmemb,(min-(char*)base)/size); + assert(lmemb==((min-(char*)base)/size)); +#endif + if (min>(char*)base+size) { +#ifdef DEBUG + assert(base==dbase); +#endif +// { int i; for (i=0; i<level; ++i) printf(" "); } +// printf("+-left %d [%d..%d] of [%d..%d]\n",level+1,left,left+lmemb,left,right); + qsort(base,lmemb,size,compar); + } + if (nmemb>lmemb+1) { +// { int i; for (i=0; i<level; ++i) printf(" "); } +// printf("+-right %d [%d..%d] of [%d..%d]\n",level+1,left+lmemb,right,left,right); + qsort(min+size,nmemb-lmemb-1,size,compar); + } + --level; +} diff --git a/mdk-stage1/dietlibc/lib/rand.c b/mdk-stage1/dietlibc/lib/rand.c new file mode 100644 index 000000000..10bfaf94d --- /dev/null +++ b/mdk-stage1/dietlibc/lib/rand.c @@ -0,0 +1,9 @@ +#include <stdlib.h> + +static unsigned int seed=1; + +int rand() { + return ((seed = seed * 1103515245 + 12345) % ((unsigned int)RAND_MAX + 1)); +} + +void srand(unsigned int i) { seed=i; } diff --git a/mdk-stage1/dietlibc/lib/random.c b/mdk-stage1/dietlibc/lib/random.c new file mode 100644 index 000000000..02d1e1004 --- /dev/null +++ b/mdk-stage1/dietlibc/lib/random.c @@ -0,0 +1,9 @@ +#include <stdlib.h> + +static unsigned int seed=1; + +int random() { + return ((seed = seed * 1103515245 + 12345) % ((unsigned int)RAND_MAX + 1)); +} + +void srandom(unsigned int i) { seed=i; } diff --git a/mdk-stage1/dietlibc/lib/readdir.c b/mdk-stage1/dietlibc/lib/readdir.c index 5accd32a1..689f5d08b 100644 --- a/mdk-stage1/dietlibc/lib/readdir.c +++ b/mdk-stage1/dietlibc/lib/readdir.c @@ -1,83 +1,13 @@ -#if 0 - -Sorry, currently broken - -#include <dirent.h> -#include <errno.h> +#include "dietdirent.h" #include <unistd.h> +#include <dirent.h> #include <stdlib.h> -#include <string.h> - -#include "dirstream.h" - -#ifdef __ELF__ -#pragma weak readdir = __libc_readdir -#endif - -struct dirent * -__libc_readdir(DIR * dir) -{ - int result; - struct dirent *de; - - if (!dir) { - errno = EBADF; - return NULL; - } - - /* Are we running an old kernel? */ - if (dir->dd_getdents == no_getdents) - { - abort(); - } - - if (dir->dd_size <= dir->dd_nextloc) - { - /* read dir->dd_max bytes of directory entries. */ - result=getdents(dir->dd_fd,dir->dd_buf,dir->dd_max); - - /* We assume we have getdents (). */ - dir->dd_getdents = have_getdents; - if (result <= 0) - { - result = -result; - if (result > 0) - { - /* Are we right? */ - if (result == ENOSYS) - { - dir->dd_getdents = no_getdents; - abort(); - } - errno = result; - } - return NULL; - } - - dir->dd_size = result; - dir->dd_nextloc = 0; +struct dirent* readdir(DIR *d) { + if (!d->num || (d->cur += ((struct dirent*)(d->buf+d->cur))->d_reclen)>=d->num) { + int res=getdents(d->fd,(struct dirent*)d->buf,1023); + if (res<=0) return 0; + d->num=res; d->cur=0; } - - de = (struct dirent *) (((char *)dir->dd_buf) + dir->dd_nextloc); - - /* Am I right? H.J. */ - dir->dd_nextloc += de->d_reclen; - - /* We have to save the next offset here. */ - dir->dd_nextoff = de->d_off; - - /* convert */ - dir->convbuf.d_ino=de->d_ino; - dir->convbuf.d_off=de->d_off; - dir->convbuf.d_reclen=de->d_reclen; - dir->convbuf.d_type=0; - if (strlen((char*)&de->d_type)>10) - de->d_name[10]=0; - strcpy(dir->convbuf.d_name,(char*)&de->d_type); - errno=0; - - return &dir->convbuf; + return (struct dirent*)(d->buf+d->cur); } - -#endif diff --git a/mdk-stage1/dietlibc/lib/reboot.c b/mdk-stage1/dietlibc/lib/reboot.c new file mode 100644 index 000000000..7f47a95dd --- /dev/null +++ b/mdk-stage1/dietlibc/lib/reboot.c @@ -0,0 +1,8 @@ +#include <sys/reboot.h> + +int __reboot(int magic1, int magic2, int cmd, void * arg); + +int reboot(int cmd, void *arg) +{ + return __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, arg); +} diff --git a/mdk-stage1/dietlibc/lib/recv.c b/mdk-stage1/dietlibc/lib/recv.c index cc778712c..bc6b1e5d7 100644 --- a/mdk-stage1/dietlibc/lib/recv.c +++ b/mdk-stage1/dietlibc/lib/recv.c @@ -2,7 +2,7 @@ extern int socketcall(int callno,long* args); -int recv(int a, const void * b, size_t c, int flags) { +int __libc_recv(int a, const void * b, size_t c, int flags) { #ifdef __i386__ return socketcall(SYS_RECV,(long*)&a); #else @@ -11,3 +11,5 @@ int recv(int a, const void * b, size_t c, int flags) { #endif } +int recv(int a, const void * b, size_t c, int flags) + __attribute__ ((weak, alias("__libc_recv"))); diff --git a/mdk-stage1/dietlibc/lib/recvfrom.c b/mdk-stage1/dietlibc/lib/recvfrom.c index a07afe7ad..802ad665f 100644 --- a/mdk-stage1/dietlibc/lib/recvfrom.c +++ b/mdk-stage1/dietlibc/lib/recvfrom.c @@ -2,7 +2,7 @@ extern int socketcall(int callno,long* args); -int recvfrom(int a, const void * b, size_t c, int flags, void *to, void *tolen) { +int __libc_recvfrom(int a, const void * b, size_t c, int flags, void *to, void *tolen) { #ifdef __i386__ return socketcall(SYS_RECVFROM, (long*)&a); #else @@ -10,3 +10,6 @@ int recvfrom(int a, const void * b, size_t c, int flags, void *to, void *tolen) return socketcall(SYS_RECVFROM, args); #endif } + +int recvfrom(int a, const void * b, size_t c, int flags, void *to, void *tolen) + __attribute__ ((weak,alias("__libc_recvfrom"))) ; diff --git a/mdk-stage1/dietlibc/lib/recvmsg.c b/mdk-stage1/dietlibc/lib/recvmsg.c new file mode 100644 index 000000000..c14c58c78 --- /dev/null +++ b/mdk-stage1/dietlibc/lib/recvmsg.c @@ -0,0 +1,15 @@ +#include <linux/net.h> + +extern int socketcall(int callno,long* args); + +int __libc_recvmsg(int a, struct msghdr* msg, int flags) { +#ifdef __i386__ + return socketcall(SYS_RECVMSG, (long*)&a); +#else + unsigned long args[] = { a, (long) msg, flags }; + return socketcall(SYS_RECVMSG, args); +#endif +} + +int recvmsg(int a, struct msghdr *msg, int flags) + __attribute__ ((weak,alias("__libc_recvmsg"))) ; diff --git a/mdk-stage1/dietlibc/lib/remove.c b/mdk-stage1/dietlibc/lib/remove.c new file mode 100644 index 000000000..d5125bfed --- /dev/null +++ b/mdk-stage1/dietlibc/lib/remove.c @@ -0,0 +1,11 @@ +#include <unistd.h> +#include <errno.h> + +int remove(const char* filename) { + if (unlink(filename)) { + if (errno==EISDIR) + return rmdir(filename); + return -1; + } + return 0; +} diff --git a/mdk-stage1/dietlibc/lib/rewinddir.c b/mdk-stage1/dietlibc/lib/rewinddir.c index 138936527..addc7bde9 100644 --- a/mdk-stage1/dietlibc/lib/rewinddir.c +++ b/mdk-stage1/dietlibc/lib/rewinddir.c @@ -1,17 +1,8 @@ +#include "dietdirent.h" #include <unistd.h> -#include <errno.h> +#include <dirent.h> -#include "dirstream.h" - -/* - * rewinddir() just does an lseek(fd,0,0) - see close for comments - */ -void rewinddir(DIR * dir) -{ - if (!dir) { - errno = EBADF; - return; - } - lseek(dir->dd_fd,0,SEEK_SET); - dir->dd_nextoff = dir->dd_nextloc = dir->dd_size = 0; +void rewinddir(DIR *d) { + if (lseek(d->fd,0,SEEK_SET) != (off_t)-1) + d->num=d->cur=0; } diff --git a/mdk-stage1/dietlibc/lib/seekdir.c b/mdk-stage1/dietlibc/lib/seekdir.c index f83052250..cf111fbc8 100644 --- a/mdk-stage1/dietlibc/lib/seekdir.c +++ b/mdk-stage1/dietlibc/lib/seekdir.c @@ -1,15 +1,8 @@ +#include "dietdirent.h" #include <unistd.h> -#include <errno.h> +#include <dirent.h> -#include "dirstream.h" - -#undef seekdir -void seekdir(DIR * dir, off_t offset) -{ - if (!dir) { - errno = EBADF; - return; - } - dir->dd_nextoff = lseek(dir->dd_fd, offset, SEEK_SET); - dir->dd_size = dir->dd_nextloc = 0; +void seekdir(DIR *d,off_t offset) { + if (lseek(d->fd,offset,SEEK_SET) != (off_t)-1) + d->num=d->cur=0; } diff --git a/mdk-stage1/dietlibc/lib/semctl.c b/mdk-stage1/dietlibc/lib/semctl.c new file mode 100644 index 000000000..ddc0aae95 --- /dev/null +++ b/mdk-stage1/dietlibc/lib/semctl.c @@ -0,0 +1,10 @@ +#include <sys/types.h> +#include <sys/ipc.h> +#include <sys/sem.h> +#include <asm/ipc.h> + +extern int __ipc(); + +int semctl(int semid, int semnum, int cmd, union semun arg) { + return __ipc(SEMCTL,semid,semnum,cmd,&arg); +} diff --git a/mdk-stage1/dietlibc/lib/semget.c b/mdk-stage1/dietlibc/lib/semget.c new file mode 100644 index 000000000..056aeae04 --- /dev/null +++ b/mdk-stage1/dietlibc/lib/semget.c @@ -0,0 +1,10 @@ +#include <sys/types.h> +#include <sys/ipc.h> +#include <sys/sem.h> +#include <asm/ipc.h> + +extern int __ipc(); + +int semget(key_t key, int nsems, int semflg) { + return __ipc(SEMGET,key,nsems,semflg,0); +} diff --git a/mdk-stage1/dietlibc/lib/semop.c b/mdk-stage1/dietlibc/lib/semop.c new file mode 100644 index 000000000..abfde73a7 --- /dev/null +++ b/mdk-stage1/dietlibc/lib/semop.c @@ -0,0 +1,10 @@ +#include <sys/types.h> +#include <sys/ipc.h> +#include <sys/sem.h> +#include <asm/ipc.h> + +extern int __ipc(); + +int semop(int semid,struct sembuf *sops,unsigned nsops) { + return __ipc(SEMOP,semid,nsops,0,sops); +} diff --git a/mdk-stage1/dietlibc/lib/send.c b/mdk-stage1/dietlibc/lib/send.c index be43b4e63..c1adf1b5d 100644 --- a/mdk-stage1/dietlibc/lib/send.c +++ b/mdk-stage1/dietlibc/lib/send.c @@ -2,7 +2,7 @@ extern int socketcall(int callno,long* args); -int send(int a, const void * b, size_t c, int flags) { +int __libc_send(int a, const void * b, size_t c, int flags) { #ifdef __i386__ return socketcall(SYS_SEND, (long*)&a); #else @@ -11,3 +11,5 @@ int send(int a, const void * b, size_t c, int flags) { #endif } +int send(int a, const void * b, size_t c, int flags) + __attribute__ ((weak, alias("__libc_send"))); diff --git a/mdk-stage1/dietlibc/lib/sendmsg.c b/mdk-stage1/dietlibc/lib/sendmsg.c new file mode 100644 index 000000000..277265985 --- /dev/null +++ b/mdk-stage1/dietlibc/lib/sendmsg.c @@ -0,0 +1,15 @@ +#include <linux/net.h> + +extern int socketcall(int callno,long* args); + +int __libc_sendmsg(int a, const struct msghdr* msg, int flags) { +#ifdef __i386__ + return socketcall(SYS_SENDMSG, (long*)&a); +#else + unsigned long args[] = { a, (long) msg, flags }; + return socketcall(SYS_SENDMSG, args); +#endif +} + +int sendmsg(int a, const struct msghdr *msg, int flags) + __attribute__ ((weak,alias("__libc_sendmsg"))) ; diff --git a/mdk-stage1/dietlibc/lib/sendto.c b/mdk-stage1/dietlibc/lib/sendto.c index e6c2560f3..078c010ea 100644 --- a/mdk-stage1/dietlibc/lib/sendto.c +++ b/mdk-stage1/dietlibc/lib/sendto.c @@ -2,7 +2,7 @@ extern int socketcall(int callno,long* args); -int sendto(int a, const void * b, size_t c, int flags, void *to, int tolen) { +int __libc_sendto(int a, const void * b, size_t c, int flags, void *to, int tolen) { #ifdef __i386__ return socketcall(SYS_SENDTO, (long*)&a); #else @@ -11,3 +11,5 @@ int sendto(int a, const void * b, size_t c, int flags, void *to, int tolen) { #endif } +int sendto(int a, const void * b, size_t c, int flags, void *to, int tolen) + __attribute__ ((weak, alias("__libc_sendto"))); diff --git a/mdk-stage1/dietlibc/lib/setpgrp.c b/mdk-stage1/dietlibc/lib/setpgrp.c new file mode 100644 index 000000000..825ca3725 --- /dev/null +++ b/mdk-stage1/dietlibc/lib/setpgrp.c @@ -0,0 +1,6 @@ +#include <unistd.h> + +int setpgrp() +{ + return setpgid(0,0); +} diff --git a/mdk-stage1/dietlibc/lib/shmat.c b/mdk-stage1/dietlibc/lib/shmat.c new file mode 100644 index 000000000..63284b1ea --- /dev/null +++ b/mdk-stage1/dietlibc/lib/shmat.c @@ -0,0 +1,15 @@ +#include <sys/types.h> +#include <sys/ipc.h> +#include <sys/shm.h> +#include <asm/ipc.h> + +extern void* __ipc(); + +void* shmat(int shmid,const void* shmaddr,int shmflg) { + void* raddr; + register void* result; + result=__ipc(SHMAT,shmid,shmflg,&raddr,shmaddr); + if ((unsigned long)result <= -(unsigned long)SHMLBA) + result=raddr; + return result; +} diff --git a/mdk-stage1/dietlibc/lib/shmctl.c b/mdk-stage1/dietlibc/lib/shmctl.c new file mode 100644 index 000000000..8f942f2a4 --- /dev/null +++ b/mdk-stage1/dietlibc/lib/shmctl.c @@ -0,0 +1,10 @@ +#include <sys/types.h> +#include <sys/ipc.h> +#include <sys/shm.h> +#include <asm/ipc.h> + +extern int __ipc(); + +int shmctl(int shmid, int cmd, struct shmid_ds *buf) { + return __ipc(SHMCTL,shmid,cmd,0,buf); +} diff --git a/mdk-stage1/dietlibc/lib/shmdt.c b/mdk-stage1/dietlibc/lib/shmdt.c new file mode 100644 index 000000000..36db10f08 --- /dev/null +++ b/mdk-stage1/dietlibc/lib/shmdt.c @@ -0,0 +1,10 @@ +#include <sys/types.h> +#include <sys/ipc.h> +#include <sys/shm.h> +#include <asm/ipc.h> + +extern int __ipc(); + +int shmdt(const void* shmaddr) { + return __ipc(SHMDT,0,0,0,shmaddr); +} diff --git a/mdk-stage1/dietlibc/lib/shmget.c b/mdk-stage1/dietlibc/lib/shmget.c new file mode 100644 index 000000000..9b03f5deb --- /dev/null +++ b/mdk-stage1/dietlibc/lib/shmget.c @@ -0,0 +1,10 @@ +#include <sys/types.h> +#include <sys/ipc.h> +#include <sys/shm.h> +#include <asm/ipc.h> + +extern int __ipc(); + +int shmget(key_t key, int size, int shmflg) { + return __ipc(SHMGET,key,size,shmflg,0); +} diff --git a/mdk-stage1/dietlibc/lib/shutdown.c b/mdk-stage1/dietlibc/lib/shutdown.c new file mode 100644 index 000000000..0a6be6c37 --- /dev/null +++ b/mdk-stage1/dietlibc/lib/shutdown.c @@ -0,0 +1,14 @@ +#include <linux/net.h> + +extern int socketcall(int callno,long* args); + +int __libc_shutdown(int s, int how) { +#ifdef __i386__ + return socketcall(SYS_SHUTDOWN, (long*)&s); +#else + unsigned long args[] = { s, (long) how, 0 }; + return socketcall(SYS_SHUTDOWN, args); +#endif +} + +int shutdown(int s, int how) __attribute__((weak,alias("__libc_shutdown"))); diff --git a/mdk-stage1/dietlibc/lib/sigaddset.c b/mdk-stage1/dietlibc/lib/sigaddset.c index 0c9d95c28..8ce69ea77 100644 --- a/mdk-stage1/dietlibc/lib/sigaddset.c +++ b/mdk-stage1/dietlibc/lib/sigaddset.c @@ -1,21 +1,15 @@ -#define __USE_EXTERN_INLINES 1 -#include <signal.h> - -# define __sigmask(sig) \ - (((unsigned long int) 1) << (((sig) - 1) % (8 * sizeof (unsigned long int)))) - -# define __sigword(sig) (((sig) - 1) / (8 * sizeof (unsigned long int))) - -# define _SIGSET_NWORDS (1024 / (8 * sizeof (unsigned long int))) -typedef struct - { - unsigned long int __val[_SIGSET_NWORDS]; - } __sigset_t; - -int __sigaddset(__sigset_t *set, int signo) { - unsigned long int __mask = __sigmask (signo); - unsigned long int __word = __sigword (signo); - return ((set->__val[__word] |= __mask), 0); +#define __KERNEL__ +#define sigaddset foobar +#include <asm/signal.h> +#undef sigaddset + +int __sigaddset(sigset_t *set, int signo) { + unsigned long sig = signo - 1; + if (_NSIG_WORDS == 1) + set->sig[0] |= 1UL << sig; + else + set->sig[sig / _NSIG_BPW] |= 1UL << (sig % _NSIG_BPW); + return 0; } int sigaddset (sigset_t *env, int signo) __attribute__((weak,alias("__sigaddset"))); diff --git a/mdk-stage1/dietlibc/lib/sigdelset.c b/mdk-stage1/dietlibc/lib/sigdelset.c new file mode 100644 index 000000000..2c3385ea8 --- /dev/null +++ b/mdk-stage1/dietlibc/lib/sigdelset.c @@ -0,0 +1,15 @@ +#define __KERNEL__ +#define sigdelset foobar +#include <asm/signal.h> +#undef sigdelset + +int __sigdelset(sigset_t *set, int signo) { + unsigned long sig = signo - 1; + if (_NSIG_WORDS == 1) + set->sig[0] &= ~(1UL << sig); + else + set->sig[sig / _NSIG_BPW] &= ~(1UL << (sig % _NSIG_BPW)); + return 0; +} + +int sigdelset (sigset_t *env, int signo) __attribute__((weak,alias("__sigdelset"))); diff --git a/mdk-stage1/dietlibc/lib/sigfillset.c b/mdk-stage1/dietlibc/lib/sigfillset.c new file mode 100644 index 000000000..ddac6e391 --- /dev/null +++ b/mdk-stage1/dietlibc/lib/sigfillset.c @@ -0,0 +1,11 @@ +#define __KERNEL__ +#include <asm/signal.h> + +int __sigfillset (sigset_t *set) { + int i; + for (i=0; i<_NSIG_WORDS; i++) + set->sig[i]=~0; + return 0; +} + +int sigfillset(sigset_t *env) __attribute__((weak,alias("__sigfillset"))); diff --git a/mdk-stage1/dietlibc/lib/sigismember.c b/mdk-stage1/dietlibc/lib/sigismember.c new file mode 100644 index 000000000..67a258884 --- /dev/null +++ b/mdk-stage1/dietlibc/lib/sigismember.c @@ -0,0 +1,21 @@ +#define __USE_EXTERN_INLINES 1 +#include <signal.h> + +# define __sigmask(sig) \ + (((unsigned long int) 1) << (((sig) - 1) % (8 * sizeof (unsigned long int)))) + +# define __sigword(sig) (((sig) - 1) / (8 * sizeof (unsigned long int))) + +# define _SIGSET_NWORDS (1024 / (8 * sizeof (unsigned long int))) +typedef struct + { + unsigned long int __val[_SIGSET_NWORDS]; + } __sigset_t; + +int __sigismember(const __sigset_t *set, int signo) { + unsigned long int __mask = __sigmask (signo); + unsigned long int __word = __sigword (signo); + return (set->__val[__word] & __mask); +} + +int sigismember(const sigset_t *env, int signo) __attribute__((weak,alias("__sigismember"))); diff --git a/mdk-stage1/dietlibc/lib/sigjmp.c b/mdk-stage1/dietlibc/lib/sigjmp.c index d7db58fd2..be97c62cc 100644 --- a/mdk-stage1/dietlibc/lib/sigjmp.c +++ b/mdk-stage1/dietlibc/lib/sigjmp.c @@ -16,7 +16,6 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include <stddef.h> #include <setjmp.h> #include <signal.h> #include <string.h> diff --git a/mdk-stage1/dietlibc/lib/sprintf.c b/mdk-stage1/dietlibc/lib/sprintf.c index f1b554ce2..b355d01f9 100644 --- a/mdk-stage1/dietlibc/lib/sprintf.c +++ b/mdk-stage1/dietlibc/lib/sprintf.c @@ -1,6 +1,7 @@ #include <stdarg.h> #include <linux/types.h> #include <stdlib.h> +#include "dietwarning.h" int vsnprintf (char *str,size_t size,const char *format, va_list arg_ptr); @@ -13,3 +14,5 @@ int sprintf(char *dest,const char *format,...) va_end (arg_ptr); return n; } + +link_warning("sprintf","warning: Avoid sprintf; use snprintf. It is more secure and faster.") diff --git a/mdk-stage1/dietlibc/lib/strcasecmp.c b/mdk-stage1/dietlibc/lib/strcasecmp.c new file mode 100644 index 000000000..d978488a4 --- /dev/null +++ b/mdk-stage1/dietlibc/lib/strcasecmp.c @@ -0,0 +1,17 @@ +#include <ctype.h> +#include "dietfeatures.h" + +int strcasecmp(register const char *s,register const char *t) { + register char x; + + for (;;) { + x = tolower(*s); if (x != tolower(*t)) break; if (!x) break; ++s; ++t; +#ifndef WANT_SMALL_STRING_ROUTINES + x = tolower(*s); if (x != tolower(*t)) break; if (!x) break; ++s; ++t; + x = tolower(*s); if (x != tolower(*t)) break; if (!x) break; ++s; ++t; + x = tolower(*s); if (x != tolower(*t)) break; if (!x) break; ++s; ++t; +#endif + } + return ((int)(unsigned int)(unsigned char) x) + - ((int)(unsigned int)(unsigned char) *t); +} diff --git a/mdk-stage1/dietlibc/lib/strchr.c b/mdk-stage1/dietlibc/lib/strchr.c index b908853f8..0c2050da6 100644 --- a/mdk-stage1/dietlibc/lib/strchr.c +++ b/mdk-stage1/dietlibc/lib/strchr.c @@ -14,3 +14,5 @@ char *strchr(register const char *t, int c) { } return (char*)t; } + +char *index(char *t,int c) __attribute__((weak,alias("strchr"))); diff --git a/mdk-stage1/dietlibc/lib/strlcpy.3 b/mdk-stage1/dietlibc/lib/strlcpy.3 new file mode 100644 index 000000000..e00af8d6b --- /dev/null +++ b/mdk-stage1/dietlibc/lib/strlcpy.3 @@ -0,0 +1,169 @@ +.\" $OpenBSD: strlcpy.3,v 1.10 2000/11/06 01:03:25 aaron Exp $ +.\" +.\" Copyright (c) 1998, 2000 Todd C. Miller <Todd.Miller@courtesan.com> +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. The name of the author may not be used to endorse or promote products +.\" derived from this software without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED ``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 AUTHOR 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. +.\" +.Dd June 22, 1998 +.Dt STRLCPY 3 +.Os +.Sh NAME +.Nm strlcpy , +.Nm strlcat +.Nd size-bounded string copying and concatenation +.Sh SYNOPSIS +.Fd #include <string.h> +.Ft size_t +.Fn strlcpy "char *dst" "const char *src" "size_t size" +.Ft size_t +.Fn strlcat "char *dst" "const char *src" "size_t size" +.Sh DESCRIPTION +The +.Fn strlcpy +and +.Fn strlcat +functions copy and concatenate strings respectively. +They are designed +to be safer, more consistent, and less error prone replacements for +.Xr strncpy 3 +and +.Xr strncat 3 . +Unlike those functions, +.Fn strlcpy +and +.Fn strlcat +take the full size of the buffer (not just the length) and guarantee to +NUL-terminate the result (as long as +.Fa size +is larger than 0 or, in the case of +.Fn strlcat , +as long as there is at least one byte free in +.Fa dst ) . +Note that you should include a byte for the NUL in +.Fa size . +Also note that +.Fn strlcpy +and +.Fn strlcat +only operate on true +.Dq C +strings. +This means that for +.Fn strlcpy +.Fa src +must be NUL-terminated and for +.Fn strlcat +both +.Fa src +and +.Fa dst +must be NUL-terminated. +.Pp +The +.Fn strlcpy +function copies up to +.Fa size +- 1 characters from the NUL-terminated string +.Fa src +to +.Fa dst , +NUL-terminating the result. +.Pp +The +.Fn strlcat +function appends the NUL-terminated string +.Fa src +to the end of +.Fa dst . +It will append at most +.Fa size +- strlen(dst) - 1 bytes, NUL-terminating the result. +.Sh RETURN VALUES +The +.Fn strlcpy +and +.Fn strlcat +functions return the total length of the string they tried to create. +For +.Fn strlcpy +that means the length of +.Fa src . +For +.Fn strlcat +that means the initial length of +.Fa dst +plus +the length of +.Fa src . +While this may seem somewhat confusing it was done to make +truncation detection simple. +.Sh EXAMPLES +The following code fragment illustrates the simple case: +.Bd -literal -offset indent +char *s, *p, buf[BUFSIZ]; + +\&... + +(void)strlcpy(buf, s, sizeof(buf)); +(void)strlcat(buf, p, sizeof(buf)); +.Ed +.Pp +To detect truncation, perhaps while building a pathname, something +like the following might be used: +.Bd -literal -offset indent +char *dir, *file, pname[MAXPATHLEN]; + +\&... + +if (strlcpy(pname, dir, sizeof(pname)) >= sizeof(pname)) + goto toolong; +if (strlcat(pname, file, sizeof(pname)) >= sizeof(pname)) + goto toolong; +.Ed +.Pp +Since we know how many characters we copied the first time, we can +speed things up a bit by using a copy instead of an append: +.Bd -literal -offset indent +char *dir, *file, pname[MAXPATHLEN]; +size_t n; + +\&... + +n = strlcpy(pname, dir, sizeof(pname)); +if (n >= sizeof(pname)) + goto toolong; +if (strlcpy(pname + n, file, sizeof(pname) - n) >= sizeof(pname) - n) + goto toolong; +.Ed +.Pp +However, one may question the validity of such optimizations, as they +defeat the whole purpose of +.Fn strlcpy +and +.Fn strlcat . +As a matter of fact, the first version of this manual page got it wrong. +.Sh SEE ALSO +.Xr snprintf 3 , +.Xr strncat 3 , +.Xr strncpy 3 diff --git a/mdk-stage1/dietlibc/lib/strncasecmp.c b/mdk-stage1/dietlibc/lib/strncasecmp.c new file mode 100644 index 000000000..8a5445e53 --- /dev/null +++ b/mdk-stage1/dietlibc/lib/strncasecmp.c @@ -0,0 +1,18 @@ +#include <ctype.h> +#include <sys/types.h> +#include <string.h> + +int strncasecmp(const char *s, const char *t, size_t n) { + register char x; + register const char* u=s+n; + for (;;) { + x = tolower(*s); if (x!=tolower(*t)) break; if (!x) break; if (++s>=u) return 0; ++t; +#ifndef WANT_SMALL_STRING_ROUTINES + x = tolower(*s); if (x!=tolower(*t)) break; if (!x) break; if (++s>=u) return 0; ++t; + x = tolower(*s); if (x!=tolower(*t)) break; if (!x) break; if (++s>=u) return 0; ++t; + x = tolower(*s); if (x!=tolower(*t)) break; if (!x) break; if (++s>=u) return 0; ++t; +#endif + } + return ((int)(unsigned int)(unsigned char) x) + - ((int)(unsigned int)(unsigned char) *t); +} diff --git a/mdk-stage1/dietlibc/lib/strncat.c b/mdk-stage1/dietlibc/lib/strncat.c index 1d3b94ca5..21e2be326 100644 --- a/mdk-stage1/dietlibc/lib/strncat.c +++ b/mdk-stage1/dietlibc/lib/strncat.c @@ -1,10 +1,17 @@ #include "dietfeatures.h" #include <string.h> +/* this implementation is not standards compliant. + * the standard says that strncat(dest,"foobar",3) should write 'f', 'o' + * and 'o'. The programmer is then expected to overwrite the last byte + * with '\0', which is often forgotten. This implementation makes sure + * the last written bytes is always '\0'. */ + char *strncat(char *s, const char *t, size_t n) { char *dest=s; - register char *max=s+n-1; + register char *max; s+=strlen(s); + max=s+n-1; for (;;) { if (!(*s = *t)) break; if (++s==max) break; ++t; #ifndef WANT_SMALL_STRING_ROUTINES diff --git a/mdk-stage1/dietlibc/lib/strrchr.c b/mdk-stage1/dietlibc/lib/strrchr.c index 3c91e9bc8..1abb655e2 100644 --- a/mdk-stage1/dietlibc/lib/strrchr.c +++ b/mdk-stage1/dietlibc/lib/strrchr.c @@ -16,3 +16,5 @@ char *strrchr(const char *t, int c) { } return (char*)l; } + +char *rindex(const char *t,int c) __attribute__((weak,alias("strrchr"))); diff --git a/mdk-stage1/dietlibc/lib/strsep.c b/mdk-stage1/dietlibc/lib/strsep.c new file mode 100644 index 000000000..a1bf1872a --- /dev/null +++ b/mdk-stage1/dietlibc/lib/strsep.c @@ -0,0 +1,16 @@ +#include <string.h> + +char *strsep(char **stringp, const char *delim) { + register char *tmp=*stringp; + register char *tmp2=tmp; + register const char *tmp3; + for (tmp2=tmp; *tmp2; ++tmp2) { + for (tmp3=delim; *tmp3; ++tmp3) + if (*tmp2==*tmp3) { /* delimiter found */ + *tmp2=0; + *stringp=tmp2+1; + return tmp; + } + } + return 0; +} diff --git a/mdk-stage1/dietlibc/lib/strtod.c b/mdk-stage1/dietlibc/lib/strtod.c index 767be679f..cbe983d84 100644 --- a/mdk-stage1/dietlibc/lib/strtod.c +++ b/mdk-stage1/dietlibc/lib/strtod.c @@ -29,10 +29,10 @@ double strtod(const char *nptr, char **endptr) { } if ((*c|32)=='e') { int exp=0; - char neg=0; + double factor=10; if (c[1]<'0') { - switch (*c) { - case '-': neg=1; + switch (c[1]) { + case '-': factor=0.1; case '+': c++; break; default: d=0; @@ -43,7 +43,7 @@ double strtod(const char *nptr, char **endptr) { while (isdigit(*++c)) exp=exp*10+(*c-'0'); while (exp) { /* XXX: this introduces rounding errors */ - d*=10; --exp; + d*=factor; --exp; } } done: diff --git a/mdk-stage1/dietlibc/lib/strtok.c b/mdk-stage1/dietlibc/lib/strtok.c index 525665e59..86337da7b 100644 --- a/mdk-stage1/dietlibc/lib/strtok.c +++ b/mdk-stage1/dietlibc/lib/strtok.c @@ -1,5 +1,7 @@ char *strtok_r(char *s, const char *delim, char **ptrptr); + static char *strtok_pos; + char *strtok(char *s, const char *delim) { return strtok_r(s,delim,&strtok_pos); diff --git a/mdk-stage1/dietlibc/lib/strtoul.c b/mdk-stage1/dietlibc/lib/strtoul.c index bee849685..3f93962a9 100644 --- a/mdk-stage1/dietlibc/lib/strtoul.c +++ b/mdk-stage1/dietlibc/lib/strtoul.c @@ -1,38 +1,31 @@ #include <ctype.h> -static char *num="0123456789abcdefghijklmnopqrstuvwxyz"; +/* static char *num="0123456789abcdefghijklmnopqrstuvwxyz"; */ unsigned long int strtoul(const char *nptr, char **endptr, int base) { long int v=0; - int a=1,i; - while(isspace(*nptr)) nptr++; + while(isspace(*nptr)) ++nptr; - if (*nptr == '+') { nptr++; } - if (!base) - { - if (*nptr=='0') - { + if (*nptr == '+') ++nptr; + if (!base) { + if (*nptr=='0') { base=8; - if ((*(nptr+1)=='x')||(*(nptr+1)=='X')) base=16; + if ((*(nptr+1)=='x')||(*(nptr+1)=='X')) { + nptr+=2; + base=16; + } } else base=10; } - while((a)&&(*nptr)) - { - a=0; - for (i=0;(!a)&&(i<base);i++) - { - if ((*nptr == num[i]) || (*nptr == (num[i]-' '))) - { - a=1; - v=(v*base)+(&num[i]-num); - } - } - if ((!a)&&(base==16)&&((*nptr=='x')||(*nptr=='X'))) a=1; - if (a) nptr++; + while(*nptr) { + register unsigned char c=*nptr; + c=(c>='a'?c-'a'+10:c>='A'?c-'A'+10:c-'0'); + if (c>=base) break; + v=v*base+c; + ++nptr; } if (endptr) *endptr=(char *)nptr; return v; diff --git a/mdk-stage1/dietlibc/lib/strtoull.c b/mdk-stage1/dietlibc/lib/strtoull.c index 64f095f60..40818958d 100644 --- a/mdk-stage1/dietlibc/lib/strtoull.c +++ b/mdk-stage1/dietlibc/lib/strtoull.c @@ -1,38 +1,29 @@ #include <ctype.h> -static char *num="0123456789abcdefghijklmnopqrstuvwxyz"; - unsigned long long int strtoull(const char *nptr, char **endptr, int base) { long long int v=0; - int a=1,i; - while(isspace(*nptr)) nptr++; + while(isspace(*nptr)) ++nptr; - if (*nptr == '+') { nptr++; } - if (!base) - { - if (*nptr=='0') - { + if (*nptr == '+') ++nptr; + if (!base) { + if (*nptr=='0') { base=8; - if ((*(nptr+1)=='x')||(*(nptr+1)=='X')) base=16; + if ((*(nptr+1)=='x')||(*(nptr+1)=='X')) { + nptr+=2; + base=16; + } } else base=10; } - while((a)&&(*nptr)) - { - a=0; - for (i=0;(!a)&&(i<base);i++) - { - if ((*nptr == num[i]) || (*nptr == (num[i]-' '))) - { - a=1; - v=(v*base)+(&num[i]-num); - } - } - if ((!a)&&(base==16)&&((*nptr=='x')||(*nptr=='X'))) a=1; - if (a) nptr++; + while(*nptr) { + register unsigned char c=*nptr; + c=(c>='a'?c-'a'+10:c>='A'?c-'A'+10:c-'0'); + if (c>=base) break; + v=v*base+c; + ++nptr; } if (endptr) *endptr=(char *)nptr; return v; diff --git a/mdk-stage1/dietlibc/lib/tcdrain.c b/mdk-stage1/dietlibc/lib/tcdrain.c new file mode 100644 index 000000000..7a760f643 --- /dev/null +++ b/mdk-stage1/dietlibc/lib/tcdrain.c @@ -0,0 +1,8 @@ +#include <sys/ioctl.h> + +int __libc_tcdrain(int fd) +{ + return ioctl(fd, TCSBRK, 1); +} + +int tcdrain(int fd) __attribute__((weak,alias("__libc_tcdrain"))); diff --git a/mdk-stage1/dietlibc/lib/tcgetpgrp.c b/mdk-stage1/dietlibc/lib/tcgetpgrp.c new file mode 100644 index 000000000..f2a290651 --- /dev/null +++ b/mdk-stage1/dietlibc/lib/tcgetpgrp.c @@ -0,0 +1,7 @@ +#include <termios.h> +#include <sys/ioctl.h> + +int tcgetpgrp(int fildes) +{ + return ioctl(fildes, TIOCGPGRP); +} diff --git a/mdk-stage1/dietlibc/lib/tcsetpgrp.c b/mdk-stage1/dietlibc/lib/tcsetpgrp.c new file mode 100644 index 000000000..6c40b5c79 --- /dev/null +++ b/mdk-stage1/dietlibc/lib/tcsetpgrp.c @@ -0,0 +1,7 @@ +#include <termios.h> +#include <sys/ioctl.h> + +int tcsetpgrp(int fildes, pid_t pgrpid) +{ + return ioctl(fildes, TIOCSPGRP, &pgrpid); +} diff --git a/mdk-stage1/dietlibc/lib/telldir.c b/mdk-stage1/dietlibc/lib/telldir.c index eca175381..58be5d034 100644 --- a/mdk-stage1/dietlibc/lib/telldir.c +++ b/mdk-stage1/dietlibc/lib/telldir.c @@ -1,38 +1,7 @@ +#include "dietdirent.h" #include <unistd.h> -#include <errno.h> +#include <dirent.h> -#include "dirstream.h" - -#undef telldir -off_t -telldir(DIR * dir) -{ - off_t offset; - - if (!dir) { - errno = EBADF; - return -1; - } - - switch (dir->dd_getdents) - { - case no_getdents: - /* We are running the old kernel. This is the starting offset - of the next readdir(). */ - offset = lseek(dir->dd_fd, 0, SEEK_CUR); - break; - - case unknown: - /* readdir () is not called yet. but seekdir () may be called. */ - case have_getdents: - /* The next entry. */ - offset = dir->dd_nextoff; - break; - - default: - errno = EBADF; - offset = -1; - } - - return offset; +off_t telldir(DIR *d) { + return lseek(d->fd,0,SEEK_CUR)-d->num+d->cur; } diff --git a/mdk-stage1/dietlibc/lib/tolower.c b/mdk-stage1/dietlibc/lib/tolower.c new file mode 100644 index 000000000..4b7c7cf2d --- /dev/null +++ b/mdk-stage1/dietlibc/lib/tolower.c @@ -0,0 +1,6 @@ +#include <ctype.h> + +inline int tolower(int c) { + return (c>='A' && c<='Z')?c-'A'+'a':c; +} + diff --git a/mdk-stage1/dietlibc/lib/toupper.c b/mdk-stage1/dietlibc/lib/toupper.c new file mode 100644 index 000000000..c048e60bb --- /dev/null +++ b/mdk-stage1/dietlibc/lib/toupper.c @@ -0,0 +1,6 @@ +#include <ctype.h> + +inline int toupper(int c) { + return (c>='a' && c<='z')?c-'a'+'A':c; +} + diff --git a/mdk-stage1/dietlibc/lib/ttyname.c b/mdk-stage1/dietlibc/lib/ttyname.c index 81a0cbc66..a6b479088 100644 --- a/mdk-stage1/dietlibc/lib/ttyname.c +++ b/mdk-stage1/dietlibc/lib/ttyname.c @@ -1,7 +1,6 @@ #include "dietfeatures.h" #include <unistd.h> #include <sys/stat.h> -#include <string.h> #ifdef __linux__ diff --git a/mdk-stage1/dietlibc/lib/usleep.c b/mdk-stage1/dietlibc/lib/usleep.c new file mode 100644 index 000000000..494f99233 --- /dev/null +++ b/mdk-stage1/dietlibc/lib/usleep.c @@ -0,0 +1,12 @@ +#include <linux/time.h> +#include <time.h> + +/* nano * 1000 == usecs + * usecs * 1000 == msecs + * msecs * 1000 = secs */ +void usleep(unsigned int usecs) { + struct timespec t; + t.tv_sec=usecs/1000000; + t.tv_nsec=(usecs%1000000)*1000; + nanosleep(&t,&t); +} diff --git a/mdk-stage1/dietlibc/lib/vfprintf.c b/mdk-stage1/dietlibc/lib/vfprintf.c index 03dfe87a9..c33a2404b 100644 --- a/mdk-stage1/dietlibc/lib/vfprintf.c +++ b/mdk-stage1/dietlibc/lib/vfprintf.c @@ -1,11 +1,19 @@ #include <stdarg.h> #include <stdio.h> #include <stdlib.h> +#include "dietstdarg.h" int vfprintf(FILE *fstream, const char *format, va_list ap) { - char tmp[1000000]; - size_t n = vsnprintf(tmp, sizeof(tmp), format, ap); - fwrite(tmp, n, 1, fstream); + char *tmp; + va_list cp_ap; + size_t n = 0; + + va_copy(cp_ap, ap); + n=vsnprintf(0, 1000000, format, cp_ap); + tmp=alloca(n+2); + vsnprintf(tmp, n+1, format, ap); + fwrite(tmp, n,1, fstream); return n; } + diff --git a/mdk-stage1/dietlibc/lib/vsnprintf.c b/mdk-stage1/dietlibc/lib/vsnprintf.c index 5bbc51620..f425066e3 100644 --- a/mdk-stage1/dietlibc/lib/vsnprintf.c +++ b/mdk-stage1/dietlibc/lib/vsnprintf.c @@ -3,33 +3,11 @@ #include <sys/types.h> #include <stdlib.h> #include <string.h> +#include "dietwarning.h" extern int __ltostr(char *s, int size, unsigned long i, int base, char UpCase); extern int __dtostr(double d,char *buf,int maxlen,int prec); -#include <unistd.h> -void print_int(int fd, int i) -{ - char buf[10]; - char * chptr = buf + 9; - int j = 0; - - if (i < 0) - { - write(1, "-", 1); - i = -1 * i; - } - - while (i) - { - *chptr-- = '0' + (i % 10); - j++; - i = i / 10; - } - - write(fd, chptr + 1, j); -} - int vsnprintf (char *str, size_t size, const char *format, va_list arg_ptr) { size_t apos,i; @@ -78,7 +56,7 @@ inn_vsnprintf: goto inn_vsnprintf; case 'l': - flag_long=1; + ++flag_long; goto inn_vsnprintf; case '0': @@ -111,10 +89,19 @@ inn_vsnprintf: format=pb; goto inn_vsnprintf; + case '*': + width=va_arg(arg_ptr,int); + goto inn_vsnprintf; + case '.': flag_dot=1; - preci=strtol(format,&pb,10); - format=pb; + if (*format=='*') { + preci=va_arg(arg_ptr,int); + ++format; + } else { + preci=strtol(format,&pb,10); + format=pb; + } goto inn_vsnprintf; /* Format conversion chars */ @@ -130,6 +117,8 @@ inn_vsnprintf: if (!pb) pb="(null)"; #endif buf_len=strlen(pb); + if (flag_dot && buf_len>preci) buf_len=preci; + if (buf_len>size-apos) buf_len=size-apos; print_out: if (str) { @@ -137,17 +126,16 @@ print_out: { for (pad=width-buf_len; pad>0; --pad) str[apos++]=padwith; } - for(i=0;(pb[i])&&(apos<size);i++) { str[apos++]=pb[i]; } /* strncpy */ + for(i=0;i<buf_len;++i) { str[apos++]=pb[i]; } /* strncpy */ if (width && (flag_left)) { for (pad=width-buf_len; pad>0; --pad) str[apos++]=padwith; } } else { - if (width) - apos+=width; - else { - int a=strlen(pb); - if (a>size) apos+=size; else apos+=a; + if (width) { + apos+=width>buf_len?width:buf_len; + } else { + apos+=size>buf_len?buf_len:size; } } @@ -214,10 +202,18 @@ num_vsnprintf: goto print_out; #ifdef WANT_FLOATING_POINT_IN_PRINTF + case 'f': case 'g': { double d=va_arg(arg_ptr,double); - buf_len=__dtostr(d,buf,sizeof(buf),6); + buf_len=__dtostr(d,buf,sizeof(buf),width?width:6); + if (flag_dot) { + char *tmp; + if ((tmp=strchr(buf,'.'))) { + while (preci>-1 && *++tmp) --preci; + *tmp=0; + } + } pb=buf; goto print_out; } @@ -237,3 +233,6 @@ num_vsnprintf: if (str) str[apos]=0; return apos; } + +link_warning("vsnprintf","warning: the printf functions add several kilobytes of bloat.") + diff --git a/mdk-stage1/dietlibc/lib/vsprintf.c b/mdk-stage1/dietlibc/lib/vsprintf.c index af4eea852..10ff04bd7 100644 --- a/mdk-stage1/dietlibc/lib/vsprintf.c +++ b/mdk-stage1/dietlibc/lib/vsprintf.c @@ -1,11 +1,10 @@ #include <stdarg.h> #include <linux/types.h> -#include <unistd.h> #include <stdlib.h> int vsnprintf (char *str,size_t size,const char *format, va_list arg_ptr); -int vsprintf(char *str, const char *format, va_list ap) +int vsprintf(char *dest,const char *format, va_list arg_ptr) { - return vsnprintf(str, 1000000, format, ap); + return vsnprintf(dest,1000000,format,arg_ptr); } diff --git a/mdk-stage1/dietlibc/lib/vsscanf.c b/mdk-stage1/dietlibc/lib/vsscanf.c index a646ad92d..108555b33 100644 --- a/mdk-stage1/dietlibc/lib/vsscanf.c +++ b/mdk-stage1/dietlibc/lib/vsscanf.c @@ -3,6 +3,7 @@ #include <sys/types.h> #include <ctype.h> #include <stdlib.h> +#include <string.h> const char *skip_ws(const char *str) { @@ -15,15 +16,15 @@ extern double strtod(const char *s,char **f); int vsscanf(const char *str, const char *format, va_list arg_ptr) { int n=0,div; - char ch; + unsigned char ch; char flag_discard, flag_malloc, flag_half, flag_long, flag_longlong; char flag_width; unsigned long width; -#ifdef WANT_FLOATING_POINT_IN_SCANF /* arg_ptr tmps */ +#ifdef WANT_FLOATING_POINT_IN_SCANF double d,*pd; float *pf; #endif @@ -216,15 +217,74 @@ inn_vsscanf: } if (*(str=skip_ws(str))) { - while (width && *str && (!isspace(*str))) + while (width && (!isspace(*str))) { if (!flag_discard) *(s++)=*(str); + if (!*str) break; ++str; --width; } - *s = '\0'; } break; + +#ifdef WANT_CHARACTER_CLASSES_IN_SCANF + case '[': + { + char cset[256]; + int flag_not=0; + int flag_dash=0; + memset(cset,0,sizeof(cset)); + ch=*format++; + + /* first char specials */ + if (ch=='^') + { + flag_not=1; + ch=*format++; + } + if ((ch=='-')||(ch==']')) + { + cset[ch]=1; + ch=*format++; + } + + /* almost all non special chars */ + for (;(*format) && (*format!=']');++format) { + if (flag_dash) + { + register unsigned char tmp=*format; + for (;ch<=tmp;++ch) cset[ch]=1; + flag_dash=0; + ch=*(++format); + } + else if (*format=='-') flag_dash=1; + else + { + cset[ch]=1; + ch=*format; + } + } + + /* last char specials */ + if (flag_dash) cset['-']=1; + else cset[ch]=1; + + /* like %c or %s */ + if (!flag_discard) + { + s=(char *)va_arg(arg_ptr,char*); + ++n; + } + while (width && (cset[(unsigned char)(*str)]-flag_not)) + { + if (!flag_discard) *(s++)=*(str); + if (!*str) break; + ++str; + --width; + } + } + break; +#endif } break; |