Mercurial > hg > aboriginal
changeset 14:8b4600334a3d
Replace the path finding logic with the stuff from toybox.
author | Rob Landley <rob@landley.net> |
---|---|
date | Sat, 02 Dec 2006 18:41:17 -0500 |
parents | d34028ce8602 |
children | 11b76d1cc1cd |
files | sources/toys/gcc-uClibc.c |
diffstat | 1 files changed, 78 insertions(+), 156 deletions(-) [+] |
line wrap: on
line diff
--- a/sources/toys/gcc-uClibc.c Sat Dec 02 13:18:58 2006 -0500 +++ b/sources/toys/gcc-uClibc.c Sat Dec 02 18:41:17 2006 -0500 @@ -1,4 +1,7 @@ /* vi: set ts=4 :*/ + +#define TARGET_DIR "gcc/armv4l-unknown-linux/gnu/4.1.1" + /* * Copyright (C) 2000 Manuel Novoa III * Copyright (C) 2002-2003 Erik Andersen @@ -17,7 +20,6 @@ static char *topdir; const char *mypath; -const char *application_name; static char static_linking[] = "-static"; static char nostdinc[] = "-nostdinc"; static char nostartfiles[] = "-nostartfiles"; @@ -28,99 +30,54 @@ static char nostdinc_plus[] = "-nostdinc++"; -char *dirname(char *path) +// Confirm that a regular file exists, and (optionally) has the executable bit. +int is_file(char *filename, int has_exe) { - static const char null_or_empty_or_noslash[] = "."; - register char *s; - register char *last; - char *first; - - last = s = path; - - if (s != NULL) { + // Confirm it has the executable bit set, if necessary. + if (!has_exe || !access(filename, X_OK)) { + struct stat st; -LOOP: - while (*s && (*s != '/')) ++s; - first = s; - while (*s == '/') ++s; - if (*s) { - last = first; - goto LOOP; - } - - if (last == path) { - if (*last != '/') { - goto DOT; - } - if ((*++last == '/') && (last[1] == 0)) { - ++last; - } - } - *last = 0; - return path; + // Confirm it exists and is not a directory. + if (!stat(filename, &st) && S_ISREG(st.st_mode)) return 1; } -DOT: - return (char *) null_or_empty_or_noslash; + return 0; } -static int myexecvp(const char *path, char *argv[]) -{ - int res; - const char *runpath; - if (strchr(path, '/')) - runpath = path; - else { - static char buf[8192]; - strcpy(buf, mypath); - if (strchr(mypath, '\0')[-1] != '/') - strcat(buf, "/"); - strcat(buf, path); - runpath = buf; - argv[0] = buf; - } - res = execvp(runpath, argv); - if (runpath != path) { - argv[0] = (char *) runpath; - res = execvp(path, argv); - } - return res; -} +// Find an executable in a colon-separated path -static void finddirs() +char *find_in_path(char *path, char *filename, int has_exe) { - char *here; - char **av; - static char *dirs[] = { - "../" TARGET_DIR "/lib", - "../lib", NULL - }; - here = getcwd (NULL, 0); - for (av = dirs; *av; av++) { - chdir (mypath); - if (chdir (*av) == 0 && access ("ld-uClibc.so.0", F_OK) == 0) { - chdir (".."); - topdir = getcwd (NULL, 0); - break; + char *cwd = getcwd(NULL, 0); + + if (index(filename, '/') && is_file(filename, has_exe)) + return strdup(filename); + + for (;;) { + char *str, *next = path ? index(path, ':') : NULL; + int len = next ? next-path : strlen(path); + struct string_list *rnext; + struct stat st; + + str = malloc(strlen(filename) + (len ? len : strlen(cwd)) + 2); + if (!len) sprintf(str, "%s/%s", cwd, filename); + else { + strncpy(str, path, len); + str += len; + *(str++) = '/'; + strcpy(str, filename); + } + + // If it's not a directory, return it. + if (is_file(str, has_exe)) return str; + else free(str); + + if (!next) break; + path += len; + path++; } - } - chdir (here); - free (here); - if (!topdir) { - fprintf (stderr, "%s: unable to find uClibc headers and libraries relative to '%s'\n", - application_name, mypath); - exit (1); - } -} + free(cwd); -extern void *xmalloc(size_t size) -{ - void *ptr = malloc(size); - - if (!ptr) { - fprintf(stderr, "memory exhausted"); - exit(EXIT_FAILURE); - } - return ptr; + return NULL; } void xstrcat(char **string, ...) @@ -130,7 +87,7 @@ /* Don't bother to calculate how big exerything * will be, just be careful to not overflow... */ va_start(p, string); - *string = xmalloc(BUFSIZ); + *string = malloc(BUFSIZ); **string = '\0'; while(1) { if (!(c = va_arg(p, const char *))) @@ -145,78 +102,50 @@ int use_build_dir = 0, linking = 1, use_static_linking = 0; int use_stdinc = 1, use_start = 1, use_stdlib = 1, use_pic = 0; int source_count = 0, use_rpath = 0, verbose = 0; - int i, j, k, l, m, n; - int sawM = 0; - int sawdotoa = 0; - int sawcES = 0; - char ** gcc_argv; - char ** gcc_argument; - char ** libraries; - char ** libpath; - char *dlstr; - char *incstr; - char *devprefix; - char *libstr; - char *build_dlstr = 0; - char *cc; - char *ep; - char *rpath_link[2]; - char *rpath[2]; - char *uClibc_inc[2]; - char *our_lib_path[2]; - char *crt0_path[2]; - char *crtbegin_path[2]; - char *crtend_path[2]; + int i, j, k, l, m, n, sawM = 0, sawdotoa = 0, sawcES = 0; + char **gcc_argv, **gcc_argument, **libraries, **libpath; + char *dlstr, *incstr, *devprefix, *libstr, *build_dlstr = 0; + char *cc, *ep, *rpath_link[2], *rpath[2], *uClibc_inc[2], *our_lib_path[2]; + char *crt0_path[2], *crtbegin_path[2], *crtend_path[2]; // For C++ - char *crti_path[2]; - char *crtn_path[2]; - int len; - int ctor_dtor = 1, cplusplus = 0, use_nostdinc_plus = 0; - char *cpp = NULL; + char *crti_path[2], *crtn_path[2], *cpp = NULL; + int len, ctor_dtor = 1, cplusplus = 0, use_nostdinc_plus = 0; // For profiling int profile = 0; char *gcrt1_path[2]; + // What directory is the wrapper script in? + if(!(mypath = find_in_path(getenv("PATH"), argv[0], 1))) { + fprintf(stderr, "can't find %s in $PATH\n", argv[0]); + exit(1); + // Add that directory to the start of $PATH. (Better safe than sorry.) + } else { + char *path = getenv("PATH"), *temp; + + *rindex(mypath,'/') = 0; + temp = malloc(strlen(mypath)+strlen(path)+7); + sprintf(temp,"PATH=%s:%s",mypath,path); + putenv(temp); + } + + // What's the name of the C compiler we're wrapping? (It may have a + // cross-prefix.) cc = getenv("UCLIBC_CC"); if (!cc) cc = GCC_BIN; - char *argvwork = strdup(argv[0]); - application_name = strdup(argvwork); - mypath = dirname(argvwork); - if (strcmp (mypath, ".") == 0) { - int n = 4096; - char *buf; - while (1) { - buf = calloc (1, n); - if (readlink ("/proc/self/exe", buf, n) < 0) - break; - if (buf[n - 1] == '\0') { - mypath = strdup(dirname(buf)); - char *p = strstr (mypath, "/" TARGET_DIR); - if (p) - strcpy (p, "/bin"); - break; - } - free(buf); - n *= 2; - } + topdir = find_in_path("../"TARGET_DIR"/lib:../lib", "ld-uClibc.so.0", 0); + if (!topdir) { + fprintf(stderr, "unable to find ld-uClibc.so.0 near '%s'\n", mypath); + exit(1); } - finddirs(); - - if (application_name[0] == '-') - application_name++; + *rindex(topdir,'/') = 0; - /* We must use strstr since g++ might be named like a - * cross compiler (i.e. arm-linux-g++). We must also - * search carefully, in case we are searching something - * like /opt/c++/gcc-3.1/bin/arm-linux-g++ or some similar - * perversion... */ - len = strlen(application_name); - if ((strcmp(application_name+len-3, "g++")==0) || - (strcmp(application_name+len-3, "c++")==0)) { + // Check end of name, since there could be a cross-prefix on the thing + len = strlen(argv[0]); + if (!strcmp(argv[0]+len-3, "g++") || !strcmp(argv[0]+len-3, "c++")) { len = strlen(cc); if (strcmp(cc+len-3, "gcc")==0) { cpp = strdup(cc); @@ -423,10 +352,7 @@ xstrcat(&(crtend_path[1]), devprefix, "/lib/crtendS.o", NULL); } - if (cplusplus && cpp) - gcc_argv[i++] = cpp; - else - gcc_argv[i++] = cc; + gcc_argv[i++] = cpp ? cpp : cc; if (EXTRAGCCFLAGS) gcc_argv[i++] = EXTRAGCCFLAGS; @@ -561,13 +487,9 @@ } fflush(stdout); } + //no need to free memory from xstrcat because we never return... - if (cplusplus && cpp) { - myexecvp(cpp, gcc_argv); - fprintf(stderr, "%s: %s\n", cpp, strerror(errno)); - } else { - myexecvp(cc, gcc_argv); - fprintf(stderr, "%s: %s\n", cc, strerror(errno)); - } + execvp(cpp ? cpp : cc, gcc_argv); + fprintf(stderr, "%s: %s\n", cpp ? cpp : cc, strerror(errno)); exit(EXIT_FAILURE); }