diff -r f9628eddef1f -r e73c204b9f1e Win32OperatingSystem.st --- a/Win32OperatingSystem.st Tue Dec 11 18:10:28 2001 +0100 +++ b/Win32OperatingSystem.st Tue Dec 11 18:43:56 2001 +0100 @@ -44,6 +44,20 @@ privateIn:Win32OperatingSystem ! +OSFileHandle subclass:#Win32FILEHandle + instanceVariableNames:'' + classVariableNames:'' + poolDictionaries:'' + privateIn:Win32OperatingSystem +! + +OSFileHandle subclass:#Win32Handle + instanceVariableNames:'' + classVariableNames:'' + poolDictionaries:'' + privateIn:Win32OperatingSystem +! + !Win32OperatingSystem primitiveDefinitions! %{ @@ -1173,7 +1187,7 @@ case ERROR_INVALID_HANDLE: sym = @symbol(ERROR_INVALID_HANDLE); - typ = @symbol(invalidArgumentSignal); + typ = @symbol(invalidArgumentsSignal); break; case ERROR_NOT_ENOUGH_MEMORY: @@ -1188,12 +1202,12 @@ case ERROR_INVALID_DATA: sym = @symbol(ERROR_INVALID_DATA); - typ = @symbol(invalidArgumentSignal); + typ = @symbol(invalidArgumentsSignal); break; case ERROR_INVALID_NAME: sym = @symbol(ERROR_INVALID_NAME); - typ = @symbol(invalidArgumentSignal); + typ = @symbol(invalidArgumentsSignal); break; case ERROR_ARENA_TRASHED: @@ -1252,7 +1266,7 @@ case ERROR_INVALID_PARAMETER: sym = @symbol(ERROR_INVALID_PARAMETER); - typ = @symbol(invalidArgumentSignal); + typ = @symbol(invalidArgumentsSignal); break; case ERROR_NET_WRITE_FAULT: @@ -1297,7 +1311,7 @@ case ERROR_INVALID_DRIVE: sym = @symbol(ERROR_INVALID_DRIVE); - typ = @symbol(invalidArgumentSignal); + typ = @symbol(invalidArgumentsSignal); break; case ERROR_WRONG_DISK: @@ -1307,7 +1321,7 @@ case ERROR_CURRENT_DIRECTORY: sym = @symbol(ERROR_CURRENT_DIRECTORY); - typ = @symbol(invalidArgumentSignal); + typ = @symbol(invalidArgumentsSignal); break; /* @@ -1331,7 +1345,7 @@ case ERROR_NOT_DOS_DISK: sym = @symbol(ERROR_NOT_DOS_DISK); - typ = @symbol(invalidArgumentSignal); + typ = @symbol(invalidArgumentsSignal); break; case ERROR_OUT_OF_PAPER: @@ -3111,6 +3125,14 @@ "Modified: 29.6.1996 / 14:06:54 / cg" ! +createFileForReadAppend:pathName + ^ self openFile:pathName attributes:#(#'GENERIC_READ' #'GENERIC_WRITE') +! + +createFileForReadWrite:pathName + ^ self openFile:pathName attributes:#(#'GENERIC_READ' #'GENERIC_WRITE') +! + linkFile:oldPath to:newPath "link the file 'oldPath' to 'newPath'. The link will be a hard link. Return true if successful, false if not." @@ -3132,6 +3154,125 @@ " ! +openFile:pathName attributes:attributeSpec + "non public internal helper. + open a file, return an os specific fileHandle. + attributes is a collection of symbols specifying how the file is + to be opened." + + |fileHandle errorNumber| + + fileHandle := Win32Handle new. + +%{ + HANDLE h; + char *name; + OBJ *ap = __ArrayInstPtr(attributeSpec)->a_element; + int numAttrib = __arraySize(attributeSpec); + int i; + DWORD access, share, create, attr; + + if (! __isString(pathName)) { + fileHandle = nil; + goto badArgument; + } + if (! __isArray(attributeSpec)) { + fileHandle = nil; + goto badArgument; + } + + name = __stringVal(pathName); + + share = 0; + access = 0; + create = 0; + attr = 0; + + for (i=0; i access:%x share:%x create:%x attr:%x\n", + name, access, share, create, attr); + + h = CreateFile(name, access, share, 0 /* sa */, create, attr, 0 /* hTempl */); + if (h != INVALID_HANDLE_VALUE) { + __externalAddressVal(fileHandle) = (void *)h; + } else { + fileHandle = nil; + errorNumber = __MKSMALLINT( __WIN32_ERR(GetLastError()) ); + } + +badArgument: ; +%}. + fileHandle notNil ifTrue:[ + fileHandle registerForFinalization. + ^ fileHandle. + ]. + errorNumber isNil ifTrue:[ + self error:'invalid argument(s)'. + ] ifFalse:[ + (self errorHolderForNumber:errorNumber) reportError + ]. + self halt. +! + +openFileForAppend:pathName + ^ self halt +! + +openFileForRead:pathName + ^ self openFile:pathName attributes:#(#'GENERIC_READ') +! + +openFileForReadAppend:pathName + ^ self halt +! + +openFileForReadWrite:pathName + ^ self openFile:pathName attributes:#(#'GENERIC_READ' #'GENERIC_WRITE') +! + +openFileForWrite:pathName + ^ self openFile:pathName attributes:#(#'GENERIC_WRITE') +! + recursiveCopyDirectory:sourcePathName to:destination "copy the directory named 'sourcePathName' and all contained files/directories to 'destination'. Return true if successful." @@ -8370,9 +8511,283 @@ "Created: / 19.5.1999 / 21:45:05 / cg" ! ! +!Win32OperatingSystem::Win32FILEHandle class methodsFor:'documentation'! + +documentation +" + I represent a FILE*, as used in the stdio library. + Since most stdio libs are inherently buggy, thread-unsave + and hard to use in a multithreading environment, + these will no longer be used in future ST/X versions. + However, they may be useful when interfacing to external + libraries... +" +! + +version + ^ '$Header: /cvs/stx/stx/libbasic/Win32OperatingSystem.st,v 1.102 2001-12-11 17:43:56 cg Exp $' +! ! + +!Win32OperatingSystem::Win32FILEHandle methodsFor:'release'! + +closeFile + "close the file" + +%{ + FILE *f = (FILE *)(__externalAddressVal(self)); + + if (f) { + __externalAddressVal(self) = NULL; + fclose(f); + } +%}. +! ! + +!Win32OperatingSystem::Win32Handle class methodsFor:'documentation'! + +documentation +" + I represent a generic HANDLE, which can be closed via CloseHandle. +" +! + +version + ^ '$Header: /cvs/stx/stx/libbasic/Win32OperatingSystem.st,v 1.102 2001-12-11 17:43:56 cg Exp $' +! ! + +!Win32OperatingSystem::Win32Handle methodsFor:'io'! + +readBytes:count into:aByteBuffer startingAt:firstIndex + "read count bytes into a byte-buffer; + Return the number of bytes read (negative on error)" + +%{ +#if 0 + unsigned char *extPtr; + int nRead = -1; + INT fd = (INT)(__externalAddressVal(self)); + INT cnt, offs; + int nInstBytes, objSize; + + if (! __bothSmallInteger(count, firstIndex)) { + goto bad; + } + cnt = __smallIntegerVal(count); + offs = __smallIntegerVal(firstIndex) - 1; + + if (fd < 0) { + goto bad; + } + if (__isExternalBytes(aByteBuffer)) { + OBJ sz; + + nInstBytes = 0; + extPtr = (char *)(__externalBytesAddress(aByteBuffer)); + sz = __externalBytesSize(aByteBuffer); + if (__isSmallInteger(sz)) { + objSize = __smallIntegerVal(sz); + } else { + objSize = -1; /* unknown */ + } + } else { + OBJ oClass; + int nInstVars; + + oClass = __Class(aByteBuffer); + switch (__smallIntegerVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) { + case BYTEARRAY: + case WORDARRAY: + case LONGARRAY: + case SWORDARRAY: + case SLONGARRAY: + case FLOATARRAY: + case DOUBLEARRAY: + break; + default: + goto bad; + } + extPtr = (char *)0; + nInstVars = __smallIntegerVal(__ClassInstPtr(oClass)->c_ninstvars); + nInstBytes = __OBJS2BYTES__(nInstVars); + objSize = __Size(aByteBuffer) - OHDR_SIZE - nInstBytes; + } + if ((offs >= 0) + && (cnt >= 0) + && ((objSize == -1) || (objSize >= (cnt + offs)))) { + nRead = 0; + + do { + int n; + + if (extPtr) { + n = read(fd, extPtr+offs, cnt); + } else { + char *bp; + + /* + * on interrupt, anObject may be moved to another location. + * So we recompute the byte-address here. + */ + bp = __ByteArrayInstPtr(aByteBuffer)->ba_element + nInstBytes; + + n = read(fd, bp + offs, cnt); + } + if (n > 0) { + cnt -= n; + offs += n; + nRead += n; + } else { + if (n < 0) { + if (errno == EINTR) { + continue; + } + break; + } + } + } while (cnt > 0); + + RETURN (__mkSmallInteger(nRead)); + } +bad: ; +#endif +%}. + ^ self primitiveFailed + + " + |h buff n| + + h := self basicNew. + h setFileDescriptor:0. + buff := ByteArray new:10. buff inspect. + n := h readBytes:10 into:buff startingAt:1. + Transcript show:n; space; showCR:buff. + " +! + +writeBytes:count from:aByteBuffer startingAt:firstIndex + "write count bytes from a byte-buffer; + Return the number of bytes written (negative on error)" + +%{ +#if 0 + unsigned char *extPtr; + int nWritten = -1; + INT fd = (INT)(__externalAddressVal(self)); + INT cnt, offs; + int nInstBytes, objSize; + + if (! __bothSmallInteger(count, firstIndex)) { + goto bad; + } + cnt = __smallIntegerVal(count); + offs = __smallIntegerVal(firstIndex) - 1; + + if (fd < 0) { + goto bad; + } + if (__isExternalBytes(aByteBuffer)) { + OBJ sz; + + nInstBytes = 0; + extPtr = (char *)(__externalBytesAddress(aByteBuffer)); + sz = __externalBytesSize(aByteBuffer); + if (__isSmallInteger(sz)) { + objSize = __smallIntegerVal(sz); + } else { + objSize = -1; /* unknown */ + } + } else { + OBJ oClass; + int nInstVars; + + oClass = __Class(aByteBuffer); + switch (__smallIntegerVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) { + case BYTEARRAY: + case WORDARRAY: + case LONGARRAY: + case SWORDARRAY: + case SLONGARRAY: + case FLOATARRAY: + case DOUBLEARRAY: + break; + default: + goto bad; + } + extPtr = (char *)0; + nInstVars = __smallIntegerVal(__ClassInstPtr(oClass)->c_ninstvars); + nInstBytes = __OBJS2BYTES__(nInstVars); + objSize = __Size(aByteBuffer) - OHDR_SIZE - nInstBytes; + } + if ((offs >= 0) + && (cnt >= 0) + && ((objSize == -1) || (objSize >= (cnt + offs)))) { + nWritten = 0; + + do { + int n; + + if (extPtr) { + n = write(fd, extPtr+offs, cnt); + } else { + char *bp; + + /* + * on interrupt, anObject may be moved to another location. + * So we recompute the byte-address here. + */ + bp = __ByteArrayInstPtr(aByteBuffer)->ba_element + nInstBytes; + + n = write(fd, bp + offs, cnt); + } + if (n > 0) { + cnt -= n; + offs += n; + nWritten += n; + } else { + if (n < 0) { + if (errno == EINTR) { + continue; + } + break; + } + } + } while (cnt > 0); + + RETURN (__mkSmallInteger(nWritten)); + } +bad: ; +#endif +%}. + ^ self primitiveFailed + + " + |h buff n| + + h := self basicNew. + h setFileDescriptor:1. + buff := '12345678901234567890'. + n := h writeBytes:10 from:buff startingAt:1. + " +! ! + +!Win32OperatingSystem::Win32Handle methodsFor:'release'! + +closeFile + "close the handle" + +%{ + HANDLE h = (HANDLE)(__externalAddressVal(self)); + + if (h) { + __externalAddressVal(self) = (HANDLE)0; + CloseHandle(h); + } +%}. +! ! + !Win32OperatingSystem class methodsFor:'documentation'! version - ^ '$Header: /cvs/stx/stx/libbasic/Win32OperatingSystem.st,v 1.101 2001-12-11 16:04:05 stefan Exp $' + ^ '$Header: /cvs/stx/stx/libbasic/Win32OperatingSystem.st,v 1.102 2001-12-11 17:43:56 cg Exp $' ! ! Win32OperatingSystem initialize!