/*******************************************************************/ /* slibtool: a skinny libtool implementation, written in C */ /* Copyright (C) 2016--2021 Z. Gilboa */ /* Released under the Standard MIT License; see COPYING.SLIBTOOL. */ /*******************************************************************/ #include #include #include #include #include #include #include "slibtool_spawn_impl.h" #include "slibtool_driver_impl.h" #include "slibtool_errinfo_impl.h" int slbt_exec_execute( const struct slbt_driver_ctx * dctx, struct slbt_exec_ctx * ectx) { int ret; int fdcwd; char * program; char * script; char * base; char * mark; char exeref [PATH_MAX]; char wrapper[PATH_MAX]; struct stat st; struct slbt_exec_ctx * actx = 0; /* dry run */ if (dctx->cctx->drvflags & SLBT_DRIVER_DRY_RUN) return 0; /* context */ if (ectx) slbt_disable_placeholders(ectx); else if ((ret = slbt_get_exec_ctx(dctx,&ectx))) return ret; else { actx = ectx; slbt_disable_placeholders(ectx); } /* script, program */ program = ectx->cargv[0]; script = ectx->cargv[1]; if (script) { /* exeref */ if ((base = strrchr(script,'/'))) base++; else base = script; strcpy(exeref,script); mark = exeref + (base - script); sprintf(mark,".libs/%s",base); /* wrapper */ if ((size_t)snprintf(wrapper,sizeof(wrapper), "%s.exe.wrapper", exeref) >= sizeof(wrapper)) { slbt_free_exec_ctx(actx); return SLBT_BUFFER_ERROR(dctx); } /* fdcwd */ fdcwd = slbt_driver_fdcwd(dctx); /* swap vector */ if (!fstatat(fdcwd,script,&st,0) && !fstatat(fdcwd,wrapper,&st,0)) { ectx->cargv[0] = wrapper; ectx->cargv[1] = program; ectx->cargv[2] = exeref; } else { script = program; } /* execute mode */ ectx->program = script; ectx->argv = ectx->cargv; } else { ectx->program = program; ectx->argv = ectx->cargv; } /* step output */ if (!(dctx->cctx->drvflags & SLBT_DRIVER_SILENT)) if (slbt_output_execute(dctx,ectx)) { slbt_free_exec_ctx(actx); return SLBT_NESTED_ERROR(dctx); } execvp(ectx->cargv[0],ectx->argv); slbt_free_exec_ctx(actx); return SLBT_SYSTEM_ERROR(dctx,0); }