@@ -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+
2027typedef struct {
2128 const char * arg ;
2229 bool is_def ;
@@ -69,7 +76,6 @@ static bool opt_MP;
6976static bool opt_S ;
7077static bool opt_c ;
7178static bool opt_verbose ;
72- static bool opt_hash_hash_hash ;
7379bool opt_pie ;
7480bool opt_nopie ;
7581bool opt_pthread ;
@@ -97,9 +103,11 @@ static StringArray input_args;
97103static StringArray sysincl_paths ;
98104static StringArray dep_files ;
99105static StringArray tmpfiles ;
106+ static const char * tmp_folder ;
100107static StringArray as_args ;
101108static MacroChangeArr macrodefs ;
102109static int incl_cnt ;
110+ static ProcMode proc_mode ;
103111
104112static bool is_fork_child ;
105113char * 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) {
883900static 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
888907void cleanup_exit (int status ) {
@@ -895,60 +914,99 @@ void cleanup_exit(int status) {
895914}
896915
897916static 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+
908936void 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+
9521010static 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