diff --git a/include/slibtool/slibtool.h b/include/slibtool/slibtool.h index c1f9ede..265ba49 100644 --- a/include/slibtool/slibtool.h +++ b/include/slibtool/slibtool.h @@ -201,8 +201,11 @@ slbt_api int slbt_exec_compile (const struct slbt_driver_ctx *, struct slbt_ex slbt_api int slbt_exec_install (const struct slbt_driver_ctx *, struct slbt_exec_ctx *); slbt_api int slbt_exec_link (const struct slbt_driver_ctx *, struct slbt_exec_ctx *); +/* helper api */ slbt_api int slbt_map_input (int fd, const char * path, int prot, struct slbt_input *); slbt_api int slbt_unmap_input (struct slbt_input *); +slbt_api int slbt_archive_import (const struct slbt_driver_ctx *, struct slbt_exec_ctx *, + char * dstarchive, char * srcarchive); /* utility api */ slbt_api int slbt_output_config (const struct slbt_driver_ctx *); diff --git a/project/common.mk b/project/common.mk index 719b6a2..ae06f28 100644 --- a/project/common.mk +++ b/project/common.mk @@ -2,6 +2,7 @@ COMMON_SRCS = \ src/internal/slibtool_symlink_impl.c \ src/driver/slbt_driver_ctx.c \ src/driver/slbt_unit_ctx.c \ + src/helper/slbt_archive_import.c \ src/logic/slbt_exec_compile.c \ src/logic/slbt_exec_ctx.c \ src/logic/slbt_exec_install.c \ diff --git a/project/tree.mk b/project/tree.mk index d91f6a2..42564b8 100644 --- a/project/tree.mk +++ b/project/tree.mk @@ -1,6 +1,7 @@ tree.tag: mkdir -p src mkdir -p src/driver + mkdir -p src/helper mkdir -p src/internal mkdir -p src/logic mkdir -p src/output diff --git a/src/helper/slbt_archive_import.c b/src/helper/slbt_archive_import.c new file mode 100644 index 0000000..7bd50cc --- /dev/null +++ b/src/helper/slbt_archive_import.c @@ -0,0 +1,95 @@ +/*******************************************************************/ +/* 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 "slibtool_spawn_impl.h" + +static int slbt_archive_import_child( + char * program, + int fd[2]) +{ + char * argv[3]; + + argv[0] = program; + argv[1] = "-M"; + argv[2] = 0; + + close(fd[1]); + close(0); + + if (dup(fd[0]) == 0) + execvp(program,argv); + + exit(EXIT_FAILURE); + return -1; +} + +inline int slbt_archive_import( + const struct slbt_driver_ctx * dctx, + struct slbt_exec_ctx * ectx, + char * dstarchive, + char * srcarchive) +{ + pid_t pid; + int ret; + int code; + int fd[2]; + FILE * fout; + char program[PATH_MAX]; + + if ((size_t)snprintf(program,sizeof(program),"%s", + dctx->cctx->host.ar) >= 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_archive_import_child( + program, + fd); + + ectx->pid = pid; + + if ((fout = fdopen(fd[1],"a"))) { + ret = (fprintf( + fout, + "OPEN %s\n" + "ADDLIB %s\n" + "SAVE\n" + "END\n", + dstarchive, + srcarchive) < 0) + ? -1 : 0; + + fclose(fout); + close(fd[0]); + } else { + ret = -1; + close(fd[0]); + close(fd[1]); + } + + code = waitpid( + pid, + &ectx->exitcode, + 0); + + return ret || (code != pid) || ectx->exitcode + ? -1 : 0; +}