|
 |
e956c8 |
/*******************************************************************/
|
|
 |
eac61a |
|
|
 |
49181b |
|
|
 |
e956c8 |
|
|
 |
e956c8 |
/*******************************************************************/
|
|
 |
e956c8 |
|
|
 |
e956c8 |
#include <string.h>
|
|
 |
e956c8 |
#include <stdbool.h>
|
|
 |
e956c8 |
#include <fcntl.h>
|
|
 |
e956c8 |
#include <errno.h>
|
|
 |
e956c8 |
#include <sys/stat.h>
|
|
 |
e956c8 |
|
|
 |
e956c8 |
#include <slibtool/slibtool.h>
|
|
 |
e956c8 |
#include "slibtool_spawn_impl.h"
|
|
 |
7ae5c1 |
#include "slibtool_driver_impl.h"
|
|
 |
19022e |
#include "slibtool_snprintf_impl.h"
|
|
 |
a47c7a |
#include "slibtool_errinfo_impl.h"
|
|
 |
e956c8 |
|
|
 |
dfb331 |
|
|
 |
dfb331 |
/*******************************************************************/
|
|
 |
dfb331 |
|
|
 |
dfb331 |
|
|
 |
dfb331 |
|
|
 |
dfb331 |
/* one common scenario where: */
|
|
 |
dfb331 |
|
|
 |
dfb331 |
|
|
 |
dfb331 |
|
|
 |
dfb331 |
|
|
 |
dfb331 |
|
|
 |
dfb331 |
|
|
 |
dfb331 |
|
|
 |
dfb331 |
|
|
 |
dfb331 |
|
|
 |
dfb331 |
|
|
 |
dfb331 |
|
|
 |
dfb331 |
|
|
 |
dfb331 |
|
|
 |
dfb331 |
|
|
 |
dfb331 |
|
|
 |
dfb331 |
|
|
 |
dfb331 |
|
|
 |
dfb331 |
/* shell command line or otherwise; or */
|
|
 |
dfb331 |
|
|
 |
dfb331 |
|
|
 |
dfb331 |
|
|
 |
dfb331 |
|
|
 |
dfb331 |
/* first non-slibtool argument) or for processing by another */
|
|
 |
dfb331 |
|
|
 |
dfb331 |
|
|
 |
dfb331 |
|
|
 |
dfb331 |
/* wrapper script. The load environment variable is set based on */
|
|
 |
dfb331 |
/* the path that was stored in it by slibtool at link time, and */
|
|
 |
dfb331 |
/* the real executable is then exec'ed. */
|
|
 |
dfb331 |
|
|
 |
dfb331 |
|
|
 |
dfb331 |
|
|
 |
dfb331 |
/* built executable program. If it is, then slibtool would invoke */
|
|
 |
dfb331 |
|
|
 |
dfb331 |
|
|
 |
dfb331 |
|
|
 |
dfb331 |
|
|
 |
dfb331 |
/* slibtool will replace any remaining command-line argument which */
|
|
 |
dfb331 |
|
|
 |
dfb331 |
|
|
 |
dfb331 |
|
|
 |
dfb331 |
|
|
 |
dfb331 |
|
|
 |
dfb331 |
/* created at link time for _all_ executable programs, including */
|
|
 |
dfb331 |
/* those programs which appear to have system libraries as their */
|
|
 |
dfb331 |
|
|
 |
dfb331 |
/*******************************************************************/
|
|
 |
dfb331 |
|
|
 |
dfb331 |
|
|
 |
dfb331 |
static int slbt_argument_is_an_executable_wrapper_script(
|
|
 |
dfb331 |
const struct slbt_driver_ctx * dctx,
|
|
 |
dfb331 |
const char * arg,
|
|
 |
dfb331 |
char (*altarg)[PATH_MAX])
|
|
 |
