From 575cdb74719dee612d7e7cf063a6c82cd7be1757 Mon Sep 17 00:00:00 2001 From: midipix Date: Sat, 23 Apr 2016 18:58:42 -0400 Subject: library: helper functions: added slbt_dump_machine. --- src/helper/slbt_dump_machine.c | 113 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 src/helper/slbt_dump_machine.c (limited to 'src/helper/slbt_dump_machine.c') 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 +#include +#include +#include +#include +#include +#include +#include + +#include +#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; +} -- cgit v1.2.3