From d5e3aeb1ff6e4b0fccbee646d51a6e370863c832 Mon Sep 17 00:00:00 2001 From: midipix Date: Nov 07 2018 14:40:43 +0000 Subject: driver: slbt_init_host_params(): enhance the target-ar related logic. --- diff --git a/src/driver/slbt_driver_ctx.c b/src/driver/slbt_driver_ctx.c index a2e71df..e0e3f52 100644 --- a/src/driver/slbt_driver_ctx.c +++ b/src/driver/slbt_driver_ctx.c @@ -7,7 +7,11 @@ #include #include #include +#include +#include #include +#include +#include #define ARGV_DRIVER @@ -18,6 +22,8 @@ #include "slibtool_lconf_impl.h" #include "argv/argv.h" +extern char ** environ; + /* package info */ static const struct slbt_source_version slbt_src_version = { SLBT_TAG_VER_MAJOR, @@ -542,6 +548,10 @@ static int slbt_init_host_params( struct slbt_host_params * host, struct slbt_host_params * cfgmeta) { + int ret; + int arprobe; + int arfd; + pid_t arpid; size_t toollen; char * dash; char * base; @@ -557,6 +567,8 @@ static int slbt_init_host_params( char machinebuf [256]; char * hostquad [4]; char * machinequad[4]; + char * arprobeargv[4]; + char archivename[] = "/tmp/slibtool.ar.probe.XXXXXXXXXXXXXXXX"; /* base */ if ((base = strrchr(cctx->cargv[0],'/'))) @@ -698,9 +710,79 @@ static int slbt_init_host_params( if (fnative) { strcpy(drvhost->ar,"ar"); cfgmeta->ar = cfgnative; + arprobe = 0; + } else if (cctx->mode == SLBT_MODE_LINK) { + arprobe = true; + } else if (cctx->mode == SLBT_MODE_INFO) { + arprobe = true; } else { + arprobe = false; + } + + /* arprobe */ + if (arprobe) { sprintf(drvhost->ar,"%s-ar",host->host); cfgmeta->ar = cfghost; + + ret = 0; + arpid = 0; + arfd = -1; + + /* empty archive */ + if ((arfd = mkstemp(archivename)) >= 0) { + slbt_dprintf(arfd,"!\n"); + + arprobeargv[0] = drvhost->ar; + arprobeargv[1] = "-t"; + arprobeargv[2] = archivename; + arprobeargv[3] = 0; + + /* -ar */ + ret = (posix_spawnp( + &arpid, + drvhost->ar, + 0,0,arprobeargv, + environ)); + } + + /* --ar */ + if (ret && (errno == ENOENT) && !strchr(base,'-')) { + sprintf(drvhost->ar,"%s-%s-ar",host->host,base); + + ret = (posix_spawnp( + &arpid, + drvhost->ar, + 0,0,arprobeargv, + environ)); + } + + /* -ar */ + if (ret && (errno == ENOENT) && !strchr(base,'-')) { + sprintf(drvhost->ar,"%s-ar",base); + + ret = (posix_spawnp( + &arpid, + drvhost->ar, + 0,0,arprobeargv, + environ)); + } + + /* if target is the native target, fallback to native ar */ + if (ret && (errno == ENOENT) && !strcmp(host->host,SLBT_MACHINE)) { + strcpy(drvhost->ar,"ar"); + cfgmeta->ar = cfgnative; + } + + /* may not unlink before ar has exited */ + if (arpid) { + waitpid(arpid,0,0); + } + + /* clean up */ + if (arfd >= 0) { + unlink(archivename); + close(arfd); + } } host->ar = drvhost->ar;