| |
| |
| |
| |
| |
| |
| #include <stdio.h> |
| #include <limits.h> |
| #include <unistd.h> |
| #include <fcntl.h> |
| #include <string.h> |
| #include <stdlib.h> |
| #include <stdbool.h> |
| #include <sys/wait.h> |
| |
| #include <slibtool/slibtool.h> |
| #include "slibtool_spawn_impl.h" |
| |
| static void slbt_dump_machine_child( |
| char * program, |
| int fd[2]) |
| { |
| char * compiler; |
| char * argv[3]; |
| |
| close(fd[0]); |
| |
| if ((compiler = strrchr(program,'/'))) |
| compiler++; |
| else |
| compiler = program; |
| |
| argv[0] = compiler; |
| argv[1] = "-dumpmachine"; |
| argv[2] = 0; |
| |
| if ((fd[0] = open("/dev/null",O_RDONLY)) >= 0) |
| if (dup2(fd[0],0) == 0) |
| if (dup2(fd[1],1) == 1) |
| execvp(program,argv); |
| |
| _exit(EXIT_FAILURE); |
| } |
| |
| int slbt_dump_machine( |
| const char * compiler, |
| char * machine, |
| size_t buflen) |
| { |
| ssize_t ret; |
| pid_t pid; |
| pid_t rpid; |
| int code; |
| int fd[2]; |
| char * mark; |
| char program[PATH_MAX]; |
| |
| |
| if (!machine || !buflen || !--buflen) { |
| errno = EINVAL; |
| return -1; |
| } |
| |
| if ((size_t)snprintf(program,sizeof(program),"%s", |
| compiler) >= 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_dump_machine_child( |
| program, |
| fd); |
| |
| |
| close(fd[1]); |
| |
| mark = machine; |
| |
| for (; buflen; ) { |
| ret = read(fd[0],mark,buflen); |
| |
| while ((ret < 0) && (errno == EINTR)) |
| ret = read(fd[0],mark,buflen); |
| |
| if (ret > 0) { |
| buflen -= ret; |
| mark += ret; |
| |
| } else if (ret == 0) { |
| close(fd[0]); |
| buflen = 0; |
| |
| } else { |
| close(fd[0]); |
| return -1; |
| } |
| } |
| |
| |
| rpid = waitpid( |
| pid, |
| &code, |
| 0); |
| |
| if ((rpid != pid) || code) { |
| errno = ESTALE; |
| return -1; |
| } |
| |
| |
| if ((mark == machine) || (*--mark != '\n')) { |
| errno = ERANGE; |
| return -1; |
| } |
| |
| *mark = 0; |
| |
| |
| if ((mark = strstr(machine,"-portbld-"))) |
| memcpy(mark,"-unknown",8); |
| |
| |
| return 0; |
| } |