firasuke / cross / slibtool

Forked from cross/slibtool 3 months ago
Clone

Blame src/helper/slbt_archive_import.c

4a01cf
/*******************************************************************/
4a01cf
/*  slibtool: a skinny libtool implementation, written in C        */
4a01cf
/*  Copyright (C) 2016  Z. Gilboa                                  */
4a01cf
/*  Released under the Standard MIT License; see COPYING.SLIBTOOL. */
4a01cf
/*******************************************************************/
4a01cf
4a01cf
#include <stdlib.h>
4a01cf
#include <limits.h>
4a01cf
#include <unistd.h>
4a01cf
#include <stdbool.h>
4a01cf
#include <sys/wait.h>
4a01cf
4a01cf
#include <slibtool/slibtool.h>
4a01cf
#include "slibtool_spawn_impl.h"
4a01cf
4a01cf
static int slbt_archive_import_child(
4a01cf
	char *	program,
4a01cf
	int	fd[2])
4a01cf
{
4a01cf
	char *	argv[3];
4a01cf
4a01cf
	argv[0] = program;
4a01cf
	argv[1] = "-M";
4a01cf
	argv[2] = 0;
4a01cf
4a01cf
	close(fd[1]);
4a01cf
	close(0);
4a01cf
4a01cf
	if (dup(fd[0]) == 0)
4a01cf
		execvp(program,argv);
4a01cf
4a01cf
	exit(EXIT_FAILURE);
4a01cf
	return -1;
4a01cf
}
4a01cf
4a01cf
inline int slbt_archive_import(
4a01cf
	const struct slbt_driver_ctx *	dctx,
4a01cf
	struct slbt_exec_ctx *		ectx,
4a01cf
	char *				dstarchive,
4a01cf
	char *				srcarchive)
4a01cf
{
4a01cf
	pid_t	pid;
4a01cf
	int	ret;
4a01cf
	int	code;
4a01cf
	int	fd[2];
4a01cf
	FILE *	fout;
4a01cf
	char	program[PATH_MAX];
4a01cf
4a01cf
	if ((size_t)snprintf(program,sizeof(program),"%s",
4a01cf
			dctx->cctx->host.ar) >= sizeof(program))
4a01cf
		return -1;
4a01cf
4a01cf
	if (pipe(fd))
4a01cf
		return -1;
4a01cf
4a01cf
	if ((pid = fork()) < 0) {
4a01cf
		close(fd[0]);
4a01cf
		close(fd[1]);
4a01cf
		return -1;
4a01cf
	}
4a01cf
4a01cf
	if (pid == 0)
4a01cf
		return slbt_archive_import_child(
4a01cf
			program,
4a01cf
			fd);
4a01cf
4a01cf
	ectx->pid = pid;
4a01cf
4a01cf
	if ((fout = fdopen(fd[1],"a"))) {
4a01cf
		ret = (fprintf(
4a01cf
				fout,
4a01cf
				"OPEN %s\n"
4a01cf
				"ADDLIB %s\n"
4a01cf
				"SAVE\n"
4a01cf
				"END\n",
4a01cf
				dstarchive,
4a01cf
				srcarchive) < 0)
4a01cf
			? -1 : 0;
4a01cf
4a01cf
		fclose(fout);
4a01cf
		close(fd[0]);
4a01cf
	} else {
4a01cf
		ret = -1;
4a01cf
		close(fd[0]);
4a01cf
		close(fd[1]);
4a01cf
	}
4a01cf
4a01cf
	code = waitpid(
4a01cf
		pid,
4a01cf
		&ectx->exitcode,
4a01cf
		0);
4a01cf
4a01cf
	return ret || (code != pid) || ectx->exitcode
4a01cf
		? -1 : 0;
4a01cf
}