| |
| |
| |
| |
| |
| |
| #include <string.h> |
| #include <stdbool.h> |
| #include <fcntl.h> |
| #include <errno.h> |
| #include <sys/stat.h> |
| |
| #include <slibtool/slibtool.h> |
| #include "slibtool_spawn_impl.h" |
| #include "slibtool_driver_impl.h" |
| #include "slibtool_snprintf_impl.h" |
| #include "slibtool_errinfo_impl.h" |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| static int slbt_argument_is_an_executable_wrapper_script( |
| const struct slbt_driver_ctx * dctx, |
| const char * arg, |
| char (*altarg)[PATH_MAX]) |
| { |
| int fdcwd; |
| const char * base; |
| char * mark; |
| struct stat st; |
| |
| |
| if (strlen(arg) > (PATH_MAX - 20)) |
| return SLBT_BUFFER_ERROR(dctx); |
| |
| |
| if ((base = strrchr(arg,'/'))) |
| base++; |
| |
| if (!base) |
| base = arg; |
| |
| mark = *altarg; |
| mark += base - arg; |
| |
| strcpy(*altarg,arg); |
| mark += sprintf(mark,".libs/%s",base); |
| strcpy(mark,".exe.wrapper"); |
| |
| |
| fdcwd = slbt_driver_fdcwd(dctx); |
| |
| if (fstatat(fdcwd,*altarg,&st,0) < 0) |
| return (errno == ENOENT) |
| ? 0 : SLBT_SYSTEM_ERROR(dctx,*altarg); |
| |
| |
| *mark = '\0'; |
| |
| return 1; |
| } |
| |
| |
| int slbt_exec_execute(const struct slbt_driver_ctx * dctx) |
| { |
| int ret; |
| char ** parg; |
| char ** aarg; |
| char * program; |
| char * exeref; |
| char wrapper[PATH_MAX]; |
| char exeprog[PATH_MAX]; |
| char argbuf [PATH_MAX]; |
| struct slbt_exec_ctx * ectx; |
| |
| |
| if (dctx->cctx->drvflags & SLBT_DRIVER_DRY_RUN) |
| return 0; |
| |
| |
| if (slbt_ectx_get_exec_ctx(dctx,&ectx) < 0) |
| return SLBT_NESTED_ERROR(dctx); |
| |
| slbt_disable_placeholders(ectx); |
| |
| |
| parg = ectx->cargv; |
| aarg = ectx->altv; |
| |
| |
| if (!(program = ectx->cargv[0])) |
| return SLBT_CUSTOM_ERROR( |
| dctx, |
| SLBT_ERR_FLOW_ERROR); |
| |
| |
| for (exeref=0; !exeref && *parg; parg++) { |
| strcpy(argbuf,*parg); |
| |
| if ((ret = slbt_argument_is_an_executable_wrapper_script( |
| dctx,argbuf,&exeprog)) < 0) { |
| return SLBT_NESTED_ERROR(dctx); |
| |
| } else if (ret == 1) { |
| if (slbt_snprintf( |
| wrapper,sizeof(wrapper), |
| "%s.exe.wrapper",exeprog) < 0) |
| return SLBT_BUFFER_ERROR(dctx); |
| |
| exeref = *parg; |
| *aarg++ = wrapper; |
| } else { |
| strcpy(*parg,argbuf); |
| } |
| } |
| |
| |
| for (parg=ectx->cargv; *parg; parg++) { |
| if ((ret = slbt_argument_is_an_executable_wrapper_script( |
| dctx,*parg,&argbuf)) < 0) { |
| return SLBT_NESTED_ERROR(dctx); |
| |
| } else if (ret == 1) { |
| strcpy(*parg,argbuf); |
| *aarg++ = *parg; |
| } else { |
| *aarg++ = *parg; |
| } |
| } |
| |
| *aarg = 0; |
| |
| |
| ectx->program = ectx->altv[0]; |
| ectx->argv = ectx->altv; |
| |
| |
| if (!(dctx->cctx->drvflags & SLBT_DRIVER_SILENT)) { |
| if (slbt_output_execute(ectx)) { |
| slbt_ectx_free_exec_ctx(ectx); |
| return SLBT_NESTED_ERROR(dctx); |
| } |
| } |
| |
| execvp(ectx->altv[0],ectx->altv); |
| |
| slbt_ectx_free_exec_ctx(ectx); |
| return SLBT_SYSTEM_ERROR(dctx,0); |
| } |