exec() fixed on win32
Gurusamy Sarathy [Mon, 23 Jun 1997 22:49:12 +0000 (10:49 +1200)]
exec() doesn't work right on Win32 because of the UNIX-specific
do_exec().

This patch fixes that, and updates the README.win32 in spots.

p5p-msgid: 199706241525.LAA06554@aatma.engin.umich.edu

README.win32
doio.c
win32/config_H.bc
win32/config_H.vc
win32/makedef.pl
win32/win32.c
win32/win32.h
win32/win32io.c
win32/win32io.h
win32/win32iop.h

index 8d14a2d..0cd070a 100644 (file)
@@ -337,7 +337,7 @@ all of the Activeware extensions and most other Win32 extensions from
 CPAN in source form, along with many added bugfixes, and with MakeMaker
 support.  This bundle is available at:
 
-   http://www.perl.com/CPAN/authors/id/GSAR/libwin32-0.06.tar.gz
+   http://www.perl.com/CPAN/authors/id/GSAR/libwin32-0.07.tar.gz
 
 See the README in that distribution for building and installation
 instructions.  Look for later versions that may be available at the
@@ -404,13 +404,19 @@ bogus.
 
 =item *
 
-The following functions are currently unavailable: C<fork()>, C<exec()>,
+The following functions are currently unavailable: C<fork()>,
 C<dump()>, C<chown()>, C<link()>, C<symlink()>, C<chroot()>,
 C<setpgrp()>, C<getpgrp()>, C<setpriority()>, C<getpriority()>,
 C<syscall()>, C<fcntl()>.  This list is possibly very incomplete.
 
 =item *
 
+crypt() is not available due to silly export restrictions.  It may
+become available when the laws change.  Meanwhile, look in CPAN for
+extensions that provide it.
+
+=item *
+
 Various C<socket()> related calls are supported, but they may not
 behave as on Unix platforms.
 
@@ -488,7 +494,7 @@ sundry hacks since then.
 
 Borland support was added in 5.004_01 (Gurusamy Sarathy).
 
-Last updated: 11 June 1997
+Last updated: 15 June 1997
 
 =cut
 
diff --git a/doio.c b/doio.c
index f98af9b..8373d09 100644 (file)
--- a/doio.c
+++ b/doio.c
@@ -942,7 +942,7 @@ do_execfree()
     }
 }
 
-#ifndef OS2
+#if !defined(OS2) && !defined(WIN32)
 
 bool
 do_exec(cmd)
@@ -1033,7 +1033,7 @@ char *cmd;
     return FALSE;
 }
 
-#endif /* OS2 */
+#endif /* OS2 || WIN32 */
 
 I32
 apply(type,mark,sp)
index 5976289..ef1193e 100644 (file)
  *     /bin/pdksh, /bin/ash, /bin/bash, or even something such as
  *     D:/bin/sh.exe.
  */
-#define SH_PATH "cmd /x /c"  /**/
+#define SH_PATH "cmd.exe"  /**/
 
 /* SIG_NAME:
  *     This symbol contains a list of signal names in order of
index ced62a1..36a9a5b 100644 (file)
  *     /bin/pdksh, /bin/ash, /bin/bash, or even something such as
  *     D:/bin/sh.exe.
  */
