--- a/AbstractOperatingSystem.st Tue Oct 25 12:31:42 2016 +0100
+++ b/AbstractOperatingSystem.st Tue Oct 25 12:35:02 2016 +0100
@@ -1,3 +1,5 @@
+"{ Encoding: utf8 }"
+
"
COPYRIGHT (c) 1988 by Claus Gittinger
All Rights Reserved
@@ -1302,6 +1304,29 @@
"Modified: / 10.11.1998 / 20:54:37 / cg"
!
+executeCommand:aCommandString inDirectory:aDirectory showWindow:showWindow
+ "execute the unix command specified by the argument, aCommandString.
+ If aCommandString is a String, the commandString is passed to a shell for execution
+ - see the description of 'sh -c' in your UNIX manual ('cmd.com' in your MSDOS manual).
+ If aCommandString is an Array, the first element is the command to be executed,
+ and the other elements are the arguments to the command. No shell is invoked in this case.
+ Return true if successful, false otherwise."
+
+ ^ self
+ executeCommand:aCommandString
+ inputFrom:nil
+ outputTo:nil
+ errorTo:nil
+ auxFrom:nil
+ environment:nil
+ inDirectory:aDirectory
+ lineWise:false
+ showWindow:showWindow
+ onError:[:exitStatus| false]
+
+ "Created: / 18-10-2016 / 15:55:29 / cg"
+!
+
executeCommand:aCommandString inputFrom:anInStream outputTo:anOutStream errorTo:anErrStream
"execute the unix command specified by the argument, aCommandString.
If aCommandString is a String, the commandString is passed to a shell for execution
--- a/Collection.st Tue Oct 25 12:31:42 2016 +0100
+++ b/Collection.st Tue Oct 25 12:35:02 2016 +0100
@@ -275,6 +275,7 @@
^ self newWithSize:n
! !
+
!Collection class methodsFor:'Signal constants'!
emptyCollectionSignal
@@ -549,6 +550,7 @@
"Created: / 22-10-2008 / 21:29:27 / cg"
! !
+
!Collection methodsFor:'accessing'!
anElement
@@ -2517,12 +2519,13 @@
individualResult := aBlock value:element.
result isNil ifTrue:[
- result := individualResult speciesForAdding new.
+ result := individualResult speciesForCollecting new.
].
result addAll:individualResult.
].
- ^ result ? #()
+ "do not answer an empty - possibly immutable - Array"
+ ^ result ? self speciesForCollecting new.
"
#(1 2 3 4) collectAll:[:n | Array new:n withAll:n ]
@@ -2541,10 +2544,7 @@
result := collectionClass new.
self do:[:element |
- |individualResult|
-
- individualResult := aBlock value:element.
- result addAll:individualResult.
+ result addAll:(aBlock value:element).
].
^ result
@@ -6001,6 +6001,7 @@
^ aVisitor visitCollection:self with:aParameter
! !
+
!Collection class methodsFor:'documentation'!
version
--- a/ExternalStream.st Tue Oct 25 12:31:42 2016 +0100
+++ b/ExternalStream.st Tue Oct 25 12:35:02 2016 +0100
@@ -1,3 +1,5 @@
+"{ Encoding: utf8 }"
+
"
COPYRIGHT (c) 1988 by Claus Gittinger
All Rights Reserved
@@ -2121,23 +2123,22 @@
OBJ _handle = __INST(handle);
if (_handle != nil) {
- if ((__INST(handleType) == @symbol(fileHandle))
- || (__INST(handleType) == @symbol(socketHandle))) {
- RETURN (_handle);
- }
- if ((__INST(handleType) == nil)
- || (__INST(handleType) == @symbol(filePointer))
- || (__INST(handleType) == @symbol(socketFilePointer))
- || (__INST(handleType) == @symbol(pipeFilePointer))) {
+ if ((__INST(handleType) == @symbol(fileHandle))
+ || (__INST(handleType) == @symbol(socketHandle))) {
+ RETURN (_handle);
+ }
+ if ((__INST(handleType) == nil)
+ || (__INST(handleType) == @symbol(filePointer))
+ || (__INST(handleType) == @symbol(socketFilePointer))
+ || (__INST(handleType) == @symbol(pipeFilePointer))) {
#ifdef __win32__
- RETURN(__MKEXTERNALADDRESS(_get_osfhandle(fileno(__FILEVal(_handle)))));
+ RETURN(__MKEXTERNALADDRESS(_get_osfhandle(fileno(__FILEVal(_handle)))));
#else
- RETURN (__MKINT(fileno(__FILEVal(_handle))));
+ RETURN (__MKINT(fileno(__FILEVal(_handle))));
#endif
- }
+ }
}
%}.
- handle isNil ifTrue:[^ self errorNotOpen].
^ handle
!
@@ -2217,6 +2218,15 @@
!ExternalStream methodsFor:'closing'!
+abortAndClose
+ "close the stream - added for protocol compatibility with Socket and PipeStream.
+ see comment there"
+
+ self close.
+
+ "Modified: 30.8.1996 / 00:39:21 / cg"
+!
+
close
"Close the stream.
No error if the stream is not open."
@@ -2230,7 +2240,7 @@
!
shutDown
- "close the stream - added for protocol compatibility with PipeStream.
+ "close the stream - added for protocol compatibility with Socket.
see comment there"
self close.
@@ -2521,10 +2531,7 @@
finalize
"some Stream has been collected - close the file if not already done"
- "/ with timeout to avoid blocking in a bad pty/socket
- [
- self closeFile
- ] valueWithTimeout:30 seconds.
+ self closeFile
!
reRegisterForFinalization
@@ -4627,7 +4634,7 @@
"
(FileStream newTemporary
nextPutUtf16:$B;
- nextPutUtf16:$Ä;
+ nextPutUtf16:$Ä;
nextPutUtf16:(Character codePoint:16r10CCCC);
reset;
binary;
@@ -4666,7 +4673,9 @@
clearEOF
hitEOF := false
-!
+! !
+
+!ExternalStream protectedMethodsFor:'private'!
closeFile
"low level close - may be redefined in subclasses
@@ -4674,81 +4683,79 @@
|fp error|
+ handle isNil ifTrue:[
+ ^ self.
+ ].
fp := handle.
"/ (didWrite==true and:[binary ~~ true and:[eolMode = #crlf]]) ifTrue: [ self breakPoint:#sr ].
%{
int rslt;
- if (fp == nil) {
- error = @symbol(errorNotOpen);
- goto out;
- }
-
if (__INST(handleType) == @symbol(socketHandle)) {
- SOCKET sock = (SOCKET)(__FILEVal(fp));
-
- if (@global(FileOpenTrace) == true) {
- fprintf(stderr, "close socket [ExternalStream] %"_lx_"\n", (INT)sock);
- }
-
- // whether the close() will be successful or not - the handle is invalid now!
- __INST(handle) = nil;
- do {
+ SOCKET sock = (SOCKET)(__FILEVal(fp));
+
+ if (@global(FileOpenTrace) == true) {
+ fprintf(stderr, "close socket [ExternalStream] %"_lx_"\n", (INT)sock);
+ }
+
+ // whether the close() will be successful or not - the handle is invalid now!
+ __INST(handle) = nil;
+ do {
#ifdef __win32__
- rslt = __STX_WSA_NOINT_CALL1("closesocket", closesocket, sock);
+ rslt = __STX_WSA_NOINT_CALL1("closesocket", closesocket, sock);
#else
- rslt = close(sock);
+ rslt = close(sock);
#endif
- } while((rslt < 0) && (__threadErrno == EINTR));
+ } while((rslt < 0) && (__threadErrno == EINTR));
} else if ((__INST(handleType) == nil)
- || (__INST(handleType) == @symbol(filePointer))
- || (__INST(handleType) == @symbol(socketFilePointer))
- || (__INST(handleType) == @symbol(pipeFilePointer)))
+ || (__INST(handleType) == @symbol(filePointer))
+ || (__INST(handleType) == @symbol(socketFilePointer))
+ || (__INST(handleType) == @symbol(pipeFilePointer)))
{
- FILEPOINTER f = __FILEVal(fp);
-
- if (@global(FileOpenTrace) == true) {
- fprintf(stderr, "fclose [ExternalStream] %"_lx_"\n", (INT)f);
- }
- // whether the close() will be successful or not - the handle is invalid now!
- __INST(handle) = nil;
+ FILEPOINTER f = __FILEVal(fp);
+
+ if (@global(FileOpenTrace) == true) {
+ fprintf(stderr, "fclose [ExternalStream] %"_lx_"\n", (INT)f);
+ }
+ // whether the close() will be successful or not - the handle is invalid now!
+ __INST(handle) = nil;
#ifdef __win32__
- if (__INST(mode) != @symbol(readonly) && __INST(buffered) != false) {
- // do a fflush() first, so that fclose() doesn't block
- // we suspect, that EINTR causes problems in fclose()
- do {
- __threadErrno = 0;
- rslt = __STX_C_CALL1("fflush", fflush, f);
- } while((rslt < 0) && (__threadErrno == EINTR));
- }
- do {
- __threadErrno = 0;
- rslt = __STX_C_NOINT_CALL1("fclose", fclose, f);
- } while((rslt < 0) && (__threadErrno == EINTR));
+ if (__INST(mode) != @symbol(readonly) && __INST(buffered) != false) {
+ // do a fflush() first, so that fclose() doesn't block
+ // we suspect, that EINTR causes problems in fclose()
+ do {
+ __threadErrno = 0;
+ rslt = __STX_C_CALL1("fflush", fflush, f);
+ } while((rslt < 0) && (__threadErrno == EINTR));
+ }
+ do {
+ __threadErrno = 0;
+ rslt = __STX_C_NOINT_CALL1("fclose", fclose, f);
+ } while((rslt < 0) && (__threadErrno == EINTR));
#else
- // cg: the pre Nov2014 code always did the fclose interruptable;
- // I am not sure, if fclose is actually prepared to do this;
- // at least when only reading, this should not block, and we
- // should be ableto do it without being interruptable.
- // Must watch this - if it leads to blockings, change and think about it.
- if (__INST(mode) != @symbol(readonly)) {
- __BEGIN_INTERRUPTABLE__
- rslt = fclose(f);
- __END_INTERRUPTABLE__
- } else {
- rslt = fclose(f);
- }
+ // cg: the pre Nov2014 code always did the fclose interruptable;
+ // I am not sure, if fclose is actually prepared to do this;
+ // at least when only reading, this should not block, and we
+ // should be ableto do it without being interruptable.
+ // Must watch this - if it leads to blockings, change and think about it.
+ if (__INST(mode) != @symbol(readonly)) {
+ __BEGIN_INTERRUPTABLE__
+ rslt = fclose(f);
+ __END_INTERRUPTABLE__
+ } else {
+ rslt = fclose(f);
+ }
#endif
} else {
- error = @symbol(badHandleType);
- goto out;
+ error = @symbol(badHandleType);
+ goto out;
}
if (rslt < 0) {
- error = __mkSmallInteger(__threadErrno);
- goto out;
+ error = __mkSmallInteger(__threadErrno);
+ goto out;
}
RETURN (self);
@@ -4756,30 +4763,29 @@
%}.
error notNil ifTrue:[
- error == #errorNotOpen ifTrue:[
- self errorNotOpen.
- ].
- error isInteger ifTrue:[
- lastErrorNumber := error.
- mode == #readonly ifTrue:[
- self ioError:error.
- ] ifFalse:[
- self writeError:error.
- ].
- ^ self.
- ].
- self primitiveFailed:error.
- ^ self.
+ error isInteger ifTrue:[
+ lastErrorNumber := error.
+ mode == #readonly ifTrue:[
+ self ioError:error.
+ ] ifFalse:[
+ self writeError:error.
+ ].
+ ^ self.
+ ].
+ self primitiveFailed:error.
+ ^ self.
].
"/ fallback for rel5
fp := handle.
fp notNil ifTrue:[
- handle := nil.
- self closeFile:fp
+ handle := nil.
+ self closeFile:fp
]
-!
+! !
+
+!ExternalStream methodsFor:'private'!
closeFile:handle
"for rel5 only"
@@ -4870,6 +4876,9 @@
|fd dupFd|
fd := self fileHandle.
+ fd isNil ifTrue:[
+ ^ self errorNotOpen.
+ ].
dupFd := OperatingSystem dup:fd.
self setFileHandle:dupFd mode:self fopenMode.
!
@@ -5150,18 +5159,18 @@
STObject handle = self.instVarAt(I_handle);
if (handle != STObject.Nil) {
- STObject next;
-
- if (self.instVarAt(I_binary) == STObject.True) {
- next = handle.nextByte();
- } else {
- next = handle.nextChar();
- }
- if (next != STObject.EOF) {
- self.instVarAt_put(I_position, STObject.Nil);
- return __c__._RETURN( next );
- }
- self.instVarAt_put(I_hitEOF, STObject.True);
+ STObject next;
+
+ if (self.instVarAt(I_binary) == STObject.True) {
+ next = handle.nextByte();
+ } else {
+ next = handle.nextChar();
+ }
+ if (next != STObject.EOF) {
+ self.instVarAt_put(I_position, STObject.Nil);
+ return __c__._RETURN( next );
+ }
+ self.instVarAt_put(I_hitEOF, STObject.True);
}
#else
FILEPOINTER f;
@@ -5175,65 +5184,63 @@
|| (__INST(handleType) == @symbol(socketFilePointer))
|| (__INST(handleType) == @symbol(socketHandle))
|| (__INST(handleType) == @symbol(pipeFilePointer))) {
- if (((fp = __INST(handle)) != nil)
- && (__INST(mode) != @symbol(writeonly))
- ) {
- f = __FILEVal(fp);
-
- _buffered = (__INST(buffered) == true);
- if (_buffered) {
- __READING__(f)
- }
- __READBYTE__(ret, f, &ch, _buffered, __INST(handleType));
-
- if (ret > 0) {
- pos = __INST(position);
- if (__isSmallInteger(pos)) {
- OBJ t;
-
- t = __MKINT(__intVal(pos) + 1); __INST(position) = t; __STORE(self, t);
- } else {
- __INST(position) = nil; /* i.e. do not know */
- }
- if (__INST(binary) == true) {
- RETURN ( __mkSmallInteger(ch) );
- }
- RETURN ( __MKCHARACTER(ch) );
- }
-
- __INST(position) = nil;
- if ((ret < 0)
-# ifdef ECONNRESET
- && (__threadErrno != ECONNRESET)
-# endif
- ){
- error = __mkSmallInteger(__threadErrno);
- } else /* ret == 0 */ {
- __INST(hitEOF) = true;
- }
- }
+ if (((fp = __INST(handle)) != nil)
+ && (__INST(mode) != @symbol(writeonly))
+ ) {
+ f = __FILEVal(fp);
+
+ _buffered = (__INST(buffered) == true);
+ if (_buffered) {
+ __READING__(f)
+ }
+ __READBYTE__(ret, f, &ch, _buffered, __INST(handleType));
+
+ if (ret > 0) {
+ pos = __INST(position);
+ if (__isSmallInteger(pos)) {
+ OBJ t;
+
+ t = __MKINT(__intVal(pos) + 1); __INST(position) = t; __STORE(self, t);
+ } else {
+ __INST(position) = nil; /* i.e. do not know */
+ }
+ if (__INST(binary) == true) {
+ RETURN ( __mkSmallInteger(ch) );
+ }
+ RETURN ( __MKCHARACTER(ch) );
+ }
+
+ __INST(position) = nil;
+ if (ret < 0) {
+ error = __mkSmallInteger(__threadErrno);
+ } else /* ret == 0 */ {
+ __INST(hitEOF) = true;
+ }
+ }
}
#endif /* not SCHTEAM */
%}.
hitEOF == true ifTrue:[^ self pastEndRead].
error notNil ifTrue:[
- lastErrorNumber := error.
- ^ self readError:error
+ lastErrorNumber := error.
+ ^ self readError:error
].
handle isNil ifTrue:[^ self errorNotOpen].
(mode == #writeonly) ifTrue:[^ self errorWriteOnly].
readAhead notNil ifTrue:[
- c := readAhead.
- readAhead := nil.
- ^ c.
+ c := readAhead.
+ readAhead := nil.
+ ^ c.
].
+
+ "unknown handleType - future"
c := self nextByteFromFile:handle.
c isNil ifTrue:[
- ^ self pastEndRead.
+ ^ self pastEndRead.
].
binary == true ifTrue:[
- ^ c
+ ^ c
].
^ Character value:c
!
@@ -5276,64 +5283,62 @@
|| (__INST(handleType) == @symbol(socketFilePointer))
|| (__INST(handleType) == @symbol(socketHandle))
|| (__INST(handleType) == @symbol(pipeFilePointer))) {
- if (((fp = __INST(handle)) != nil)
- && (__INST(mode) != @symbol(writeonly))
- ) {
- f = __FILEVal(fp);
-
- _buffered = (__INST(buffered) == true);
- if (_buffered) {
- __READING__(f)
- }
- __READBYTE__(ret, f, &ch, _buffered, __INST(handleType));
-
- if (ret > 0) {
- pos = __INST(position);
- if (__isSmallInteger(pos)) {
- OBJ t;
-
- t = __MKINT(__intVal(pos) + 1); __INST(position) = t; __STORE(self, t);
- } else {
- __INST(position) = nil; /* i.e. do not know */
- }
- if (__INST(binary) == true) {
- RETURN ( __mkSmallInteger(ch) );
- }
- RETURN ( __MKCHARACTER(ch) );
- }
-
- __INST(position) = nil;
- if ((ret < 0)
-#ifdef ECONNRESET
- && (__threadErrno != ECONNRESET)
-#endif
- ){
- error = __mkSmallInteger(__threadErrno);
- } else /* ret == 0 */ {
- __INST(hitEOF) = true;
- }
- }
+ if (((fp = __INST(handle)) != nil)
+ && (__INST(mode) != @symbol(writeonly))
+ ) {
+ f = __FILEVal(fp);
+
+ _buffered = (__INST(buffered) == true);
+ if (_buffered) {
+ __READING__(f)
+ }
+ __READBYTE__(ret, f, &ch, _buffered, __INST(handleType));
+
+ if (ret > 0) {
+ pos = __INST(position);
+ if (__isSmallInteger(pos)) {
+ OBJ t;
+
+ t = __MKINT(__intVal(pos) + 1); __INST(position) = t; __STORE(self, t);
+ } else {
+ __INST(position) = nil; /* i.e. do not know */
+ }
+ if (__INST(binary) == true) {
+ RETURN ( __mkSmallInteger(ch) );
+ }
+ RETURN ( __MKCHARACTER(ch) );
+ }
+
+ __INST(position) = nil;
+ if (ret < 0) {
+ error = __mkSmallInteger(__threadErrno);
+ } else /* ret == 0 */ {
+ __INST(hitEOF) = true;
+ }
+ }
}
%}.
hitEOF == true ifTrue:[^ nil].
error notNil ifTrue:[
- lastErrorNumber := error.
- ^ self readError:error.
+ lastErrorNumber := error.
+ ^ self readError:error.
].
handle isNil ifTrue:[^ self errorNotOpen].
(mode == #writeonly) ifTrue:[^ self errorWriteOnly].
readAhead notNil ifTrue:[
- c := readAhead.
- readAhead := nil.
- ^ c.
+ c := readAhead.
+ readAhead := nil.
+ ^ c.
].
+
+ "unknown handleType - future"
c := self nextByteFromFile:handle.
c isNil ifTrue:[
- ^ nil.
+ ^ nil.
].
binary == true ifTrue:[
- ^ c
+ ^ c
].
^ Character value:c
!
@@ -5353,11 +5358,11 @@
OBJ ra;
if ((ra = __INST(readAhead)) != nil) {
- if (__INST(binary) == true) {
- RETURN ( ra );
- }
- c = __intVal(ra);
- RETURN ( __MKCHARACTER(c) );
+ if (__INST(binary) == true) {
+ RETURN ( ra );
+ }
+ c = __intVal(ra);
+ RETURN ( __MKCHARACTER(c) );
}
__INST(lastErrorNumber) = nil;
@@ -5367,49 +5372,45 @@
|| (__INST(handleType) == @symbol(socketFilePointer))
|| (__INST(handleType) == @symbol(socketHandle))
|| (__INST(handleType) == @symbol(pipeFilePointer))) {
- if (((fp = __INST(handle)) != nil)
- && (__INST(mode) != @symbol(writeonly))
- ) {
- f = __FILEVal(fp);
- _buffered = (__INST(buffered) == true);
- if (_buffered) {
- __READING__(f)
- }
- __READBYTE__(ret, f, &c, _buffered, __INST(handleType));
-
- if (ret > 0) {
- __UNGETC__(c, f, _buffered);
-
- if (__INST(binary) == true) {
- RETURN ( __mkSmallInteger(c) );
- }
- RETURN ( __MKCHARACTER(c) );
- }
- if ((ret < 0)
-#ifdef ECONNRESET
- && (__threadErrno != ECONNRESET)
-#endif
- ){
- error = __mkSmallInteger(__threadErrno);
- } else /* ret == 0 */ {
- __INST(hitEOF) = true;
- }
- }
+ if (((fp = __INST(handle)) != nil)
+ && (__INST(mode) != @symbol(writeonly))
+ ) {
+ f = __FILEVal(fp);
+ _buffered = (__INST(buffered) == true);
+ if (_buffered) {
+ __READING__(f)
+ }
+ __READBYTE__(ret, f, &c, _buffered, __INST(handleType));
+
+ if (ret > 0) {
+ __UNGETC__(c, f, _buffered);
+
+ if (__INST(binary) == true) {
+ RETURN ( __mkSmallInteger(c) );
+ }
+ RETURN ( __MKCHARACTER(c) );
+ }
+ if (ret < 0) {
+ error = __mkSmallInteger(__threadErrno);
+ } else /* ret == 0 */ {
+ __INST(hitEOF) = true;
+ }
+ }
}
%}.
hitEOF == true ifTrue:[^ self pastEndRead].
error notNil ifTrue:[
- lastErrorNumber := error.
- ^ self readError:error.
+ lastErrorNumber := error.
+ ^ self readError:error.
].
handle isNil ifTrue:[^ self errorNotOpen].
(mode == #writeonly) ifTrue:[^ self errorWriteOnly].
readAhead isNil ifTrue:[
- readAhead := self nextOrNil.
- readAhead isNil ifTrue:[
- ^ self pastEndRead.
- ].
+ readAhead := self nextOrNil.
+ readAhead isNil ifTrue:[
+ ^ self pastEndRead.
+ ].
].
^ readAhead
!
@@ -5429,11 +5430,11 @@
OBJ ra;
if ((ra = __INST(readAhead)) != nil) {
- if (__INST(binary) == true) {
- RETURN ( ra );
- }
- c = __intVal(ra);
- RETURN ( __MKCHARACTER(c) );
+ if (__INST(binary) == true) {
+ RETURN ( ra );
+ }
+ c = __intVal(ra);
+ RETURN ( __MKCHARACTER(c) );
}
__INST(lastErrorNumber) = nil;
@@ -5443,46 +5444,42 @@
|| (__INST(handleType) == @symbol(socketFilePointer))
|| (__INST(handleType) == @symbol(socketHandle))
|| (__INST(handleType) == @symbol(pipeFilePointer))) {
- if (((fp = __INST(handle)) != nil)
- && (__INST(mode) != @symbol(writeonly))
- ) {
- f = __FILEVal(fp);
- _buffered = (__INST(buffered) == true);
- if (_buffered) {
- __READING__(f)
- }
- __READBYTE__(ret, f, &c, _buffered, __INST(handleType));
-
- if (ret > 0) {
- __UNGETC__(c, f, _buffered);
-
- if (__INST(binary) == true) {
- RETURN ( __mkSmallInteger(c) );
- }
- RETURN ( __MKCHARACTER(c) );
- }
- if ((ret < 0)
-#ifdef ECONNRESET
- && (__threadErrno != ECONNRESET)
-#endif
- ){
- error = __mkSmallInteger(__threadErrno);
- } else /* ret == 0 */ {
- __INST(hitEOF) = true;
- }
- }
+ if (((fp = __INST(handle)) != nil)
+ && (__INST(mode) != @symbol(writeonly))
+ ) {
+ f = __FILEVal(fp);
+ _buffered = (__INST(buffered) == true);
+ if (_buffered) {
+ __READING__(f)
+ }
+ __READBYTE__(ret, f, &c, _buffered, __INST(handleType));
+
+ if (ret > 0) {
+ __UNGETC__(c, f, _buffered);
+
+ if (__INST(binary) == true) {
+ RETURN ( __mkSmallInteger(c) );
+ }
+ RETURN ( __MKCHARACTER(c) );
+ }
+ if (ret < 0) {
+ error = __mkSmallInteger(__threadErrno);
+ } else /* ret == 0 */ {
+ __INST(hitEOF) = true;
+ }
+ }
}
%}.
hitEOF == true ifTrue:[^ nil].
error notNil ifTrue:[
- lastErrorNumber := error.
- ^ self readError:error.
+ lastErrorNumber := error.
+ ^ self readError:error.
].
handle isNil ifTrue:[^ self errorNotOpen].
(mode == #writeonly) ifTrue:[^ self errorWriteOnly].
readAhead isNil ifTrue:[
- readAhead := self nextOrNil.
+ readAhead := self nextOrNil.
].
^ readAhead
!
@@ -5565,7 +5562,9 @@
!ExternalStream methodsFor:'testing'!
atEnd
- "return true, if position is at end"
+ "return true, if position is at end.
+ A stream is at the end, if the next read operation
+ would return immediately without waiting."
%{
OBJ fp, pos, lim;
@@ -5635,26 +5634,17 @@
__INST(hitEOF) = true;
RETURN (true);
}
-#ifdef ECONNRESET
- // connection reset by peer is also an EOF
- if (__threadErrno == ECONNRESET) {
- __INST(hitEOF) = true;
- RETURN (true);
- }
-#endif
- /* ret < 0 */
+ /* ret < 0 -> error */
__INST(lastErrorNumber) = __mkSmallInteger(__threadErrno);
}
+ // we do not raise an error here - the next read operation will raise the error.
+ RETURN(false);
}
%}.
- lastErrorNumber notNil ifTrue:[^ self readError].
- handle isNil ifTrue:[^ self errorNotOpen].
- mode == #writeonly ifTrue:[^ self errorWriteOnly].
- readAhead notNil ifTrue:[^ false].
-
+
+ "/ we come here if the handle type is unknown
"/ migration support
- ^ self
- atEndFile:handle
+ ^ self atEndFile:handle
"Modified: / 30.10.1998 / 20:16:06 / cg"
!
@@ -5695,7 +5685,7 @@
!
gotErrorOrEOF
- "answerv true, if amn error or eof has been occurred on the stream"
+ "answer true, if amn error or eof has been occurred on the stream"
^ hitEOF == true or:[lastErrorNumber notNil]
!
@@ -6579,7 +6569,7 @@
].
"
- 'Bönnigheim' asUnicode16String errorPrintCR
+ 'Bönnigheim' asUnicode16String errorPrintCR
"
!
--- a/Filename.st Tue Oct 25 12:31:42 2016 +0100
+++ b/Filename.st Tue Oct 25 12:35:02 2016 +0100
@@ -2522,6 +2522,30 @@
"Modified: / 12-09-2010 / 15:43:22 / cg"
!
+recursiveDirectoryContentsAsFilenamesDo:aBlock filterForVisitingDirectories:filterOrNil
+ "evaluate aBlock for all files and directories found under the receiver.
+ The block is invoked with the filenames as argument.
+ The walk is bread-first.
+ This excludes any entries for '.' or '..'.
+ Subdirectory files are included with a relative pathname.
+ If filterOrNil is nonNil, it is passed every directory about to be walked into;
+ if it returns false, that directory is not entered.
+ Warning: this may take a long time to execute
+ (especially with deep and/or remote fileSystems)."
+
+ self
+ recursiveDirectoryContentsDo:[:relFn |
+ aBlock value:(self construct:relFn)
+ ]
+ filterForVisitingDirectories:filterOrNil.
+
+ "
+ '.' asFilename recursiveDirectoryContentsAsFilenamesDo:[:f | Transcript showCR:f]
+ "
+
+ "Modified: / 12-09-2010 / 15:43:22 / cg"
+!
+
recursiveDirectoryContentsDo:aBlock
"evaluate aBlock for all files and directories found under the receiver.
The block is invoked with the relative filenames as string-argument.
@@ -2562,13 +2586,64 @@
"
!
+recursiveDirectoryContentsDo:aBlock filterForVisitingDirectories:filterOrNil
+ "evaluate aBlock for all files and directories found under the receiver.
+ The block is invoked with the relative filenames as string-argument.
+ The walk is bread-first.
+ This excludes any entries for '.' or '..'.
+ Subdirectory files are included with a relative pathname.
+ If filterOrNil is nonNil, it is passed every directory about to be walked into;
+ if it returns false, that directory is not entered.
+ Warning: this may take a long time to execute
+ (especially with deep and/or remote fileSystems)."
+
+ self
+ recursiveDirectoryContentsWithPrefix:''
+ filesDo:aBlock
+ directoriesDo:aBlock
+ filterForVisitingDirectories:filterOrNil
+
+ "
+ '.' asFilename recursiveDirectoryContentsDo:[:f | Transcript showCR:f]
+ "
+
+ "Modified: / 12-09-2010 / 15:43:22 / cg"
+!
+
recursiveDirectoryContentsWithPrefix:aPrefix filesDo:fileBlock directoriesDo:dirBlock
"evaluate aBlock for all files and directories found under the receiver.
The blocks are invoked with a relative pathname as string-argument.
The walk is breadth-first (first files, then directories).
This excludes any entries for '.' or '..'.
A proceedable exception is raised for non-accessible directories.
- Warning: this may take a long time to execute (especially with deep and/or remote fileSystems)."
+ Warning: this may take a long time to execute
+ (especially with deep and/or remote fileSystems)."
+
+ self
+ recursiveDirectoryContentsWithPrefix:aPrefix
+ filesDo:fileBlock
+ directoriesDo:dirBlock
+ filterForVisitingDirectories:nil
+
+ "
+ '.' asFilename
+ recursiveDirectoryContentsWithPrefix:'bla'
+ filesDo:[:f | Transcript show:'file: '; showCR:f]
+ directoriesDo:[:f | Transcript show:'dir: '; showCR:f]
+ "
+!
+
+recursiveDirectoryContentsWithPrefix:aPrefix filesDo:fileBlock directoriesDo:dirBlock filterForVisitingDirectories:filterOrNil
+ "evaluate aBlock for all files and directories found under the receiver.
+ The blocks are invoked with a relative pathname as string-argument.
+ The walk is breadth-first (first files, then directories).
+ This excludes any entries for '.' or '..'.
+ A proceedable exception is raised for non-accessible directories.
+ If filterOrNil is nonNil, it is passed every directory about to be walked into;
+ if it returns false, that directory is not entered.
+ Warning: this may take a long time to execute
+ (especially with deep and/or remote fileSystems).
+ "
|fileNames dirNames p|
@@ -2579,9 +2654,11 @@
self directoryContentsDo:[:f | |t|
t := self construct:f.
t isDirectory ifTrue:[
- dirBlock notNil ifTrue:[
- t isSymbolicLink ifFalse:[
- dirNames add:f
+ (filterOrNil isNil or:[filterOrNil value:t]) ifTrue:[
+ dirBlock notNil ifTrue:[
+ t isSymbolicLink ifFalse:[
+ dirNames add:f
+ ]
]
]
] ifFalse:[
@@ -2602,10 +2679,15 @@
].
dirBlock notNil ifTrue:[
dirNames do:[:dN |
- dirBlock value:(p , dN).
- (self construct:dN)
- recursiveDirectoryContentsWithPrefix:(p , dN)
- filesDo:fileBlock directoriesDo:dirBlock
+ |subDir|
+
+ subDir := (self construct:dN).
+ (filterOrNil isNil or:[filterOrNil value:subDir]) ifTrue:[
+ dirBlock value:(p , dN).
+ subDir
+ recursiveDirectoryContentsWithPrefix:(p , dN)
+ filesDo:fileBlock directoriesDo:dirBlock
+ ].
].
].
@@ -4418,30 +4500,44 @@
on unix, an xterm is opened."
OperatingSystem isOSXlike ifTrue:[
- "/ I dont know yet how to tell the terminal to
- "/ go to a particular directory.
- "/ therefore, use the built in terminal
- VT100TerminalView openShellIn:self pathName.
- ^ self.
+ "/ I dont know yet how to tell the terminal to
+ "/ go to a particular directory.
+ "/ therefore, use the built in terminal
+ VT100TerminalView openShellIn:self pathName.
+ ^ self.
+ ].
+ "/ using the code below seems to close the window immediately
+ "/ at least on win7.
+ "/ use out own terminal, to make sure.
+ (OperatingSystem isMSWINDOWSlike
+ and:[OperatingSystem isWin7Like]) ifTrue:[
+ "/ I dont know yet how to tell the terminal to
+ "/ go to a particular directory.
+ "/ therefore, use the built in terminal
+ VT100TerminalView openShellIn:self pathName.
+ ^ self.
].
[
- |cmd|
-
- OperatingSystem isOSXlike ifTrue:[
- cmd := '/Applications/Utilities/Terminal.app/Contents/MacOS/Terminal '
- ] ifFalse:[
- OperatingSystem isMSWINDOWSlike ifTrue:[
- cmd := 'c:\windows\System32\cmd.exe'
- ] ifFalse:[
- "/ VT100TerminalView openShellIn:self pathName
- cmd := 'xterm'
- ]
- ].
- OperatingSystem
- executeCommand:cmd
- inDirectory:self pathName.
+ |cmd|
+
+ OperatingSystem isOSXlike ifTrue:[
+ cmd := '/Applications/Utilities/Terminal.app/Contents/MacOS/Terminal '
+ ] ifFalse:[
+ OperatingSystem isMSWINDOWSlike ifTrue:[
+ cmd := #('c:\windows\System32\cmd.exe')
+ ] ifFalse:[
+ "/ VT100TerminalView openShellIn:self pathName
+ cmd := 'xterm'
+ ]
+ ].
+ OperatingSystem
+ executeCommand:cmd
+ inDirectory:self pathName
+ showWindow:#default.
] fork
+
+ "Modified: / 18-10-2016 / 16:08:15 / cg"
! !
!Filename methodsFor:'printing & storing'!
--- a/Integer.st Tue Oct 25 12:31:42 2016 +0100
+++ b/Integer.st Tue Oct 25 12:35:02 2016 +0100
@@ -818,6 +818,7 @@
"Modified: 18.7.1996 / 12:26:38 / cg"
! !
+
!Integer class methodsFor:'prime numbers'!
flushPrimeCache
@@ -1195,25 +1196,9 @@
^ self == Integer
! !
+
!Integer methodsFor:'Compatibility-Dolphin'!
-& aNumber
- "return the bitwise-and of the receiver and the argument, anInteger.
- Same as bitAnd: - added for compatibility with Dolphin Smalltalk.
- Notice:
- PLEASE DO NOT USE & for integers in new code; it makes the code harder
- to understand, as it may be not obvious, whether a boolean-and a bitWise-and is intended.
- For integers, use bitAnd: to make the intention explicit.
- Also, consider using and: for booleans, which is does not evaluate the right part if the left is false."
-
- ^ self bitAnd:aNumber
-
- "
- 14 | 1
- 9 & 8
- "
-!
-
highWord
"return the high 16 bits of a 32 bit value"
@@ -1459,6 +1444,8 @@
"
! !
+
+
!Integer methodsFor:'bcd conversion'!
decodeFromBCD
@@ -4853,6 +4840,7 @@
"Created: / 09-01-2012 / 17:18:06 / cg"
! !
+
!Integer methodsFor:'special modulo arithmetic'!
add_32:anInteger
--- a/Method.st Tue Oct 25 12:31:42 2016 +0100
+++ b/Method.st Tue Oct 25 12:35:02 2016 +0100
@@ -1059,6 +1059,7 @@
"Modified (format): / 18-11-2011 / 14:47:06 / cg"
! !
+
!Method methodsFor:'accessing-visibility'!
isIgnored
@@ -2725,6 +2726,16 @@
^ self externalLibraryFunction notNil
!
+isForCompatibility
+ "returns true, if this method only used for compatibility
+ and should use only when porting foreign code but not otherwise"
+
+ |res|
+
+ ^ self package == #'stx:libcompat'
+ or:[(res := self resources) notNil and:[res includesKey:#compatibility]]
+!
+
isInvalid
"return true, if this method is not executable due to
a (re)-compilation error. Since invalidation is by patching the
@@ -3073,16 +3084,6 @@
"Created: / 9.11.1998 / 06:15:08 / cg"
!
-overrides: aMethod
- <resource: #obsolete>
-
- self obsoleteMethodWarning: 'Use overwrites: instead, stupid naming'.
- self overwrites: aMethod.
-
- "Modified: / 18-06-2009 / 12:15:53 / Jan Vrany <vranyj1@fel.cvut.cz>"
- "Modified: / 05-07-2012 / 10:52:38 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-!
-
overwrites:aMethod
|mth|
@@ -3760,6 +3761,7 @@
"Created: / 23-07-2012 / 11:16:36 / cg"
! !
+
!Method methodsFor:'source management'!
revisionInfo
--- a/NonPositionableExternalStream.st Tue Oct 25 12:31:42 2016 +0100
+++ b/NonPositionableExternalStream.st Tue Oct 25 12:35:02 2016 +0100
@@ -1,3 +1,5 @@
+"{ Encoding: utf8 }"
+
"
COPYRIGHT (c) 1989 by Claus Gittinger
All Rights Reserved
@@ -206,25 +208,6 @@
].
! !
-!NonPositionableExternalStream methodsFor:'closing'!
-
-close
- "Close the stream.
- No error if the stream is not open."
-
- |semasToSignal|
-
- self isOpen ifTrue:[
- "make sure, that no select is performed on closed file descriptors"
- semasToSignal := Processor disableFd:self fileHandle doSignal:false.
- super close.
- "tell the waiters that they must not wait any longer"
- semasToSignal do:[:eachSema|
- eachSema signalForAll.
- ].
- ].
-! !
-
!NonPositionableExternalStream methodsFor:'error handling'!
positionError
@@ -421,6 +404,23 @@
super storeOn:aStream
! !
+!NonPositionableExternalStream protectedMethodsFor:'private'!
+
+closeFile
+ |semasToSignal|
+
+ handle notNil ifTrue:[
+ "make sure, that no select is performed on closed file descriptors"
+ semasToSignal := Processor disableFd:self fileHandle doSignal:false.
+ super closeFile.
+
+ "tell the waiters that they must not wait any longer"
+ semasToSignal do:[:eachSema|
+ eachSema signalForAll.
+ ].
+ ].
+! !
+
!NonPositionableExternalStream methodsFor:'private'!
handleForStderr
@@ -549,12 +549,14 @@
]
].
- "first, wait to avoid blocking on the read.
- On end of stream or error, readWait will return"
+ handle notNil ifTrue:[
+ "first, wait to avoid blocking on the read.
+ On end of stream or error, readWait will return"
- self readWaitWithTimeoutMs:nil.
+ self readWaitWithTimeoutMs:nil.
+ ].
handle isNil ifTrue:[
- "we were closed while waiting - so we are at the end"
+ "we are closed or were closed while waiting - so we are at the end"
^ true.
].
^ super atEnd.
@@ -652,7 +654,11 @@
Redefined, to wait on pipes and sockets"
- self atEnd ifTrue:[^ nil].
+ self readWaitWithTimeoutMs:nil.
+ handle isNil ifTrue:[
+ "we were closed while waiting - so we are at the end"
+ ^ nil.
+ ].
^ super nextOrNil
!
@@ -670,7 +676,11 @@
Redefined, to wait on pipes and sockets"
- self atEnd ifTrue:[^ nil].
+ self readWaitWithTimeoutMs:nil.
+ handle isNil ifTrue:[
+ "we were closed while waiting - so we are at the end"
+ ^ nil.
+ ].
^ self peek
!
--- a/PCFilename.st Tue Oct 25 12:31:42 2016 +0100
+++ b/PCFilename.st Tue Oct 25 12:35:02 2016 +0100
@@ -1,3 +1,5 @@
+"{ Encoding: utf8 }"
+
"
COPYRIGHT (c) 1997 by eXept Software AG
All Rights Reserved
@@ -601,7 +603,7 @@
^ true.
].
- (self suffix asLowercase = 'bat') ifTrue:[
+ (#('bat' 'cmd') includes:self suffix asLowercase) ifTrue:[
^ (OperatingSystem isValidPath:osName)
and:[(OperatingSystem isDirectory:osName) not].
].
--- a/PipeStream.st Tue Oct 25 12:31:42 2016 +0100
+++ b/PipeStream.st Tue Oct 25 12:35:02 2016 +0100
@@ -489,7 +489,7 @@
!PipeStream methodsFor:'closing'!
-shutDown
+abortAndClose
"close the Stream and terminate the command"
self unregisterForFinalization.
@@ -506,6 +506,31 @@
self terminatePipeCommand.
!
+close
+ "low level close
+ This waits for the command to finish.
+ Use abortAndClose for a fast (nonBlocking) close."
+
+ handle notNil ifTrue:[
+ super close.
+ pid notNil ifTrue:[
+ "/ wait for the pipe-command to terminate.
+ self waitForPipeCommandWithTimeout:nil.
+ ].
+ ].
+
+ "Modified: / 12.9.1998 / 16:51:04 / cg"
+!
+
+shutDown
+ <resource: #obsolete>
+ "this is a historic leftover kept for backward compatibility.
+ The name collides wuth the same name in Socket, which does
+ not hard terminate the connection."
+
+ self abortAndClose.
+!
+
shutDownOutput
"signal to the pipestream's command, that no more data will be sent"
@@ -524,30 +549,7 @@
finalize
"redefined to avoid blocking in close."
- self shutDown
-! !
-
-!PipeStream protectedMethodsFor:'private'!
-
-closeFile
- "low level close
- This waits for the command to finish.
- Use shutDown for a fast (nonBlocking) close."
-
- handle notNil ifTrue:[
- super closeFile.
-"/ OperatingSystem isMSDOSlike ifTrue:[
-"/ self terminatePipeCommand.
-"/ ].
-
- handle := nil.
- pid notNil ifTrue:[
- "/ wait for the pipe-command to terminate.
- self waitForPipeCommandWithTimeout:nil.
- ].
- ].
-
- "Modified: / 12.9.1998 / 16:51:04 / cg"
+ self abortAndClose
! !
!PipeStream methodsFor:'private'!
--- a/Process.st Tue Oct 25 12:31:42 2016 +0100
+++ b/Process.st Tue Oct 25 12:35:02 2016 +0100
@@ -2195,7 +2195,8 @@
!
threadVariableValueOf:aKey
- "return the value of a thread local variable, or nil if no such variable exists"
+ "return the value of a thread local variable,
+ or nil if no such variable exists"
^ self environmentAt:aKey ifAbsent:nil
@@ -2236,42 +2237,46 @@
|var oldValue result|
environment isNil ifTrue:[
- environment := IdentityDictionary new
+ environment := IdentityDictionary new
].
var := environment at:variableNameSymbol ifAbsent:nil.
var isNil ifTrue:[
- var := ValueHolder new.
- environment at:variableNameSymbol put:var.
+ var := ValueHolder new.
+ environment at:variableNameSymbol put:var.
].
oldValue := var value.
[
- var value:aValue.
- result := aBlock value.
+ var value:aValue.
+ result := aBlock value.
] ensure:[
- oldValue isNil
- ifTrue:[ environment removeKey:variableNameSymbol]
- ifFalse:[ var value:oldValue ]
+ oldValue isNil
+ ifTrue:[ environment removeKey:variableNameSymbol]
+ ifFalse:[ var value:oldValue ]
].
^ result
"
|printIt|
- printIt := [ Transcript showCR:'foo is now ',(Processor activeProcess threadVariableValueOf:#foo) printString ].
+ printIt := [
+ Transcript
+ showCR:'foo is now ',
+ (Processor activeProcess threadVariableValueOf:#foo) printString
+ ].
Processor activeProcess
- withThreadVariable:#foo
- boundTo:1234
- do:[
- printIt value.
- Processor activeProcess
- withThreadVariable:#foo
- boundTo:2345
- do:[
- printIt value
- ].
- ]
+ withThreadVariable:#foo
+ boundTo:1234
+ do:[
+ printIt value.
+ Processor activeProcess
+ withThreadVariable:#foo
+ boundTo:2345
+ do:[
+ printIt value
+ ].
+ ]
"
! !
--- a/String.st Tue Oct 25 12:31:42 2016 +0100
+++ b/String.st Tue Oct 25 12:35:02 2016 +0100
@@ -519,6 +519,8 @@
! !
+
+
!String class methodsFor:'queries'!
defaultPlatformClass
@@ -539,6 +541,11 @@
! !
+
+
+
+
+
!String methodsFor:'accessing'!
at:index
@@ -2412,30 +2419,6 @@
!String methodsFor:'converting'!
-asArrayOfSubstrings
- "Answer an array with all the substrings of the receiver separated by
- separator characters (space, cr, tab, linefeed, formfeed, etc).
- CG: This is ported Squeak code, and I am not sure if it is more efficient than
- the inherited one... after all: who added it anyway ?"
-
- | substrings start end stop |
-
- substrings := OrderedCollection new.
- start := 1.
- stop := self size.
- [start <= stop] whileTrue: [
- (self at: start) isSeparator ifFalse: [
- end := start + 1.
- [end <= stop and: [(self at: end) isSeparator not]]
- whileTrue: [end := end + 1].
- substrings add: (self copyFrom: start to: end - 1).
- start := end - 1
- ].
- start := start + 1
- ].
- ^ substrings asArray
-!
-
asAsciiZ
"if the receiver does not end with a 0-valued character, return a copy of it,
with an additional 0-character. Otherwise return the receiver. This is sometimes
@@ -4276,6 +4259,7 @@
^ super reverse
! !
+
!String methodsFor:'substring searching'!
indexOfSubCollection:aSubString startingAt:startIndex ifAbsent:exceptionValue caseSensitive:caseSensitive
@@ -4952,6 +4936,7 @@
! !
+
!String class methodsFor:'documentation'!
version
--- a/Win32OperatingSystem.st Tue Oct 25 12:31:42 2016 +0100
+++ b/Win32OperatingSystem.st Tue Oct 25 12:35:02 2016 +0100
@@ -18,8 +18,8 @@
AbstractOperatingSystem subclass:#Win32OperatingSystem
instanceVariableNames:''
- classVariableNames:'Initialized HostName DomainName CurrentDirectory LastOsTimeLow
- LastOsTimeHi LastTimeInfoIsLocal LastTimeInfo'
+ classVariableNames:'CurrentDirectory DomainName HostName Initialized LastOsTimeHi
+ LastOsTimeLow LastTimeInfo LastTimeInfoIsLocal'
poolDictionaries:'Win32Constants'
category:'OS-Windows'
!
@@ -3675,67 +3675,71 @@
!
exec:aCommandPath withArguments:argString environment:environment fileDescriptors:fdArray fork:doFork
- newPgrp:newPgrp inDirectory:aDirectory
- showWindow:showWindowBooleanOrNil
+ newPgrp:newPgrp inDirectory:aDirectory
+ showWindow:showWindowBooleanOrNil
"Internal lowLevel entry for combined fork & exec for WIN32
If fork is false (chain a command):
- execute the OS command specified by the argument, aCommandPath, with
- arguments in argArray (no arguments, if nil).
- If successful, this method does not return and smalltalk is gone.
- If not successful, it does return.
- Normal use is with forkForCommand.
+ execute the OS command specified by the argument, aCommandPath, with
+ arguments in argArray (no arguments, if nil).
+ If successful, this method does not return and smalltalk is gone.
+ If not successful, it does return.
+ Normal use is with forkForCommand.
If fork is true (subprocess command execution):
- fork a child to do the above.
- The Win32ProcessHandle of the child process is returned; nil if the fork failed.
+ fork a child to do the above.
+ The Win32ProcessHandle of the child process is returned; nil if the fork failed.
fdArray contains the filedescriptors, to be used for the child (if fork is true).
- fdArray[1] = 15 -> use fd 15 as stdin.
- If an element of the array is set to nil, the corresponding filedescriptor
- will be closed for the child.
- fdArray[0] == StdIn for child
- fdArray[1] == StdOut for child
- fdArray[2] == StdErr for child
+ fdArray[1] = 15 -> use fd 15 as stdin.
+ If an element of the array is set to nil, the corresponding filedescriptor
+ will be closed for the child.
+ fdArray[0] == StdIn for child
+ fdArray[1] == StdOut for child
+ fdArray[2] == StdErr for child
NOTE that in WIN32 the fds are HANDLES.
If newPgrp is true, the subprocess will be established in a new process group.
- The processgroup will be equal to id.
- newPgrp is not used on WIN32 and VMS systems.
+ The processgroup will be equal to id.
+ newPgrp is not used on WIN32 and VMS systems.
showWindowOrBoolean may be:
- true - a window is shown on start of the command
- false - the command window is hidden
- nil - the nCmdShown parameter of the commans's winmain function determins,
- if a window is shown."
+ true - a window is shown on start of the command
+ false - the command window is hidden
+ nil - the nCmdShown parameter of the commans's winmain function determins,
+ if a window is shown.
+ #default
+ - same as nil
+ "
|dirPath rslt|
aDirectory notNil ifTrue:[
- dirPath := aDirectory asFilename asAbsoluteFilename osNameForDirectory.
- (dirPath endsWith:':') ifTrue:[
- dirPath := dirPath , '\'.
- ].
+ dirPath := aDirectory asFilename asAbsoluteFilename osNameForDirectory.
+ (dirPath endsWith:':') ifTrue:[
+ dirPath := dirPath , '\'.
+ ].
].
rslt := self
- primExec:aCommandPath
- commandLine:argString
- fileDescriptors:fdArray
- fork:doFork
- newPgrp:newPgrp
- inPath:dirPath
- createFlags:nil
- inheritHandles:true
- showWindow:showWindowBooleanOrNil.
+ primExec:aCommandPath
+ commandLine:argString
+ fileDescriptors:fdArray
+ fork:doFork
+ newPgrp:newPgrp
+ inPath:dirPath
+ createFlags:nil
+ inheritHandles:true
+ showWindow:showWindowBooleanOrNil.
"/ 'created ' print. cmdLine print. ' -> ' print. rslt printCR.
^ rslt
- "Modified: / 31.1.1998 / 10:54:24 / md"
- "Modified: / 15.5.1999 / 18:07:51 / cg"
+ "Modified: / 31-01-1998 / 10:54:24 / md"
+ "Modified: / 15-05-1999 / 18:07:51 / cg"
+ "Modified (comment): / 18-10-2016 / 16:00:26 / cg"
!
getStatusOfProcess:aProcessId
@@ -3859,15 +3863,18 @@
!
primExec:commandPath commandLine:commandLine fileDescriptors:fdArray fork:doFork newPgrp:newPgrp
- inPath:dirName createFlags:flagsOrNil inheritHandles:inheritHandles
- showWindow:showWindowBooleanOrNil
+ inPath:dirName createFlags:flagsOrNil inheritHandles:inheritHandles
+ showWindow:showWindowBooleanOrNil
"Internal lowLevel entry for combined fork & exec for WIN32
showWindowBooleanOrNil may be:
- true - a window is shown on start of the command
- false - the command window is hidden
- nil - the nCmdShown parameter of the commans's winmain function determins,
- if a window is shown."
+ true - a window is shown on start of the command
+ false - the command window is hidden
+ nil - the nCmdShown parameter of the commans's winmain function determins,
+ if a window is shown.
+ #default
+ - same as nil
+ "
|handle commandPathUni16 commandLineUni16 dirNameUni16|
@@ -3878,13 +3885,13 @@
dirNameUni16 := dirName.
commandPathUni16 notNil ifTrue:[
- commandPathUni16 := commandPathUni16 asUnicode16String.
+ commandPathUni16 := commandPathUni16 asUnicode16String.
].
commandLineUni16 notNil ifTrue:[
- commandLineUni16 := commandLineUni16 asUnicode16String.
+ commandLineUni16 := commandLineUni16 asUnicode16String.
].
dirNameUni16 notNil ifTrue:[
- dirNameUni16 := dirNameUni16 asUnicode16String.
+ dirNameUni16 := dirNameUni16 asUnicode16String.
].
@@ -3922,280 +3929,280 @@
SECURITY_DESCRIPTOR securityDescriptor;
if ((__isUnicode16String(commandPathUni16) || (commandPathUni16 == nil)) && __isUnicode16String(commandLineUni16)) {
- HANDLE stdinHandle = NULL;
- HANDLE stdoutHandle = NULL;
- HANDLE stderrHandle = NULL;
- int mustClose_stdinHandle = 0;
- int mustClose_stdoutHandle = 0;
- int mustClose_stderrHandle = 0;
-
- /*
- * terminate the multi byte strings
- */
- // #commandPathUni16
- if (commandPathUni16 != nil) {
- l = __unicode16StringSize(commandPathUni16);
- if (l >= 4096) { // >= need 1 space for terminator
- #ifdef PROCESSDEBUGWIN32
- console_fprintf(stderr, "argument #commandPathUni16 is to long\n");
- #endif
- RETURN(nil);
- }
- for (i = 0; i < l; i++) {
- cmdPathW[i] = __unicode16StringVal(commandPathUni16)[i];
- }
- cmdPathW[i] = 0; // set terminator
- cmdPathWP = &cmdPathW[0];
- }
-
- // commandLineUni16
- l = __unicode16StringSize(commandLineUni16);
- if (l >= 4096) { // >= need 1 space for terminator
- #ifdef PROCESSDEBUGWIN32
- console_fprintf(stderr, "argument #commandLineUni16 is to long\n");
- #endif
- RETURN(nil);
- }
- for (i = 0; i < l; i++) {
- cmdLineW[i] = __unicode16StringVal(commandLineUni16)[i];
- }
- cmdLineW[i] = 0; // set terminator
- cmdLineWP = &cmdLineW[0];
-
- // #dirNameUni16
- if (__isUnicode16String(dirNameUni16)) {
- l = __unicode16StringSize(dirNameUni16);
- if (l >= 4096) { // >= need 1 space for terminator
- #ifdef PROCESSDEBUGWIN32
- console_fprintf(stderr, "argument #dirNameUni16 is to long\n");
- #endif
- RETURN(nil);
- }
- for (i = 0; i < l; i++) {
- dirNameW[i] = __unicode16StringVal(dirNameUni16)[i];
- }
- dirNameW[i] = 0; // set terminator
- dirNameWP = &dirNameW[0];
- }
-
- /*
- * create descriptors as req'd
- */
- memset(&securityAttributes, 0, sizeof(securityAttributes));
- securityAttributes.nLength = sizeof(securityAttributes);
- securityAttributes.bInheritHandle = (inheritHandles == true) ? TRUE : FALSE;
-
- InitializeSecurityDescriptor(&securityDescriptor, SECURITY_DESCRIPTOR_REVISION);
- SetSecurityDescriptorDacl(&securityDescriptor, -1, 0, 0);
-
- securityAttributes.lpSecurityDescriptor = &securityDescriptor;
- memset(&lppiProcInfo, 0, sizeof (lppiProcInfo));
-
- memset(&lpsiStartInfo, 0, sizeof(lpsiStartInfo));
- lpsiStartInfo.cb = sizeof(lpsiStartInfo);
- lpsiStartInfo.lpReserved = NULL;
- lpsiStartInfo.lpDesktop = NULL;
- lpsiStartInfo.lpTitle = NULL;
- lpsiStartInfo.dwX = 0;
- lpsiStartInfo.dwY = 0;
- lpsiStartInfo.dwXSize = 100;
- lpsiStartInfo.dwYSize = 100;
- lpsiStartInfo.dwXCountChars = 0;
- lpsiStartInfo.dwYCountChars = 0;
- lpsiStartInfo.dwFillAttribute = 0;
- lpsiStartInfo.dwFlags = STARTF_USESTDHANDLES /*| STARTF_USEPOSITION*/;
- if (showWindowBooleanOrNil != nil) {
- lpsiStartInfo.dwFlags |= STARTF_USESHOWWINDOW;
- lpsiStartInfo.wShowWindow = showWindowBooleanOrNil == true ? SW_SHOWNORMAL : SW_HIDE;
- }
- lpsiStartInfo.cbReserved2 = 0;
- lpsiStartInfo.lpReserved2 = NULL;
- lpsiStartInfo.hStdInput = NULL;
- lpsiStartInfo.hStdOutput = NULL;
- lpsiStartInfo.hStdError = NULL;
-
- /*
- * set create process flags
- * if the flags arg is nil, use common defaults;
- * if non-nil, it must be a positive integer containing the fdwCreate bits.
- */
- if (flagsOrNil != nil) {
- fdwCreate = __longIntVal(flagsOrNil);
- } else {
- fdwCreate = CREATE_NEW_CONSOLE; //|IDLE_PRIORITY_CLASS; // DETACHED_PROCESS; // NORMAL_PRIORITY_CLASS ;
- if (newPgrp == true) {
- fdwCreate |= CREATE_NEW_PROCESS_GROUP;
- }
- fdwCreate |= CREATE_DEFAULT_ERROR_MODE;
- }
-
- if (fdArray == nil) {
- stdinHandle = (HANDLE) _get_osfhandle (0);
- stdoutHandle = (HANDLE) _get_osfhandle (1);
- stderrHandle = (HANDLE) _get_osfhandle (2);
- } else if (__isArrayLike(fdArray) && (__arraySize(fdArray) >= 3)) {
- if (__ArrayInstPtr(fdArray)->a_element[0] != nil) {
- if (__isExternalAddressLike(__ArrayInstPtr(fdArray)->a_element[0])) {
- stdinHandle = _HANDLEVal(__ArrayInstPtr(fdArray)->a_element[0]);
- } else {
- stdinHandle = (HANDLE) _get_osfhandle (__intVal(__ArrayInstPtr(fdArray)->a_element[0]));
- }
- }
- if (__ArrayInstPtr(fdArray)->a_element[1] != nil) {
- if (__isExternalAddressLike(__ArrayInstPtr(fdArray)->a_element[1])) {
- stdoutHandle = _HANDLEVal(__ArrayInstPtr(fdArray)->a_element[1]);
- } else {
- stdoutHandle = (HANDLE) _get_osfhandle (__intVal(__ArrayInstPtr(fdArray)->a_element[1]));
- }
- }
- if (__ArrayInstPtr(fdArray)->a_element[2] != nil) {
- if (__isExternalAddressLike(__ArrayInstPtr(fdArray)->a_element[2])) {
- stderrHandle = _HANDLEVal(__ArrayInstPtr(fdArray)->a_element[2]);
- } else {
- stderrHandle = (HANDLE) _get_osfhandle (__intVal(__ArrayInstPtr(fdArray)->a_element[2]));
- }
- }
- } else {
- console_fprintf(stderr, "Win32OS [warning]: bad fd arg in createProcess\n");
- }
+ HANDLE stdinHandle = NULL;
+ HANDLE stdoutHandle = NULL;
+ HANDLE stderrHandle = NULL;
+ int mustClose_stdinHandle = 0;
+ int mustClose_stdoutHandle = 0;
+ int mustClose_stderrHandle = 0;
+
+ /*
+ * terminate the multi byte strings
+ */
+ // #commandPathUni16
+ if (commandPathUni16 != nil) {
+ l = __unicode16StringSize(commandPathUni16);
+ if (l >= 4096) { // >= need 1 space for terminator
+ #ifdef PROCESSDEBUGWIN32
+ console_fprintf(stderr, "argument #commandPathUni16 is to long\n");
+ #endif
+ RETURN(nil);
+ }
+ for (i = 0; i < l; i++) {
+ cmdPathW[i] = __unicode16StringVal(commandPathUni16)[i];
+ }
+ cmdPathW[i] = 0; // set terminator
+ cmdPathWP = &cmdPathW[0];
+ }
+
+ // commandLineUni16
+ l = __unicode16StringSize(commandLineUni16);
+ if (l >= 4096) { // >= need 1 space for terminator
+ #ifdef PROCESSDEBUGWIN32
+ console_fprintf(stderr, "argument #commandLineUni16 is to long\n");
+ #endif
+ RETURN(nil);
+ }
+ for (i = 0; i < l; i++) {
+ cmdLineW[i] = __unicode16StringVal(commandLineUni16)[i];
+ }
+ cmdLineW[i] = 0; // set terminator
+ cmdLineWP = &cmdLineW[0];
+
+ // #dirNameUni16
+ if (__isUnicode16String(dirNameUni16)) {
+ l = __unicode16StringSize(dirNameUni16);
+ if (l >= 4096) { // >= need 1 space for terminator
+ #ifdef PROCESSDEBUGWIN32
+ console_fprintf(stderr, "argument #dirNameUni16 is to long\n");
+ #endif
+ RETURN(nil);
+ }
+ for (i = 0; i < l; i++) {
+ dirNameW[i] = __unicode16StringVal(dirNameUni16)[i];
+ }
+ dirNameW[i] = 0; // set terminator
+ dirNameWP = &dirNameW[0];
+ }
+
+ /*
+ * create descriptors as req'd
+ */
+ memset(&securityAttributes, 0, sizeof(securityAttributes));
+ securityAttributes.nLength = sizeof(securityAttributes);
+ securityAttributes.bInheritHandle = (inheritHandles == true) ? TRUE : FALSE;
+
+ InitializeSecurityDescriptor(&securityDescriptor, SECURITY_DESCRIPTOR_REVISION);
+ SetSecurityDescriptorDacl(&securityDescriptor, -1, 0, 0);
+
+ securityAttributes.lpSecurityDescriptor = &securityDescriptor;
+ memset(&lppiProcInfo, 0, sizeof (lppiProcInfo));
+
+ memset(&lpsiStartInfo, 0, sizeof(lpsiStartInfo));
+ lpsiStartInfo.cb = sizeof(lpsiStartInfo);
+ lpsiStartInfo.lpReserved = NULL;
+ lpsiStartInfo.lpDesktop = NULL;
+ lpsiStartInfo.lpTitle = NULL;
+ lpsiStartInfo.dwX = 0;
+ lpsiStartInfo.dwY = 0;
+ lpsiStartInfo.dwXSize = 100;
+ lpsiStartInfo.dwYSize = 100;
+ lpsiStartInfo.dwXCountChars = 0;
+ lpsiStartInfo.dwYCountChars = 0;
+ lpsiStartInfo.dwFillAttribute = 0;
+ lpsiStartInfo.dwFlags = STARTF_USESTDHANDLES /*| STARTF_USEPOSITION*/;
+ if ((showWindowBooleanOrNil != nil) && (showWindowBooleanOrNil != @symbol(default))) {
+ lpsiStartInfo.dwFlags |= STARTF_USESHOWWINDOW;
+ lpsiStartInfo.wShowWindow = showWindowBooleanOrNil == true ? SW_SHOWNORMAL : SW_HIDE;
+ }
+ lpsiStartInfo.cbReserved2 = 0;
+ lpsiStartInfo.lpReserved2 = NULL;
+ lpsiStartInfo.hStdInput = NULL;
+ lpsiStartInfo.hStdOutput = NULL;
+ lpsiStartInfo.hStdError = NULL;
+
+ /*
+ * set create process flags
+ * if the flags arg is nil, use common defaults;
+ * if non-nil, it must be a positive integer containing the fdwCreate bits.
+ */
+ if (flagsOrNil != nil) {
+ fdwCreate = __longIntVal(flagsOrNil);
+ } else {
+ fdwCreate = CREATE_NEW_CONSOLE; //|IDLE_PRIORITY_CLASS; // DETACHED_PROCESS; // NORMAL_PRIORITY_CLASS ;
+ if (newPgrp == true) {
+ fdwCreate |= CREATE_NEW_PROCESS_GROUP;
+ }
+ fdwCreate |= CREATE_DEFAULT_ERROR_MODE;
+ }
+
+ if (fdArray == nil) {
+ stdinHandle = (HANDLE) _get_osfhandle (0);
+ stdoutHandle = (HANDLE) _get_osfhandle (1);
+ stderrHandle = (HANDLE) _get_osfhandle (2);
+ } else if (__isArrayLike(fdArray) && (__arraySize(fdArray) >= 3)) {
+ if (__ArrayInstPtr(fdArray)->a_element[0] != nil) {
+ if (__isExternalAddressLike(__ArrayInstPtr(fdArray)->a_element[0])) {
+ stdinHandle = _HANDLEVal(__ArrayInstPtr(fdArray)->a_element[0]);
+ } else {
+ stdinHandle = (HANDLE) _get_osfhandle (__intVal(__ArrayInstPtr(fdArray)->a_element[0]));
+ }
+ }
+ if (__ArrayInstPtr(fdArray)->a_element[1] != nil) {
+ if (__isExternalAddressLike(__ArrayInstPtr(fdArray)->a_element[1])) {
+ stdoutHandle = _HANDLEVal(__ArrayInstPtr(fdArray)->a_element[1]);
+ } else {
+ stdoutHandle = (HANDLE) _get_osfhandle (__intVal(__ArrayInstPtr(fdArray)->a_element[1]));
+ }
+ }
+ if (__ArrayInstPtr(fdArray)->a_element[2] != nil) {
+ if (__isExternalAddressLike(__ArrayInstPtr(fdArray)->a_element[2])) {
+ stderrHandle = _HANDLEVal(__ArrayInstPtr(fdArray)->a_element[2]);
+ } else {
+ stderrHandle = (HANDLE) _get_osfhandle (__intVal(__ArrayInstPtr(fdArray)->a_element[2]));
+ }
+ }
+ } else {
+ console_fprintf(stderr, "Win32OS [warning]: bad fd arg in createProcess\n");
+ }
#if defined(PROCESSDEBUGWIN32)
- console_fprintf(stderr, "stdin %x\n", stdinHandle);
- console_fprintf(stderr, "stdout %x\n", stdoutHandle);
- console_fprintf(stderr, "stderr %x\n", stderrHandle);
-#endif
-
- {
- HANDLE childHandle;
- int sameHandle = (stdoutHandle == stderrHandle);
-
- // these MUST be inheritable!
- if (stdinHandle) {
+ console_fprintf(stderr, "stdin %x\n", stdinHandle);
+ console_fprintf(stderr, "stdout %x\n", stdoutHandle);
+ console_fprintf(stderr, "stderr %x\n", stderrHandle);
+#endif
+
+ {
+ HANDLE childHandle;
+ int sameHandle = (stdoutHandle == stderrHandle);
+
+ // these MUST be inheritable!
+ if (stdinHandle) {
#if 0
- if (SetHandleInformation(stdinHandle, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT)) {
- // good
- } else {
- console_fprintf(stderr, "Win32OS [warning]: SetHandleInformation failed in createProcess\n");
- }
-#else
- if (DuplicateHandle(GetCurrentProcess(), stdinHandle, GetCurrentProcess(),
- &childHandle, 0, TRUE, DUPLICATE_SAME_ACCESS)) {
- stdinHandle = childHandle;
- mustClose_stdinHandle = 1;
- } else {
- console_fprintf(stderr, "Win32OS [warning]: duplicateHandle failed in createProcess\n");
- }
-#endif
- }
- if (stdoutHandle) {
+ if (SetHandleInformation(stdinHandle, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT)) {
+ // good
+ } else {
+ console_fprintf(stderr, "Win32OS [warning]: SetHandleInformation failed in createProcess\n");
+ }
+#else
+ if (DuplicateHandle(GetCurrentProcess(), stdinHandle, GetCurrentProcess(),
+ &childHandle, 0, TRUE, DUPLICATE_SAME_ACCESS)) {
+ stdinHandle = childHandle;
+ mustClose_stdinHandle = 1;
+ } else {
+ console_fprintf(stderr, "Win32OS [warning]: duplicateHandle failed in createProcess\n");
+ }
+#endif
+ }
+ if (stdoutHandle) {
#if 0
- if (SetHandleInformation(stdoutHandle, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT)) {
- // good
- } else {
- console_fprintf(stderr, "Win32OS [warning]: SetHandleInformation failed in createProcess\n");
- }
-#else
- if (DuplicateHandle(GetCurrentProcess(), stdoutHandle, GetCurrentProcess(),
- &childHandle, 0, TRUE, DUPLICATE_SAME_ACCESS)) {
- stdoutHandle = childHandle;
- mustClose_stdoutHandle = 1;
- } else {
- console_fprintf(stderr, "Win32OS [warning]: duplicateHandle failed in createProcess\n");
- }
-#endif
- }
- if (stderrHandle) {
- if (sameHandle) {
- stderrHandle = stdoutHandle;
- } else {
+ if (SetHandleInformation(stdoutHandle, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT)) {
+ // good
+ } else {
+ console_fprintf(stderr, "Win32OS [warning]: SetHandleInformation failed in createProcess\n");
+ }
+#else
+ if (DuplicateHandle(GetCurrentProcess(), stdoutHandle, GetCurrentProcess(),
+ &childHandle, 0, TRUE, DUPLICATE_SAME_ACCESS)) {
+ stdoutHandle = childHandle;
+ mustClose_stdoutHandle = 1;
+ } else {
+ console_fprintf(stderr, "Win32OS [warning]: duplicateHandle failed in createProcess\n");
+ }
+#endif
+ }
+ if (stderrHandle) {
+ if (sameHandle) {
+ stderrHandle = stdoutHandle;
+ } else {
#if 0
- if (SetHandleInformation(stderrHandle, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT)) {
- // good
- } else {
- console_fprintf(stderr, "Win32OS [warning]: SetHandleInformation failed in createProcess\n");
- }
-#else
- if (DuplicateHandle(GetCurrentProcess(), stderrHandle, GetCurrentProcess(),
- &childHandle, 0, TRUE, DUPLICATE_SAME_ACCESS)) {
- stderrHandle = childHandle;
- mustClose_stderrHandle = 1;
- } else {
- console_fprintf(stderr, "Win32OS [warning]: duplicateHandle failed in createProcess\n");
- }
-#endif
- }
- }
- }
- lpsiStartInfo.hStdInput = stdinHandle;
- lpsiStartInfo.hStdOutput = stdoutHandle;
- lpsiStartInfo.hStdError = stderrHandle;
-
- if (doFork == true) {
+ if (SetHandleInformation(stderrHandle, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT)) {
+ // good
+ } else {
+ console_fprintf(stderr, "Win32OS [warning]: SetHandleInformation failed in createProcess\n");
+ }
+#else
+ if (DuplicateHandle(GetCurrentProcess(), stderrHandle, GetCurrentProcess(),
+ &childHandle, 0, TRUE, DUPLICATE_SAME_ACCESS)) {
+ stderrHandle = childHandle;
+ mustClose_stderrHandle = 1;
+ } else {
+ console_fprintf(stderr, "Win32OS [warning]: duplicateHandle failed in createProcess\n");
+ }
+#endif
+ }
+ }
+ }
+ lpsiStartInfo.hStdInput = stdinHandle;
+ lpsiStartInfo.hStdOutput = stdoutHandle;
+ lpsiStartInfo.hStdError = stderrHandle;
+
+ if (doFork == true) {
#ifdef PROCESSDEBUGWIN32
- console_fprintf(stderr, "create process cmdPath:<%s> cmdLine:<%s> in <%s>\n", cmdPath, cmdLine, dir);
-#endif
- if (CreateProcessW( cmdPathWP,
- cmdLineWP,
- &securityAttributes, NULL /* &securityAttributes */,
- securityAttributes.bInheritHandle, /* inherit handles */
- fdwCreate | CREATE_SUSPENDED, /* resume after setting affinity */
- NULL, /* env */
- dirNameWP,
- &lpsiStartInfo,
- &lppiProcInfo ))
- {
- DWORD_PTR processAffinityMask, systemAffinityMask;
-
- /*
- * Process was created suspended, now set the affinity mask
- * to any processor, and resume the processes main thread.
- * (librun/process.s limited the affinity to a single processor).
- */
- GetProcessAffinityMask(lppiProcInfo.hProcess, &processAffinityMask, &systemAffinityMask);
- SetProcessAffinityMask(lppiProcInfo.hProcess, systemAffinityMask);
- if ((fdwCreate & CREATE_SUSPENDED) == 0) {
- ResumeThread(lppiProcInfo.hThread);
- }
- CloseHandle(lppiProcInfo.hThread);
+ console_fprintf(stderr, "create process cmdPath:<%s> cmdLine:<%s> in <%s>\n", cmdPath, cmdLine, dir);
+#endif
+ if (CreateProcessW( cmdPathWP,
+ cmdLineWP,
+ &securityAttributes, NULL /* &securityAttributes */,
+ securityAttributes.bInheritHandle, /* inherit handles */
+ fdwCreate | CREATE_SUSPENDED, /* resume after setting affinity */
+ NULL, /* env */
+ dirNameWP,
+ &lpsiStartInfo,
+ &lppiProcInfo ))
+ {
+ DWORD_PTR processAffinityMask, systemAffinityMask;
+
+ /*
+ * Process was created suspended, now set the affinity mask
+ * to any processor, and resume the processes main thread.
+ * (librun/process.s limited the affinity to a single processor).
+ */
+ GetProcessAffinityMask(lppiProcInfo.hProcess, &processAffinityMask, &systemAffinityMask);
+ SetProcessAffinityMask(lppiProcInfo.hProcess, systemAffinityMask);
+ if ((fdwCreate & CREATE_SUSPENDED) == 0) {
+ ResumeThread(lppiProcInfo.hThread);
+ }
+ CloseHandle(lppiProcInfo.hThread);
#if 0
- // only works with real console handles
- {
- // change the child's stdIn (console) mode
- DWORD mode = 0;
-
- if (! GetConsoleMode(stdinHandle, &mode)) {
- console_fprintf(stderr, "Win32OS [warning]: GetConsoleMode failed in createProcess\n");
- }
- if (! SetConsoleMode(stdinHandle, mode & (~ENABLE_ECHO_INPUT))){
- console_fprintf(stderr, "Win32OS [warning]: SetConsoleMode failed in createProcess\n");
- }
- }
-#endif
- if (mustClose_stdinHandle) {
- CloseHandle(stdinHandle);
- }
- if (mustClose_stdoutHandle) {
- CloseHandle(stdoutHandle);
- }
- if (mustClose_stderrHandle) {
- CloseHandle(stderrHandle);
- }
+ // only works with real console handles
+ {
+ // change the child's stdIn (console) mode
+ DWORD mode = 0;
+
+ if (! GetConsoleMode(stdinHandle, &mode)) {
+ console_fprintf(stderr, "Win32OS [warning]: GetConsoleMode failed in createProcess\n");
+ }
+ if (! SetConsoleMode(stdinHandle, mode & (~ENABLE_ECHO_INPUT))){
+ console_fprintf(stderr, "Win32OS [warning]: SetConsoleMode failed in createProcess\n");
+ }
+ }
+#endif
+ if (mustClose_stdinHandle) {
+ CloseHandle(stdinHandle);
+ }
+ if (mustClose_stdoutHandle) {
+ CloseHandle(stdoutHandle);
+ }
+ if (mustClose_stderrHandle) {
+ CloseHandle(stderrHandle);
+ }
#ifdef PROCESSDEBUGWIN32
- console_fprintf(stderr, "created process hProcess=%x\n", lppiProcInfo.hProcess);
-#endif
-
- __externalAddressVal(handle) = lppiProcInfo.hProcess;
- ((struct __Win32OperatingSystem__Win32ProcessHandle_struct *)(handle))->pid = __mkSmallInteger(lppiProcInfo.dwProcessId);
- RETURN (handle);
- }
+ console_fprintf(stderr, "created process hProcess=%x\n", lppiProcInfo.hProcess);
+#endif
+
+ __externalAddressVal(handle) = lppiProcInfo.hProcess;
+ ((struct __Win32OperatingSystem__Win32ProcessHandle_struct *)(handle))->pid = __mkSmallInteger(lppiProcInfo.dwProcessId);
+ RETURN (handle);
+ }
#ifdef PROCESSDEBUGWIN32
- console_fprintf(stderr, "created process error %d\n", GetLastError());
-#endif
- RETURN (nil);
- } else {
- ; /* should never be called that way */
- }
+ console_fprintf(stderr, "created process error %d\n", GetLastError());
+#endif
+ RETURN (nil);
+ } else {
+ ; /* should never be called that way */
+ }
}
%}.
"
@@ -4205,6 +4212,8 @@
or not supported by OS
"
^ self primitiveFailed
+
+ "Modified: / 18-10-2016 / 16:00:03 / cg"
!
shellExecute:hwndArg lpOperation:lpOperationArg lpFile:lpFileArg lpParameters:lpParametersArg lpDirectory:lpDirectoryArg nShowCmd:nShowCmd