|
|
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 |
|
|
|
f058a6 |
#include <stdio.h>
|
|
|
4a01cf |
#include <limits.h>
|
|
|
4a01cf |
#include <unistd.h>
|
|
|
2da3b0 |
#include <string.h>
|
|
|
2da3b0 |
#include <stdlib.h>
|
|
|
4a01cf |
#include <stdbool.h>
|
|
|
4a01cf |
#include <sys/wait.h>
|
|
|
4a01cf |
|
|
|
4a01cf |
#include <slibtool/slibtool.h>
|
|
|
4a01cf |
#include "slibtool_spawn_impl.h"
|
|
|
8a1d14 |
#include "slibtool_errinfo_impl.h"
|
|
|
4a01cf |
|
|
|
2da3b0 |
static char * slbt_mri_argument(
|
|
|
2da3b0 |
char * arg,
|
|
|
2da3b0 |
char * buf)
|
|
|
2da3b0 |
{
|
|
|
2da3b0 |
int i;
|
|
|
2da3b0 |
char * lnk;
|
|
|
3c03b3 |
char * target;
|
|
|
2da3b0 |
char mricwd[PATH_MAX];
|
|
|
3c03b3 |
char dstbuf[PATH_MAX];
|
|
|
2da3b0 |
|
|
|
2da3b0 |
if ((!(strchr(arg,'+'))) && (!(strchr(arg,'-'))))
|
|
|
2da3b0 |
return arg;
|
|
|
2da3b0 |
|
|
|
3c03b3 |
if (arg[0] == '/')
|
|
|
3c03b3 |
target = arg;
|
|
|
3c03b3 |
else {
|
|
|
3c03b3 |
if (!(getcwd(mricwd,sizeof(mricwd))))
|
|
|
3c03b3 |
return 0;
|
|
|
3c03b3 |
|
|
|
3c03b3 |
if ((size_t)snprintf(dstbuf,sizeof(dstbuf),"%s/%s",
|
|
|
3c03b3 |
mricwd,arg) >= sizeof(dstbuf))
|
|
|
3c03b3 |
return 0;
|
|
|
2da3b0 |
|
|
|
3c03b3 |
target = dstbuf;
|
|
|
3c03b3 |
}
|
|
|
2da3b0 |
|
|
|
2da3b0 |
for (i=0,lnk=0; i<1024 && !lnk; i++) {
|
|
|
2da3b0 |
if (!(tmpnam(buf)))
|
|
|
2da3b0 |
return 0;
|
|
|
2da3b0 |
|
|
|
2da3b0 |
if (!(symlink(target,buf)))
|
|
|
2da3b0 |
lnk = buf;
|
|
|
2da3b0 |
}
|
|
|
2da3b0 |
|
|
|
2da3b0 |
return lnk;
|
|
|
2da3b0 |
}
|
|
|
2da3b0 |
|
|
|
8a3cc2 |
static void 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 |
}
|
|
|
4a01cf |
|
|
|
cfec3a |
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 |
int ret;
|
|
|
f058a6 |
pid_t pid;
|
|
|
f058a6 |
pid_t rpid;
|
|
|
4a01cf |
int fd[2];
|
|
|
4a01cf |
FILE * fout;
|
|
|
2da3b0 |
char * dst;
|
|
|
2da3b0 |
char * src;
|
|
|
2da3b0 |
char mridst [L_tmpnam];
|
|
|
2da3b0 |
char mrisrc [L_tmpnam];
|
|
|
4a01cf |
char program[PATH_MAX];
|
|
|
4a01cf |
|
|
|
4a01cf |
if ((size_t)snprintf(program,sizeof(program),"%s",
|
|
|
4a01cf |
dctx->cctx->host.ar) >= sizeof(program))
|
|
|
8a1d14 |
return SLBT_BUFFER_ERROR(dctx);
|
|
|
4a01cf |
|
|
|
4a01cf |
if (pipe(fd))
|
|
|
8a1d14 |
return SLBT_SYSTEM_ERROR(dctx);
|
|
|
4a01cf |
|
|
|
4a01cf |
if ((pid = fork()) < 0) {
|
|
|
4a01cf |
close(fd[0]);
|
|
|
4a01cf |
close(fd[1]);
|
|
|
8a1d14 |
return SLBT_SYSTEM_ERROR(dctx);
|
|
|
4a01cf |
}
|
|
|
4a01cf |
|
|
|
4a01cf |
if (pid == 0)
|
|
|
8a3cc2 |
slbt_archive_import_child(
|
|
|
4a01cf |
program,
|
|
|
4a01cf |
fd);
|
|
|
4a01cf |
|
|
|
4a01cf |
ectx->pid = pid;
|
|
|
4a01cf |
|
|
|
2da3b0 |
dst = slbt_mri_argument(dstarchive,mridst);
|
|
|
2da3b0 |
src = slbt_mri_argument(srcarchive,mrisrc);
|
|
|
2da3b0 |
|
|
|
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",
|
|
|
2da3b0 |
dst,
|
|
|
2da3b0 |
src) < 0)
|
|
|
8a1d14 |
? SLBT_SYSTEM_ERROR(dctx)
|
|
|
8a1d14 |
: 0;
|
|
|
4a01cf |
|
|
|
4a01cf |
fclose(fout);
|
|
|
4a01cf |
close(fd[0]);
|
|
|
4a01cf |
} else {
|
|
|
8a1d14 |
ret = SLBT_SYSTEM_ERROR(dctx);
|
|
|
4a01cf |
close(fd[0]);
|
|
|
4a01cf |
close(fd[1]);
|
|
|
4a01cf |
}
|
|
|
4a01cf |
|
|
|
f058a6 |
rpid = waitpid(
|
|
|
4a01cf |
pid,
|
|
|
4a01cf |
&ectx->exitcode,
|
|
|
4a01cf |
0);
|
|
|
4a01cf |
|
|
|
2da3b0 |
if (dst == mridst)
|
|
|
2da3b0 |
unlink(dst);
|
|
|
2da3b0 |
|
|
|
2da3b0 |
if (src == mrisrc)
|
|
|
2da3b0 |
unlink(src);
|
|
|
2da3b0 |
|
|
|
f058a6 |
return ret || (rpid != pid) || ectx->exitcode
|
|
|
8a1d14 |
? SLBT_CUSTOM_ERROR(dctx,0) : 0;
|
|
|
4a01cf |
}
|