Eliot Miranda uploaded a new version of FileAttributesPlugin to project VM Maker: http://source.squeak.org/VMMaker/FileAttributesPlugin.oscog-AlistairGrant.31.mcz ==================== Summary ==================== Name: FileAttributesPlugin.oscog-AlistairGrant.31 Author: AlistairGrant Time: 17 June 2018, 7:19:22.996287 pm UUID: aeb07abd-07f5-4277-8dd5-f176f1b9222d Ancestors: FileAttributesPlugin.oscog-AlistairGrant.30 1.3.2: Get builds working on MacOS (and subsequently Windows) =============== Diff against FileAttributesPlugin.oscog-AlistairGrant.30 =============== Item was changed: ----- Method: FileAttributesPlugin class>>declareCVarsIn: (in category 'translation') ----- declareCVarsIn: cg self declareC: #('sCLPfn' 'sCOFfn') as: #'void *' in: cg. "Assume the security plugin can be loaded until proven otherwise" cg var: 'hasSecurityPlugin' declareC: 'int hasSecurityPlugin = 1'. cg addHeaderFile: '<limits.h>'. cg addHeaderFile: '<sys/types.h>'. cg addHeaderFile: '<dirent.h> #ifdef _WIN32 #include <windows.h> #include <winbase.h> #define FAIL() { return -1; } #include "sqWin32File.h" - #else - #include "sqMemoryAccess.h" - extern sqLong convertToLongSqueakTime(time_t unixTime); #endif typedef struct dirptrstruct { DIR *dp; int path_len; char *path_file; char path[PATH_MAX+4]; } osdir;'. cg addHeaderFile: '<sys/stat.h> #if !!defined(HAVE_LSTAT) && !!defined(_WIN32) #define HAVE_LSTAT 1 #endif'. cg addHeaderFile: '<unistd.h> /* AKG 2017 - ', self moduleName, '.c translated from class ', self name, ' */'! Item was added: + ----- Method: FileAttributesPlugin>>faConvertUnixToLongSqueakTime: (in category 'private - posix') ----- + faConvertUnixToLongSqueakTime: unixTime + "Convert the supplied Unix (UTC) time to Squeak time. + + Squeak time has an epoch of 1901 and uses local time + i.e. timezone + daylight savings + + Answer an sqLong which is guaranteed to be 64 bits on all platforms." + + | squeakTime | + + <returnTypeC: #'sqLong'> + <var: 'unixTime' type: #'time_t'> + <var: 'squeakTime' type: #'sqLong'> + + self cppIf: #_WIN32 defined ifTrue: + [squeakTime := 0] + ifFalse: [ + squeakTime := unixTime. + self cppIf: (self defined: #HAVE_TM_GMTOFF) ifTrue: + [ squeakTime := squeakTime + (self cCode: 'localtime(&unixTime)->tm_gmtoff')] + ifFalse: [ self cppIf: (self defined: #HAVE_TIMEZONE) ifTrue: + [ squeakTime := squeakTime + (self cCode: '(daylight*60*60) - timezone')] + ifFalse: [ self cPreprocessorDirective: '#error: cannot determine timezone correction']]. + "Squeak epoch is Jan 1, 1901. Unix epoch is Jan 1, 1970: 17 leap years + and 52 non-leap years later than Squeak." + squeakTime := squeakTime + + (self cCode: '(52*365UL + 17*366UL) * 24*60*60UL' + inSmalltalk: [((52*365) + (17*366)) * 24*60*60]) ]. + ^squeakTime + + + ! Item was changed: ----- Method: FileAttributesPlugin>>posixFileTimesFrom:to: (in category 'private - posix') ----- posixFileTimesFrom: statBufPointer to: attributeArray "Populate attributeArray with the file times from statBufPointer" | attributeDate | <var: 'statBufPointer' type: #'struct stat *'> <var: 'attributeDate' type: #'sqLong'> self cppIf: #_WIN32 defined ifTrue: [] ifFalse: [ + attributeDate := self faConvertUnixToLongSqueakTime: statBufPointer st_atime. - attributeDate := self convertToLongSqueakTime: statBufPointer st_atime. interpreterProxy storePointer: 8 ofObject: attributeArray withValue: (interpreterProxy signed64BitIntegerFor: attributeDate). + attributeDate := self faConvertUnixToLongSqueakTime: statBufPointer st_mtime. - attributeDate := self convertToLongSqueakTime: statBufPointer st_mtime. interpreterProxy storePointer: 9 ofObject: attributeArray withValue: (interpreterProxy signed64BitIntegerFor: attributeDate). + attributeDate := self faConvertUnixToLongSqueakTime: statBufPointer st_ctime. - attributeDate := self convertToLongSqueakTime: statBufPointer st_ctime. interpreterProxy storePointer: 10 ofObject: attributeArray withValue: (interpreterProxy signed64BitIntegerFor: attributeDate); storePointer: 11 ofObject: attributeArray withValue: interpreterProxy nilObject ]. ^0! Item was changed: ----- Method: FileAttributesPlugin>>primitiveFileAttribute (in category 'file primitives') ----- primitiveFileAttribute "Answer a single file attribute. primFileAttributes: aString attributeNumber: attributeNumber aString is the path to the file attributeNumber identifies which attribute to return: 1 - 12: stat(): name, mode, ino, dev, nlink, uid, gid, size, accessDate, modifiedDate, changeDate, creationDate 13 - 15: access(): R_OK, W_OK, X_OK 16: isSymlink On error, answer a single element array containing the appropriate error code." | fileName attributeNumber resultOop fileNameOop statBuf cPathName sizeIfFile mode attributeDate status | <export: true> <var: 'statBuf' type: #'struct stat'> <var: 'cPathName' declareC: 'char cPathName[PATH_MAX]'> <var: 'attributeDate' type: #'sqLong'> fileName := interpreterProxy stackObjectValue: 1. attributeNumber := interpreterProxy stackIntegerValue: 0. (interpreterProxy failed or: [(attributeNumber between: 1 and: 16) not or: [(interpreterProxy is: fileName KindOf: 'String') not]]) ifTrue: [^interpreterProxy primitiveFailFor: PrimErrBadArgument]. status := self pathOop: fileName toBuffer: cPathName maxLen: #PATH_MAX. status ~= 0 ifTrue: [^interpreterProxy primitiveFailForOSError: status]. resultOop := 0. attributeNumber < 12 ifTrue: "Get requested stat entry" [ status := self putStatFor: cPathName intoBuffer: (self addressOf: statBuf) targetName: (self addressOf: fileNameOop). status ~= 0 ifTrue: [^interpreterProxy primitiveFailForOSError: status]. "In C, this would naturally be a switch statement, but I don't know to mix in the smalltalk code" attributeNumber = 1 ifTrue: [resultOop := fileNameOop]. attributeNumber = 2 ifTrue: [resultOop := interpreterProxy positiveMachineIntegerFor: statBuf st_mode]. attributeNumber = 3 ifTrue: [resultOop := interpreterProxy positive64BitIntegerFor: statBuf st_ino]. attributeNumber = 4 ifTrue: [resultOop := interpreterProxy positive64BitIntegerFor: statBuf st_dev]. attributeNumber = 5 ifTrue: [resultOop := interpreterProxy positive64BitIntegerFor: statBuf st_nlink]. attributeNumber = 6 ifTrue: [resultOop := interpreterProxy positiveMachineIntegerFor: statBuf st_uid]. attributeNumber = 7 ifTrue: [resultOop := interpreterProxy positiveMachineIntegerFor: statBuf st_gid]. attributeNumber = 8 ifTrue: [ sizeIfFile := ((self S_ISDIR: statBuf st_mode) = 0) ifTrue: [statBuf st_size] ifFalse: [0]. resultOop := interpreterProxy positiveMachineIntegerFor: sizeIfFile ]. attributeNumber = 9 ifTrue: [ "Access Time" self cppIf: #_WIN32 defined ifTrue: [ status := self fileLastAccessTimeFor: cPathName length: cPathName strlen to: (self addressOf: attributeDate put: [:val| attributeDate := val]). status ~= 0 ifTrue: [^interpreterProxy primitiveFailForOSError: status]. resultOop := interpreterProxy signed64BitIntegerFor: attributeDate ] ifFalse: [ + attributeDate := self faConvertUnixToLongSqueakTime: statBuf st_atime. - attributeDate := self convertToLongSqueakTime: statBuf st_atime. resultOop := interpreterProxy signed64BitIntegerFor: attributeDate]]. attributeNumber = 10 ifTrue: [ "Modified Time" self cppIf: #_WIN32 defined ifTrue: [ status := self fileLastWriteTimeFor: cPathName length: cPathName strlen to: (self addressOf: attributeDate put: [:val| attributeDate := val]). status ~= 0 ifTrue: [^interpreterProxy primitiveFailForOSError: status]. resultOop := interpreterProxy signed64BitIntegerFor: attributeDate ] ifFalse: [ + attributeDate := self faConvertUnixToLongSqueakTime: statBuf st_mtime. - attributeDate := self convertToLongSqueakTime: statBuf st_mtime. resultOop := interpreterProxy signed64BitIntegerFor: attributeDate]]. attributeNumber = 11 ifTrue: [ "Change Time" self cppIf: #_WIN32 defined ifTrue: [resultOop := interpreterProxy nilObject] ifFalse: [ + attributeDate := self faConvertUnixToLongSqueakTime: statBuf st_ctime. - attributeDate := self convertToLongSqueakTime: statBuf st_ctime. resultOop := interpreterProxy signed64BitIntegerFor: attributeDate]]. ] ifFalse: [attributeNumber = 12 ifTrue: [ "Creation Time" self cppIf: #_WIN32 defined ifTrue: [ status := self fileCreationTimeFor: cPathName length: cPathName strlen to: (self addressOf: attributeDate put: [:val| attributeDate := val]). status ~= 0 ifTrue: [^interpreterProxy primitiveFailForOSError: status]. resultOop := interpreterProxy signed64BitIntegerFor: attributeDate ] ifFalse: [ resultOop := interpreterProxy nilObject ] ] ifFalse: [attributeNumber < 16 ifTrue: "Get requested access entry" [ attributeNumber = 13 ifTrue: [mode := self fileReadableFlag]. attributeNumber = 14 ifTrue: [mode := self fileWriteableFlag]. attributeNumber = 15 ifTrue: [mode := self fileExecutableFlag]. resultOop := ((self acc: cPathName ess: mode) = 0) ifTrue: [interpreterProxy trueObject] ifFalse: [interpreterProxy falseObject]. ] ifFalse: "attributeNumber = 16, #isSymlink" [ status := self isSymlink: cPathName boolean: (self addressOf: resultOop put: [:val| resultOop := val]). status ~= 0 ifTrue: [^interpreterProxy primitiveFailForOSError: status]. ]]]. resultOop = 0 ifTrue: ["It shouldn't be possible to get here" interpreterProxy primitiveFail] ifFalse: [interpreterProxy pop: 3 thenPush: resultOop]! Item was changed: ----- Method: FileAttributesPlugin>>versionString (in category 'version string') ----- versionString "Answer a string containing the version string for this plugin." <inline: #always> + ^'1.3.2'! - ^'1.3.1'! |
Free forum by Nabble | Edit this page |