bug-make
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

OS/2: "sh" versus "sh -.c"


From: Andreas Buening
Subject: OS/2: "sh" versus "sh -.c"
Date: Sun, 14 Jul 2002 22:21:11 +0200

Hello!

A simple Makefile like

SHELL = /bin/sh
all:
        ./some_perl_script

fails on OS/2 because normally spawn()/exec() cannot start
a shell script. Alternatively make uses
"/bin/sh ./some_perl_script" in exec_command() which works
only for sh scripts, not for e.g. perl scripts. I suggest
to use "/bin/sh -c ./some_perl_script" instead. This trick
works only because OS/2 has no executable flag.
I've made a diff relative to the last patches I've sent.
I hope this is okay.


------------------------------
--- old/make-3.79.2a1/job.c     Fri Jul 12 22:52:48 2002
+++ gnu/make-3.79.2a1/job.c     Sun Jul 14 21:24:12 2002
@@ -2489,7 +2489,7 @@
   pid = spawnvpe(P_NOWAIT, argv[0], argv, envp);
 
   /* the file might have a strange shell extension */
-  if (pid < 0 && errno == ENOENT) errno = ENOEXEC;
+  if (pid < 0 && unixy_shell && errno == ENOENT) errno = ENOEXEC;
 
   if (pid < 0)
 # else
@@ -2513,6 +2513,8 @@
        int argc;
 
 # ifdef __EMX__
+        char *new_command;
+
         /* do not use $SHELL */
        struct variable *p = lookup_variable("SHELL", 5);
 
@@ -2529,6 +2531,75 @@
        while (argv[argc] != 0)
          ++argc;
 
+# ifdef __EMX__
+        /* OS/2 supports no executable flag. Normally shell scripts cannot
+           be executed by spawn() or exec(). In this case ENOEXEC is returned.
+           Then make normally tries "/bin/sh foo" which works only for sh
+           scripts. In this case it had better use "/bin/sh -c foo" because
+           this works also for other scripts (i.e. the first "#!/bin/xyz"
+           line is interpreted).
+           Note that this works only because OS/2 has no executable flag.
+           "sh -c foo" expects that "foo" is executable while "sh foo" can
+           execute also files that have no executable flag.
+           With this treatment a simple Makefile like that would also work
+           on OS/2:
+             SHELL = /bin/sh
+             all:
+                     ./some_perl_script
+          
+           Note: Most shells (like bash or ksh) nowadays have no problem with
+                 "sh -c foo some_option" but oldstyle shells like ash expect
+                 that the command to be executed is ONE single argument, i.e.
+                 "sh -c 'foo some_option'" is required. Therefore all argv[i]
+                 will be connected to one single argument. */
+
+        if (unixy_shell)
+          { /* Unix style sh */
+            char *q;
+            unsigned i;
+            size_t new_size = 0;
+
+           /* get maximal length for the new command */
+            for (i = 0; i < argc; i++)
+              new_size += strlen(argv[i]) + 1;
+
+            new_command = (char *) alloca (new_size);
+            new_argv = (char **) alloca (4 * sizeof(char*));
+            new_argv[0] = shell;
+            new_argv[1] = "-c";
+            new_argv[2] = new_command;
+            new_argv[3] = NULL;
+
+            /* now copy all the argv[i] arguments into new_command */
+            for (i = 0; i < argc; i++)
+              {
+                q = argv[i];
+                while (*q)
+                  *new_command++ = *q++;
+
+                *new_command++ = ' '; /* trailing space */
+              }
+
+            *--new_command = '\0';  /* replace last ' ' by trailing 0 */
+          }            
+
+        else
+          { /* !unix_shell */
+            new_argv = (char **) alloca ((2 + argc + 1) * sizeof (char *));
+           new_argv[0] = shell;
+            new_argv[1] = "/c";
+           new_argv[2] = argv[0];
+           while (argc > 0)
+             {
+               new_argv[2 + argc] = argv[argc];
+               --argc;
+             }
+          }
+
+       pid = spawnvpe(P_NOWAIT, shell, new_argv, envp);
+       if (pid < 0) { /* note: opening brace! */
+
+# else /* !__EMX__ */
        new_argv = (char **) alloca ((1 + argc + 1) * sizeof (char *));
        new_argv[0] = shell;
        new_argv[1] = argv[0];
@@ -2538,10 +2609,6 @@
            --argc;
          }
 
-# ifdef __EMX__
-       pid = spawnvpe(P_NOWAIT, shell, new_argv, envp);
-       if (pid < 0) { /* note: opening brace! */
-# else
        execvp (shell, new_argv);
 # endif
        if (errno == ENOENT)
------------------------------

bye,
Andreas



reply via email to

[Prev in Thread] Current Thread [Next in Thread]