diff options
author | midipix <writeonce@midipix.org> | 2016-04-23 18:58:42 -0400 |
---|---|---|
committer | midipix <writeonce@midipix.org> | 2016-04-23 22:06:41 -0400 |
commit | 575cdb74719dee612d7e7cf063a6c82cd7be1757 (patch) | |
tree | 8bf6204585a809d577334452ab2d4b3949d7178a /src | |
parent | f058a6b12fb33c7ce5ecf4a644040979f0e32ef7 (diff) | |
download | slibtool-575cdb74719dee612d7e7cf063a6c82cd7be1757.tar.bz2 slibtool-575cdb74719dee612d7e7cf063a6c82cd7be1757.tar.xz |
library: helper functions: added slbt_dump_machine.
Diffstat (limited to 'src')
-rw-r--r-- | src/helper/slbt_dump_machine.c | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/src/helper/slbt_dump_machine.c b/src/helper/slbt_dump_machine.c new file mode 100644 index 0000000..0ef13d5 --- /dev/null +++ b/src/helper/slbt_dump_machine.c @@ -0,0 +1,113 @@ +/*******************************************************************/ +/* slibtool: a skinny libtool implementation, written in C */ +/* Copyright (C) 2016 Z. Gilboa */ +/* Released under the Standard MIT License; see COPYING.SLIBTOOL. */ +/*******************************************************************/ + +#include <stdio.h> +#include <limits.h> +#include <unistd.h> +#include <fcntl.h> +#include <string.h> +#include <stdlib.h> +#include <stdbool.h> +#include <sys/wait.h> + +#include <slibtool/slibtool.h> +#include "slibtool_spawn_impl.h" + +static int slbt_dump_machine_child( + char * program, + int fd[2]) +{ + char * compiler; + char * argv[3]; + + if ((compiler = strchr(program,'/'))) + compiler++; + else + compiler = program; + + argv[0] = compiler; + argv[1] = "-dumpmachine"; + argv[2] = 0; + + close(fd[0]); + close(0); + close(1); + + if ((fd[0] = open("/dev/null",O_RDONLY))) + exit(EXIT_FAILURE); + + if (dup(fd[1]) == 1) + execvp(program,argv); + + exit(EXIT_FAILURE); + return -1; +} + +int slbt_dump_machine( + const char * compiler, + char * machine, + size_t bufsize) +{ + pid_t pid; + pid_t rpid; + int code; + int fd[2]; + FILE * fmachine; + char * newline; + char check[2]; + char program[PATH_MAX]; + + if (!machine || !bufsize) + return -1; + + if ((size_t)snprintf(program,sizeof(program),"%s", + compiler) >= sizeof(program)) + return -1; + + if (pipe(fd)) + return -1; + + if ((pid = fork()) < 0) { + close(fd[0]); + close(fd[1]); + return -1; + } + + if (pid == 0) + return slbt_dump_machine_child( + program, + fd); + + rpid = waitpid( + pid, + &code, + 0); + + if ((rpid != pid) || code) { + close(fd[0]); + close(fd[1]); + return -1; + } + + if ((fmachine = fdopen(fd[0],"r"))) { + close(fd[1]); + newline = 0; + + if (fgets(machine,bufsize,fmachine) == machine) + if (!fgets(check,sizeof(check),fmachine)) + if (feof(fmachine)) + if ((newline = strrchr(machine,'\n'))) + *newline = 0; + + fclose(fmachine); + } else { + newline = 0; + close(fd[0]); + close(fd[1]); + } + + return newline ? 0 : -1; +} |