1313 * contained within it.
1414 */
1515
16- static const char script_name [] = "jruby.sh" ;
16+ #define LENGTH ( a ) (sizeof(a) / sizeof(0[a]))
1717
18+ static const char * script_names [] = { "jruby.sh" , "jruby.sh.bak" };
19+ static const char * no_scripts_error = "jruby.sh or jruby.sh.bak" ;
1820
1921static char * which (const char * const executable ) {
2022 const size_t exe_length = strlen (executable );
@@ -100,7 +102,7 @@ int unixlauncher_run(int argc, char *argv[], char *envp[]) {
100102 self_path = which (argv [0 ]);
101103
102104 if (self_path == NULL ) {
103- fprintf (stderr , "Error: Could not find %s executable\n" , script_name );
105+ fprintf (stderr , "Error: Could not find %s executable\n" , argv [ 0 ] );
104106 return 1 ;
105107 }
106108
@@ -118,25 +120,30 @@ int unixlauncher_run(int argc, char *argv[], char *envp[]) {
118120 }
119121 size_t script_dir_length = strlen (script_dir );
120122
121- // Allocate space for complete script path
122- size_t script_path_length = strlen (script_name ) + script_dir_length + 1 ;
123- // Leave space for null terminator
124- char * script_path = malloc (script_path_length + 1 );
123+ // Try main script and backup script before giving up
124+ for (int i = 0 ; i < LENGTH (script_names ); i ++ ) {
125+ const char * script_name = script_names [i ];
125126
126- // Concatenate script dir and script name
127- memcpy (script_path , script_dir , script_dir_length );
128- script_path [script_dir_length ] = '/' ;
129- memcpy (script_path + script_dir_length + 1 , script_name , strlen (script_name ));
130- script_path [script_path_length ] = '\0' ;
127+ // Allocate space for complete script path
128+ size_t script_path_length = strlen (script_name ) + script_dir_length + 1 ;
129+ // Leave space for null terminator
130+ char * script_path = malloc (script_path_length + 1 );
131131
132- // Reuse argv for script command line
133- argv [0 ] = script_path ;
134- int ret = execv (argv [0 ], argv );
132+ // Concatenate script dir and script name
133+ memcpy (script_path , script_dir , script_dir_length );
134+ script_path [script_dir_length ] = '/' ;
135+ memcpy (script_path + script_dir_length + 1 , script_name , strlen (script_name ));
136+ script_path [script_path_length ] = '\0' ;
135137
136- if (ret < 0 ) {
137- fprintf (stderr , "%s: %s: %s\n" , original_self , strerror (errno ), script_path );
138+ // Reuse argv for script command line
139+ argv [0 ] = script_path ;
140+ execv (argv [0 ], argv );
141+
142+ free (script_path );
138143 }
139144
140- free (script_path );
145+ // If we get here neither script was available, so we error
146+ fprintf (stderr , "%s: No executable %s found in %s\n" , original_self , no_scripts_error , script_dir );
147+
141148 return EXIT_FAILURE ;
142149}
0 commit comments