/* * Guillaume Cottenceau (gc@mandrakesoft.com) * * Copyright 2000 MandrakeSoft * * This software may be freely redistributed under the terms of the GNU * public license. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* * Portions from Erik Troan (ewt@redhat.com) * * Copyright 1996 Red Hat Software * */ #define MINILIBC_INTERNAL #include "minilibc.h" int atexit (void (*__func) (void) __attribute__ ((unused))) { return 0; } void exit() { _do_exit(0); for (;;); /* Shut up gcc */ } char ** _environ = NULL; int errno = 0; void _init (int __status __attribute__ ((unused))) { } void __libc_init_first (int __status __attribute__ ((unused))) { } void __libc_csu_fini(int __status __attribute__ ((unused))) { } void __libc_csu_init(int __status __attribute__ ((unused))) { } int __libc_start_main (int (*main) (int, char **, char **), int argc, char **argv, void (*init) (void) __attribute__ ((unused)), void (*fini) (void) __attribute__ ((unused)), void (*rtld_fini) (void) __attribute__ ((unused)), void *stack_end __attribute__ ((unused))) { exit ((*main) (argc, argv, NULL)); /* never get here */ return 0; } void _fini (int __status __attribute__ ((unused))) { } #ifdef __x86_64__ /* x86-64 implementation of signal() derived from glibc sources */ static inline int sigemptyset(sigset_t *set) { *set = 0; return 0; } static inline int sigaddset(sigset_t *set, int sig) { __asm__("btsq %1,%0" : "=m" (*set) : "Ir" (sig - 1L) : "cc"); return 0; } #define __NR___rt_sigaction __NR_rt_sigaction static inline _syscall3(int,__rt_sigaction,int,signum,const void *,act,void *,oldact) #define __NR___rt_sigreturn __NR_rt_sigreturn static _syscall1(int,__rt_sigreturn,unsigned long,unused) static void restore_rt(void) { __rt_sigreturn(0); } int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact) { struct sigaction *newact = (struct sigaction *)act; if (act) { newact = __builtin_alloca(sizeof(*newact)); newact->sa_handler = act->sa_handler; newact->sa_flags = act->sa_flags | SA_RESTORER; newact->sa_restorer = &restore_rt; newact->sa_mask = act->sa_mask; } return __rt_sigaction(signum, newact, oldact); } __sighandler_t signal(int signum, __sighandler_t action) { struct sigaction sa,oa; sa.sa_handler=action; sigemptyset(&sa.sa_mask); sigaddset(&sa.sa_mask,signum); sa.sa_flags=SA_RESTART; if (sigaction(signum,&sa,&oa)) return SIG_ERR; return oa.sa_handler; } #endif #ifdef __NR_socketcall int socket(int a, int b, int c) { unsigned long args[] = { a, b, c }; return socketcall(SYS_SOCKET, args); } int bind(int a, void * b, int c) { unsigned long args[] = { a, (long) b, c }; return socketcall(SYS_BIND, args); } int listen(int a, int b) { unsigned long args[] = { a, b, 0 }; return socketcall(SYS_LISTEN, args); } int accept(int a, void * addr, void * addr2) { unsigned long args[] = { a, (long) addr, (long) addr2 }; return socketcall(SYS_ACCEPT, args); } #else _syscall3(int,socket,int,domain,int,type,int,protocol) _syscall3(int,bind,int,sockfd,void *,my_addr,int,addrlen) _syscall2(int,listen,int,s,int,backlog) _syscall3(int,accept,int,s,void *,addr,void *,addrlen) #endif void sleep(int secs) { struct timeval tv; tv.tv_sec = secs; tv.tv_usec = 0; select(0, NULL, NULL, NULL, &tv); } int strlen(const char * string) { int i = 0; while (*string++) i++; return i; } char * strncpy(char * dst, const char * src, int len) { char * chptr = dst; int i = 0; while (*src && i < len) *dst++ = *src++, i++; if (i < len) *dst = '\0'; return chptr; } char * strcpy(char * dst, const char * src) { char * chptr = dst; while (*src) *dst++ = *src++; *dst = '\0'; return chptr; } void * memcpy(void * dst, const void * src, size_t count) { char * a = dst; const char * b = src; while (count--) *a++ = *b++; return dst; } int strcmp(const char * a, const char * b) { int i, j; i = strlen(a); j = strlen(b); if (i < j) return -1; else if (j < i) return 1; while (*a && (*a == *b)) a++, b++; if (!*a) return 0; if (*a < *b) return -1; else return 1; } int strncmp(const char * a, const char * b, int len) { char buf1[1000], buf2[1000]; strncpy(buf1, a, len); strncpy(buf2, b, len); buf1[len] = '\0'; buf2[len] = '\0'; return strcmp(buf1, buf2); } char * strchr(char * str, int ch) { char * chptr; chptr = str; while (*chptr) { if (*chptr == ch) return chptr; chptr++; } return NULL; } char * strstr(char *haystack, char *needle) { char * tmp = haystack; while ((tmp = strchr(tmp, needle[0])) != NULL) { int i = 1; while (i < strlen(tmp) && i < strlen(needle) && tmp[i] == needle[i]) i++; if (needle[i] == '\0') return tmp; tmp++; } return NULL; } /* Minimum printf which handles only characters, %d's and %s's */ void printf(char * fmt, ...) { char buf[2048]; char * start = buf; char * chptr = buf; va_list args; char * strarg; int numarg; strncpy(buf, fmt, sizeof(buf)); va_start(args, fmt); while (start) { while (*chptr != '%' && *chptr) chptr++; if (*chptr == '%') { *chptr++ = '\0'; print_str_init(1, start); switch (*chptr++) { case 's': strarg = va_arg(args, char *); print_str_init(1, strarg); break; case 'd': numarg = va_arg(args, int); print_int_init(1, numarg); break; } start = chptr; } else { print_str_init(1, start); start = NULL; } } }