Print this page
make: remove maketool support


  44 
  45 
  46 #include <signal.h>
  47 
  48 #       include <stropts.h>
  49 
  50 #include <sys/errno.h>
  51 #include <sys/stat.h>
  52 #include <sys/types.h>
  53 #include <sys/utsname.h>  /* uname() */
  54 #include <sys/wait.h>
  55 #include <unistd.h>               /* close() */
  56 
  57 /*
  58  * Defined macros
  59  */
  60 #       define LOCALHOST "localhost"
  61 
  62 #define MAXRULES 100
  63 
  64 #define SEND_MTOOL_MSG(cmds) 
  65 
  66 // Sleep for .1 seconds between stat()'s
  67 const int       STAT_RETRY_SLEEP_TIME = 100000;
  68 
  69 /*
  70  * typedefs & structs
  71  */
  72 
  73 /*
  74  * Static variables
  75  */
  76 static char     hostName[MAXNAMELEN] = "";
  77 static char     userName[MAXNAMELEN] = "";
  78 
  79 
  80 static int      second_pass = 0;
  81 
  82 /*
  83  * File table of contents
  84  */
  85 extern  Doname          doname_check(register Name target, register Boolean do_get, register Boolean implicit, register Boolean automatic);


1756  *
1757  *      Global variables used:
1758  *              continue_after_error -k flag
1759  *              do_not_exec_rule -n flag
1760  *              report_dependencies -P flag
1761  *              silent          Don't echo commands before executing
1762  *              temp_file_name  Temp file for auto dependencies
1763  *              vpath_defined   If true, translate path for command
1764  */
1765 Doname
1766 execute_serial(Property line)
1767 {
1768         int                     child_pid = 0;
1769         Boolean                 printed_serial;
1770         Doname                  result = build_ok;
1771         Cmd_line                rule, cmd_tail, command = NULL;
1772         char                    mbstring[MAXPATHLEN];
1773         int                     filed;
1774         Name                    target = line->body.line.target;
1775 
1776         SEND_MTOOL_MSG(
1777                 if (!sent_rsrc_info_msg) {
1778                         if (userName[0] == '\0') {
1779                                 avo_get_user(userName, NULL);
1780                         }
1781                         if (hostName[0] == '\0') {
1782                                 strcpy(hostName, avo_hostname());
1783                         }
1784                         send_rsrc_info_msg(1, hostName, userName);
1785                         sent_rsrc_info_msg = 1;
1786                 }
1787                 send_job_start_msg(line);
1788                 job_result_msg = new Avo_MToolJobResultMsg();
1789         );
1790 
1791         target->has_recursive_dependency = false;
1792         // We have to create a copy of the rules chain for processing because
1793         // the original one can be destroyed during .make.state file rereading.
1794         for (rule = line->body.line.command_used;
1795              rule != NULL;
1796              rule = rule->next) {
1797                 if (command == NULL) {
1798                         command = cmd_tail = ALLOC(Cmd_line);
1799                 } else {
1800                         cmd_tail->next = ALLOC(Cmd_line);
1801                         cmd_tail = cmd_tail->next;
1802                 }
1803                 *cmd_tail = *rule;
1804         }
1805         if (command) {
1806                 cmd_tail->next = NULL;
1807         }
1808         for (rule = command; rule != NULL; rule = rule->next) {
1809                 if (posix && (touch || quest) && !rule->always_exec) {
1810                         continue;
1811                 }
1812                 if (vpath_defined) {
1813                         rule->command_line =
1814                           vpath_translation(rule->command_line);
1815                 }
1816                 /* Echo command line, maybe. */
1817                 if ((rule->command_line->hash.length > 0) &&
1818                     !silent &&
1819                     (!rule->silent || do_not_exec_rule) &&
1820                     (report_dependencies_level == 0)) {
1821                         (void) printf("%s\n", rule->command_line->string_mb);
1822                         SEND_MTOOL_MSG(
1823                                 job_result_msg->appendOutput(AVO_STRDUP(rule->command_line->string_mb));
1824                         );
1825                 }
1826                 if (rule->command_line->hash.length > 0) {
1827                         SEND_MTOOL_MSG(
1828                                 (void) sprintf(mbstring,
1829                                                 NOCATGETS("%s/make.stdout.%d.%d.XXXXXX"),
1830                                                 tmpdir,
1831                                                 getpid(),
1832                                                 file_number++);
1833 
1834                                 int tmp_fd = mkstemp(mbstring);
1835                                 if(tmp_fd) {
1836                                         (void) close(tmp_fd);
1837                                 }
1838 
1839                                 stdout_file = strdup(mbstring);
1840                                 stderr_file = NULL;
1841                                 child_pid = pollResults(stdout_file,
1842                                                         (char *)NULL,
1843                                                         (char *)NULL);
1844                         );
1845                         /* Do assignment if command line prefixed with "=" */
1846                         if (rule->assign) {
1847                                 result = build_ok;
1848                                 do_assign(rule->command_line, target);
1849                         } else if (report_dependencies_level == 0) {
1850                                 /* Execute command line. */
1851                                 setvar_envvar();
1852                                 result = dosys(rule->command_line,
1853                                                (Boolean) rule->ignore_error,
1854                                                (Boolean) rule->make_refd,
1855                                                /* ds 98.04.23 bug #4085164. make should always show error messages */
1856                                                false,
1857                                                /* BOOLEAN(rule->silent &&
1858                                                        rule->ignore_error), */
1859                                                (Boolean) rule->always_exec,
1860                                                target,
1861                                                send_mtool_msgs);
1862                                 check_state(temp_file_name);
1863                         }
1864                         SEND_MTOOL_MSG(
1865                                 append_job_result_msg(job_result_msg);
1866                                 if (child_pid > 0) {
1867                                         kill(child_pid, SIGUSR1);
1868                                         while (!((waitpid(child_pid, 0, 0) == -1)
1869                                                 && (errno == ECHILD)));
1870                                 }
1871                                 child_pid = 0;
1872                                 (void) unlink(stdout_file);
1873                                 retmem_mb(stdout_file);
1874                                 stdout_file = NULL;
1875                         );
1876                 } else {
1877                         result = build_ok;
1878                 }
1879                 if (result == build_failed) {
1880                         if (silent || rule->silent) {
1881                                 (void) printf(catgets(catd, 1, 242, "The following command caused the error:\n%s\n"),
1882                                               rule->command_line->string_mb);
1883                                 SEND_MTOOL_MSG(
1884                                         job_result_msg->appendOutput(AVO_STRDUP(catgets(catd, 1, 243, "The following command caused the error:")));
1885                                         job_result_msg->appendOutput(AVO_STRDUP(rule->command_line->string_mb));
1886                                 );
1887                         }
1888                         if (!rule->ignore_error && !ignore_errors) {
1889                                 if (!continue_after_error) {
1890                                         SEND_MTOOL_MSG(
1891                                                 job_result_msg->setResult(job_msg_id, (result == build_ok) ? 0 : 1, DONE);
1892                                                 xdr_msg = (RWCollectable*)
1893                                                         job_result_msg;
1894                                                 xdr(&xdrs, xdr_msg);
1895                                                 (void) fflush(mtool_msgs_fp);
1896                                                 delete job_result_msg;
1897                                         );
1898                                         fatal(catgets(catd, 1, 244, "Command failed for target `%s'"),
1899                                               target->string_mb);
1900                                 }
1901                                 /*
1902                                  * Make sure a failing command is not
1903                                  * saved in .make.state.
1904                                  */
1905                                 line->body.line.command_used = NULL;
1906                                 break;
1907                         } else {
1908                                 result = build_ok;
1909                         }
1910                 }
1911         }
1912         for (rule = command; rule != NULL; rule = cmd_tail) {
1913                 cmd_tail = rule->next;
1914                 free(rule);
1915         }
1916         command = NULL;
1917         SEND_MTOOL_MSG(
1918                 job_result_msg->setResult(job_msg_id, (result == build_ok) ? 0 : 1, DONE);
1919                 xdr_msg = (RWCollectable*) job_result_msg;
1920                 xdr(&xdrs, xdr_msg);
1921                 (void) fflush(mtool_msgs_fp);
1922 
1923                 delete job_result_msg;
1924         );
1925         if (temp_file_name != NULL) {
1926                 free_name(temp_file_name);
1927         }
1928         temp_file_name = NULL;
1929 
1930         Property spro = get_prop(sunpro_dependencies->prop, macro_prop);
1931         if(spro != NULL) {
1932                 Name val = spro->body.macro.value;
1933                 if(val != NULL) {
1934                         free_name(val);
1935                         spro->body.macro.value = NULL;
1936                 }
1937         }
1938         spro = get_prop(sunpro_dependencies->prop, env_mem_prop);
1939         if(spro) {
1940                 char *val = spro->body.env_mem.value;
1941                 if(val != NULL) {
1942                         /* 
1943                          * Do not return memory allocated for SUNPRO_DEPENDENCIES
1944                          * It will be returned in setvar_daemon() in macro.cc 


2566  *
2567  *      Parameters:
2568  *              line            The command line to update
2569  *              target          The target we are touching
2570  *              result          Initial value for the result we return
2571  *
2572  *      Global variables used:
2573  *              do_not_exec_rule Indicates that -n is on
2574  *              silent          Do not echo commands
2575  */
2576 static Doname
2577 touch_command(register Property line, register Name target, Doname result)
2578 {
2579         Name                    name;
2580         register Chain          target_group;
2581         String_rec              touch_string;
2582         wchar_t                 buffer[MAXPATHLEN];
2583         Name                    touch_cmd;
2584         Cmd_line                rule;
2585 
2586 
2587         SEND_MTOOL_MSG(
2588                 if (!sent_rsrc_info_msg) {
2589                         if (userName[0] == '\0') {
2590                                 avo_get_user(userName, NULL);
2591                         }
2592                         if (hostName[0] == '\0') {
2593                                 strcpy(hostName, avo_hostname());
2594                         }
2595                         send_rsrc_info_msg(1, hostName, userName);
2596                         sent_rsrc_info_msg = 1;
2597                 }
2598                 send_job_start_msg(line);
2599                 job_result_msg = new Avo_MToolJobResultMsg();
2600         );
2601         for (name = target, target_group = NULL; name != NULL;) {
2602                 if (!name->is_member) {
2603                         /*
2604                          * Build a touch command that can be passed
2605                          * to dosys(). If KEEP_STATE is on, "make -t"
2606                          * will save the proper command, not the
2607                          * "touch" in .make.state.
2608                          */
2609                         INIT_STRING_FROM_STACK(touch_string, buffer);
2610                         MBSTOWCS(wcs_buffer, NOCATGETS("touch "));
2611                         append_string(wcs_buffer, &touch_string, FIND_LENGTH);
2612                         touch_cmd = name;
2613                         if (name->has_vpath_alias_prop) {
2614                                 touch_cmd = get_prop(name->prop,
2615                                                  vpath_alias_prop)->
2616                                                    body.vpath_alias.alias;
2617                         }
2618                         APPEND_NAME(touch_cmd,
2619                                       &touch_string,
2620                                       FIND_LENGTH);
2621                         touch_cmd = GETNAME(touch_string.buffer.start,
2622                                             FIND_LENGTH);
2623                         if (touch_string.free_after_use) {
2624                                 retmem(touch_string.buffer.start);
2625                         }
2626                         if (!silent ||
2627                             do_not_exec_rule &&
2628                             (target_group == NULL)) {
2629                                 (void) printf("%s\n", touch_cmd->string_mb);
2630                                 SEND_MTOOL_MSG(
2631                                         job_result_msg->appendOutput(AVO_STRDUP(touch_cmd->string_mb));
2632                                 );
2633                         }
2634                         /* Run the touch command, or simulate it */
2635                         if (!do_not_exec_rule) {
2636 
2637                                 SEND_MTOOL_MSG(
2638                                         (void) sprintf(mbstring,
2639                                                         NOCATGETS("%s/make.stdout.%d.%d.XXXXXX"),
2640                                                         tmpdir,
2641                                                         getpid(),
2642                                                         file_number++);
2643                                 
2644                                         int tmp_fd = mkstemp(mbstring);
2645                                         if(tmp_fd) {
2646                                                 (void) close(tmp_fd);
2647                                         }
2648 
2649                                         stdout_file = strdup(mbstring);
2650                                         stderr_file = NULL;
2651                                         child_pid = pollResults(stdout_file,
2652                                                                 (char *)NULL,
2653                                                                 (char *)NULL);
2654                                 );
2655 
2656                                 result = dosys(touch_cmd,
2657                                                false,
2658                                                false,
2659                                                false,
2660                                                false,
2661                                                name,
2662                                                send_mtool_msgs);
2663 
2664                                 SEND_MTOOL_MSG(
2665                                         append_job_result_msg(job_result_msg);
2666                                         if (child_pid > 0) {
2667                                                 kill(child_pid, SIGUSR1);
2668                                                 while (!((waitpid(child_pid, 0, 0) == -1)
2669                                                         && (errno == ECHILD)));
2670                                         }
2671                                         child_pid = 0;
2672                                         (void) unlink(stdout_file);
2673                                         retmem_mb(stdout_file);
2674                                         stdout_file = NULL;
2675                                 );
2676 
2677                         } else {
2678                                 result = build_ok;
2679                         }
2680                 } else {
2681                         result = build_ok;
2682                 }
2683                 if (target_group == NULL) {
2684                         target_group = line->body.line.target_group;
2685                 } else {
2686                         target_group = target_group->next;
2687                 }
2688                 if (target_group != NULL) {
2689                         name = target_group->name;
2690                 } else {
2691                         name = NULL;
2692                 }
2693         }
2694         SEND_MTOOL_MSG(
2695                 job_result_msg->setResult(job_msg_id, (result == build_ok) ? 0 : 1, DONE);
2696                 xdr_msg = (RWCollectable*) job_result_msg;
2697                 xdr(&xdrs, xdr_msg);
2698                 (void) fflush(mtool_msgs_fp);
2699                 delete job_result_msg;
2700         );
2701         return result;
2702 }
2703 
2704 /*
2705  *      update_target(line, result)
2706  *
2707  *      updates the status of a target after executing its commands.
2708  *
2709  *      Parameters:
2710  *              line            The command line block to update
2711  *              result          Indicates that build is OK so can update
2712  *
2713  *      Global variables used:
2714  *              do_not_exec_rule Indicates that -n is on
2715  *              touch           Fake the new timestamp if we are just touching
2716  */
2717 void
2718 update_target(Property line, Doname result)
2719 {
2720         Name                    target;




  44 
  45 
  46 #include <signal.h>
  47 
  48 #       include <stropts.h>
  49 
  50 #include <sys/errno.h>
  51 #include <sys/stat.h>
  52 #include <sys/types.h>
  53 #include <sys/utsname.h>  /* uname() */
  54 #include <sys/wait.h>
  55 #include <unistd.h>               /* close() */
  56 
  57 /*
  58  * Defined macros
  59  */
  60 #       define LOCALHOST "localhost"
  61 
  62 #define MAXRULES 100
  63 


  64 // Sleep for .1 seconds between stat()'s
  65 const int       STAT_RETRY_SLEEP_TIME = 100000;
  66 
  67 /*
  68  * typedefs & structs
  69  */
  70 
  71 /*
  72  * Static variables
  73  */
  74 static char     hostName[MAXNAMELEN] = "";
  75 static char     userName[MAXNAMELEN] = "";
  76 
  77 
  78 static int      second_pass = 0;
  79 
  80 /*
  81  * File table of contents
  82  */
  83 extern  Doname          doname_check(register Name target, register Boolean do_get, register Boolean implicit, register Boolean automatic);


1754  *
1755  *      Global variables used:
1756  *              continue_after_error -k flag
1757  *              do_not_exec_rule -n flag
1758  *              report_dependencies -P flag
1759  *              silent          Don't echo commands before executing
1760  *              temp_file_name  Temp file for auto dependencies
1761  *              vpath_defined   If true, translate path for command
1762  */
1763 Doname
1764 execute_serial(Property line)
1765 {
1766         int                     child_pid = 0;
1767         Boolean                 printed_serial;
1768         Doname                  result = build_ok;
1769         Cmd_line                rule, cmd_tail, command = NULL;
1770         char                    mbstring[MAXPATHLEN];
1771         int                     filed;
1772         Name                    target = line->body.line.target;
1773 















1774         target->has_recursive_dependency = false;
1775         // We have to create a copy of the rules chain for processing because
1776         // the original one can be destroyed during .make.state file rereading.
1777         for (rule = line->body.line.command_used;
1778              rule != NULL;
1779              rule = rule->next) {
1780                 if (command == NULL) {
1781                         command = cmd_tail = ALLOC(Cmd_line);
1782                 } else {
1783                         cmd_tail->next = ALLOC(Cmd_line);
1784                         cmd_tail = cmd_tail->next;
1785                 }
1786                 *cmd_tail = *rule;
1787         }
1788         if (command) {
1789                 cmd_tail->next = NULL;
1790         }
1791         for (rule = command; rule != NULL; rule = rule->next) {
1792                 if (posix && (touch || quest) && !rule->always_exec) {
1793                         continue;
1794                 }
1795                 if (vpath_defined) {
1796                         rule->command_line =
1797                           vpath_translation(rule->command_line);
1798                 }
1799                 /* Echo command line, maybe. */
1800                 if ((rule->command_line->hash.length > 0) &&
1801                     !silent &&
1802                     (!rule->silent || do_not_exec_rule) &&
1803                     (report_dependencies_level == 0)) {
1804                         (void) printf("%s\n", rule->command_line->string_mb);



1805                 }
1806                 if (rule->command_line->hash.length > 0) {


















1807                         /* Do assignment if command line prefixed with "=" */
1808                         if (rule->assign) {
1809                                 result = build_ok;
1810                                 do_assign(rule->command_line, target);
1811                         } else if (report_dependencies_level == 0) {
1812                                 /* Execute command line. */
1813                                 setvar_envvar();
1814                                 result = dosys(rule->command_line,
1815                                                (Boolean) rule->ignore_error,
1816                                                (Boolean) rule->make_refd,
1817                                                /* ds 98.04.23 bug #4085164. make should always show error messages */
1818                                                false,
1819                                                /* BOOLEAN(rule->silent &&
1820                                                        rule->ignore_error), */
1821                                                (Boolean) rule->always_exec,
1822                                                target);

1823                                 check_state(temp_file_name);
1824                         }












1825                 } else {
1826                         result = build_ok;
1827                 }
1828                 if (result == build_failed) {
1829                         if (silent || rule->silent) {
1830                                 (void) printf(catgets(catd, 1, 242, "The following command caused the error:\n%s\n"),
1831                                               rule->command_line->string_mb);




1832                         }
1833                         if (!rule->ignore_error && !ignore_errors) {
1834                                 if (!continue_after_error) {








1835                                         fatal(catgets(catd, 1, 244, "Command failed for target `%s'"),
1836                                               target->string_mb);
1837                                 }
1838                                 /*
1839                                  * Make sure a failing command is not
1840                                  * saved in .make.state.
1841                                  */
1842                                 line->body.line.command_used = NULL;
1843                                 break;
1844                         } else {
1845                                 result = build_ok;
1846                         }
1847                 }
1848         }
1849         for (rule = command; rule != NULL; rule = cmd_tail) {
1850                 cmd_tail = rule->next;
1851                 free(rule);
1852         }
1853         command = NULL;








1854         if (temp_file_name != NULL) {
1855                 free_name(temp_file_name);
1856         }
1857         temp_file_name = NULL;
1858 
1859         Property spro = get_prop(sunpro_dependencies->prop, macro_prop);
1860         if(spro != NULL) {
1861                 Name val = spro->body.macro.value;
1862                 if(val != NULL) {
1863                         free_name(val);
1864                         spro->body.macro.value = NULL;
1865                 }
1866         }
1867         spro = get_prop(sunpro_dependencies->prop, env_mem_prop);
1868         if(spro) {
1869                 char *val = spro->body.env_mem.value;
1870                 if(val != NULL) {
1871                         /* 
1872                          * Do not return memory allocated for SUNPRO_DEPENDENCIES
1873                          * It will be returned in setvar_daemon() in macro.cc 


2495  *
2496  *      Parameters:
2497  *              line            The command line to update
2498  *              target          The target we are touching
2499  *              result          Initial value for the result we return
2500  *
2501  *      Global variables used:
2502  *              do_not_exec_rule Indicates that -n is on
2503  *              silent          Do not echo commands
2504  */
2505 static Doname
2506 touch_command(register Property line, register Name target, Doname result)
2507 {
2508         Name                    name;
2509         register Chain          target_group;
2510         String_rec              touch_string;
2511         wchar_t                 buffer[MAXPATHLEN];
2512         Name                    touch_cmd;
2513         Cmd_line                rule;
2514 















2515         for (name = target, target_group = NULL; name != NULL;) {
2516                 if (!name->is_member) {
2517                         /*
2518                          * Build a touch command that can be passed
2519                          * to dosys(). If KEEP_STATE is on, "make -t"
2520                          * will save the proper command, not the
2521                          * "touch" in .make.state.
2522                          */
2523                         INIT_STRING_FROM_STACK(touch_string, buffer);
2524                         MBSTOWCS(wcs_buffer, NOCATGETS("touch "));
2525                         append_string(wcs_buffer, &touch_string, FIND_LENGTH);
2526                         touch_cmd = name;
2527                         if (name->has_vpath_alias_prop) {
2528                                 touch_cmd = get_prop(name->prop,
2529                                                  vpath_alias_prop)->
2530                                                    body.vpath_alias.alias;
2531                         }
2532                         APPEND_NAME(touch_cmd,
2533                                       &touch_string,
2534                                       FIND_LENGTH);
2535                         touch_cmd = GETNAME(touch_string.buffer.start,
2536                                             FIND_LENGTH);
2537                         if (touch_string.free_after_use) {
2538                                 retmem(touch_string.buffer.start);
2539                         }
2540                         if (!silent ||
2541                             do_not_exec_rule &&
2542                             (target_group == NULL)) {
2543                                 (void) printf("%s\n", touch_cmd->string_mb);



2544                         }
2545                         /* Run the touch command, or simulate it */
2546                         if (!do_not_exec_rule) {




















2547                                 result = dosys(touch_cmd,
2548                                                false,
2549                                                false,
2550                                                false,
2551                                                false,
2552                                                name);















2553                         } else {
2554                                 result = build_ok;
2555                         }
2556                 } else {
2557                         result = build_ok;
2558                 }
2559                 if (target_group == NULL) {
2560                         target_group = line->body.line.target_group;
2561                 } else {
2562                         target_group = target_group->next;
2563                 }
2564                 if (target_group != NULL) {
2565                         name = target_group->name;
2566                 } else {
2567                         name = NULL;
2568                 }
2569         }







2570         return result;
2571 }
2572 
2573 /*
2574  *      update_target(line, result)
2575  *
2576  *      updates the status of a target after executing its commands.
2577  *
2578  *      Parameters:
2579  *              line            The command line block to update
2580  *              result          Indicates that build is OK so can update
2581  *
2582  *      Global variables used:
2583  *              do_not_exec_rule Indicates that -n is on
2584  *              touch           Fake the new timestamp if we are just touching
2585  */
2586 void
2587 update_target(Property line, Doname result)
2588 {
2589         Name                    target;