[Vm-dev] [commit][2723] Add some error checking to the UnixOSProcessPlugin' s forkAndExecInDirectory

commits at squeakvm.org commits at squeakvm.org
Thu Apr 18 20:21:34 UTC 2013


Revision: 2723
Author:   eliot
Date:     2013-04-18 13:21:32 -0700 (Thu, 18 Apr 2013)
Log Message:
-----------
Add some error checking to the UnixOSProcessPlugin's forkAndExecInDirectory
prim.  Eliminate some compiler warnings in the plugin.

Modified Paths:
--------------
    branches/Cog/nscogsrc/plugins/UnixOSProcessPlugin/UnixOSProcessPlugin.c
    branches/Cog/src/plugins/UnixOSProcessPlugin/UnixOSProcessPlugin.c

Property Changed:
----------------
    branches/Cog/platforms/Cross/vm/sqSCCSVersion.h

Modified: branches/Cog/nscogsrc/plugins/UnixOSProcessPlugin/UnixOSProcessPlugin.c
===================================================================
--- branches/Cog/nscogsrc/plugins/UnixOSProcessPlugin/UnixOSProcessPlugin.c	2013-04-13 20:22:17 UTC (rev 2722)
+++ branches/Cog/nscogsrc/plugins/UnixOSProcessPlugin/UnixOSProcessPlugin.c	2013-04-18 20:21:32 UTC (rev 2723)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	VMPluginCodeGenerator VMMaker.oscog-eem.235 uuid: 954df856-3f83-498c-9735-6cd3777ba9c7
+	VMPluginCodeGenerator VMMaker.oscog-eem.285 uuid: cb7737d2-7959-4494-ba87-9be6e6f1226b
    from
-	UnixOSProcessPlugin VMConstruction-Plugins-OSProcessPlugin.oscog-eem.41 uuid: 0406d3fc-7b8b-4b72-b20a-f254eeb1b893
+	UnixOSProcessPlugin VMConstruction-Plugins-OSProcessPlugin.oscog-eem.42 uuid: dfa6d147-0a2d-42a8-a10d-c1fbb4dd8e06
  */
-static char __buildInfo[] = "UnixOSProcessPlugin VMConstruction-Plugins-OSProcessPlugin.oscog-eem.41 uuid: 0406d3fc-7b8b-4b72-b20a-f254eeb1b893 " __DATE__ ;
+static char __buildInfo[] = "UnixOSProcessPlugin VMConstruction-Plugins-OSProcessPlugin.oscog-eem.42 uuid: dfa6d147-0a2d-42a8-a10d-c1fbb4dd8e06 " __DATE__ ;
 /* D T Lewis - UnixOSProcessPlugin.c translated from class
    UnixOSProcessPlugin of OSProcessPlugin version 4.3.3 Cog */
 
@@ -54,7 +54,10 @@
 /*** Constants ***/
 #define BytesPerWord 4
 #define FILEHANDLETYPE FILE *  /* the type of low level stream to be used in a struct SQFile */
+#define PrimErrBadArgument 3
+#define PrimErrBadNumArgs 5
 #define PrimErrNoMemory 9
+#define PrimErrNotFound 11
 #define PrimErrUnsupported 7
 #define SESSIONIDENTIFIERTYPE int
 
@@ -72,7 +75,7 @@
 static FILEHANDLETYPE fileHandleFrom(sqInt sqFileStructByteArray);
 static sqInt fileRecordSize(void);
 static SQFile * fileValueOf(sqInt anSQFileRecord);
-static sqInt fixPointersInArrayOfStringswithOffsetscount(char *flattenedArrayOfStrings, sqInt *offsetArray, sqInt count);
+static char ** fixPointersInArrayOfStringswithOffsets(sqInt flattenedStrings, sqInt offsets);
 static sqInt forkAndExecInDirectory(sqInt useSignalHandler);
 EXPORT(pid_t) forkSqueak(sqInt useSignalHandler);
 static void * forwardSignaltoSemaphoreAt(sqInt sigNum, sqInt semaphoreIndex);
@@ -103,7 +106,7 @@
 static void ** originalSignalHandlers(void);
 static void * pointerFrom(sqInt aByteArray);
 EXPORT(sqInt) primitiveArgumentAt(void);
-EXPORT(sqInt) primitiveCanReceiveSignals(sqInt anIntegerPid);
+EXPORT(sqInt) primitiveCanReceiveSignals(void);
 EXPORT(sqInt) primitiveChdir(void);
 EXPORT(sqInt) primitiveCreatePipe(void);
 EXPORT(sqInt) primitiveCreatePipeWithSessionIdentifier(void);
@@ -148,19 +151,19 @@
 EXPORT(sqInt) primitiveRealpath(void);
 EXPORT(sqInt) primitiveReapChildProcess(void);
 EXPORT(sqInt) primitiveSemaIndexFor(void);
-EXPORT(sqInt) primitiveSendSigabrtTo(sqInt anIntegerPid);
-EXPORT(sqInt) primitiveSendSigalrmTo(sqInt anIntegerPid);
-EXPORT(sqInt) primitiveSendSigchldTo(sqInt anIntegerPid);
-EXPORT(sqInt) primitiveSendSigcontTo(sqInt anIntegerPid);
-EXPORT(sqInt) primitiveSendSighupTo(sqInt anIntegerPid);
-EXPORT(sqInt) primitiveSendSigintTo(sqInt anIntegerPid);
-EXPORT(sqInt) primitiveSendSigkillTo(sqInt anIntegerPid);
-EXPORT(sqInt) primitiveSendSigpipeTo(sqInt anIntegerPid);
-EXPORT(sqInt) primitiveSendSigquitTo(sqInt anIntegerPid);
-EXPORT(sqInt) primitiveSendSigstopTo(sqInt anIntegerPid);
-EXPORT(sqInt) primitiveSendSigtermTo(sqInt anIntegerPid);
-EXPORT(sqInt) primitiveSendSigusr1To(sqInt anIntegerPid);
-EXPORT(sqInt) primitiveSendSigusr2To(sqInt anIntegerPid);
+EXPORT(sqInt) primitiveSendSigabrtTo(void);
+EXPORT(sqInt) primitiveSendSigalrmTo(void);
+EXPORT(sqInt) primitiveSendSigchldTo(void);
+EXPORT(sqInt) primitiveSendSigcontTo(void);
+EXPORT(sqInt) primitiveSendSighupTo(void);
+EXPORT(sqInt) primitiveSendSigintTo(void);
+EXPORT(sqInt) primitiveSendSigkillTo(void);
+EXPORT(sqInt) primitiveSendSigpipeTo(void);
+EXPORT(sqInt) primitiveSendSigquitTo(void);
+EXPORT(sqInt) primitiveSendSigstopTo(void);
+EXPORT(sqInt) primitiveSendSigtermTo(void);
+EXPORT(sqInt) primitiveSendSigusr1To(void);
+EXPORT(sqInt) primitiveSendSigusr2To(void);
 EXPORT(sqInt) primitiveSetPGid(void);
 EXPORT(sqInt) primitiveSetPGrp(void);
 EXPORT(sqInt) primitiveSetSemaIndex(void);
@@ -203,7 +206,7 @@
 static void setSigChldHandler(void);
 static void setSigIntDefaultHandler(void);
 static void setSigIntIgnore(void);
-static void * setSignalNumberhandler(sqInt signalNumber, sqInt signalHandlerAddress);
+static void * setSignalNumberhandler(sqInt signalNumber, void *signalHandlerAddress);
 static void setSigPipeDefaultHandler(void);
 static sqInt setSigPipeHandler(void);
 static void setSigPipeIgnore(void);
@@ -258,6 +261,7 @@
 static void * (*ioLoadFunctionFrom)(char *functionName, char *moduleName);
 static sqInt (*isBytes)(sqInt oop);
 static sqInt (*isIntegerObject)(sqInt objectPointer);
+static sqInt (*methodArgumentCount)(void);
 static sqInt (*nilObject)(void);
 static sqInt (*pop)(sqInt nItems);
 static sqInt (*popthenPush)(sqInt nItems, sqInt oop);
