brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.9 KiB · 0f5e01f Raw
307 lines · c
1/* -*- coding: utf-8 -*-2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5*/6 7#include "config.h"8 9#include <sys/wait.h>10#include <unistd.h>11#include <stdio.h>12#include <stdlib.h>13#include <paths.h>14 15#if defined HAVE_POSIX_SPAWN || defined HAVE_POSIX_SPAWNP16#include <spawn.h>17#endif18 19// ..:: environment access fixer - begin ::..20#ifdef HAVE_NSGETENVIRON21#include <crt_externs.h>22#else23extern char **environ;24#endif25 26char **get_environ() {27#ifdef HAVE_NSGETENVIRON28    return *_NSGetEnviron();29#else30    return environ;31#endif32}33// ..:: environment access fixer - end ::..34 35// ..:: test fixtures - begin ::..36static char const *cwd = NULL;37static FILE *fd = NULL;38static int need_comma = 0;39 40void expected_out_open(const char *expected) {41    cwd = getcwd(NULL, 0);42    fd = fopen(expected, "w");43    if (!fd) {44        perror("fopen");45        exit(EXIT_FAILURE);46    }47    fprintf(fd, "[\n");48    need_comma = 0;49}50 51void expected_out_close() {52    fprintf(fd, "]\n");53    fclose(fd);54    fd = NULL;55 56    free((void *)cwd);57    cwd = NULL;58}59 60void expected_out(const char *file) {61    if (need_comma)62        fprintf(fd, ",\n");63    else64        need_comma = 1;65 66    fprintf(fd, "{\n");67    fprintf(fd, "  \"directory\": \"%s\",\n", cwd);68    fprintf(fd, "  \"command\": \"cc -c %s\",\n", file);69    fprintf(fd, "  \"file\": \"%s/%s\"\n", cwd, file);70    fprintf(fd, "}\n");71}72 73void create_source(char *file) {74    FILE *fd = fopen(file, "w");75    if (!fd) {76        perror("fopen");77        exit(EXIT_FAILURE);78    }79    fprintf(fd, "typedef int score;\n");80    fclose(fd);81}82 83typedef void (*exec_fun)();84 85void wait_for(pid_t child) {86    int status;87    if (-1 == waitpid(child, &status, 0)) {88        perror("wait");89        exit(EXIT_FAILURE);90    }91    if (WIFEXITED(status) ? WEXITSTATUS(status) : EXIT_FAILURE) {92        fprintf(stderr, "children process has non zero exit code\n");93        exit(EXIT_FAILURE);94    }95}96 97#define FORK(FUNC)                                                             \98    {                                                                          \99        pid_t child = fork();                                                  \100        if (-1 == child) {                                                     \101            perror("fork");                                                    \102            exit(EXIT_FAILURE);                                                \103        } else if (0 == child) {                                               \104            FUNC fprintf(stderr, "children process failed to exec\n");         \105            exit(EXIT_FAILURE);                                                \106        } else {                                                               \107            wait_for(child);                                                   \108        }                                                                      \109    }110// ..:: test fixtures - end ::..111 112#ifdef HAVE_EXECV113void call_execv() {114    char *const file = "execv.c";115    char *const compiler = "/usr/bin/cc";116    char *const argv[] = {"cc", "-c", file, 0};117 118    expected_out(file);119    create_source(file);120 121    FORK(execv(compiler, argv);)122}123#endif124 125#ifdef HAVE_EXECVE126void call_execve() {127    char *const file = "execve.c";128    char *const compiler = "/usr/bin/cc";129    char *const argv[] = {compiler, "-c", file, 0};130    char *const envp[] = {"THIS=THAT", 0};131 132    expected_out(file);133    create_source(file);134 135    FORK(execve(compiler, argv, envp);)136}137#endif138 139#ifdef HAVE_EXECVP140void call_execvp() {141    char *const file = "execvp.c";142    char *const compiler = "cc";143    char *const argv[] = {compiler, "-c", file, 0};144 145    expected_out(file);146    create_source(file);147 148    FORK(execvp(compiler, argv);)149}150#endif151 152#ifdef HAVE_EXECVP2153void call_execvP() {154    char *const file = "execv_p.c";155    char *const compiler = "cc";156    char *const argv[] = {compiler, "-c", file, 0};157 158    expected_out(file);159    create_source(file);160 161    FORK(execvP(compiler, _PATH_DEFPATH, argv);)162}163#endif164 165#ifdef HAVE_EXECVPE166void call_execvpe() {167    char *const file = "execvpe.c";168    char *const compiler = "cc";169    char *const argv[] = {"/usr/bin/cc", "-c", file, 0};170    char *const envp[] = {"THIS=THAT", 0};171 172    expected_out(file);173    create_source(file);174 175    FORK(execvpe(compiler, argv, envp);)176}177#endif178 179#ifdef HAVE_EXECT180void call_exect() {181    char *const file = "exect.c";182    char *const compiler = "/usr/bin/cc";183    char *const argv[] = {compiler, "-c", file, 0};184    char *const envp[] = {"THIS=THAT", 0};185 186    expected_out(file);187    create_source(file);188 189    FORK(exect(compiler, argv, envp);)190}191#endif192 193#ifdef HAVE_EXECL194void call_execl() {195    char *const file = "execl.c";196    char *const compiler = "/usr/bin/cc";197 198    expected_out(file);199    create_source(file);200 201    FORK(execl(compiler, "cc", "-c", file, (char *)0);)202}203#endif204 205#ifdef HAVE_EXECLP206void call_execlp() {207    char *const file = "execlp.c";208    char *const compiler = "cc";209 210    expected_out(file);211    create_source(file);212 213    FORK(execlp(compiler, compiler, "-c", file, (char *)0);)214}215#endif216 217#ifdef HAVE_EXECLE218void call_execle() {219    char *const file = "execle.c";220    char *const compiler = "/usr/bin/cc";221    char *const envp[] = {"THIS=THAT", 0};222 223    expected_out(file);224    create_source(file);225 226    FORK(execle(compiler, compiler, "-c", file, (char *)0, envp);)227}228#endif229 230#ifdef HAVE_POSIX_SPAWN231void call_posix_spawn() {232    char *const file = "posix_spawn.c";233    char *const compiler = "cc";234    char *const argv[] = {compiler, "-c", file, 0};235 236    expected_out(file);237    create_source(file);238 239    pid_t child;240    if (0 != posix_spawn(&child, "/usr/bin/cc", 0, 0, argv, get_environ())) {241        perror("posix_spawn");242        exit(EXIT_FAILURE);243    }244    wait_for(child);245}246#endif247 248#ifdef HAVE_POSIX_SPAWNP249void call_posix_spawnp() {250    char *const file = "posix_spawnp.c";251    char *const compiler = "cc";252    char *const argv[] = {compiler, "-c", file, 0};253 254    expected_out(file);255    create_source(file);256 257    pid_t child;258    if (0 != posix_spawnp(&child, "cc", 0, 0, argv, get_environ())) {259        perror("posix_spawnp");260        exit(EXIT_FAILURE);261    }262    wait_for(child);263}264#endif265 266int main(int argc, char *const argv[]) {267    if (argc != 2)268        exit(EXIT_FAILURE);269 270    expected_out_open(argv[1]);271#ifdef HAVE_EXECV272    call_execv();273#endif274#ifdef HAVE_EXECVE275    call_execve();276#endif277#ifdef HAVE_EXECVP278    call_execvp();279#endif280#ifdef HAVE_EXECVP2281    call_execvP();282#endif283#ifdef HAVE_EXECVPE284    call_execvpe();285#endif286#ifdef HAVE_EXECT287    call_exect();288#endif289#ifdef HAVE_EXECL290    call_execl();291#endif292#ifdef HAVE_EXECLP293    call_execlp();294#endif295#ifdef HAVE_EXECLE296    call_execle();297#endif298#ifdef HAVE_POSIX_SPAWN299    call_posix_spawn();300#endif301#ifdef HAVE_POSIX_SPAWNP302    call_posix_spawnp();303#endif304    expected_out_close();305    return 0;306}307