boot2

Playing with the boostrap
git clone https://git.ryansepassi.com/git/boot2.git
Log | Files | Refs | README

relocatable-driver.after (2138B)


      1 /* Find the invoked compiler without relying on /proc or a shell wrapper.
      2    An argv[0] containing a slash is already usable. Otherwise search PATH
      3    with open(2); access(2) is intentionally unavailable in mes-libc. */
      4 static int tcc_find_self(char *buf, int size, const char *argv0)
      5 {
      6     const char *path, *p, *q;
      7     int n, fd, valid;
      8 
      9     if (strchr(argv0, '/')) {
     10         snprintf(buf, size, "%s", argv0);
     11         return 1;
     12     }
     13     path = getenv("PATH");
     14     if (!path)
     15         return 0;
     16     p = path;
     17     for (;;) {
     18         q = p;
     19         while (*q && *q != ':')
     20             ++q;
     21         n = q - p;
     22         valid = 0;
     23         if (n == 0) {
     24             if (strlen(argv0) + 3 <= size) {
     25                 strcpy(buf, "./");
     26                 strcat(buf, argv0);
     27                 valid = 1;
     28             }
     29         } else if (n + strlen(argv0) + 2 <= size) {
     30             memcpy(buf, p, n);
     31             buf[n] = '/';
     32             strcpy(buf + n + 1, argv0);
     33             valid = 1;
     34         }
     35         if (valid) {
     36             fd = open(buf, 0);
     37             if (fd >= 0) {
     38                 close(fd);
     39                 return 1;
     40             }
     41         }
     42         if (!*q)
     43             break;
     44         p = q + 1;
     45     }
     46     return 0;
     47 }
     48 
     49 /* The installed layout is PREFIX/bin/tcc + PREFIX/lib/tcc. Keep the
     50    unnormalized "bin/.." component: it is valid on every runtime in the
     51    bootstrap and avoids requiring realpath(3) or readlink(2). */
     52 static void tcc_set_self_lib_path(TCCState *s, const char *argv0)
     53 {
     54     char executable[1024], lib_path[1024], *base;
     55 
     56     if (!tcc_find_self(executable, sizeof(executable), argv0))
     57         return;
     58     base = tcc_basename(executable);
     59     if (base > executable)
     60         base[-1] = 0;
     61     else
     62         strcpy(executable, ".");
     63     snprintf(lib_path, sizeof(lib_path), "%s/../lib/tcc", executable);
     64     tcc_set_lib_path(s, lib_path);
     65 }
     66 
     67 int main(int argc, char **argv)
     68 {
     69     TCCState *s;
     70     int ret, opt, n = 0;
     71     unsigned start_time = 0;
     72     const char *first_file;
     73     const char *argv0 = argv[0];
     74 
     75 redo:
     76     s = tcc_new();
     77     tcc_set_self_lib_path(s, argv0);
     78     opt = tcc_parse_args(s, &argc, &argv, 1);