summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/slibtool/slibtool.h1
-rw-r--r--project/common.mk1
-rw-r--r--src/helper/slbt_dump_machine.c113
3 files changed, 115 insertions, 0 deletions
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 <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;
+}