diff --git a/include/slibtool/slibtool.h b/include/slibtool/slibtool.h index 1430fdc..2b55a84 100644 --- a/include/slibtool/slibtool.h +++ b/include/slibtool/slibtool.h @@ -231,6 +231,7 @@ slbt_api int slbt_archive_import (const struct slbt_driver_ctx *, struct slbt_e char * dstarchive, char * srcarchive); slbt_api int slbt_copy_file (const struct slbt_driver_ctx *, struct slbt_exec_ctx *, char * src, char * dst); +slbt_api int slbt_dump_machine (const char * compiler, char * machine, size_t bufsize); /* utility api */ slbt_api int slbt_output_config (const struct slbt_driver_ctx *); diff --git a/project/common.mk b/project/common.mk index 6a8c3f1..4bcbc5f 100644 --- a/project/common.mk +++ b/project/common.mk @@ -4,6 +4,7 @@ COMMON_SRCS = \ src/driver/slbt_unit_ctx.c \ src/helper/slbt_archive_import.c \ src/helper/slbt_copy_file.c \ + src/helper/slbt_dump_machine.c \ src/logic/slbt_exec_compile.c \ src/logic/slbt_exec_ctx.c \ src/logic/slbt_exec_install.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; +}