@@ -292,6 +296,7 @@
 extern void * ioLoadFunctionFrom(char *functionName, char *moduleName);
 extern sqInt isBytes(sqInt oop);
 extern sqInt isIntegerObject(sqInt objectPointer);
+extern sqInt methodArgumentCount(void);
 extern sqInt nilObject(void);
 extern sqInt pop(sqInt nItems);
 extern sqInt popthenPush(sqInt nItems, sqInt oop);
@@ -315,9 +320,9 @@
 struct VirtualMachine* interpreterProxy;
 static const char *moduleName =
 #ifdef SQUEAK_BUILTIN_PLUGIN
-	"UnixOSProcessPlugin VMConstruction-Plugins-OSProcessPlugin.oscog-eem.41 (i)"
+	"UnixOSProcessPlugin VMConstruction-Plugins-OSProcessPlugin.oscog-eem.42 (i)"
 #else
-	"UnixOSProcessPlugin VMConstruction-Plugins-OSProcessPlugin.oscog-eem.41 (e)"
+	"UnixOSProcessPlugin VMConstruction-Plugins-OSProcessPlugin.oscog-eem.42 (e)"
 #endif
 ;
 static void *originalSigHandlers[NSIG];
@@ -406,14 +411,16 @@
 }
 
 
-/*	Answer the size of the file descriptor table for a process. I am not sure
+/*	dtl:
+	Answer the size of the file descriptor table for a process. I am not sure
 	of the most portable
 	way to do this. If this implementation does not work on your Unix
 	platform, try changing
 	it to answer the value of FOPEN:=MAX, which will hopefully be defined in
-	stdio.h. If
-	all else fails, just hard code it to answer 20, which would be safe for
-	any Unix.
+	stdio.h. 
+	eem:
+	If we know that (e.g.) stdin is open we can use fd=dup(0);close(fd);fd
+	instead. 
  */
 
 static sqInt
@@ -584,23 +591,50 @@
 }
 
 
+/*	The image constructs a flattened string of all the argument and/or
+	environment strings.
+	There is room at the beginning for the null-terminated array of pointers
+	to strings.
+	The rest of the string contains the null-terminated strings. */
 /*	Use the address offsets in offsetArray to fix up the pointers in
 	cStringArray. The result is a C array of pointers to char, used for argv
 	and env vectors.
  */
 
-static sqInt
-fixPointersInArrayOfStringswithOffsetscount(char *flattenedArrayOfStrings, sqInt *offsetArray, sqInt count)
+static char **
+fixPointersInArrayOfStringswithOffsets(sqInt flattenedStrings, sqInt offsets)
 {
+    sqInt count;
     sqInt idx;
+    sqInt *offsetArray;
     char **ptr;
+    usqInt sz;
+    sqInt val;
 
-	ptr = ((char **) flattenedArrayOfStrings);
+	count = stSizeOf(offsets);
+	offsetArray = firstIndexableField(offsets);
+	sz = ((usqInt)(byteSizeOf(flattenedStrings)));
+	if ((count * (sizeof(char *))) >= sz) {
+		primitiveFailFor(PrimErrBadArgument);
+		return 0;
+	}
+	ptr = ((char **) (arrayValueOf(flattenedStrings)));
 	idx = 0;
 	while (idx < count) {
-		ptr[idx] = (flattenedArrayOfStrings + (integerValueOf(offsetArray[idx])));
+		val = integerValueOf(offsetArray[idx]);
+		if ((((usqInt)val)) >= sz) {
+			primitiveFailFor(PrimErrBadArgument);
+			return 0;
+		}
+		ptr[idx] = ((((char *) ptr)) + val);
 		idx += 1;
 	}
+	if ((ptr[idx]) != 0) {
+		primitiveFailFor(PrimErrBadArgument);
+	}
+	return (failed()
+		? 0
+		: ptr);
 }
 
 