-#define SH_PATH "cmd /x /c"  /**/
+#define SH_PATH "cmd.exe"  /**/
 
 /* SIG_NAME:
  *     This symbol contains a list of signal names in order of
index 73380b4..82c3da5 100644 (file)
@@ -275,6 +275,7 @@ win32_mkdir
 win32_rmdir
 win32_chdir
 win32_flock
+win32_execvp
 win32_htons
 win32_ntohs
 win32_htonl
index 4663f86..3d226ce 100644 (file)
 #define CROAK croak
 #define WARN warn
 
+#define EXECF_EXEC 1
+#define EXECF_SPAWN 2
+#define EXECF_SPAWN_NOWAIT 3
+
 static DWORD IdOS(void);
 
 extern WIN32_IOSUBSYSTEM       win32stdio;
@@ -42,6 +46,8 @@ char  szShellPath[MAX_PATH+1];
 char  szPerlLibRoot[MAX_PATH+1];
 HANDLE PerlDllHandle = INVALID_HANDLE_VALUE;
 
+static int do_spawn2(char *cmd, int exectype);
+
 int 
 IsWin95(void) {
     return (IdOS() == VER_PLATFORM_WIN32_WINDOWS);
@@ -390,7 +396,7 @@ do_aspawn(void* really, void** mark, void** arglast)
 }
 
 int
-do_spawn(char *cmd)
+do_spawn2(char *cmd, int exectype)
 {
     char **a;
     char *s;
@@ -420,7 +426,19 @@ do_spawn(char *cmd)
        }
        *a = Nullch;
        if(argv[0]) {
-           status = win32_spawnvp(P_WAIT, argv[0], (const char* const*)argv);
+           switch (exectype) {
+           case EXECF_SPAWN:
+               status = win32_spawnvp(P_WAIT, argv[0],
+                                      (const char* const*)argv);
+               break;
+           case EXECF_SPAWN_NOWAIT:
+               status = win32_spawnvp(P_NOWAIT, argv[0],
+                                      (const char* const*)argv);
+               break;
+           case EXECF_EXEC:
+               status = win32_execvp(argv[0], (const char* const*)argv);
+               break;
+           }
            if(status != -1 || errno == 0)
                needToTry = FALSE;
        }
@@ -431,17 +449,44 @@ do_spawn(char *cmd)
        char *argv[5];
        argv[0] = shell; argv[1] = "/x"; argv[2] = "/c";
        argv[3] = cmd; argv[4] = Nullch;
-       status = win32_spawnvp(P_WAIT, argv[0], (const char* const*)argv);
+       switch (exectype) {
+       case EXECF_SPAWN:
+           status = win32_spawnvp(P_WAIT, argv[0],
+                                  (const char* const*)argv);
+           break;
+       case EXECF_SPAWN_NOWAIT:
+           status = win32_spawnvp(P_NOWAIT, argv[0],
+                                  (const char* const*)argv);
+           break;
+       case EXECF_EXEC:
+           status = win32_execvp(argv[0], (const char* const*)argv);
+           break;
+       }
     }
     if (status < 0) {
        if (dowarn)
-           warn("Can't spawn \"%s\": %s", needToTry ? shell : argv[0],
+           warn("Can't %s \"%s\": %s",
+                (exectype == EXECF_EXEC ? "exec" : "spawn"),
+                needToTry ? shell : argv[0],
                 strerror(errno));
        status = 255 << 8;
     }
     return (status);
 }
 
+int
+do_spawn(char *cmd)
+{
+    return do_spawn2(cmd, EXECF_SPAWN);
+}
+
+bool
+do_exec(char *cmd)
+{
+    do_spawn2(cmd, EXECF_EXEC);
+    return FALSE;
+}
+
 
 #define PATHLEN 1024
 
@@ -1107,6 +1152,12 @@ win32_spawnvp(int mode, const char *cmdname, const char *const *argv)
     return pIOSubSystem->pfnspawnvp(mode, cmdname, argv);
 }
 
+DllExport int
+win32_execvp(const char *cmdname, const char *const *argv)
+{
+    return pIOSubSystem->pfnexecvp(cmdname, argv);
+}
+
 int
 stolen_open_osfhandle(long handle, int flags)
 {
index d295a75..c6746d2 100644 (file)
@@ -104,6 +104,7 @@ int mytimes(struct tms *timebuf);
 unsigned int myalarm(unsigned int sec);
 int do_aspawn(void* really, void** mark, void** arglast);
 int do_spawn(char *cmd);
+char do_exec(char *cmd);
 
 typedef  char *                caddr_t;        /* In malloc.c (core address). */
 
index 0651781..96ceb3e 100644 (file)
@@ -297,6 +297,7 @@ WIN32_IOSUBSYSTEM   win32stdio = {
     _rmdir,
     _chdir,
     my_flock,          /* (*pfunc_flock)(int fd, int oper) */
+    execvp,
     87654321L,         /* end of structure */
 };
 
index 678327c..98ee874 100644 (file)
@@ -60,7 +60,8 @@ int   (*pfnmkdir)(const char *path);
 int    (*pfnrmdir)(const char *path);
 int    (*pfnchdir)(const char *path);
 int    (*pfnflock)(int fd, int oper);
-int            signature_end;
+int    (*pfnexecvp)(const char *cmdname, const char *const *argv);
+int    signature_end;
 } WIN32_IOSUBSYSTEM; 
 
 typedef WIN32_IOSUBSYSTEM      *PWIN32_IOSUBSYSTEM;
index 4b4b997..6ec25b0 100644 (file)
@@ -63,6 +63,7 @@ EXT int               win32_mkdir(const char *dir, int mode);
 EXT int                win32_rmdir(const char *dir);
 EXT int                win32_chdir(const char *dir);
 EXT int                win32_flock(int fd, int oper);
+EXT int                win32_execvp(const char *cmdname, const char *const *argv);
 
 /*
  * these two are win32 specific but still io related
@@ -154,6 +155,7 @@ void *      SetIOSubSystem(void     *piosubsystem);
 #define rmdir                  win32_rmdir
 #define chdir                  win32_chdir
 #define flock(fd,o)            win32_flock(fd,o)
+#define execvp                 win32_execvp
 #endif /* WIN32IO_IS_STDIO */
 
 #endif /* WIN32IOP_H */