|
|
575cdb |
/*******************************************************************/
|
|
|
eac61a |
/* slibtool: a strong libtool implementation, written in C */
|
|
|
49181b |
/* Copyright (C) 2016--2024 SysDeer Technologies, LLC */
|
|
|
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"
|
|
|
19022e |
#include "slibtool_snprintf_impl.h"
|
|
|
575cdb |
|
|
|
8dc63d |
static void slbt_util_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 |
|
|
|
ff9a90 |
if ((fd[0] = openat(AT_FDCWD,"/dev/null",O_RDONLY,0)) >= 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 |
|
|
|
8dc63d |
int slbt_util_dump_machine(
|
|
|
575cdb |
const char * compiler,
|
|
|
575cdb |
char * machine,
|
|
|
db27dd |
size_t buflen)
|
|
|
575cdb |
{
|
|
|
8ecddc |
ssize_t 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 |
|
|
|
19022e |
if (slbt_snprintf(program,sizeof(program),
|
|
|
19022e |
"%s",compiler) < 0)
|
|
|
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)
|
|
|
8dc63d |
slbt_util_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]);
|
|
|
8ecddc |
return -1;
|
|
|
db27dd |
}
|
|
|
db27dd |
}
|
|
|
db27dd |
|
|
|
db27dd |
/* execve verification */
|
|
|
575cdb |
rpid = waitpid(
|
|
|
575cdb |
pid,
|
|
|
575cdb |
&code,
|
|
|
575cdb |
0);
|
|
|
575cdb |
|
|
|
575cdb |
if ((rpid != pid) || code) {
|
|
|
632dbf |
errno = ESTALE;
|
|
|
575cdb |
return -1;
|
|
|
575cdb |
}
|
|
|
575cdb |
|
|
|
db27dd |
/* newline verification */
|
|
|
db27dd |
if ((mark == machine) || (*--mark != '\n')) {
|
|
|
632dbf |
errno = ERANGE;
|
|
|
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 |
}
|