| |
| |
| |
| |
| |
| |
| #include <stdio.h> |
| #include <limits.h> |
| #include <unistd.h> |
| #include <string.h> |
| #include <stdlib.h> |
| #include <stdbool.h> |
| #include <sys/wait.h> |
| |
| #include <slibtool/slibtool.h> |
| #include "slibtool_spawn_impl.h" |
| |
| static char * slbt_mri_argument( |
| char * arg, |
| char * buf) |
| { |
| int i; |
| char * lnk; |
| char mricwd[PATH_MAX]; |
| char target[PATH_MAX]; |
| |
| if ((!(strchr(arg,'+'))) && (!(strchr(arg,'-')))) |
| return arg; |
| |
| if (!(getcwd(mricwd,sizeof(mricwd)))) |
| return 0; |
| |
| if ((size_t)snprintf(target,sizeof(target),"%s/%s", |
| mricwd,arg) >= sizeof(target)) |
| return 0; |
| |
| for (i=0,lnk=0; i<1024 && !lnk; i++) { |
| if (!(tmpnam(buf))) |
| return 0; |
| |
| if (!(symlink(target,buf))) |
| lnk = buf; |
| } |
| |
| return lnk; |
| } |
| |
| static void slbt_archive_import_child( |
| char * program, |
| int fd[2]) |
| { |
| char * argv[3]; |
| |
| argv[0] = program; |
| argv[1] = "-M"; |
| argv[2] = 0; |
| |
| close(fd[1]); |
| close(0); |
| |
| if (dup(fd[0]) == 0) |
| execvp(program,argv); |
| |
| exit(EXIT_FAILURE); |
| } |
| |
| int slbt_archive_import( |
| const struct slbt_driver_ctx * dctx, |
| struct slbt_exec_ctx * ectx, |
| char * dstarchive, |
| char * srcarchive) |
| { |
| int ret; |
| pid_t pid; |
| pid_t rpid; |
| int fd[2]; |
| FILE * fout; |
| char * dst; |
| char * src; |
| char mridst [L_tmpnam]; |
| char mrisrc [L_tmpnam]; |
| char program[PATH_MAX]; |
| |
| if ((size_t)snprintf(program,sizeof(program),"%s", |
| dctx->cctx->host.ar) >= sizeof(program)) |
| return -1; |
| |
| if (pipe(fd)) |
| return -1; |
| |
| if ((pid = fork()) < 0) { |
| close(fd[0]); |
| close(fd[1]); |
| return -1; |
| } |
| |
| if (pid == 0) |
| slbt_archive_import_child( |
| program, |
| fd); |
| |
| ectx->pid = pid; |
| |
| dst = slbt_mri_argument(dstarchive,mridst); |
| src = slbt_mri_argument(srcarchive,mrisrc); |
| |
| if ((fout = fdopen(fd[1],"a"))) { |
| ret = (fprintf( |
| fout, |
| "OPEN %s\n" |
| "ADDLIB %s\n" |
| "SAVE\n" |
| "END\n", |
| dst, |
| src) < 0) |
| ? -1 : 0; |
| |
| fclose(fout); |
| close(fd[0]); |
| } else { |
| ret = -1; |
| close(fd[0]); |
| close(fd[1]); |
| } |
| |
| rpid = waitpid( |
| pid, |
| &ectx->exitcode, |
| 0); |
| |
| if (dst == mridst) |
| unlink(dst); |
| |
| if (src == mrisrc) |
| unlink(src); |
| |
| return ret || (rpid != pid) || ectx->exitcode |
| ? -1 : 0; |
| } |