--- a/Unix.st Sat Dec 16 02:23:39 1995 +0100
+++ b/Unix.st Sat Dec 16 03:21:11 1995 +0100
@@ -1796,12 +1796,32 @@
exec:aPath withArguments:argArray
"execute the unix command specified by the argument, aPath, with
arguments in argArray (no arguments, if nil).
- If successful, this method does not return and smalltalk is gone.
- If not successful, false is returned. Normal use is with forkForCommand."
+ If successful, this method does NOT return and smalltalk is gone.
+ If not successful, false is returned. Can be used with fork or to transfer
+ to another program."
+
+ self exec:aPath withArguments:argArray fork:false
+!
+
+exec:aPath withArguments:argArray fork:doFork
+ "Internal combined fork & exec;
+ If fork is false:
+ execute the unix command specified by the argument, aPath, with
+ arguments in argArray (no arguments, if nil).
+ If successful, this method does not return and smalltalk is gone.
+ If not successful, false is returned. Normal use is with forkForCommand.
+ if its true:
+ for a child to do the above.
+ The id of the child process is returned.
+
+ Notice: this used to be two separate ST-methods; however, in order to use
+ vfork on some machines, it had to be merged into one, to avoid write
+ accesses to ST/X memory from the vforked-child. The code below only does
+ read accesses."
%{
char **argv;
- int nargs, i;
+ int nargs, i, id;
OBJ arg;
if (__isString(aPath) && ((argArray == nil) || __isArray(argArray))) {
@@ -1817,13 +1837,29 @@
}
}
argv[i] = NULL;
- execv(_stringVal(aPath), argv);
- /*
- * should not be reached
- * (well, it is, if you pass a wrong command-path)
- */
- free(argv);
- RETURN ( false );
+
+ if (doFork == true) {
+#ifdef HAS_VFORK
+ id = vfork();
+#else
+ id = fork();
+#endif
+ if (id == 0) {
+ execv(_stringVal(aPath), argv);
+ /* should not be reached */
+ _exit(1);
+ }
+ free(argv);
+ RETURN (__MKSMALLINT(id));
+ } else {
+ execv(_stringVal(aPath), argv);
+ /*
+ * should not be reached
+ * (well, it is, if you pass a wrong command-path)
+ */
+ free(argv);
+ RETURN ( false );
+ }
}
}
%}.
@@ -1837,7 +1873,7 @@
"
|id|
- id := OperatingSystem forkForCommand.
+ id := OperatingSystem fork.
id == 0 ifTrue:[
"I am the child"
OperatingSystem exec:'/bin/ls' withArguments:#('ls' '/tmp').
@@ -1847,7 +1883,7 @@
"
|id|
- id := OperatingSystem forkForCommand.
+ id := OperatingSystem fork.
id == 0 ifTrue:[
"I am the child"
OperatingSystem exec:'/bin/sh' withArguments:#('sh' '-c' 'sleep 2;echo 1;sleep 2;echo 2').
@@ -1918,8 +1954,7 @@
unix-process-id) to the parent (original) process.
In normal situations, you dont need to use this low level entry; see
- #startProcess: and #executCommand: for higher level interfaces.
- If you need a process for command execution, please use forkForCommand."
+ #startProcess: and #executCommand: for higher level interfaces."
%{ /* NOCONTEXT */
@@ -1938,25 +1973,6 @@
"
!
-forkForCommand
- "fork a new (HEAVY-weight) unix process for command execution.
- See description of fork for what it does.
- This one should be used, if all you need a new proces for is to
- execute another command. On some systems (namely old SYSV3 / BSD systems),
- this executes faster thatn fork."
-
-%{ /* NOCONTEXT */
- int pid;
-
-#ifdef HAS_VFORK
- pid = vfork();
-#else
- pid = fork();
-#endif
- RETURN ( _MKSMALLINT(pid) );
-%}
-!
-
pathOfCommand:aCommand
"find where aCommand's executable file is"
@@ -1988,18 +2004,10 @@
Use #waitForProcess: for synchronization and exec status return,
or #killProcess: to stop it."
- |id|
-
- id := self forkForCommand.
- id == 0 ifTrue:[
- "I am the child"
- self exec:'/bin/sh' withArguments:(Array with:'sh'
- with:'-c'
- with:aCommandString).
- self exit:1.
- "not reached"
- ].
- ^ id
+ ^ self
+ exec:'/bin/sh'
+ withArguments:(Array with:'sh' with:'-c' with:aCommandString)
+ fork:true.
"
|pid|
@@ -5327,6 +5335,6 @@
!OperatingSystem class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic/Attic/Unix.st,v 1.96 1995-12-15 22:40:29 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/Attic/Unix.st,v 1.97 1995-12-16 02:21:11 cg Exp $'
! !
OperatingSystem initialize!