|
|
575cdb |
/*******************************************************************/
|
|
|
575cdb |
/* slibtool: a skinny libtool implementation, written in C */
|
|
|
6803d8 |
/* Copyright (C) 2016--2018 Z. Gilboa */
|
|
|
575cdb |
/* Released under the Standard MIT License; see COPYING.SLIBTOOL. */
|
|
|
575cdb |
/*******************************************************************/
|
|
|
575cdb |
|
|
|
575cdb |
#include <stdio.h>
|
|
|
575cdb |
#include <limits.h>
|
|
|
575cdb |
#include <unistd.h>
|
|
|
575cdb |
#include <fcntl.h>
|
|
|
575cdb |
#include <string.h>
|
|
|
575cdb |
#include <stdlib.h>
|
|
|
575cdb |
#include <stdbool.h>
|
|
|
575cdb |
#include <sys/wait.h>
|
|
|
575cdb |
|
|
|
575cdb |
#include <slibtool/slibtool.h>
|
|
|
575cdb |
#include "slibtool_spawn_impl.h"
|
|
|
575cdb |
|
|
|
d986a0 |
static void slbt_dump_machine_child(
|
|
|
575cdb |
char * program,
|
|
|
575cdb |
int fd[2])
|
|
|
575cdb |
{
|
|
|
575cdb |
char * compiler;
|
|
|
575cdb |
char * argv[3];
|
|
|
575cdb |
|
|
|
db27dd |
close(fd[0]);
|
|
|
db27dd |
|
|
|
f7d56b |
if ((compiler = strrchr(program,'/')))
|
|
|
575cdb |
compiler++;
|
|
|
575cdb |
else
|
|
|
575cdb |
compiler = program;
|
|
|
575cdb |
|
|
|
575cdb |
argv[0] = compiler;
|
|
|
575cdb |
argv[1] = "-dumpmachine";
|
|
|
575cdb |
argv[2] = 0;
|
|
|
575cdb |
|
|
|
f4ed8e |
if ((fd[0] = open("/dev/null",O_RDONLY)) >= 0)
|
|
|
f4ed8e |
if (dup2(fd[0],0) == 0)
|
|
|
f4ed8e |
if (dup2(fd[1],1) == 1)
|
|
|
f4ed8e |
execvp(program,argv);
|
|
|
575cdb |
|
|
|
ec6d7a |
_exit(EXIT_FAILURE);
|
|
|
575cdb |
}
|
|
|
575cdb |
|
|
|
575cdb |
int slbt_dump_machine(
|
|
|
575cdb |
const char * compiler,
|
|
|
575cdb |
char * machine,
|
|
|
db27dd |
size_t buflen)
|
|
|
575cdb |
{
|
|
|
db27dd |
int ret;
|
|
|
575cdb |
pid_t pid;
|
|
|
575cdb |
pid_t rpid;
|
|
|
575cdb |
int code;
|
|
|
575cdb |
int fd[2];
|
|
|
c67e64 |
char * mark;
|
|
|
575cdb |
char program[PATH_MAX];
|
|
|
575cdb |
|
|
|
db27dd |
/* setup */
|
|
|
fb9424 |
if (!machine || !buflen || !--buflen) {
|
|
|
db27dd |
errno = EINVAL;
|
|
|
575cdb |
return -1;
|
|
|
db27dd |
}
|
|
|
575cdb |
|
|
|
575cdb |
if ((size_t)snprintf(program,sizeof(program),"%s",
|
|
|
575cdb |
compiler) >= sizeof(program))
|
|
|
575cdb |
return -1;
|
|
|
575cdb |
|
|
|
db27dd |
/* fork */
|
|
|
575cdb |
if (pipe(fd))
|
|
|
575cdb |
return -1;
|
|
|
575cdb |
|
|
|
575cdb |
if ((pid = fork()) < 0) {
|
|
|
575cdb |
close(fd[0]);
|
|
|
575cdb |
close(fd[1]);
|
|
|
575cdb |
return -1;
|
|
|
575cdb |
}
|
|
|
575cdb |
|
|
|
db27dd |
/* child */
|
|
|
575cdb |
if (pid == 0)
|
|
|
d986a0 |
slbt_dump_machine_child(
|
|
|
575cdb |
program,
|
|
|
575cdb |
fd);
|
|
|
575cdb |
|
|
|
db27dd |
/* parent */
|
|
|
db27dd |
close(fd[1]);
|
|
|
db27dd |
|
|
|
db27dd |
mark = machine;
|
|
|
db27dd |
|
|
|
db27dd |
for (; buflen; ) {
|
|
|
db27dd |
ret = read(fd[0],mark,buflen);
|
|
|
db27dd |
|
|
|
db27dd |
while ((ret < 0) && (errno == EINTR))
|
|
|
db27dd |
ret = read(fd[0],mark,buflen);
|
|
|
db27dd |
|
|
|
db27dd |
if (ret > 0) {
|
|
|
db27dd |
buflen -= ret;
|
|
|
db27dd |
mark += ret;
|
|
|
db27dd |
|
|
|
db27dd |
} else if (ret == 0) {
|
|
|
db27dd |
close(fd[0]);
|
|
|
db27dd |
buflen = 0;
|
|
|
db27dd |
|
|
|
db27dd |
} else {
|
|
|
db27dd |
close(fd[0]);
|
|
|
db27dd |
return ret;
|
|
|
db27dd |
}
|
|
|
db27dd |
}
|
|
|
db27dd |
|
|
|
db27dd |
/* execve verification */
|
|
|
575cdb |
rpid = waitpid(
|
|
|
575cdb |
pid,
|
|
|
575cdb |
&code,
|
|
|
575cdb |
0);
|
|
|
575cdb |
|
|
|
575cdb |
if ((rpid != pid) || code) {
|
|
|
db27dd |
errno = EBADR;
|
|
|
575cdb |
return -1;
|
|
|
575cdb |
}
|
|
|
575cdb |
|
|
|
db27dd |
/* newline verification */
|
|
|
db27dd |
if ((mark == machine) || (*--mark != '\n')) {
|
|
|
db27dd |
errno = EBADR;
|
|
|
db27dd |
return -1;
|
|
|
575cdb |
}
|
|
|
575cdb |
|
|
|
db27dd |
*mark = 0;
|
|
|
db27dd |
|
|
|
db27dd |
/* portbld <--> unknown synonym? */
|
|
|
db27dd |
if ((mark = strstr(machine,"-portbld-")))
|
|
|
db27dd |
memcpy(mark,"-unknown",8);
|
|
|
c67e64 |
|
|
|
db27dd |
/* all done */
|
|
|
db27dd |
return 0;
|
|
|
575cdb |
}
|