diff options
author | midipix <writeonce@midipix.org> | 2018-11-07 23:45:25 -0500 |
---|---|---|
committer | midipix <writeonce@midipix.org> | 2018-11-07 23:45:25 -0500 |
commit | a62f9038bdfb998958afbd3097656dfa6d611cc2 (patch) | |
tree | 2209d468f184812e7fcfca8e4ef431fcdb660012 /src/driver | |
parent | 4c6c6b405a732e2ad1c9fb1278cfd8f40927828c (diff) | |
download | slibtool-a62f9038bdfb998958afbd3097656dfa6d611cc2.tar.bz2 slibtool-a62f9038bdfb998958afbd3097656dfa6d611cc2.tar.xz |
driver: enhanced target-ar logic: accommodate legacy systems.
On legacy systems, posix_spawnp() might return 0 even if the execvp()
invocation in the child had failed with ENOENT.
Replace posix_spawnp() with an internal, fork+execvp based internal
function.
Diffstat (limited to 'src/driver')
-rw-r--r-- | src/driver/slbt_driver_ctx.c | 64 |
1 files changed, 35 insertions, 29 deletions
diff --git a/src/driver/slbt_driver_ctx.c b/src/driver/slbt_driver_ctx.c index e0e3f52..90321ed 100644 --- a/src/driver/slbt_driver_ctx.c +++ b/src/driver/slbt_driver_ctx.c @@ -541,6 +541,28 @@ static void slbt_get_host_quad( } } +static void slbt_spawn_ar(char ** argv, int * ecode) +{ + int estatus; + pid_t pid; + + *ecode = 127; + + if ((pid = fork()) < 0) { + return; + + } else if (pid == 0) { + execvp(argv[0],argv); + _exit(errno); + + } else { + waitpid(pid,&estatus,0); + + if (WIFEXITED(estatus)) + *ecode = WEXITSTATUS(estatus); + } +} + static int slbt_init_host_params( const struct slbt_driver_ctx * dctx, const struct slbt_common_ctx * cctx, @@ -548,10 +570,9 @@ 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; + int ecode; size_t toollen; char * dash; char * base; @@ -724,10 +745,6 @@ static int slbt_init_host_params( 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,"!<arch>\n"); @@ -738,46 +755,35 @@ static int slbt_init_host_params( arprobeargv[3] = 0; /* <target>-ar */ - ret = (posix_spawnp( - &arpid, - drvhost->ar, - 0,0,arprobeargv, - environ)); + slbt_spawn_ar( + arprobeargv, + &ecode); } /* <target>-<compiler>-ar */ - if (ret && (errno == ENOENT) && !strchr(base,'-')) { + if (ecode && !strchr(base,'-')) { sprintf(drvhost->ar,"%s-%s-ar",host->host,base); - ret = (posix_spawnp( - &arpid, - drvhost->ar, - 0,0,arprobeargv, - environ)); + slbt_spawn_ar( + arprobeargv, + &ecode); } /* <compiler>-ar */ - if (ret && (errno == ENOENT) && !strchr(base,'-')) { + if (ecode && !strchr(base,'-')) { sprintf(drvhost->ar,"%s-ar",base); - ret = (posix_spawnp( - &arpid, - drvhost->ar, - 0,0,arprobeargv, - environ)); + slbt_spawn_ar( + arprobeargv, + &ecode); } /* if target is the native target, fallback to native ar */ - if (ret && (errno == ENOENT) && !strcmp(host->host,SLBT_MACHINE)) { + if (ecode && !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); |