dfb331 |
{
|
|
 |
dfb331 |
int fdcwd;
|
|
 |
dfb331 |
const char * base;
|
|
 |
dfb331 |
char * mark;
|
|
 |
dfb331 |
struct stat st;
|
|
 |
dfb331 |
|
|
 |
dfb331 |
|
|
 |
dfb331 |
if (strlen(arg) > (PATH_MAX - 20))
|
|
 |
dfb331 |
return SLBT_BUFFER_ERROR(dctx);
|
|
 |
dfb331 |
|
|
 |
dfb331 |
/* path/to/progname
|
|
 |
dfb331 |
if ((base = strrchr(arg,'/')))
|
|
 |
dfb331 |
base++;
|
|
 |
dfb331 |
|
|
 |
dfb331 |
if (!base)
|
|
 |
dfb331 |
base = arg;
|
|
 |
dfb331 |
|
|
 |
dfb331 |
mark = *altarg;
|
|
 |
dfb331 |
mark += base - arg;
|
|
 |
dfb331 |
|
|
 |
dfb331 |
strcpy(*altarg,arg);
|
|
 |
dfb331 |
mark += sprintf(mark,".libs/%s",base);
|
|
 |
dfb331 |
strcpy(mark,".exe.wrapper");
|
|
 |
dfb331 |
|
|
 |
dfb331 |
|
|
 |
dfb331 |
fdcwd = slbt_driver_fdcwd(dctx);
|
|
 |
dfb331 |
|
|
 |
dfb331 |
if (fstatat(fdcwd,*altarg,&st,0) < 0)
|
|
 |
dfb331 |
return (errno == ENOENT)
|
|
 |
dfb331 |
? 0 : SLBT_SYSTEM_ERROR(dctx,*altarg);
|
|
 |
dfb331 |
|
|
 |
dfb331 |
/* path/to/.libs/progname.exe.wapper
|
|
 |
dfb331 |
*mark = '\0';
|
|
 |
dfb331 |
|
|
 |
dfb331 |
return 1;
|
|
 |
dfb331 |
}
|
|
 |
dfb331 |
|
|
 |
dfb331 |
|
|
 |
2e30eb |
int slbt_exec_execute(const struct slbt_driver_ctx * dctx)
|
|
 |
e956c8 |
{
|
|
 |
dfb331 |
int ret;
|
|
 |
dfb331 |
char ** parg;
|
|
 |
dfb331 |
char ** aarg;
|
|
 |
e956c8 |
char * program;
|
|
 |
dfb331 |
char * exeref;
|
|
 |
e956c8 |
char wrapper[PATH_MAX];
|
|
 |
dfb331 |
char exeprog[PATH_MAX];
|
|
 |
dfb331 |
char argbuf [PATH_MAX];
|
|
 |
2e30eb |
struct slbt_exec_ctx * ectx;
|
|
 |
e956c8 |
|
|
 |
c4a389 |
/* dry run */
|
|
 |
c4a389 |
if (dctx->cctx->drvflags & SLBT_DRIVER_DRY_RUN)
|
|
 |
c4a389 |
return 0;
|
|
 |
c4a389 |
|
|
 |
e956c8 |
|
|
 |
2e30eb |
if (slbt_ectx_get_exec_ctx(dctx,&ectx) < 0)
|
|
 |
2e30eb |
return SLBT_NESTED_ERROR(dctx);
|
|
 |
2e30eb |
|
|
 |
2e30eb |
slbt_disable_placeholders(ectx);
|
|
 |
e956c8 |
|
|
 |
dfb331 |
|
|
 |
dfb331 |
parg = ectx->cargv;
|
|
 |
dfb331 |
aarg = ectx->altv;
|
|
 |
70949a |
|
|
 |
dfb331 |
|
|
 |
dfb331 |
if (!(program = ectx->cargv[0]))
|
|
 |
dfb331 |
return SLBT_CUSTOM_ERROR(
|
|
 |
dfb331 |
dctx,
|
|
 |
dfb331 |
SLBT_ERR_FLOW_ERROR);
|
|
 |
7ae5c1 |
|
|
 |
dfb331 |
|
|
 |
dfb331 |
for (exeref=0; !exeref && *parg; parg++) {
|
|
 |
dfb331 |
strcpy(argbuf,*parg);
|
|
 |
dfb331 |
|
|
 |
dfb331 |
if ((ret = slbt_argument_is_an_executable_wrapper_script(
|
|
 |
dfb331 |
dctx,argbuf,&exeprog)) < 0) {
|
|
 |
dfb331 |
return SLBT_NESTED_ERROR(dctx);
|
|
 |
dfb331 |
|
|
 |
dfb331 |
} else if (ret == 1) {
|
|
 |
c1ce86 |
if (slbt_snprintf(
|
|
 |
c1ce86 |
wrapper,sizeof(wrapper),
|
|
 |
c1ce86 |
"%s.exe.wrapper",exeprog) < 0)
|
|
 |
c1ce86 |
return SLBT_BUFFER_ERROR(dctx);
|
|
 |
c1ce86 |
|
|
 |
dfb331 |
exeref = *parg;
|
|
 |
dfb331 |
*aarg++ = wrapper;
|
|
Lucio Andrés Illanes Albornoz |
f27e85 |
} else {
|
|
 |
dfb331 |
strcpy(*parg,argbuf);
|
|
Lucio Andrés Illanes Albornoz |
f27e85 |
}
|
|
 |
dfb331 |
}
|
|
Lucio Andrés Illanes Albornoz |
f27e85 |
|
|
 |
dfb331 |
/* transform in place as needed all arguments */
|
|
 |
dfb331 |
for (parg=ectx->cargv; *parg; parg++) {
|
|
 |
dfb331 |
if ((ret = slbt_argument_is_an_executable_wrapper_script(
|
|
 |
dfb331 |
dctx,*parg,&argbuf)) < 0) {
|
|
 |
dfb331 |
return SLBT_NESTED_ERROR(dctx);
|
|
 |
dfb331 |
|
|
 |
dfb331 |
} else if (ret == 1) {
|
|
 |
dfb331 |
strcpy(*parg,argbuf);
|
|
 |
dfb331 |
*aarg++ = *parg;
|
|
 |
dfb331 |
} else {
|
|
 |
dfb331 |
*aarg++ = *parg;
|
|
 |
dfb331 |
}
|
|
 |
1ed71a |
}
|
|
 |
e956c8 |
|
|
 |
dfb331 |
*aarg = 0;
|
|
 |
dfb331 |
|
|
 |
dfb331 |
|
|
 |
dfb331 |
ectx->program = ectx->altv[0];
|
|
 |
dfb331 |
ectx->argv = ectx->altv;
|
|
 |
dfb331 |
|
|
 |
e956c8 |
|
|
 |
dfb331 |
if (!(dctx->cctx->drvflags & SLBT_DRIVER_SILENT)) {
|
|
 |
33a569 |
if (slbt_output_execute(ectx)) {
|
|
 |
2e30eb |
slbt_ectx_free_exec_ctx(ectx);
|
|
 |
a47c7a |
return SLBT_NESTED_ERROR(dctx);
|
|
 |
e956c8 |
}
|
|
 |
dfb331 |
}
|
|
 |
e956c8 |
|
|
 |
dfb331 |
execvp(ectx->altv[0],ectx->altv);
|
|
 |
e956c8 |
|
|
 |
2e30eb |
slbt_ectx_free_exec_ctx(ectx);
|
|
 |
6beda1 |
return SLBT_SYSTEM_ERROR(dctx,0);
|
|
 |
e956c8 |
}
|