From a62f9038bdfb998958afbd3097656dfa6d611cc2 Mon Sep 17 00:00:00 2001 From: midipix Date: Wed, 7 Nov 2018 23:45:25 -0500 Subject: 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. --- src/driver/slbt_driver_ctx.c | 64 ++++++++++++++++++++++++-------------------- 1 file 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,"!\n"); @@ -738,46 +755,35 @@ static int slbt_init_host_params( arprobeargv[3] = 0; /* -ar */ - ret = (posix_spawnp( - &arpid, - drvhost->ar, - 0,0,arprobeargv, - environ)); + slbt_spawn_ar( + arprobeargv, + &ecode); } /* --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); } /* -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); -- cgit v1.2.3