Skip to content

Commit 607c5cc

Browse files
committed
Support -pipe via named pipe
1 parent 551b7c7 commit 607c5cc

File tree

1 file changed

+93
-43
lines changed

1 file changed

+93
-43
lines changed

main.c

Lines changed: 93 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@ typedef enum {
1717
LT_PIE,
1818
} LinkType;
1919

20+
typedef enum {
21+
PR_NORMAL = 0,
22+
PR_NOFORK,
23+
PR_PIPE,
24+
PR_HHH,
25+
} ProcMode;
26+
2027
typedef struct {
2128
const char *arg;
2229
bool is_def;
@@ -69,7 +76,6 @@ static bool opt_MP;
6976
static bool opt_S;
7077
static bool opt_c;
7178
static bool opt_verbose;
72-
static bool opt_hash_hash_hash;
7379
bool opt_pie;
7480
bool opt_nopie;
7581
bool opt_pthread;
@@ -97,9 +103,11 @@ static StringArray input_args;
97103
static StringArray sysincl_paths;
98104
static StringArray dep_files;
99105
static StringArray tmpfiles;
106+
static const char *tmp_folder;
100107
static StringArray as_args;
101108
static MacroChangeArr macrodefs;
102109
static int incl_cnt;
110+
static ProcMode proc_mode;
103111

104112
static bool is_fork_child;
105113
char *argv0;
@@ -357,10 +365,12 @@ static void build_ld_paths(const char *opt_B, StringArray *paths) {
357365
platform_search_dirs(&ld_paths);
358366
}
359367

360-
static void parse_args(int argc, char **argv, bool *run_ld, bool *no_fork) {
368+
static void parse_args(int argc, char **argv, bool *run_ld) {
361369
const char *arg;
362370
int input_cnt = 0;
363371
const char *opt_B = NULL;
372+
bool opt_pipe = false;
373+
bool opt_hash_hash_hash = false;
364374
bool has_wl = false;
365375
bool has_gnu_keywords_option = false;
366376
bool opt_nostdinc = false;
@@ -741,7 +751,8 @@ static void parse_args(int argc, char **argv, bool *run_ld, bool *no_fork) {
741751
set_true(arg, "static-libgcc", &opt_static_libgcc) ||
742752
set_true(arg, "shared", &opt_shared) ||
743753
set_true(arg, "pie", &opt_pie) ||
744-
set_true(arg, "nopie", &opt_nopie))
754+
set_true(arg, "nopie", &opt_nopie) ||
755+
set_true(arg, "pipe", &opt_pipe))
745756
continue;
746757

747758
if (!strcmp(arg, "no-pie")) {
@@ -844,7 +855,13 @@ static void parse_args(int argc, char **argv, bool *run_ld, bool *no_fork) {
844855
if (no_input)
845856
error("no input files");
846857

847-
*no_fork = (input_cnt == 1);
858+
if (opt_hash_hash_hash)
859+
proc_mode = PR_HHH;
860+
else if (opt_pipe)
861+
proc_mode = PR_PIPE;
862+
else if (input_cnt == 1)
863+
proc_mode = PR_NOFORK;
864+
848865
*run_ld = has_wl && !(opt_c || opt_S || opt_E);
849866
}
850867

@@ -883,6 +900,8 @@ static const char *replace_extn(const char *tmpl, const char *extn) {
883900
static void cleanup(void) {
884901
for (int i = 0; i < tmpfiles.len; i++)
885902
unlink(tmpfiles.data[i]);
903+
if (tmp_folder)
904+
rmdir(tmp_folder);
886905
}
887906

888907
void cleanup_exit(int status) {
@@ -895,60 +914,99 @@ void cleanup_exit(int status) {
895914
}
896915

897916
static char *create_tmpfile(void) {
898-
char *path = strdup("/tmp/slimcc-XXXXXX");
899-
int fd = mkstemp(path);
900-
if (fd == -1)
901-
error("mkstemp failed: %s", strerror(errno));
902-
close(fd);
917+
if (!tmp_folder) {
918+
tmp_folder = mkdtemp(strdup("/tmp/slimcc-XXXXXX"));
919+
if (!tmp_folder)
920+
error("mkdtemp failed: %s", strerror(errno));
921+
}
922+
static int64_t i;
923+
char *path = format("%s/%" PRIi64, tmp_folder, i++);
903924

904925
strarray_push(&tmpfiles, path);
905926
return path;
906927
}
907928

929+
static char *create_pipefile(void) {
930+
char *path = create_tmpfile();
931+
if (mkfifo(path, (S_IRUSR | S_IWUSR)) == -1)
932+
error("mkfifo failed: %s", strerror(errno));
933+
return path;
934+
}
935+
908936
void run_subprocess(const char **argv) {
909-
if (opt_hash_hash_hash || opt_verbose) {
937+
if (opt_verbose || proc_mode == PR_HHH) {
910938
fprintf(stderr, "\"%s\"", argv[0]);
911939
for (int i = 1; argv[i]; i++)
912940
fprintf(stderr, " \"%s\"", argv[i]);
913941
fprintf(stderr, "\n");
914-
if (opt_hash_hash_hash)
942+
if (proc_mode == PR_HHH)
915943
return;
916944
}
917945

918-
if (fork() == 0) {
946+
pid_t id = fork();
947+
if (id == 0) {
919948
is_fork_child = true;
920949
execvp(argv[0], (void *)argv);
921950
fprintf(stderr, "exec failed: %s: %s\n", argv[0], strerror(errno));
922951
_exit(1);
923952
}
924953

925954
int status;
926-
if (wait(&status) <= 0 || status != 0) {
955+
if (waitpid(id, &status, 0) <= 0 || status != 0) {
927956
fprintf(stderr, "exec failed: %s\n", argv[0]);
928957
cleanup_exit(1);
929958
}
930959
}
931960

932-
static void run_cc1(const char *input, const char *output, bool no_fork, bool is_asm_pp) {
933-
if (opt_hash_hash_hash)
961+
static int fork_cc1(const char *input, const char *output, bool is_asm_pp) {
962+
pid_t id = fork();
963+
if (id == 0) {
964+
is_fork_child = true;
965+
cc1(input, output, is_asm_pp);
966+
_exit(0);
967+
}
968+
return id;
969+
}
970+
971+
static void run_cc1(const char *input, const char *output, bool is_asm_pp) {
972+
if (proc_mode == PR_HHH)
934973
return;
935974

936-
if (no_fork) {
975+
if (proc_mode == PR_NOFORK) {
937976
cc1(input, output, is_asm_pp);
938977
return;
939978
}
940979

941-
if (fork() == 0) {
942-
is_fork_child = true;
943-
cc1(input, output, is_asm_pp);
944-
_exit(0);
945-
}
980+
int id = fork_cc1(input, output, is_asm_pp);
946981

947982
int status;
948-
if (wait(&status) <= 0 || status != 0)
983+
if (waitpid(id, &status, 0) <= 0 || status != 0)
949984
cleanup_exit(1);
950985
}
951986

987+
static void run_cc1_as(const char *input, const char *output, bool is_asm_pp) {
988+
if (proc_mode == PR_HHH) {
989+
char *tmp = create_tmpfile();
990+
run_assembler(&as_args, tmp, output);
991+
return;
992+
}
993+
994+
if (proc_mode == PR_PIPE) {
995+
char *tmp = create_pipefile();
996+
int id = fork_cc1(input, tmp, is_asm_pp);
997+
run_assembler(&as_args, tmp, output);
998+
999+
int status;
1000+
if (waitpid(id, &status, 0) <= 0 || status != 0)
1001+
cleanup_exit(1);
1002+
return;
1003+
}
1004+
1005+
char *tmp = create_tmpfile();
1006+
run_cc1(input, tmp, is_asm_pp);
1007+
run_assembler(&as_args, tmp, output);
1008+
}
1009+
9521010
static void print_linemarker(FILE *out, Token *tok) {
9531011
const char *name = display_files.data[tok->display_file_no];
9541012
if (!strcmp(name, "-"))
@@ -1312,8 +1370,8 @@ int main(int argc, char **argv) {
13121370
init_macros();
13131371
platform_init();
13141372

1315-
bool run_ld, no_fork;
1316-
parse_args(argc, argv, &run_ld, &no_fork);
1373+
bool run_ld;
1374+
parse_args(argc, argv, &run_ld);
13171375

13181376
StringArray ld_args = {0};
13191377
FileType opt_x = FILE_NONE;
@@ -1369,48 +1427,40 @@ int main(int argc, char **argv) {
13691427
// Handle .S
13701428
if (type == FILE_PP_ASM) {
13711429
if (opt_S || opt_E || opt_M) {
1372-
run_cc1(input, (opt_o ? opt_o : "-"), no_fork, true);
1430+
run_cc1(input, (opt_o ? opt_o : "-"), true);
13731431
continue;
13741432
}
13751433
if (opt_c) {
1376-
char *tmp = create_tmpfile();
1377-
run_cc1(input, tmp, no_fork, true);
1378-
run_assembler(&as_args, tmp, output);
1434+
run_cc1_as(input, output, true);
13791435
continue;
13801436
}
1381-
char *tmp1 = create_tmpfile();
1382-
char *tmp2 = create_tmpfile();
1383-
run_cc1(input, tmp1, no_fork, true);
1384-
run_assembler(&as_args, tmp1, tmp2);
1385-
strarray_push(&ld_args, tmp2);
1437+
char *tmp = create_tmpfile();
1438+
run_cc1_as(input, tmp, true);
1439+
strarray_push(&ld_args, tmp);
13861440
run_ld = true;
13871441
continue;
13881442
}
13891443

13901444
assert(type == FILE_C);
13911445

13921446
if (opt_E || opt_M) {
1393-
run_cc1(input, (opt_o ? opt_o : "-"), no_fork, false);
1447+
run_cc1(input, (opt_o ? opt_o : "-"), false);
13941448
continue;
13951449
}
13961450

13971451
if (opt_S) {
1398-
run_cc1(input, output, no_fork, false);
1452+
run_cc1(input, output, false);
13991453
continue;
14001454
}
14011455

14021456
if (opt_c) {
1403-
char *tmp = create_tmpfile();
1404-
run_cc1(input, tmp, no_fork, false);
1405-
run_assembler(&as_args, tmp, output);
1457+
run_cc1_as(input, output, false);
14061458
continue;
14071459
}
14081460

1409-
char *tmp1 = create_tmpfile();
1410-
char *tmp2 = create_tmpfile();
1411-
run_cc1(input, tmp1, no_fork, false);
1412-
run_assembler(&as_args, tmp1, tmp2);
1413-
strarray_push(&ld_args, tmp2);
1461+
char *tmp = create_tmpfile();
1462+
run_cc1_as(input, tmp, false);
1463+
strarray_push(&ld_args, tmp);
14141464
run_ld = true;
14151465
continue;
14161466
}

0 commit comments

Comments
 (0)