From 575cdb74719dee612d7e7cf063a6c82cd7be1757 Mon Sep 17 00:00:00 2001
From: midipix <writeonce@midipix.org>
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')

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;
+}
-- 
cgit v1.2.3