@@ -1780,32 +1780,33 @@ static const char *get_frequency(enum schedule_priority schedule)
17801780 * * If $GIT_TEST_MAINT_SCHEDULER is set, return true.
17811781 * In this case, the *cmd value is read as input.
17821782 *
1783- * * if the input value * cmd is the key of one of the comma-separated list
1784- * item, then *is_available is set to true and *cmd is modified and becomes
1783+ * * if the input value cmd is the key of one of the comma-separated list
1784+ * item, then *is_available is set to true and *out is set to
17851785 * the mock command.
17861786 *
17871787 * * if the input value *cmd isn’t the key of any of the comma-separated list
1788- * item, then *is_available is set to false.
1788+ * item, then *is_available is set to false and *out is set to the original
1789+ * command.
17891790 *
17901791 * Ex.:
17911792 * GIT_TEST_MAINT_SCHEDULER not set
17921793 * +-------+-------------------------------------------------+
17931794 * | Input | Output |
1794- * | *cmd | return code | *cmd | *is_available |
1795+ * | *cmd | return code | *out | *is_available |
17951796 * +-------+-------------+-------------------+---------------+
1796- * | "foo" | false | "foo" (unchanged) | (unchanged) |
1797+ * | "foo" | false | NULL | (unchanged) |
17971798 * +-------+-------------+-------------------+---------------+
17981799 *
17991800 * GIT_TEST_MAINT_SCHEDULER set to “foo:./mock_foo.sh,bar:./mock_bar.sh”
18001801 * +-------+-------------------------------------------------+
18011802 * | Input | Output |
1802- * | *cmd | return code | *cmd | *is_available |
1803+ * | *cmd | return code | *out | *is_available |
18031804 * +-------+-------------+-------------------+---------------+
18041805 * | "foo" | true | "./mock.foo.sh" | true |
1805- * | "qux" | true | "qux" (unchanged ) | false |
1806+ * | "qux" | true | "qux" (allocated ) | false |
18061807 * +-------+-------------+-------------------+---------------+
18071808 */
1808- static int get_schedule_cmd (const char * * cmd , int * is_available )
1809+ static int get_schedule_cmd (const char * cmd , int * is_available , char * * out )
18091810{
18101811 char * testing = xstrdup_or_null (getenv ("GIT_TEST_MAINT_SCHEDULER" ));
18111812 struct string_list_item * item ;
@@ -1824,16 +1825,22 @@ static int get_schedule_cmd(const char **cmd, int *is_available)
18241825 if (string_list_split_in_place (& pair , item -> string , ":" , 2 ) != 2 )
18251826 continue ;
18261827
1827- if (!strcmp (* cmd , pair .items [0 ].string )) {
1828- * cmd = pair .items [1 ].string ;
1828+ if (!strcmp (cmd , pair .items [0 ].string )) {
1829+ if (out )
1830+ * out = xstrdup (pair .items [1 ].string );
18291831 if (is_available )
18301832 * is_available = 1 ;
1831- string_list_clear (& list , 0 );
1832- UNLEAK (testing );
1833- return 1 ;
1833+ string_list_clear (& pair , 0 );
1834+ goto out ;
18341835 }
1836+
1837+ string_list_clear (& pair , 0 );
18351838 }
18361839
1840+ if (out )
1841+ * out = xstrdup (cmd );
1842+
1843+ out :
18371844 string_list_clear (& list , 0 );
18381845 free (testing );
18391846 return 1 ;
@@ -1850,9 +1857,8 @@ static int get_random_minute(void)
18501857
18511858static int is_launchctl_available (void )
18521859{
1853- const char * cmd = "launchctl" ;
18541860 int is_available ;
1855- if (get_schedule_cmd (& cmd , & is_available ))
1861+ if (get_schedule_cmd ("launchctl" , & is_available , NULL ))
18561862 return is_available ;
18571863
18581864#ifdef __APPLE__
@@ -1890,12 +1896,12 @@ static char *launchctl_get_uid(void)
18901896
18911897static int launchctl_boot_plist (int enable , const char * filename )
18921898{
1893- const char * cmd = "launchctl" ;
1899+ char * cmd ;
18941900 int result ;
18951901 struct child_process child = CHILD_PROCESS_INIT ;
18961902 char * uid = launchctl_get_uid ();
18971903
1898- get_schedule_cmd (& cmd , NULL );
1904+ get_schedule_cmd ("launchctl" , NULL , & cmd );
18991905 strvec_split (& child .args , cmd );
19001906 strvec_pushl (& child .args , enable ? "bootstrap" : "bootout" , uid ,
19011907 filename , NULL );
@@ -1908,6 +1914,7 @@ static int launchctl_boot_plist(int enable, const char *filename)
19081914
19091915 result = finish_command (& child );
19101916
1917+ free (cmd );
19111918 free (uid );
19121919 return result ;
19131920}
@@ -1959,10 +1966,10 @@ static int launchctl_schedule_plist(const char *exec_path, enum schedule_priorit
19591966 static unsigned long lock_file_timeout_ms = ULONG_MAX ;
19601967 struct strbuf plist = STRBUF_INIT , plist2 = STRBUF_INIT ;
19611968 struct stat st ;
1962- const char * cmd = "launchctl" ;
1969+ char * cmd ;
19631970 int minute = get_random_minute ();
19641971
1965- get_schedule_cmd (& cmd , NULL );
1972+ get_schedule_cmd ("launchctl" , NULL , & cmd );
19661973 preamble = "<?xml version=\"1.0\"?>\n"
19671974 "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
19681975 "<plist version=\"1.0\">"
@@ -2052,6 +2059,7 @@ static int launchctl_schedule_plist(const char *exec_path, enum schedule_priorit
20522059
20532060 free (filename );
20542061 free (name );
2062+ free (cmd );
20552063 strbuf_release (& plist );
20562064 strbuf_release (& plist2 );
20572065 return 0 ;
@@ -2076,9 +2084,8 @@ static int launchctl_update_schedule(int run_maintenance, int fd UNUSED)
20762084
20772085static int is_schtasks_available (void )
20782086{
2079- const char * cmd = "schtasks" ;
20802087 int is_available ;
2081- if (get_schedule_cmd (& cmd , & is_available ))
2088+ if (get_schedule_cmd ("schtasks" , & is_available , NULL ))
20822089 return is_available ;
20832090
20842091#ifdef GIT_WINDOWS_NATIVE
@@ -2097,15 +2104,16 @@ static char *schtasks_task_name(const char *frequency)
20972104
20982105static int schtasks_remove_task (enum schedule_priority schedule )
20992106{
2100- const char * cmd = "schtasks" ;
2107+ char * cmd ;
21012108 struct child_process child = CHILD_PROCESS_INIT ;
21022109 const char * frequency = get_frequency (schedule );
21032110 char * name = schtasks_task_name (frequency );
21042111
2105- get_schedule_cmd (& cmd , NULL );
2112+ get_schedule_cmd ("schtasks" , NULL , & cmd );
21062113 strvec_split (& child .args , cmd );
21072114 strvec_pushl (& child .args , "/delete" , "/tn" , name , "/f" , NULL );
21082115 free (name );
2116+ free (cmd );
21092117
21102118 return run_command (& child );
21112119}
@@ -2119,7 +2127,7 @@ static int schtasks_remove_tasks(void)
21192127
21202128static int schtasks_schedule_task (const char * exec_path , enum schedule_priority schedule )
21212129{
2122- const char * cmd = "schtasks" ;
2130+ char * cmd ;
21232131 int result ;
21242132 struct child_process child = CHILD_PROCESS_INIT ;
21252133 const char * xml ;
@@ -2129,7 +2137,7 @@ static int schtasks_schedule_task(const char *exec_path, enum schedule_priority
21292137 struct strbuf tfilename = STRBUF_INIT ;
21302138 int minute = get_random_minute ();
21312139
2132- get_schedule_cmd (& cmd , NULL );
2140+ get_schedule_cmd ("schtasks" , NULL , & cmd );
21332141
21342142 strbuf_addf (& tfilename , "%s/schedule_%s_XXXXXX" ,
21352143 get_git_common_dir (), frequency );
@@ -2235,6 +2243,7 @@ static int schtasks_schedule_task(const char *exec_path, enum schedule_priority
22352243
22362244 delete_tempfile (& tfile );
22372245 free (name );
2246+ free (cmd );
22382247 return result ;
22392248}
22402249
@@ -2276,29 +2285,36 @@ static int check_crontab_process(const char *cmd)
22762285
22772286static int is_crontab_available (void )
22782287{
2279- const char * cmd = "crontab" ;
2288+ char * cmd ;
22802289 int is_available ;
2290+ int ret ;
22812291
2282- if (get_schedule_cmd (& cmd , & is_available ))
2283- return is_available ;
2292+ if (get_schedule_cmd ("crontab" , & is_available , & cmd )) {
2293+ ret = is_available ;
2294+ goto out ;
2295+ }
22842296
22852297#ifdef __APPLE__
22862298 /*
22872299 * macOS has cron, but it requires special permissions and will
22882300 * create a UI alert when attempting to run this command.
22892301 */
2290- return 0 ;
2302+ ret = 0 ;
22912303#else
2292- return check_crontab_process (cmd );
2304+ ret = check_crontab_process (cmd );
22932305#endif
2306+
2307+ out :
2308+ free (cmd );
2309+ return ret ;
22942310}
22952311
22962312#define BEGIN_LINE "# BEGIN GIT MAINTENANCE SCHEDULE"
22972313#define END_LINE "# END GIT MAINTENANCE SCHEDULE"
22982314
22992315static int crontab_update_schedule (int run_maintenance , int fd )
23002316{
2301- const char * cmd = "crontab" ;
2317+ char * cmd ;
23022318 int result = 0 ;
23032319 int in_old_region = 0 ;
23042320 struct child_process crontab_list = CHILD_PROCESS_INIT ;
@@ -2308,15 +2324,17 @@ static int crontab_update_schedule(int run_maintenance, int fd)
23082324 struct tempfile * tmpedit = NULL ;
23092325 int minute = get_random_minute ();
23102326
2311- get_schedule_cmd (& cmd , NULL );
2327+ get_schedule_cmd ("crontab" , NULL , & cmd );
23122328 strvec_split (& crontab_list .args , cmd );
23132329 strvec_push (& crontab_list .args , "-l" );
23142330 crontab_list .in = -1 ;
23152331 crontab_list .out = dup (fd );
23162332 crontab_list .git_cmd = 0 ;
23172333
2318- if (start_command (& crontab_list ))
2319- return error (_ ("failed to run 'crontab -l'; your system might not support 'cron'" ));
2334+ if (start_command (& crontab_list )) {
2335+ result = error (_ ("failed to run 'crontab -l'; your system might not support 'cron'" ));
2336+ goto out ;
2337+ }
23202338
23212339 /* Ignore exit code, as an empty crontab will return error. */
23222340 finish_command (& crontab_list );
@@ -2386,8 +2404,10 @@ static int crontab_update_schedule(int run_maintenance, int fd)
23862404 result = error (_ ("'crontab' died" ));
23872405 else
23882406 fclose (cron_list );
2407+
23892408out :
23902409 delete_tempfile (& tmpedit );
2410+ free (cmd );
23912411 return result ;
23922412}
23932413
@@ -2410,10 +2430,9 @@ static int real_is_systemd_timer_available(void)
24102430
24112431static int is_systemd_timer_available (void )
24122432{
2413- const char * cmd = "systemctl" ;
24142433 int is_available ;
24152434
2416- if (get_schedule_cmd (& cmd , & is_available ))
2435+ if (get_schedule_cmd ("systemctl" , & is_available , NULL ))
24172436 return is_available ;
24182437
24192438 return real_is_systemd_timer_available ();
@@ -2594,9 +2613,10 @@ static int systemd_timer_enable_unit(int enable,
25942613 enum schedule_priority schedule ,
25952614 int minute )
25962615{
2597- const char * cmd = "systemctl" ;
2616+ char * cmd = NULL ;
25982617 struct child_process child = CHILD_PROCESS_INIT ;
25992618 const char * frequency = get_frequency (schedule );
2619+ int ret ;
26002620
26012621 /*
26022622 * Disabling the systemd unit while it is already disabled makes
@@ -2607,30 +2627,43 @@ static int systemd_timer_enable_unit(int enable,
26072627 * On the other hand, enabling a systemd unit which is already enabled
26082628 * produces no error.
26092629 */
2610- if (!enable )
2630+ if (!enable ) {
26112631 child .no_stderr = 1 ;
2612- else if (systemd_timer_write_timer_file (schedule , minute ))
2613- return -1 ;
2632+ } else if (systemd_timer_write_timer_file (schedule , minute )) {
2633+ ret = -1 ;
2634+ goto out ;
2635+ }
26142636
2615- get_schedule_cmd (& cmd , NULL );
2637+ get_schedule_cmd ("systemctl" , NULL , & cmd );
26162638 strvec_split (& child .args , cmd );
26172639 strvec_pushl (& child .args , "--user" , enable ? "enable" : "disable" ,
26182640 "--now" , NULL );
26192641 strvec_pushf (& child .args , SYSTEMD_UNIT_FORMAT , frequency , "timer" );
26202642
2621- if (start_command (& child ))
2622- return error (_ ("failed to start systemctl" ));
2623- if (finish_command (& child ))
2643+ if (start_command (& child )) {
2644+ ret = error (_ ("failed to start systemctl" ));
2645+ goto out ;
2646+ }
2647+
2648+ if (finish_command (& child )) {
26242649 /*
26252650 * Disabling an already disabled systemd unit makes
26262651 * systemctl fail.
26272652 * Let's ignore this failure.
26282653 *
26292654 * Enabling an enabled systemd unit doesn't fail.
26302655 */
2631- if (enable )
2632- return error (_ ("failed to run systemctl" ));
2633- return 0 ;
2656+ if (enable ) {
2657+ ret = error (_ ("failed to run systemctl" ));
2658+ goto out ;
2659+ }
2660+ }
2661+
2662+ ret = 0 ;
2663+
2664+ out :
2665+ free (cmd );
2666+ return ret ;
26342667}
26352668
26362669/*
0 commit comments