@@ -658,30 +692,19 @@
 static sqInt
 forkAndExecInDirectory(sqInt useSignalHandler)
 {
-    sqInt argCount;
-    sqInt *argOffsetPtr;
     sqInt argOffsets;
     char **args;
-    char *argsPtr;
     sqInt argVecBuffer;
     char **env;
-    sqInt envCount;
-    sqInt *envOffsetPtr;
     sqInt envOffsets;
-    char *envPtr;
     extern char **envVec;
     sqInt envVecBuffer;
     sqInt executableFile;
-    sqInt handleCount;
-    sqInt idx;
-    sqInt idx1;
-    sqInt idx2;
+    sqInt fd;
+    sqInt fdLimiT;
     struct itimerval intervalTimer;
     pid_t pid;
     char *progNamePtr;
-    char **ptr;
-    char **ptr1;
-    sqInt pwd;
     char *pwdPtr;
     struct itimerval saveIntervalTimer;
     sqInt sigNum;
@@ -690,139 +713,116 @@
     sqInt stdOut;
     sqInt workingDir;
 
+	if ((methodArgumentCount()) != 9) {
+		return primitiveFailFor(PrimErrBadNumArgs);
+	}
 	if (useSignalHandler) {
 		setSigChldHandler();
 	}
 	if ((sandboxSecurity()) == 1) {
 		pop(10);
 		pushInteger(-1);
+		return null;
 	}
-	else {
+	workingDir = stackObjectValue(0);
+	envOffsets = stackObjectValue(1);
+	envVecBuffer = stackObjectValue(2);
+	argOffsets = stackObjectValue(3);
+	argVecBuffer = stackObjectValue(4);
+	stdErr = stackObjectValue(5);
+	stdOut = stackObjectValue(6);
+	stdIn = stackObjectValue(7);
+	executableFile = stackObjectValue(8);
+	if ((isIntegerObject(workingDir))
+	 || ((isIntegerObject(envOffsets))
+	 || ((isIntegerObject(envVecBuffer))
+	 || ((isIntegerObject(argOffsets))
+	 || ((isIntegerObject(argVecBuffer))
+	 || ((isIntegerObject(stdErr))
+	 || ((isIntegerObject(stdOut))
+	 || ((isIntegerObject(stdIn))
+	 || (isIntegerObject(executableFile)))))))))) {
+		return primitiveFailFor(PrimErrBadArgument);
+	}
+	intervalTimer.it_interval.tv_sec = 0;
+	intervalTimer.it_interval.tv_usec = 0;
+	intervalTimer.it_value.tv_sec = 0;
+	intervalTimer.it_value.tv_usec = 0;
+	setitimer (ITIMER_REAL, &intervalTimer, &saveIntervalTimer);
+	if (((pid = vfork())) != 0) {
 
-		/* Turn off the interval timer. If this is not done, then the program which we exec in
-		   the child process will receive a timer interrupt, and will not know how to handle it. */
+		/* Normal return to Smalltalk - this is the old parent process. */
+		/* Enable the timer again before resuming Smalltalk. */
 
-		intervalTimer.it_interval.tv_sec = 0;
-		intervalTimer.it_interval.tv_usec = 0;
-		intervalTimer.it_value.tv_sec = 0;
-		intervalTimer.it_value.tv_usec = 0;
-		setitimer (ITIMER_REAL, &intervalTimer, &saveIntervalTimer);
-		if (((pid = vfork())) == 0) {
+		setitimer (ITIMER_REAL, &saveIntervalTimer, 0L);
+		if (!(failed())) {
 
-			/* This is the new child process */
+			/* Pop 9 arguments plus receiver, push pid. */
 
-			workingDir = stackObjectValue(0);
-			envOffsets = stackObjectValue(1);
-			envVecBuffer = stackObjectValue(2);
-			argOffsets = stackObjectValue(3);
-			argVecBuffer = stackObjectValue(4);
-			stdErr = stackObjectValue(5);
-			stdOut = stackObjectValue(6);
-			stdIn = stackObjectValue(7);
+			pop(10);
+			pushInteger(pid);
+		}
+		return null;
+	}
+	if (workingDir != (nilObject())) {
+		pwdPtr = arrayValueOf(workingDir);
+		if ((failed())
+		 || (pwdPtr == 0)) {
+			primitiveFailFor(PrimErrBadArgument);
+			fprintf(stderr, "bad workingDir parameter\n");
+			_exit(-1);
+		}
+		if ((chdir(pwdPtr)) != 0) {
+			primitiveFailFor(PrimErrNotFound);
+			perror("chdir");
+			_exit(-1);
+		}
+	}
 
-			/* If a new working directory has been specified, try to chdir() to it. */
+	/* Dup the file handles to attach the new child process to the right streams
+	   on descriptors 0, 1 and 2. */
 
-			executableFile = stackObjectValue(8);
-			if (workingDir != (nilObject())) {
-				pwdPtr = firstIndexableField(workingDir);
-				if (pwdPtr == 0) {
-					fprintf(stderr, "bad workingDir parameter\n");
-					_exit(-1);
-				}
-				else {
-					pwd = chdir(pwdPtr);
-					if (pwd != 0) {
-						perror("chdir");
-						_exit(-1);
-					}
-				}
-			}
+	progNamePtr = arrayValueOf(executableFile);
+	if (!(stdErr == (nilObject()))) {
+		dupToStdErr(stdErr);
+	}
+	if (!(stdOut == (nilObject()))) {
+		dupToStdOut(stdOut);
+	}
+	if (!(stdIn == (nilObject()))) {
+		dupToStdIn(stdIn);
+	}
+	for (fd = 3, fdLimiT = ((getdtablesize()) - 1); fd <= fdLimiT; fd += 1) {
+		close(fd);
+	}
+	if (envVecBuffer == (nilObject())) {
+		env = envVec;
+	}
+	else {
+		env = ((char **) (fixPointersInArrayOfStringswithOffsets(envVecBuffer, envOffsets)));
+	}
+	args = ((char **) (fixPointersInArrayOfStringswithOffsets(argVecBuffer, argOffsets)));
+	if ((env == 0)
+	 || (args == 0)) {
+		perror("bad env or bad args");
+		_exit(-1);
+	}
+	/* begin restoreDefaultSignalHandlers */
+	if (!(semaIndices == null)) {
 
-			/* Dup the file handles to attach the new child process to the right streams
-			   on descriptors 0, 1 and 2. */
+		/* nil if in interpreter simulation */
 
-			progNamePtr = arrayValueOf(executableFile);
-			if (!(stdErr == (nilObject()))) {
-				dupToStdErr(stdErr);
+		sigNum = 1;
+		while (sigNum <= (signalArraySize())) {
+			if ((semaIndices[sigNum]) > 0) {
+				setSignalNumberhandler(sigNum, (originalSignalHandlers())[sigNum]);
 			}
-			if (!(stdOut == (nilObject()))) {
-				dupToStdOut(stdOut);
-			}
-			if (!(stdIn == (nilObject()))) {
-				dupToStdIn(stdIn);
-			}
-
-			/* First Unix file descriptor after stdin, stdout, stderr. */
-
-			idx = 3;
-			handleCount = descriptorTableSize();
-			while (idx < handleCount) {
-				close(idx);
-				idx += 1;
-			}
-			if (envVecBuffer == (nilObject())) {
-				env = envVec;
-			}
-			else {
-				envCount = stSizeOf(envOffsets);
-				envPtr = arrayValueOf(envVecBuffer);
-				envOffsetPtr = firstIndexableField(envOffsets);
-				/* begin fixPointersInArrayOfStrings:withOffsets:count: */
-				ptr = ((char **) envPtr);
-				idx1 = 0;
-				while (idx1 < envCount) {
-					ptr[idx1] = (envPtr + (integerValueOf(envOffsetPtr[idx1])));
-					idx1 += 1;
-				}
-				env = ((char **) envPtr);
-			}
-			argCount = stSizeOf(argOffsets);
-			argsPtr = arrayValueOf(argVecBuffer);
-			argOffsetPtr = firstIndexableField(argOffsets);
-			/* begin fixPointersInArrayOfStrings:withOffsets:count: */
-			ptr1 = ((char **) argsPtr);
-			idx2 = 0;
-			while (idx2 < argCount) {
-				ptr1[idx2] = (argsPtr + (integerValueOf(argOffsetPtr[idx2])));
-				idx2 += 1;
-			}
-
-			/* Clean things up before clobbering the running image. */
-			/* Note: If any file descriptors, signal handlers, or other references to external
-			   resources need to be cleaned up, do it here. */
-
-			args = ((char **) argsPtr);
-			/* begin restoreDefaultSignalHandlers */
-			if (!(semaIndices == null)) {
-
-				/* nil if in interpreter simulation */
-
-				sigNum = 1;
-				while (sigNum <= (signalArraySize())) {
-					if ((semaIndices[sigNum]) > 0) {
-						setSignalNumberhandler(sigNum, (originalSignalHandlers())[sigNum]);
-					}
-					sigNum += 1;
-				}
-			}
-			if ((execve(progNamePtr, args, env)) == -1) {
-				perror(progNamePtr);
-				_exit(-1);
-			}
-			else {
-				/* Can't get here from there */;
-			}
+			sigNum += 1;
 		}
-		else {
-
-			/* Normal return to Smalltalk - this is the old parent process. */
-			/* Enable the timer again before resuming Smalltalk. */
-
-			setitimer (ITIMER_REAL, &saveIntervalTimer, 0L);
-			pop(10);
-			pushInteger(pid);
-		}
 	}
+	execve(progNamePtr, args, env);
+	perror(progNamePtr);
+	_exit(-1);
 }
 
 
@@ -1073,7 +1073,7 @@
 static sqInt
 isNonNullSQFile(sqInt objectPointer)
 {
-    sqInt idx;
+    unsigned idx;
     unsigned char *sqFileBytes;
 
 	sqFileBytes = arrayValueOf(objectPointer);
@@ -1403,9 +1403,9 @@
 }
 
 
-/*	Send a null signal to the OS process identified by anIntegerPid. Answer
+/*	Send a null signal to the OS process identified by the argument. Answer
 	false for
-	a bad parameter on the stack (the common case is for anIntegerPid equal to
+	a bad parameter on the stack (the common case is for the argument equal to
 	nil, for which case we should answer false). Answer true if the process
 	exists and can
 	receive signals from this process, otherwise false. This test is useful
@@ -1414,7 +1414,7 @@
  */
 
 EXPORT(sqInt)
-primitiveCanReceiveSignals(sqInt anIntegerPid)
+primitiveCanReceiveSignals(void)
 {
     pid_t pidToSignal;
     int result;
@@ -1812,26 +1812,18 @@
 {
     sqInt count;
     sqInt cStringArray;
-    char *flattenedArrayOfStrings;
-    sqInt idx;
     sqInt offsetArray;
-    sqInt *offsets;
-    char **ptr;
 
 	count = stackIntegerValue(0);
 	offsetArray = stackObjectValue(1);
 	cStringArray = stackObjectValue(2);
-	offsets = firstIndexableField(offsetArray);
-	flattenedArrayOfStrings = arrayValueOf(cStringArray);
-	/* begin fixPointersInArrayOfStrings:withOffsets:count: */
-	ptr = ((char **) flattenedArrayOfStrings);
-	idx = 0;
-	while (idx < count) {
-		ptr[idx] = (flattenedArrayOfStrings + (integerValueOf(offsets[idx])));
-		idx += 1;
+	if ((failed())
+	 || ((fixPointersInArrayOfStringswithOffsets(cStringArray, offsetArray)) == 0)) {
+		primitiveFail();
 	}
-	pop(4);
-	push(cStringArray);
+	else {
+		popthenPush(4, cStringArray);
+	}
 }
 
 
@@ -2747,14 +2739,14 @@
 }
 
 
-/*	Send SIGABRT (abort) to the OS process identified by anIntegerPid. Use an
+/*	Send SIGABRT (abort) to the OS process identified by the argument. Use an
 	explicit check for isIntegerObject so we can return -1 on error (the
 	stackIntegerValue: method
 	answers 1 on error, and 1 is a valid pid number).
  */
 
 EXPORT(sqInt)
-primitiveSendSigabrtTo(sqInt anIntegerPid)
+primitiveSendSigabrtTo(void)
 {
     pid_t pidToSignal;
     int result;
@@ -2781,7 +2773,7 @@
 }
 
 
-/*	Send SIGALRM (alarm clock) to the OS process identified by anIntegerPid.
+/*	Send SIGALRM (alarm clock) to the OS process identified by the argument.
 	Use an explicit
 	check for isIntegerObject so we can return -1 on error (the
 	stackIntegerValue: method
@@ -2789,7 +2781,7 @@
  */
 
 EXPORT(sqInt)
-primitiveSendSigalrmTo(sqInt anIntegerPid)
+primitiveSendSigalrmTo(void)
 {
     pid_t pidToSignal;
     int result;
@@ -2817,7 +2809,7 @@
 
 
 /*	Send SIGCHLD (child status has changed, usually death of child) to the OS
-	process identified by anIntegerPid. Use an explicit check for
+	process identified by the argument. Use an explicit check for
 	isIntegerObject so we can
 	return -1 on error (the stackIntegerValue: method answers 1 on error, and
 	1 is a
@@ -2825,7 +2817,7 @@
  */
 
 EXPORT(sqInt)
-primitiveSendSigchldTo(sqInt anIntegerPid)
+primitiveSendSigchldTo(void)
 {
     pid_t pidToSignal;
     int result;
@@ -2852,7 +2844,7 @@
 }
 
 
-/*	Send SIGCONT (continue) to the OS process identified by anIntegerPid. Use
+/*	Send SIGCONT (continue) to the OS process identified by the argument. Use
 	an explicit
 	check for isIntegerObject so we can return -1 on error (the
 	stackIntegerValue: method
@@ -2860,7 +2852,7 @@
  */
 
 EXPORT(sqInt)
-primitiveSendSigcontTo(sqInt anIntegerPid)
+primitiveSendSigcontTo(void)
 {
     pid_t pidToSignal;
     int result;
@@ -2887,14 +2879,14 @@
 }
 
 
-/*	Send SIGHUP (hangup) to the OS process identified by anIntegerPid. Use an
+/*	Send SIGHUP (hangup) to the OS process identified by the argument. Use an
 	explicit check for isIntegerObject so we can return -1 on error (the
 	stackIntegerValue: method
 	answers 1 on error, and 1 is a valid pid number).
  */
 
 EXPORT(sqInt)
-primitiveSendSighupTo(sqInt anIntegerPid)
+primitiveSendSighupTo(void)
 {
     pid_t pidToSignal;
     int result;
@@ -2921,7 +2913,7 @@
 }
 
 
-/*	Send SIGINT (interrupt) to the OS process identified by anIntegerPid. Use
+/*	Send SIGINT (interrupt) to the OS process identified by the argument. Use
 	an explicit
 	check for isIntegerObject so we can return -1 on error (the
 	stackIntegerValue: method
@@ -2929,7 +2921,7 @@
  */
 
 EXPORT(sqInt)
-primitiveSendSigintTo(sqInt anIntegerPid)
+primitiveSendSigintTo(void)
 {
     pid_t pidToSignal;
     int result;
@@ -2956,15 +2948,15 @@
 }
 
 
-/*	Send SIGKILL (kill, unblockable) to the OS process identified by
-	anIntegerPid. Use an explicit
+/*	Send SIGKILL (kill, unblockable) to the OS process identified by the
+	argument. Use an explicit
 	check for isIntegerObject so we can return -1 on error (the
 	stackIntegerValue: method
 	answers 1 on error, and 1 is a valid pid number).
  */
 
 EXPORT(sqInt)
-primitiveSendSigkillTo(sqInt anIntegerPid)
+primitiveSendSigkillTo(void)
 {
     pid_t pidToSignal;
     int result;
@@ -2991,7 +2983,7 @@
 }
 
 
-/*	Send SIGPIPE (broken pipe) to the OS process identified by anIntegerPid.
+/*	Send SIGPIPE (broken pipe) to the OS process identified by the argument.
 	Use an explicit
 	check for isIntegerObject so we can return -1 on error (the
 	stackIntegerValue: method
@@ -2999,7 +2991,7 @@
  */
 
 EXPORT(sqInt)
-primitiveSendSigpipeTo(sqInt anIntegerPid)
+primitiveSendSigpipeTo(void)
 {
     pid_t pidToSignal;
     int result;
@@ -3026,14 +3018,14 @@
 }
 
 
-/*	Send SIGQUIT (quit) to the OS process identified by anIntegerPid. Use an
+/*	Send SIGQUIT (quit) to the OS process identified by the argument. Use an
 	explicit check for isIntegerObject so we can return -1 on error (the
 	stackIntegerValue: method
 	answers 1 on error, and 1 is a valid pid number).
  */
 
 EXPORT(sqInt)
-primitiveSendSigquitTo(sqInt anIntegerPid)
+primitiveSendSigquitTo(void)
 {
     pid_t pidToSignal;
     int result;
@@ -3060,15 +3052,15 @@
 }
 
 
-/*	Send SIGSTOP (stop, unblockable) to the OS process identified by
-	anIntegerPid. Use an explicit
+/*	Send SIGSTOP (stop, unblockable) to the OS process identified by the
+	argument. Use an explicit
 	check for isIntegerObject so we can return -1 on error (the
 	stackIntegerValue: method
 	answers 1 on error, and 1 is a valid pid number).
  */
 
 EXPORT(sqInt)
-primitiveSendSigstopTo(sqInt anIntegerPid)
+primitiveSendSigstopTo(void)
 {
     pid_t pidToSignal;
     int result;
@@ -3095,7 +3087,7 @@
 }
 
 
-/*	Send SIGTERM (termination) to the OS process identified by anIntegerPid.
+/*	Send SIGTERM (termination) to the OS process identified by the argument.
 	Use an explicit
 	check for isIntegerObject so we can return -1 on error (the
 	stackIntegerValue: method
@@ -3103,7 +3095,7 @@
  */
 
 EXPORT(sqInt)
-primitiveSendSigtermTo(sqInt anIntegerPid)
+primitiveSendSigtermTo(void)
 {
     pid_t pidToSignal;
     int result;
@@ -3130,15 +3122,15 @@
 }
 
 
-/*	Send SIGUSR1 (User-defined signal 1) to the OS process identified by
-	anIntegerPid. Use
+/*	Send SIGUSR1 (User-defined signal 1) to the OS process identified by the
+	argument. Use
 	an explicit check for isIntegerObject so we can return -1 on error (the
 	stackIntegerValue: method answers 1 on error, and 1 is a valid pid
 	number). 
  */
 
 EXPORT(sqInt)
-primitiveSendSigusr1To(sqInt anIntegerPid)
+primitiveSendSigusr1To(void)
 {
     pid_t pidToSignal;
     int result;
@@ -3165,15 +3157,15 @@
 }
 
 
-/*	Send SIGUSR2 (User-defined signal 2) to the OS process identified by
-	anIntegerPid. Use
+/*	Send SIGUSR2 (User-defined signal 2) to the OS process identified by the
+	argument. Use
 	an explicit check for isIntegerObject so we can return -1 on error (the
 	stackIntegerValue: method answers 1 on error, and 1 is a valid pid
 	number). 
  */
 
 EXPORT(sqInt)
-primitiveSendSigusr2To(sqInt anIntegerPid)
+primitiveSendSigusr2To(void)
 {
     pid_t pidToSignal;
     int result;
@@ -4152,6 +4144,7 @@
 		ioLoadFunctionFrom = interpreterProxy->ioLoadFunctionFrom;
 		isBytes = interpreterProxy->isBytes;
 		isIntegerObject = interpreterProxy->isIntegerObject;
+		methodArgumentCount = interpreterProxy->methodArgumentCount;
 		nilObject = interpreterProxy->nilObject;
 		pop = interpreterProxy->pop;
 		popthenPush = interpreterProxy->popthenPush;
@@ -4222,7 +4215,7 @@
  */
 
 static void *
-setSignalNumberhandler(sqInt signalNumber, sqInt signalHandlerAddress)
+setSignalNumberhandler(sqInt signalNumber, void *signalHandlerAddress)
 {
     struct sigaction oldHandlerAction;
     struct sigaction sigHandlerAction;


Property changes on: branches/Cog/platforms/Cross/vm/sqSCCSVersion.h
___________________________________________________________________
Modified: checkindate
   - Fri Apr 12 15:15:32 PDT 2013
   + Thu Apr 18 13:20:52 PDT 2013

Modified: branches/Cog/src/plugins/UnixOSProcessPlugin/UnixOSProcessPlugin.c
===================================================================
--- branches/Cog/src/plugins/UnixOSProcessPlugin/UnixOSProcessPlugin.c	2013-04-13 20:22:17 UTC (rev 2722)
+++ branches/Cog/src/plugins/UnixOSProcessPlugin/UnixOSProcessPlugin.c	2013-04-18 20:21:32 UTC (rev 2723)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	VMPluginCodeGenerator VMMaker.oscog-eem.235 uuid: 954df856-3f83-498c-9735-6cd3777ba9c7
+	VMPluginCodeGenerator VMMaker.oscog-eem.285 uuid: cb7737d2-7959-4494-ba87-9be6e6f1226b
    from
-	UnixOSProcessPlugin VMConstruction-Plugins-OSProcessPlugin.oscog-eem.41 uuid: 0406d3fc-7b8b-4b72-b20a-f254eeb1b893
+	UnixOSProcessPlugin VMConstruction-Plugins-OSProcessPlugin.oscog-eem.42 uuid: dfa6d147-0a2d-42a8-a10d-c1fbb4dd8e06
  */
-static char __buildInfo[] = "UnixOSProcessPlugin VMConstruction-Plugins-OSProcessPlugin.oscog-eem.41 uuid: 0406d3fc-7b8b-4b72-b20a-f254eeb1b893 " __DATE__ ;
+static char __buildInfo[] = "UnixOSProcessPlugin VMConstruction-Plugins-OSProcessPlugin.oscog-eem.42 uuid: dfa6d147-0a2d-42a8-a10d-c1fbb4dd8e06 " __DATE__ ;
 /* D T Lewis - UnixOSProcessPlugin.c translated from class
    UnixOSProcessPlugin of OSProcessPlugin version 4.3.3 Cog */
 
@@ -54,7 +54,10 @@
 /*** Constants ***/
 #define BytesPerWord 4
 #define FILEHANDLETYPE FILE *  /* the type of low level stream to be used in a struct SQFile */
+#define PrimErrBadArgument 3
+#define PrimErrBadNumArgs 5
 #define PrimErrNoMemory 9
+#define PrimErrNotFound 11
 #define PrimErrUnsupported 7
 #define SESSIONIDENTIFIERTYPE int
 
@@ -72,7 +75,7 @@
 static FILEHANDLETYPE fileHandleFrom(sqInt sqFileStructByteArray);
 static sqInt fileRecordSize(void);
 static SQFile * fileValueOf(sqInt anSQFileRecord);
-static sqInt fixPointersInArrayOfStringswithOffsetscount(char *flattenedArrayOfStrings, sqInt *offsetArray, sqInt count);
+static char ** fixPointersInArrayOfStringswithOffsets(sqInt flattenedStrings, sqInt offsets);
 static sqInt forkAndExecInDirectory(sqInt useSignalHandler);
 EXPORT(pid_t) forkSqueak(sqInt useSignalHandler);
 static void * forwardSignaltoSemaphoreAt(sqInt sigNum, sqInt semaphoreIndex);
@@ -103,7 +106,7 @@
 static void ** originalSignalHandlers(void);
 static void * pointerFrom(sqInt aByteArray);
 EXPORT(sqInt) primitiveArgumentAt(void);
-EXPORT(sqInt) primitiveCanReceiveSignals(sqInt anIntegerPid);
+EXPORT(sqInt) primitiveCanReceiveSignals(void);
 EXPORT(sqInt) primitiveChdir(void);
 EXPORT(sqInt) primitiveCreatePipe(void);
 EXPORT(sqInt) primitiveCreatePipeWithSessionIdentifier(void);
@@ -148,19 +151,19 @@
 EXPORT(sqInt) primitiveRealpath(void);
 EXPORT(sqInt) primitiveReapChildProcess(void);
 EXPORT(sqInt) primitiveSemaIndexFor(void);
-EXPORT(sqInt) primitiveSendSigabrtTo(sqInt anIntegerPid);
-EXPORT(sqInt) primitiveSendSigalrmTo(sqInt anIntegerPid);
-EXPORT(sqInt) primitiveSendSigchldTo(sqInt anIntegerPid);
-EXPORT(sqInt) primitiveSendSigcontTo(sqInt anIntegerPid);
-EXPORT(sqInt) primitiveSendSighupTo(sqInt anIntegerPid);
-EXPORT(sqInt) primitiveSendSigintTo(sqInt anIntegerPid);
-EXPORT(sqInt) primitiveSendSigkillTo(sqInt anIntegerPid);
-EXPORT(sqInt) primitiveSendSigpipeTo(sqInt anIntegerPid);
-EXPORT(sqInt) primitiveSendSigquitTo(sqInt anIntegerPid);
-EXPORT(sqInt) primitiveSendSigstopTo(sqInt anIntegerPid);
-EXPORT(sqInt) primitiveSendSigtermTo(sqInt anIntegerPid);
-EXPORT(sqInt) primitiveSendSigusr1To(sqInt anIntegerPid);
-EXPORT(sqInt) primitiveSendSigusr2To(sqInt anIntegerPid);
+EXPORT(sqInt) primitiveSendSigabrtTo(void);
+EXPORT(sqInt) primitiveSendSigalrmTo(void);
+EXPORT(sqInt) primitiveSendSigchldTo(void);
+EXPORT(sqInt) primitiveSendSigcontTo(void);
+EXPORT(sqInt) primitiveSendSighupTo(void);
+EXPORT(sqInt) primitiveSendSigintTo(void);
+EXPORT(sqInt) primitiveSendSigkillTo(void);
+EXPORT(sqInt) primitiveSendSigpipeTo(void);
+EXPORT(sqInt) primitiveSendSigquitTo(void);
+EXPORT(sqInt) primitiveSendSigstopTo(void);
+EXPORT(sqInt) primitiveSendSigtermTo(void);
+EXPORT(sqInt) primitiveSendSigusr1To(void);
+EXPORT(sqInt) primitiveSendSigusr2To(void);
 EXPORT(sqInt) primitiveSetPGid(void);
 EXPORT(sqInt) primitiveSetPGrp(void);
 EXPORT(sqInt) primitiveSetSemaIndex(void);
@@ -203,7 +206,7 @@
 static void setSigChldHandler(void);
 static void setSigIntDefaultHandler(void);
 static void setSigIntIgnore(void);
-static void * setSignalNumberhandler(sqInt signalNumber, sqInt signalHandlerAddress);
+static void * setSignalNumberhandler(sqInt signalNumber, void *signalHandlerAddress);
 static void setSigPipeDefaultHandler(void);
 static sqInt setSigPipeHandler(void);
 static void setSigPipeIgnore(void);
@@ -258,6 +261,7 @@
 static void * (*ioLoadFunctionFrom)(char *functionName, char *moduleName);
 static sqInt (*isBytes)(sqInt oop);
 static sqInt (*isIntegerObject)(sqInt objectPointer);
+static sqInt (*methodArgumentCount)(void);
 static sqInt (*nilObject)(void);
 static sqInt (*pop)(sqInt nItems);
 static sqInt (*popthenPush)(sqInt nItems, sqInt oop);
@@ -292,6 +296,7 @@
 extern void * ioLoadFunctionFrom(char *functionName, char *moduleName);
 extern sqInt isBytes(sqInt oop);
 extern sqInt isIntegerObject(sqInt objectPointer);
+extern sqInt methodArgumentCount(void);
 extern sqInt nilObject(void);
 extern sqInt pop(sqInt nItems);
 extern sqInt popthenPush(sqInt nItems, sqInt oop);
@@ -315,9 +320,9 @@
 struct VirtualMachine* interpreterProxy;
 static const char *moduleName =
 #ifdef SQUEAK_BUILTIN_PLUGIN
-	"UnixOSProcessPlugin VMConstruction-Plugins-OSProcessPlugin.oscog-eem.41 (i)"
+	"UnixOSProcessPlugin VMConstruction-Plugins-OSProcessPlugin.oscog-eem.42 (i)"
 #else
-	"UnixOSProcessPlugin VMConstruction-Plugins-OSProcessPlugin.oscog-eem.41 (e)"
+	"UnixOSProcessPlugin VMConstruction-Plugins-OSProcessPlugin.oscog-eem.42 (e)"
 #endif
 ;
 static void *originalSigHandlers[NSIG];
@@ -406,14 +411,16 @@
 }
 
 
-/*	Answer the size of the file descriptor table for a process. I am not sure
+/*	dtl:
+	Answer the size of the file descriptor table for a process. I am not sure
 	of the most portable
 	way to do this. If this implementation does not work on your Unix
 	platform, try changing
 	it to answer the value of FOPEN:=MAX, which will hopefully be defined in
-	stdio.h. If
-	all else fails, just hard code it to answer 20, which would be safe for
-	any Unix.
+	stdio.h. 
+	eem:
+	If we know that (e.g.) stdin is open we can use fd=dup(0);close(fd);fd
+	instead. 
  */
 
 static sqInt
@@ -584,23 +591,50 @@
 }
 
 
+/*	The image constructs a flattened string of all the argument and/or
+	environment strings.
+	There is room at the beginning for the null-terminated array of pointers
+	to strings.
+	The rest of the string contains the null-terminated strings. */
 /*	Use the address offsets in offsetArray to fix up the pointers in
 	cStringArray. The result is a C array of pointers to char, used for argv
 	and env vectors.
  */
 
-static sqInt
-fixPointersInArrayOfStringswithOffsetscount(char *flattenedArrayOfStrings, sqInt *offsetArray, sqInt count)
+static char **
+fixPointersInArrayOfStringswithOffsets(sqInt flattenedStrings, sqInt offsets)
 {
+    sqInt count;
     sqInt idx;
+    sqInt *offsetArray;
     char **ptr;
+    usqInt sz;
+    sqInt val;
 
-	ptr = ((char **) flattenedArrayOfStrings);
+	count = stSizeOf(offsets);
+	offsetArray = firstIndexableField(offsets);
+	sz = ((usqInt)(byteSizeOf(flattenedStrings)));
+	if ((count * (sizeof(char *))) >= sz) {
+		primitiveFailFor(PrimErrBadArgument);
+		return 0;
+	}
+	ptr = ((char **) (arrayValueOf(flattenedStrings)));
 	idx = 0;
 	while (idx < count) {
-		ptr[idx] = (flattenedArrayOfStrings + (integerValueOf(offsetArray[idx])));
+		val = integerValueOf(offsetArray[idx]);
+		if ((((usqInt)val)) >= sz) {
+			primitiveFailFor(PrimErrBadArgument);
+			return 0;
+		}
+		ptr[idx] = ((((char *) ptr)) + val);
 		idx += 1;
 	}
+	if ((ptr[idx]) != 0) {
+		primitiveFailFor(PrimErrBadArgument);
+	}
+	return (failed()
+		? 0
+		: ptr);
 }
 
 
@@ -658,30 +692,19 @@
 static sqInt
 forkAndExecInDirectory(sqInt useSignalHandler)
 {
-    sqInt argCount;
-    sqInt *argOffsetPtr;
     sqInt argOffsets;
     char **args;
-    char *argsPtr;
     sqInt argVecBuffer;
     char **env;
-    sqInt envCount;
-    sqInt *envOffsetPtr;
     sqInt envOffsets;
-    char *envPtr;
     extern char **envVec;
     sqInt envVecBuffer;
     sqInt executableFile;
-    sqInt handleCount;
-    sqInt idx;
-    sqInt idx1;
-    sqInt idx2;
+    sqInt fd;
+    sqInt fdLimiT;
     struct itimerval intervalTimer;
     pid_t pid;
     char *progNamePtr;
-    char **ptr;
-    char **ptr1;
-    sqInt pwd;
     char *pwdPtr;
     struct itimerval saveIntervalTimer;
     sqInt sigNum;
@@ -690,139 +713,116 @@
     sqInt stdOut;
     sqInt workingDir;
 
+	if ((methodArgumentCount()) != 9) {
+		return primitiveFailFor(PrimErrBadNumArgs);
+	}
 	if (useSignalHandler) {
 		setSigChldHandler();
 	}
 	if ((sandboxSecurity()) == 1) {
 		pop(10);
 		pushInteger(-1);
+		return null;
 	}
-	else {
+	workingDir = stackObjectValue(0);
+	envOffsets = stackObjectValue(1);
+	envVecBuffer = stackObjectValue(2);
+	argOffsets = stackObjectValue(3);
+	argVecBuffer = stackObjectValue(4);
+	stdErr = stackObjectValue(5);
+	stdOut = stackObjectValue(6);
+	stdIn = stackObjectValue(7);
+	executableFile = stackObjectValue(8);
+	if ((isIntegerObject(workingDir))
+	 || ((isIntegerObject(envOffsets))
+	 || ((isIntegerObject(envVecBuffer))
+	 || ((isIntegerObject(argOffsets))
+	 || ((isIntegerObject(argVecBuffer))
+	 || ((isIntegerObject(stdErr))
+	 || ((isIntegerObject(stdOut))
+	 || ((isIntegerObject(stdIn))
+	 || (isIntegerObject(executableFile)))))))))) {
+		return primitiveFailFor(PrimErrBadArgument);
+	}
+	intervalTimer.it_interval.tv_sec = 0;
+	intervalTimer.it_interval.tv_usec = 0;
+	intervalTimer.it_value.tv_sec = 0;
+	intervalTimer.it_value.tv_usec = 0;
+	setitimer (ITIMER_REAL, &intervalTimer, &saveIntervalTimer);
+	if (((pid = vfork())) != 0) {
 
-		/* Turn off the interval timer. If this is not done, then the program which we exec in
-		   the child process will receive a timer interrupt, and will not know how to handle it. */
+		/* Normal return to Smalltalk - this is the old parent process. */
+		/* Enable the timer again before resuming Smalltalk. */
 
-		intervalTimer.it_interval.tv_sec = 0;
-		intervalTimer.it_interval.tv_usec = 0;
-		intervalTimer.it_value.tv_sec = 0;
-		intervalTimer.it_value.tv_usec = 0;
-		setitimer (ITIMER_REAL, &intervalTimer, &saveIntervalTimer);
-		if (((pid = vfork())) == 0) {
+		setitimer (ITIMER_REAL, &saveIntervalTimer, 0L);
+		if (!(failed())) {
 
-			/* This is the new child process */
+			/* Pop 9 arguments plus receiver, push pid. */
 
-			workingDir = stackObjectValue(0);
-			envOffsets = stackObjectValue(1);
-			envVecBuffer = stackObjectValue(2);
-			argOffsets = stackObjectValue(3);
-			argVecBuffer = stackObjectValue(4);
-			stdErr = stackObjectValue(5);
-			stdOut = stackObjectValue(6);
-			stdIn = stackObjectValue(7);
+			pop(10);
+			pushInteger(pid);
+		}
+		return null;
+	}
+	if (workingDir != (nilObject())) {
+		pwdPtr = arrayValueOf(workingDir);
+		if ((failed())
+		 || (pwdPtr == 0)) {
+			primitiveFailFor(PrimErrBadArgument);
+			fprintf(stderr, "bad workingDir parameter\n");
+			_exit(-1);
+		}
+		if ((chdir(pwdPtr)) != 0) {
+			primitiveFailFor(PrimErrNotFound);
+			perror("chdir");
+			_exit(-1);
+		}
+	}
 
-			/* If a new working directory has been specified, try to chdir() to it. */
+	/* Dup the file handles to attach the new child process to the right streams
+	   on descriptors 0, 1 and 2. */
 
-			executableFile = stackObjectValue(8);
-			if (workingDir != (nilObject())) {
-				pwdPtr = firstIndexableField(workingDir);
-				if (pwdPtr == 0) {
-					fprintf(stderr, "bad workingDir parameter\n");
-					_exit(-1);
-				}
-				else {
-					pwd = chdir(pwdPtr);
-					if (pwd != 0) {
-						perror("chdir");
-						_exit(-1);
-					}
-				}
-			}
+	progNamePtr = arrayValueOf(executableFile);
+	if (!(stdErr == (nilObject()))) {
+		dupToStdErr(stdErr);
+	}
+	if (!(stdOut == (nilObject()))) {
+		dupToStdOut(stdOut);
+	}
+	if (!(stdIn == (nilObject()))) {
+		dupToStdIn(stdIn);
+	}
+	for (fd = 3, fdLimiT = ((getdtablesize()) - 1); fd <= fdLimiT; fd += 1) {
+		close(fd);
+	}
+	if (envVecBuffer == (nilObject())) {
+		env = envVec;
+	}
+	else {
+		env = ((char **) (fixPointersInArrayOfStringswithOffsets(envVecBuffer, envOffsets)));
+	}
+	args = ((char **) (fixPointersInArrayOfStringswithOffsets(argVecBuffer, argOffsets)));
+	if ((env == 0)
+	 || (args == 0)) {
+		perror("bad env or bad args");
+		_exit(-1);
+	}
+	/* begin restoreDefaultSignalHandlers */
+	if (!(semaIndices == null)) {
 
-			/* Dup the file handles to attach the new child process to the right streams
-			   on descriptors 0, 1 and 2. */
+		/* nil if in interpreter simulation */
 
-			progNamePtr = arrayValueOf(executableFile);
-			if (!(stdErr == (nilObject()))) {
-				dupToStdErr(stdErr);
+		sigNum = 1;
+		while (sigNum <= (signalArraySize())) {
+			if ((semaIndices[sigNum]) > 0) {
+				setSignalNumberhandler(sigNum, (originalSignalHandlers())[sigNum]);
 			}
-			if (!(stdOut == (nilObject()))) {
-				dupToStdOut(stdOut);
-			}
-			if (!(stdIn == (nilObject()))) {
-				dupToStdIn(stdIn);
-			}
-
-			/* First Unix file descriptor after stdin, stdout, stderr. */
-
-			idx = 3;
-			handleCount = descriptorTableSize();
-			while (idx < handleCount) {
-				close(idx);
-				idx += 1;
-			}
-			if (envVecBuffer == (nilObject())) {
-				env = envVec;
-			}
-			else {
-				envCount = stSizeOf(envOffsets);
-				envPtr = arrayValueOf(envVecBuffer);
-				envOffsetPtr = firstIndexableField(envOffsets);
-				/* begin fixPointersInArrayOfStrings:withOffsets:count: */
-				ptr = ((char **) envPtr);
-				idx1 = 0;
-				while (idx1 < envCount) {
-					ptr[idx1] = (envPtr + (integerValueOf(envOffsetPtr[idx1])));
-					idx1 += 1;
-				}
-				env = ((char **) envPtr);
-			}
-			argCount = stSizeOf(argOffsets);
-			argsPtr = arrayValueOf(argVecBuffer);
-			argOffsetPtr = firstIndexableField(argOffsets);
-			/* begin fixPointersInArrayOfStrings:withOffsets:count: */
-			ptr1 = ((char **) argsPtr);
-			idx2 = 0;
-			while (idx2 < argCount) {
-				ptr1[idx2] = (argsPtr + (integerValueOf(argOffsetPtr[idx2])));
-				idx2 += 1;
-			}
-
-			/* Clean things up before clobbering the running image. */
-			/* Note: If any file descriptors, signal handlers, or other references to external
-			   resources need to be cleaned up, do it here. */
-
-			args = ((char **) argsPtr);
-			/* begin restoreDefaultSignalHandlers */
-			if (!(semaIndices == null)) {
-
-				/* nil if in interpreter simulation */
-
-				sigNum = 1;
-				while (sigNum <= (signalArraySize())) {
-					if ((semaIndices[sigNum]) > 0) {
-						setSignalNumberhandler(sigNum, (originalSignalHandlers())[sigNum]);
-					}
-					sigNum += 1;
-				}
-			}
-			if ((execve(progNamePtr, args, env)) == -1) {
-				perror(progNamePtr);
-				_exit(-1);
-			}
-			else {
-				/* Can't get here from there */;
-			}
+			sigNum += 1;
 		}
-		else {
-
-			/* Normal return to Smalltalk - this is the old parent process. */
-			/* Enable the timer again before resuming Smalltalk. */
-
-			setitimer (ITIMER_REAL, &saveIntervalTimer, 0L);
-			pop(10);
-			pushInteger(pid);
-		}
 	}
+	execve(progNamePtr, args, env);
+	perror(progNamePtr);
+	_exit(-1);
 }
 
 
@@ -1073,7 +1073,7 @@
 static sqInt
 isNonNullSQFile(sqInt objectPointer)
 {
-    sqInt idx;
+    unsigned idx;
     unsigned char *sqFileBytes;
 
 	sqFileBytes = arrayValueOf(objectPointer);
@@ -1403,9 +1403,9 @@
 }
 
 
-/*	Send a null signal to the OS process identified by anIntegerPid. Answer
+/*	Send a null signal to the OS process identified by the argument. Answer
 	false for
-	a bad parameter on the stack (the common case is for anIntegerPid equal to
+	a bad parameter on the stack (the common case is for the argument equal to
 	nil, for which case we should answer false). Answer true if the process
 	exists and can
 	receive signals from this process, otherwise false. This test is useful
@@ -1414,7 +1414,7 @@
  */
 
 EXPORT(sqInt)
-primitiveCanReceiveSignals(sqInt anIntegerPid)
+primitiveCanReceiveSignals(void)
 {
     pid_t pidToSignal;
     int result;
@@ -1812,26 +1812,18 @@
 {
     sqInt count;
     sqInt cStringArray;
-    char *flattenedArrayOfStrings;
-    sqInt idx;
     sqInt offsetArray;
-    sqInt *offsets;
-    char **ptr;
 
 	count = stackIntegerValue(0);
 	offsetArray = stackObjectValue(1);
 	cStringArray = stackObjectValue(2);
-	offsets = firstIndexableField(offsetArray);
-	flattenedArrayOfStrings = arrayValueOf(cStringArray);
-	/* begin fixPointersInArrayOfStrings:withOffsets:count: */
-	ptr = ((char **) flattenedArrayOfStrings);
-	idx = 0;
-	while (idx < count) {
-		ptr[idx] = (flattenedArrayOfStrings + (integerValueOf(offsets[idx])));
-		idx += 1;
+	if ((failed())
+	 || ((fixPointersInArrayOfStringswithOffsets(cStringArray, offsetArray)) == 0)) {
+		primitiveFail();
 	}
-	pop(4);
-	push(cStringArray);
+	else {
+		popthenPush(4, cStringArray);
+	}
 }
 
 
@@ -2747,14 +2739,14 @@
 }
 
 
-/*	Send SIGABRT (abort) to the OS process identified by anIntegerPid. Use an
+/*	Send SIGABRT (abort) to the OS process identified by the argument. Use an
 	explicit check for isIntegerObject so we can return -1 on error (the
 	stackIntegerValue: method
 	answers 1 on error, and 1 is a valid pid number).
  */
 
 EXPORT(sqInt)
-primitiveSendSigabrtTo(sqInt anIntegerPid)
+primitiveSendSigabrtTo(void)
 {
     pid_t pidToSignal;
     int result;
@@ -2781,7 +2773,7 @@
 }
 
 
-/*	Send SIGALRM (alarm clock) to the OS process identified by anIntegerPid.
+/*	Send SIGALRM (alarm clock) to the OS process identified by the argument.
 	Use an explicit
 	check for isIntegerObject so we can return -1 on error (the
 	stackIntegerValue: method
@@ -2789,7 +2781,7 @@
  */
 
 EXPORT(sqInt)
-primitiveSendSigalrmTo(sqInt anIntegerPid)
+primitiveSendSigalrmTo(void)
 {
     pid_t pidToSignal;
     int result;
@@ -2817,7 +2809,7 @@
 
 
 /*	Send SIGCHLD (child status has changed, usually death of child) to the OS
-	process identified by anIntegerPid. Use an explicit check for
+	process identified by the argument. Use an explicit check for
 	isIntegerObject so we can
 	return -1 on error (the stackIntegerValue: method answers 1 on error, and
 	1 is a
@@ -2825,7 +2817,7 @@
  */
 
 EXPORT(sqInt)
-primitiveSendSigchldTo(sqInt anIntegerPid)
+primitiveSendSigchldTo(void)
 {
     pid_t pidToSignal;
     int result;
@@ -2852,7 +2844,7 @@
 }
 
 
-/*	Send SIGCONT (continue) to the OS process identified by anIntegerPid. Use
+/*	Send SIGCONT (continue) to the OS process identified by the argument. Use
 	an explicit
 	check for isIntegerObject so we can return -1 on error (the
 	stackIntegerValue: method
@@ -2860,7 +2852,7 @@
  */
 
 EXPORT(sqInt)
-primitiveSendSigcontTo(sqInt anIntegerPid)
+primitiveSendSigcontTo(void)
 {
     pid_t pidToSignal;
     int result;
@@ -2887,14 +2879,14 @@
 }
 
 
-/*	Send SIGHUP (hangup) to the OS process identified by anIntegerPid. Use an
+/*	Send SIGHUP (hangup) to the OS process identified by the argument. Use an
 	explicit check for isIntegerObject so we can return -1 on error (the
 	stackIntegerValue: method
 	answers 1 on error, and 1 is a valid pid number).
  */
 
 EXPORT(sqInt)
-primitiveSendSighupTo(sqInt anIntegerPid)
+primitiveSendSighupTo(void)
 {
     pid_t pidToSignal;
     int result;
@@ -2921,7 +2913,7 @@
 }
 
 
-/*	Send SIGINT (interrupt) to the OS process identified by anIntegerPid. Use
+/*	Send SIGINT (interrupt) to the OS process identified by the argument. Use
 	an explicit
 	check for isIntegerObject so we can return -1 on error (the
 	stackIntegerValue: method
@@ -2929,7 +2921,7 @@
  */
 
 EXPORT(sqInt)
-primitiveSendSigintTo(sqInt anIntegerPid)
+primitiveSendSigintTo(void)
 {
     pid_t pidToSignal;
     int result;
@@ -2956,15 +2948,15 @@
 }
 
 
-/*	Send SIGKILL (kill, unblockable) to the OS process identified by
-	anIntegerPid. Use an explicit
+/*	Send SIGKILL (kill, unblockable) to the OS process identified by the
+	argument. Use an explicit
 	check for isIntegerObject so we can return -1 on error (the
 	stackIntegerValue: method
 	answers 1 on error, and 1 is a valid pid number).
  */
 
 EXPORT(sqInt)
-primitiveSendSigkillTo(sqInt anIntegerPid)
+primitiveSendSigkillTo(void)
 {
     pid_t pidToSignal;
     int result;
@@ -2991,7 +2983,7 @@
 }
 
 
-/*	Send SIGPIPE (broken pipe) to the OS process identified by anIntegerPid.
+/*	Send SIGPIPE (broken pipe) to the OS process identified by the argument.
 	Use an explicit
 	check for isIntegerObject so we can return -1 on error (the
 	stackIntegerValue: method
@@ -2999,7 +2991,7 @@
  */
 
 EXPORT(sqInt)
-primitiveSendSigpipeTo(sqInt anIntegerPid)
+primitiveSendSigpipeTo(void)
 {
     pid_t pidToSignal;
     int result;
@@ -3026,14 +3018,14 @@
 }
 
 
-/*	Send SIGQUIT (quit) to the OS process identified by anIntegerPid. Use an
+/*	Send SIGQUIT (quit) to the OS process identified by the argument. Use an
 	explicit check for isIntegerObject so we can return -1 on error (the
 	stackIntegerValue: method
 	answers 1 on error, and 1 is a valid pid number).
  */
 
 EXPORT(sqInt)
-primitiveSendSigquitTo(sqInt anIntegerPid)
+primitiveSendSigquitTo(void)
 {
     pid_t pidToSignal;
     int result;
@@ -3060,15 +3052,15 @@
 }
 
 
-/*	Send SIGSTOP (stop, unblockable) to the OS process identified by
-	anIntegerPid. Use an explicit
+/*	Send SIGSTOP (stop, unblockable) to the OS process identified by the
+	argument. Use an explicit
 	check for isIntegerObject so we can return -1 on error (the
 	stackIntegerValue: method
 	answers 1 on error, and 1 is a valid pid number).
  */
 
 EXPORT(sqInt)
-primitiveSendSigstopTo(sqInt anIntegerPid)
+primitiveSendSigstopTo(void)
 {
     pid_t pidToSignal;
     int result;
@@ -3095,7 +3087,7 @@
 }
 
 
-/*	Send SIGTERM (termination) to the OS process identified by anIntegerPid.
+/*	Send SIGTERM (termination) to the OS process identified by the argument.
 	Use an explicit
 	check for isIntegerObject so we can return -1 on error (the
 	stackIntegerValue: method
@@ -3103,7 +3095,7 @@
  */
 
 EXPORT(sqInt)
-primitiveSendSigtermTo(sqInt anIntegerPid)
+primitiveSendSigtermTo(void)
 {
     pid_t pidToSignal;
     int result;
@@ -3130,15 +3122,15 @@
 }
 
 
-/*	Send SIGUSR1 (User-defined signal 1) to the OS process identified by
-	anIntegerPid. Use
+/*	Send SIGUSR1 (User-defined signal 1) to the OS process identified by the
+	argument. Use
 	an explicit check for isIntegerObject so we can return -1 on error (the
 	stackIntegerValue: method answers 1 on error, and 1 is a valid pid
 	number). 
  */
 
 EXPORT(sqInt)
-primitiveSendSigusr1To(sqInt anIntegerPid)
+primitiveSendSigusr1To(void)
 {
     pid_t pidToSignal;
     int result;
@@ -3165,15 +3157,15 @@
 }
 
 
-/*	Send SIGUSR2 (User-defined signal 2) to the OS process identified by
-	anIntegerPid. Use
+/*	Send SIGUSR2 (User-defined signal 2) to the OS process identified by the
+	argument. Use
 	an explicit check for isIntegerObject so we can return -1 on error (the
 	stackIntegerValue: method answers 1 on error, and 1 is a valid pid
 	number). 
  */
 
 EXPORT(sqInt)
-primitiveSendSigusr2To(sqInt anIntegerPid)
+primitiveSendSigusr2To(void)
 {
     pid_t pidToSignal;
     int result;
@@ -4152,6 +4144,7 @@
 		ioLoadFunctionFrom = interpreterProxy->ioLoadFunctionFrom;
 		isBytes = interpreterProxy->isBytes;
 		isIntegerObject = interpreterProxy->isIntegerObject;
+		methodArgumentCount = interpreterProxy->methodArgumentCount;
 		nilObject = interpreterProxy->nilObject;
 		pop = interpreterProxy->pop;
 		popthenPush = interpreterProxy->popthenPush;
@@ -4222,7 +4215,7 @@
  */
 
 static void *
-setSignalNumberhandler(sqInt signalNumber, sqInt signalHandlerAddress)
+setSignalNumberhandler(sqInt signalNumber, void *signalHandlerAddress)
 {
     struct sigaction oldHandlerAction;
     struct sigaction sigHandlerAction;



More information about the Vm-dev mailing list