--- a/UnixOperatingSystem.st Thu Dec 13 14:19:37 2012 +0100
+++ b/UnixOperatingSystem.st Thu Dec 13 14:20:12 2012 +0100
@@ -3410,12 +3410,16 @@
Return true if successful (or the directory existed already), false if failed.
This is a low-level entry - use Filename protocol for compatibility."
-%{
- if (__isStringLike(aPathName) && __isSmallInteger(umask)) {
- if (mkdir(__stringVal(aPathName), __smallIntegerVal(umask)) >= 0) {
- RETURN(true);
- }
- @global(LastErrorNumber) = __mkSmallInteger(errno);
+ |encodedPathName|
+
+ encodedPathName := self encodePath:aPathName.
+
+%{
+ if (__isStringLike(encodedPathName) && __isSmallInteger(umask)) {
+ if (mkdir(__stringVal(encodedPathName), __smallIntegerVal(umask)) >= 0) {
+ RETURN(true);
+ }
+ @global(LastErrorNumber) = __mkSmallInteger(errno);
}
%}.
"/ could not create - if it already existed this is ok
@@ -3448,20 +3452,25 @@
"link the file 'oldPath' to 'newPath'. The link will be a hard link.
Return true if successful, false if not."
+ |encodedOldPathName encodedNewPathName|
+
+ encodedOldPathName := self encodePath:oldPath.
+ encodedNewPathName := self encodePath:newPath.
+
%{
int ret;
- if (__isStringLike(oldPath) && __isStringLike(newPath)) {
- __BEGIN_INTERRUPTABLE__
- do {
- ret = link((char *) __stringVal(oldPath), (char *) __stringVal(newPath));
- } while (ret < 0 && errno == EINTR);
- __END_INTERRUPTABLE__
- if (ret < 0) {
- @global(LastErrorNumber) = __mkSmallInteger(errno);
- RETURN ( false );
- }
- RETURN (true);
+ if (__isStringLike(encodedOldPathName) && __isStringLike(encodedNewPathName)) {
+ __BEGIN_INTERRUPTABLE__
+ do {
+ ret = link((char *) __stringVal(encodedOldPathName), (char *) __stringVal(encodedNewPathName));
+ } while (ret < 0 && errno == EINTR);
+ __END_INTERRUPTABLE__
+ if (ret < 0) {
+ @global(LastErrorNumber) = __mkSmallInteger(errno);
+ RETURN ( false );
+ }
+ RETURN (true);
}
%}.
"/
@@ -3479,29 +3488,33 @@
The link will be a soft (symbolic) link.
Return true if successful, false if not."
+ |encodedOldPathName encodedNewPathName|
+
+ encodedOldPathName := self encodePath:oldPath.
+ encodedNewPathName := self encodePath:newPath.
%{
#ifdef S_IFLNK
int ret;
- if (__isStringLike(oldPath) && __isStringLike(newPath)) {
- __BEGIN_INTERRUPTABLE__
- do {
- ret = symlink((char *) __stringVal(oldPath), (char *) __stringVal(newPath));
- } while (ret < 0 && errno == EINTR);
- __END_INTERRUPTABLE__
- if (ret < 0) {
- @global(LastErrorNumber) = __mkSmallInteger(errno);
- RETURN ( false );
- }
- RETURN (true);
- }
-#endif
-%}.
- (oldPath isString not or:[newPath isString not]) ifTrue:[
- "/
- "/ bad argument(s) given
- "/
- ^ self primitiveFailed
+ if (__isStringLike(encodedOldPathName) && __isStringLike(encodedNewPathName)) {
+ __BEGIN_INTERRUPTABLE__
+ do {
+ ret = symlink((char *) __stringVal(encodedOldPathName), (char *) __stringVal(encodedNewPathName));
+ } while (ret < 0 && errno == EINTR);
+ __END_INTERRUPTABLE__
+ if (ret < 0) {
+ @global(LastErrorNumber) = __mkSmallInteger(errno);
+ RETURN ( false );
+ }
+ RETURN (true);
+ }
+#endif
+%}.
+ (encodedOldPathName isString not or:[encodedNewPathName isString not]) ifTrue:[
+ "/
+ "/ bad argument(s) given
+ "/
+ ^ self primitiveFailed
].
"/
@@ -3518,18 +3531,20 @@
"open a file, return an os specific fileHandle.
openmode is a symbol defining the way to open
valid modes are:
- #O_RDONLY
- #O_RDWR
- #O_WRONLY
- #O_CREAT
- #O_APPEND
- #O_SYNC
- #O_LARGEFILE
+ #O_RDONLY
+ #O_RDWR
+ #O_WRONLY
+ #O_CREAT
+ #O_APPEND
+ #O_SYNC
+ #O_LARGEFILE
This is a private entry, but maybe useful to open/create a file in a special mode,
which is proprietrary to the operatingSystem."
- |error fileDescriptor|
+ |error fileDescriptor encodedPathName|
+
+ encodedPathName := self encodePath:path.
%{
OBJ *ap;
@@ -3538,56 +3553,56 @@
int mode, openFlags = 0;
int n;
- if (!__isStringLike(path)) {
- error = @symbol(badArgument1);
- goto err;
+ if (!__isStringLike(encodedPathName)) {
+ error = @symbol(badArgument1);
+ goto err;
}
if (!__isArrayLike(attributes)) {
- error = @symbol(badArgument2);
- goto err;
+ error = @symbol(badArgument2);
+ goto err;
}
if (modeInteger == nil) {
- mode = 0644;
+ mode = 0644;
} else if (__isSmallInteger(modeInteger)) {
- mode = __intVal(modeInteger);
+ mode = __intVal(modeInteger);
} else {
- error = @symbol(badArgument3);
- goto err;
+ error = @symbol(badArgument3);
+ goto err;
}
nAttributes = __arraySize(attributes);
for (n = 0, ap = __arrayVal(attributes); n < nAttributes; n++) {
- OBJ attribute = ap[n];
-
- if (attribute == @symbol(O_RDONLY)) {
- openFlags |= O_RDONLY;
- } else if (attribute == @symbol(O_RDWR)) {
- openFlags |= O_RDWR;
- } else if (attribute == @symbol(O_WRONLY)) {
- openFlags |= O_WRONLY;
- } else if (attribute == @symbol(O_CREAT)) {
- openFlags |= O_CREAT;
- } else if (attribute == @symbol(O_APPEND)) {
- openFlags |= O_APPEND;
- } else if (attribute == @symbol(O_EXCL)) {
- openFlags |= O_EXCL;
- } else if (attribute == @symbol(O_TRUNC)) {
- openFlags |= O_TRUNC;
- } else if (attribute == @symbol(O_LARGEFILE)) {
+ OBJ attribute = ap[n];
+
+ if (attribute == @symbol(O_RDONLY)) {
+ openFlags |= O_RDONLY;
+ } else if (attribute == @symbol(O_RDWR)) {
+ openFlags |= O_RDWR;
+ } else if (attribute == @symbol(O_WRONLY)) {
+ openFlags |= O_WRONLY;
+ } else if (attribute == @symbol(O_CREAT)) {
+ openFlags |= O_CREAT;
+ } else if (attribute == @symbol(O_APPEND)) {
+ openFlags |= O_APPEND;
+ } else if (attribute == @symbol(O_EXCL)) {
+ openFlags |= O_EXCL;
+ } else if (attribute == @symbol(O_TRUNC)) {
+ openFlags |= O_TRUNC;
+ } else if (attribute == @symbol(O_LARGEFILE)) {
#ifdef O_LARGEFILE
- openFlags |= O_LARGEFILE;
+ openFlags |= O_LARGEFILE;
#else
- error = @symbol(badArgument2);
- goto err;
-#endif
- } else if (attribute == @symbol(O_SYNC)) {
+ error = @symbol(badArgument2);
+ goto err;
+#endif
+ } else if (attribute == @symbol(O_SYNC)) {
#ifdef O_SYNC
- openFlags |= O_SYNC;
+ openFlags |= O_SYNC;
#else
- error = @symbol(badArgument2);
- goto err;
-#endif
- }
+ error = @symbol(badArgument2);
+ goto err;
+#endif
+ }
}
#if defined(O_NONBLOCK)
@@ -3597,31 +3612,31 @@
#endif
again:
- fd = open((char *) __stringVal(path), openFlags, mode);
+ fd = open((char *) __stringVal(encodedPathName), openFlags, mode);
if (fd < 0) {
- if (errno == EINTR) {
- __HANDLE_INTERRUPTS__;
- goto again;
- } else {
- error = __mkSmallInteger(errno);
- goto err;
- }
+ if (errno == EINTR) {
+ __HANDLE_INTERRUPTS__;
+ goto again;
+ } else {
+ error = __mkSmallInteger(errno);
+ goto err;
+ }
}
fileDescriptor = __mkSmallInteger(fd);
err:;
%}.
^ fileDescriptor notNil ifTrue:[
- FileDescriptorHandle for:fileDescriptor.
+ FileDescriptorHandle for:fileDescriptor.
] ifFalse:[
- (self errorHolderForNumber:error) reportError
- ].
-
- "
- self open:'/etc/hosts' attributes:#(O_RDONLY) mode:nil
- self open:'/tmp/xxzz' attributes:#(O_RDWR O_CREAT) mode:8r611
- self open:'/etc/passwd' attributes:#(O_RDWR) mode:nil
- self open:'/no one knows this file' attributes:#(O_RDONLY) mode:nil
- self open:'foo/bar/baz' attributes:#(O_RDWR O_CREAT) mode:nil
+ (self errorHolderForNumber:error) reportError
+ ].
+
+ "
+ self open:'/etc/hosts' attributes:#(O_RDONLY) mode:nil
+ self open:'/tmp/xxzz' attributes:#(O_RDWR O_CREAT) mode:8r611
+ self open:'/etc/passwd' attributes:#(O_RDWR) mode:nil
+ self open:'/no one knows this file' attributes:#(O_RDONLY) mode:nil
+ self open:'foo/bar/baz' attributes:#(O_RDWR O_CREAT) mode:nil
"
!
@@ -3679,20 +3694,23 @@
Return true if successful, false if directory is not empty or no permission.
This is a lowLevel entry - use Filename protocol for compatibility."
+ |encodedPathName|
+
+ encodedPathName := self encodePath:fullPathName.
%{
int ret;
- if (__isStringLike(fullPathName)) {
- __BEGIN_INTERRUPTABLE__
- do {
- ret = rmdir((char *) __stringVal(fullPathName));
- } while (ret < 0 && errno == EINTR);
- __END_INTERRUPTABLE__
- if (ret < 0) {
- @global(LastErrorNumber) = __mkSmallInteger(errno);
- RETURN ( false );
- }
- RETURN (true);
+ if (__isStringLike(encodedPathName)) {
+ __BEGIN_INTERRUPTABLE__
+ do {
+ ret = rmdir((char *) __stringVal(encodedPathName));
+ } while (ret < 0 && errno == EINTR);
+ __END_INTERRUPTABLE__
+ if (ret < 0) {
+ @global(LastErrorNumber) = __mkSmallInteger(errno);
+ RETURN ( false );
+ }
+ RETURN (true);
}
%}.
"/
@@ -3711,20 +3729,23 @@
"remove the file named 'fullPathName'; return true if successful.
This is a lowLevel entry - use Filename protocol for compatibility."
+ |encodedPathName|
+
+ encodedPathName := self encodePath:fullPathName.
%{
int ret;
- if (__isStringLike(fullPathName)) {
- __BEGIN_INTERRUPTABLE__
- do {
- ret = unlink((char *) __stringVal(fullPathName));
- } while (ret < 0 && errno == EINTR);
- __END_INTERRUPTABLE__
- if (ret < 0) {
- @global(LastErrorNumber) = __mkSmallInteger(errno);
- RETURN ( false );
- }
- RETURN (true);
+ if (__isStringLike(encodedPathName)) {
+ __BEGIN_INTERRUPTABLE__
+ do {
+ ret = unlink((char *) __stringVal(encodedPathName));
+ } while (ret < 0 && errno == EINTR);
+ __END_INTERRUPTABLE__
+ if (ret < 0) {
+ @global(LastErrorNumber) = __mkSmallInteger(errno);
+ RETURN ( false );
+ }
+ RETURN (true);
}
%}.
^ self primitiveFailed
@@ -3738,32 +3759,36 @@
any invalid names.
Returns true if successful, false if not"
+ |encodedOldPathName encodedNewPathName|
+
+ encodedOldPathName := self encodePath:oldPath.
+ encodedNewPathName := self encodePath:newPath.
%{
int ret, eno;
- if (__isStringLike(oldPath) && __isStringLike(newPath)) {
+ if (__isStringLike(encodedOldPathName) && __isStringLike(encodedNewPathName)) {
#if defined(HAS_RENAME)
- __BEGIN_INTERRUPTABLE__
- do {
- ret = rename((char *) __stringVal(oldPath), (char *) __stringVal(newPath));
- } while (ret < 0 && errno == EINTR);
- __END_INTERRUPTABLE__
+ __BEGIN_INTERRUPTABLE__
+ do {
+ ret = rename((char *) __stringVal(encodedOldPathName), (char *) __stringVal(encodedNewPathName));
+ } while (ret < 0 && errno == EINTR);
+ __END_INTERRUPTABLE__
#else
- ret = link((char *) __stringVal(oldPath), (char *) __stringVal(newPath));
- if (ret >= 0) {
- ret = unlink((char *) __stringVal(oldPath));
- if (ret < 0) {
- eno = errno;
- unlink((char *) __stringVal(newPath));
- errno = eno;
- }
- }
-#endif
- if (ret < 0) {
- @global(LastErrorNumber) = __mkSmallInteger(errno);
- RETURN ( false );
- }
- RETURN (true);
+ ret = link((char *) __stringVal(encodedOldPathName), (char *) __stringVal(encodedNewPathName));
+ if (ret >= 0) {
+ ret = unlink((char *) __stringVal(encodedOldPathName));
+ if (ret < 0) {
+ eno = errno;
+ unlink((char *) __stringVal(encodedNewPathName));
+ errno = eno;
+ }
+ }
+#endif
+ if (ret < 0) {
+ @global(LastErrorNumber) = __mkSmallInteger(errno);
+ RETURN ( false );
+ }
+ RETURN (true);
}
%}.
^ self primitiveFailed
@@ -3779,62 +3804,66 @@
This is a low-level entry - use Filename protocol."
+ |encodedPathName|
+
+ encodedPathName := self encodePath:aPathName.
+
%{
#if defined(HAS_TRUNCATE) || defined(HAS_FTRUNCATE)
int ret;
off_t truncateSize;
- if (!__isStringLike(aPathName))
- goto getOutOfHere;
+ if (!__isStringLike(encodedPathName))
+ goto getOutOfHere;
if (__isSmallInteger(newSize)) {
- truncateSize = __intVal(newSize);
- if (truncateSize < 0) {
- goto getOutOfHere;
- }
+ truncateSize = __intVal(newSize);
+ if (truncateSize < 0) {
+ goto getOutOfHere;
+ }
} else {
- truncateSize = __signedLongIntVal(newSize);
- if (truncateSize < 0) {
- goto getOutOfHere;
- }
- if (truncateSize == 0) {
- if (sizeof(truncateSize) == 8) {
- if (__signedLong64IntVal(newSize, &truncateSize) == 0 || truncateSize < 0) {
- goto getOutOfHere;
- }
- } else {
- goto getOutOfHere;
- }
- }
+ truncateSize = __signedLongIntVal(newSize);
+ if (truncateSize < 0) {
+ goto getOutOfHere;
+ }
+ if (truncateSize == 0) {
+ if (sizeof(truncateSize) == 8) {
+ if (__signedLong64IntVal(newSize, &truncateSize) == 0 || truncateSize < 0) {
+ goto getOutOfHere;
+ }
+ } else {
+ goto getOutOfHere;
+ }
+ }
}
#if defined(HAS_TRUNCATE)
- __BEGIN_INTERRUPTABLE__
- do {
- ret = truncate((char *) __stringVal(aPathName), truncateSize);
- } while (ret < 0 && errno == EINTR);
- __END_INTERRUPTABLE__
+ __BEGIN_INTERRUPTABLE__
+ do {
+ ret = truncate((char *) __stringVal(encodedPathName), truncateSize);
+ } while (ret < 0 && errno == EINTR);
+ __END_INTERRUPTABLE__
#else
# ifdef HAS_FTRUNCATE
{
- int fd;
-
- do {
- fd = open((char *) __stringVal(aPathName), 2);
- } while (fd < 0 && errno == EINTR);
- if (fd < 0) {
- @global(LastErrorNumber) = __mkSmallInteger(errno);
- RETURN ( false );
- }
-
- ret = ftruncate(fd, truncateSize);
- close(fd);
+ int fd;
+
+ do {
+ fd = open((char *) __stringVal(encodedPathName), 2);
+ } while (fd < 0 && errno == EINTR);
+ if (fd < 0) {
+ @global(LastErrorNumber) = __mkSmallInteger(errno);
+ RETURN ( false );
+ }
+
+ ret = ftruncate(fd, truncateSize);
+ close(fd);
}
# endif /* HAS_FTRUNCATE */
#endif
if (ret < 0) {
- @global(LastErrorNumber) = __mkSmallInteger(errno);
- RETURN ( false );
+ @global(LastErrorNumber) = __mkSmallInteger(errno);
+ RETURN ( false );
}
RETURN (true);
getOutOfHere:;
@@ -3922,29 +3951,32 @@
"
this could have been implemented as:
- (self infoOf:aPathName) at:#mode
+ (self infoOf:aPathName) at:#mode
but for huge directory searches the code below is faster
"
+ |encodedPathName|
+
+ encodedPathName := self encodePath:aPathName.
%{
struct stat buf;
int ret;
- if (__isStringLike(aPathName)) {
+ if (__isStringLike(encodedPathName)) {
# ifdef TRACE_STAT_CALLS
- printf("stat on '%s' for accessMode\n", __stringVal(aPathName));
-# endif
- __BEGIN_INTERRUPTABLE__
- do {
- ret = stat((char *) __stringVal(aPathName), &buf);
- } while ((ret < 0) && (errno == EINTR));
- __END_INTERRUPTABLE__
-
- if (ret < 0) {
- @global(LastErrorNumber) = __mkSmallInteger(errno);
- RETURN ( nil );
- }
- RETURN ( __mkSmallInteger(buf.st_mode & 0777) );
+ printf("stat on '%s' for accessMode\n", __stringVal(encodedPathName));
+# endif
+ __BEGIN_INTERRUPTABLE__
+ do {
+ ret = stat((char *) __stringVal(encodedPathName), &buf);
+ } while ((ret < 0) && (errno == EINTR));
+ __END_INTERRUPTABLE__
+
+ if (ret < 0) {
+ @global(LastErrorNumber) = __mkSmallInteger(errno);
+ RETURN ( nil );
+ }
+ RETURN ( __mkSmallInteger(buf.st_mode & 0777) );
}
%}.
^ self primitiveFailed
@@ -3960,20 +3992,23 @@
independent. Return true if changed,
false if such a file does not exist or change was not allowd."
+ |encodedPathName|
+
+ encodedPathName := self encodePath:aPathName.
%{
int ret;
- if (__isStringLike(aPathName) && __isSmallInteger(modeBits)) {
- __BEGIN_INTERRUPTABLE__
- do {
- ret = chmod((char *)__stringVal(aPathName), __intVal(modeBits));
- } while (ret < 0 && errno == EINTR);
- __END_INTERRUPTABLE__
- if (ret < 0) {
- @global(LastErrorNumber) = __mkSmallInteger(errno);
- RETURN ( false );
- }
- RETURN ( true );
+ if (__isStringLike(encodedPathName) && __isSmallInteger(modeBits)) {
+ __BEGIN_INTERRUPTABLE__
+ do {
+ ret = chmod((char *)__stringVal(encodedPathName), __intVal(modeBits));
+ } while (ret < 0 && errno == EINTR);
+ __END_INTERRUPTABLE__
+ if (ret < 0) {
+ @global(LastErrorNumber) = __mkSmallInteger(errno);
+ RETURN ( false );
+ }
+ RETURN ( true );
}
%}.
^ self primitiveFailed
@@ -4293,20 +4328,22 @@
|path|
%{ /* UNLIMITEDSTACK */
- char nameBuffer[MAXPATHLEN + 1];
-
- if (getcwd(nameBuffer, MAXPATHLEN)) {
- OBJ d;
-
- @global(CurrentDirectory) = d = __MKSTRING(nameBuffer);
- __GSTORE(d);
- RETURN (d);
- }
-%}.
- ^ self primitiveFailed
-
- "
- self getCurrentDirectory
+ char nameBuffer[MAXPATHLEN + 1];
+
+ if (getcwd(nameBuffer, MAXPATHLEN)) {
+ path = __MKSTRING(nameBuffer);
+ }
+%}.
+ path isNil ifTrue:[
+ ^ self primitiveFailed.
+ ].
+ path := self decodePath:path.
+ CurrentDirectory := path.
+
+ ^ path.
+
+ "
+ self getCurrentDirectory
"
!
@@ -4466,21 +4503,21 @@
"return some object filled with info for the file 'aPathName';
the info (for which corresponding access methods are understood by
the returned object) is:
- type - a symbol giving the files type
- mode - numeric access mode
- uid - owners user id
- gid - owners group id
- size - files size
- id - files number (i.e. inode number)
- accessed - last access time (as Timestamp)
- modified - last modification time (as Timestamp)
- statusChanged - last status change time (as Timestamp)
- alternativeName - (windows only:) the MSDOS name of the file
- recordFormatNumeric - (VMS only:) numeric value of the recordFormat
- recordFormat - (VMS only:) symbolic value of the recordFormat
- recordAttributes - (VMS only:) recordAttributes
- fixedHeaderSize - (VMS only:) fixed header size in a variable record format
- recordSize - (VMS only:) record size.
+ type - a symbol giving the files type
+ mode - numeric access mode
+ uid - owners user id
+ gid - owners group id
+ size - files size
+ id - files number (i.e. inode number)
+ accessed - last access time (as Timestamp)
+ modified - last modification time (as Timestamp)
+ statusChanged - last status change time (as Timestamp)
+ alternativeName - (windows only:) the MSDOS name of the file
+ recordFormatNumeric - (VMS only:) numeric value of the recordFormat
+ recordFormat - (VMS only:) symbolic value of the recordFormat
+ recordAttributes - (VMS only:) recordAttributes
+ fixedHeaderSize - (VMS only:) fixed header size in a variable record format
+ recordSize - (VMS only:) record size.
Some of the fields may be returned as nil on systems which do not provide
all of the information.
@@ -4490,14 +4527,16 @@
use #linkInfoOf: to get info about the link itself.
"
- |type mode uid gid size id nLink aOStime mOStime cOStime error|
+ |type mode uid gid size id nLink aOStime mOStime cOStime error encodedPathName|
+
+ encodedPathName := self encodePath:aPathName.
%{
struct stat buf;
int ret;
- if (!__isStringLike(aPathName)) {
- error = @symbol(badArgument);
- goto out;
+ if (!__isStringLike(encodedPathName)) {
+ error = @symbol(badArgument);
+ goto out;
}
# ifdef TRACE_STAT_CALLS
@@ -4505,76 +4544,76 @@
# endif
__BEGIN_INTERRUPTABLE__
do {
- ret = stat((char *) __stringVal(aPathName), &buf);
+ ret = stat((char *) __stringVal(encodedPathName), &buf);
} while ((ret < 0) && (errno == EINTR));
__END_INTERRUPTABLE__
if (ret < 0) {
- error = __mkSmallInteger(errno);
- @global(LastErrorNumber) = error;
- goto out;
+ error = __mkSmallInteger(errno);
+ @global(LastErrorNumber) = error;
+ goto out;
}
switch (buf.st_mode & S_IFMT) {
- case S_IFDIR:
- type = @symbol(directory);
- break;
-
- case S_IFREG:
- type = @symbol(regular);
- break;
+ case S_IFDIR:
+ type = @symbol(directory);
+ break;
+
+ case S_IFREG:
+ type = @symbol(regular);
+ break;
# ifdef S_IFCHR
- case S_IFCHR:
- type = @symbol(characterSpecial);
- break;
+ case S_IFCHR:
+ type = @symbol(characterSpecial);
+ break;
# endif
# ifdef S_IFBLK
- case S_IFBLK:
- type = @symbol(blockSpecial);
- break;
+ case S_IFBLK:
+ type = @symbol(blockSpecial);
+ break;
# endif
# ifdef S_IFMPC
- case S_IFMPC:
- type = @symbol(multiplexedCharacterSpecial);
- break;
+ case S_IFMPC:
+ type = @symbol(multiplexedCharacterSpecial);
+ break;
# endif
# ifdef S_IFMPB
- case S_IFMPB:
- type = @symbol(multiplexedBlockSpecial);
- break;
+ case S_IFMPB:
+ type = @symbol(multiplexedBlockSpecial);
+ break;
# endif
# ifdef S_IFLNK
- case S_IFLNK:
- type = @symbol(symbolicLink);
- break;
+ case S_IFLNK:
+ type = @symbol(symbolicLink);
+ break;
# endif
# ifdef S_IFSOCK
- case S_IFSOCK:
- type = @symbol(socket);
- break;
+ case S_IFSOCK:
+ type = @symbol(socket);
+ break;
# endif
# ifdef S_IFIFO
- case S_IFIFO:
- type = @symbol(fifo);
- break;
-# endif
- default:
- type = @symbol(unknown);
- break;
+ case S_IFIFO:
+ type = @symbol(fifo);
+ break;
+# endif
+ default:
+ type = @symbol(unknown);
+ break;
}
if (sizeof(buf.st_ino) == 8) {
- id = __MKUINT64(&buf.st_ino);
+ id = __MKUINT64(&buf.st_ino);
} else {
- id = __MKUINT(buf.st_ino);
+ id = __MKUINT(buf.st_ino);
}
mode = __mkSmallInteger(buf.st_mode & 0777);
uid = __mkSmallInteger(buf.st_uid);
gid = __mkSmallInteger(buf.st_gid);
nLink = __mkSmallInteger(buf.st_nlink);
if (sizeof(buf.st_size) == 8) {
- size = __MKINT64(&buf.st_size);
+ size = __MKINT64(&buf.st_size);
} else {
- size = __MKINT(buf.st_size);
+ size = __MKINT(buf.st_size);
}
aOStime = __MKUINT(buf.st_atime);
mOStime = __MKUINT(buf.st_mtime);
@@ -4583,26 +4622,26 @@
out:;
%}.
mode notNil ifTrue:[
- "/ now done lazy in FileStatusInfo
- "/ atime := Timestamp fromOSTime:(aOStime * 1000).
- "/ mtime := Timestamp fromOSTime:(mOStime * 1000).
- "/ ctime := Timestamp fromOSTime:(cOStime * 1000).
-
- ^ FileStatusInfo
- type:type
- mode:mode
- uid:uid
- gid:gid
- size:size
- id:id
- accessed:aOStime
- modified:mOStime
- statusChanged:cOStime
- path:nil
- numLinks:nLink.
+ "/ now done lazy in FileStatusInfo
+ "/ atime := Timestamp fromOSTime:(aOStime * 1000).
+ "/ mtime := Timestamp fromOSTime:(mOStime * 1000).
+ "/ ctime := Timestamp fromOSTime:(cOStime * 1000).
+
+ ^ FileStatusInfo
+ type:type
+ mode:mode
+ uid:uid
+ gid:gid
+ size:size
+ id:id
+ accessed:aOStime
+ modified:mOStime
+ statusChanged:cOStime
+ path:nil
+ numLinks:nLink.
].
error notNil ifTrue:[
- ^ nil.
+ ^ nil.
].
^ self primitiveFailed
@@ -4620,31 +4659,35 @@
This also returns true for symbolic links pointing to a directory;
if you need to check for this, use #linkInfo:."
+ |encodedPathName|
+
+ encodedPathName := self encodePath:aPathName.
+
%{
int ret;
- if (__isStringLike(aPathName)) {
- struct stat buf;
+ if (__isStringLike(encodedPathName)) {
+ struct stat buf;
# ifdef TRACE_STAT_CALLS
- printf("stat on '%s' for isDirectory\n", __stringVal(aPathName));
-# endif
- __BEGIN_INTERRUPTABLE__
- do {
- ret = stat((char *) __stringVal(aPathName), &buf);
- } while ((ret < 0) && (errno == EINTR));
- __END_INTERRUPTABLE__
- if (ret < 0) {
- @global(LastErrorNumber) = __mkSmallInteger(errno);
- RETURN ( false );
- }
- RETURN ( ((buf.st_mode & S_IFMT) == S_IFDIR) ? true : false);
+ printf("stat on '%s' for isDirectory\n", __stringVal(encodedPathName));
+# endif
+ __BEGIN_INTERRUPTABLE__
+ do {
+ ret = stat((char *) __stringVal(encodedPathName), &buf);
+ } while ((ret < 0) && (errno == EINTR));
+ __END_INTERRUPTABLE__
+ if (ret < 0) {
+ @global(LastErrorNumber) = __mkSmallInteger(errno);
+ RETURN ( false );
+ }
+ RETURN ( ((buf.st_mode & S_IFMT) == S_IFDIR) ? true : false);
}
%}.
^ self primitiveFailed
"an alternative implementation would be:
- ^ (self infoOf:aPathName) type == #directory
+ ^ (self infoOf:aPathName) type == #directory
"
!
@@ -4652,22 +4695,26 @@
"return true, if the given file is executable.
For symbolic links, the pointed-to-file is checked."
+ |encodedPathName|
+
+ encodedPathName := self encodePath:aPathName.
+
%{
int ret;
- if (__isStringLike(aPathName)) {
+ if (__isStringLike(encodedPathName)) {
# ifdef TRACE_ACCESS_CALLS
- printf("access on '%s' for executable\n", __stringVal(aPathName));
-# endif
- __BEGIN_INTERRUPTABLE__
- do {
- ret = access(__stringVal(aPathName), X_OK);
- } while ((ret < 0) && (errno == EINTR));
- __END_INTERRUPTABLE__
- if (ret < 0) {
- @global(LastErrorNumber) = __mkSmallInteger(errno);
- }
- RETURN ( ((ret == 0) ? true : false) );
+ printf("access on '%s' for executable\n", __stringVal(encodedPathName));
+# endif
+ __BEGIN_INTERRUPTABLE__
+ do {
+ ret = access(__stringVal(encodedPathName), X_OK);
+ } while ((ret < 0) && (errno == EINTR));
+ __END_INTERRUPTABLE__
+ if (ret < 0) {
+ @global(LastErrorNumber) = __mkSmallInteger(errno);
+ }
+ RETURN ( ((ret == 0) ? true : false) );
}
%}.
^ self primitiveFailed
@@ -4677,22 +4724,25 @@
"return true, if the file/dir 'aPathName' is readable.
For symbolic links, the pointed-to-file is checked."
+ |encodedPathName|
+
+ encodedPathName := self encodePath:aPathName.
%{
int ret;
- if (__isStringLike(aPathName)) {
+ if (__isStringLike(encodedPathName)) {
# ifdef TRACE_ACCESS_CALLS
- printf("access on '%s' for readable\n", __stringVal(aPathName));
-# endif
- __BEGIN_INTERRUPTABLE__
- do {
- ret = access(__stringVal(aPathName), R_OK);
- } while ((ret < 0) && (errno == EINTR));
- __END_INTERRUPTABLE__
- if (ret < 0) {
- @global(LastErrorNumber) = __mkSmallInteger(errno);
- }
- RETURN ( ((ret == 0) ? true : false) );
+ printf("access on '%s' for readable\n", __stringVal(encodedPathName));
+# endif
+ __BEGIN_INTERRUPTABLE__
+ do {
+ ret = access(__stringVal(encodedPathName), R_OK);
+ } while ((ret < 0) && (errno == EINTR));
+ __END_INTERRUPTABLE__
+ if (ret < 0) {
+ @global(LastErrorNumber) = __mkSmallInteger(errno);
+ }
+ RETURN ( ((ret == 0) ? true : false) );
}
%}.
^ self primitiveFailed
@@ -4702,24 +4752,27 @@
"return true, if 'aPathName' is a valid path name
(i.e. the file or directory exists)"
+ |encodedPathName|
+
+ encodedPathName := self encodePath:aPathName.
%{
struct stat buf;
int ret;
- if (__isStringLike(aPathName)) {
+ if (__isStringLike(encodedPathName)) {
# ifdef TRACE_STAT_CALLS
- printf("stat on '%s' for isValidPath\n", __stringVal(aPathName));
-# endif
- __BEGIN_INTERRUPTABLE__
- do {
- ret = stat((char *) __stringVal(aPathName), &buf);
- } while ((ret < 0) && (errno == EINTR));
- __END_INTERRUPTABLE__
- if (ret < 0) {
- @global(LastErrorNumber) = __mkSmallInteger(errno);
- RETURN (false);
- }
- RETURN ( ret ? false : true );
+ printf("stat on '%s' for isValidPath\n", __stringVal(encodedPathName));
+# endif
+ __BEGIN_INTERRUPTABLE__
+ do {
+ ret = stat((char *) __stringVal(encodedPathName), &buf);
+ } while ((ret < 0) && (errno == EINTR));
+ __END_INTERRUPTABLE__
+ if (ret < 0) {
+ @global(LastErrorNumber) = __mkSmallInteger(errno);
+ RETURN (false);
+ }
+ RETURN ( ret ? false : true );
}
%}.
^ self primitiveFailed
@@ -4732,22 +4785,25 @@
"return true, if the given file is writable.
For symbolic links, the pointed-to-file is checked."
+ |encodedPathName|
+
+ encodedPathName := self encodePath:aPathName.
%{
int ret;
- if (__isStringLike(aPathName)) {
+ if (__isStringLike(encodedPathName)) {
# ifdef TRACE_ACCESS_CALLS
- printf("access on '%s' for writable\n", __stringVal(aPathName));
-# endif
- __BEGIN_INTERRUPTABLE__
- do {
- ret = access(__stringVal(aPathName), W_OK);
- } while ((ret < 0) && (errno == EINTR));
- __END_INTERRUPTABLE__
- if (ret < 0) {
- @global(LastErrorNumber) = __mkSmallInteger(errno);
- }
- RETURN ( ((ret == 0) ? true : false) );
+ printf("access on '%s' for writable\n", __stringVal(encodedPathName));
+# endif
+ __BEGIN_INTERRUPTABLE__
+ do {
+ ret = access(__stringVal(encodedPathName), W_OK);
+ } while ((ret < 0) && (errno == EINTR));
+ __END_INTERRUPTABLE__
+ if (ret < 0) {
+ @global(LastErrorNumber) = __mkSmallInteger(errno);
+ }
+ RETURN ( ((ret == 0) ? true : false) );
}
%}.
^ self primitiveFailed
@@ -4784,7 +4840,9 @@
on contrast to #infoOf:, which returns the info of the pointed to file
in case of a symbolic link."
- |type mode uid gid size id nLink aOStime mOStime cOStime path|
+ |type mode uid gid size id nLink aOStime mOStime cOStime path encodedPathName|
+
+ encodedPathName := self encodePath:aPathName.
%{ /* STACK: 1200 */
#if defined(S_IFLNK)
@@ -4792,10 +4850,10 @@
int ret;
char pathBuffer[1024];
- if (__isStringLike(aPathName)) {
+ if (__isStringLike(encodedPathName)) {
__BEGIN_INTERRUPTABLE__
do {
- ret = lstat((char *) __stringVal(aPathName), &buf);
+ ret = lstat((char *) __stringVal(encodedPathName), &buf);
} while ((ret < 0) && (errno == EINTR));
__END_INTERRUPTABLE__
@@ -4807,7 +4865,7 @@
# ifdef S_IFLNK
case S_IFLNK:
type = @symbol(symbolicLink);
- if ((ret = readlink((char *) __stringVal(aPathName), pathBuffer, sizeof(pathBuffer))) < 0) {
+ if ((ret = readlink((char *) __stringVal(encodedPathName), pathBuffer, sizeof(pathBuffer))) < 0) {
@global(LastErrorNumber) = __mkSmallInteger(errno);
RETURN ( nil );
}
@@ -4880,15 +4938,6 @@
#endif
%}.
- path notNil ifTrue:[
- [
- path := path utf8Decoded.
- ] on:InvalidEncodingError do:[:ex|
- "maybe there are old filenames in ISO8859-x,
- just keep them untranslated"
- ].
- ].
-
mode notNil ifTrue:[
^ FileStatusInfo
type:type
@@ -4900,7 +4949,7 @@
accessed:aOStime
modified:mOStime
statusChanged:cOStime
- path:path
+ path:(self decodePath:path)
numLinks:nLink.
].
^ self primitiveFailed
@@ -4957,47 +5006,51 @@
|p path command|
+ path = '.' ifTrue:[
+ ^ self getCurrentDirectory.
+ ].
+
"some systems have a convenient function for this ..."
- path := self primPathNameOf:pathName.
+ path := self primPathNameOf:(self encodePath:pathName).
path isNil ifTrue:[
- (self isValidPath:pathName) ifFalse:[
- p := pathName.
- [(p size > 1)
- and:[p endsWith:(self fileSeparator)]
- ] whileTrue:[
- p := p copyWithoutLast:1.
- ].
- ^ p
- ].
-
- (SlowFork==true or:[PipeFailed==true]) ifFalse:[
- PipeStream openErrorSignal handle:[:ex |
- PipeFailed := true.
- 'UnixOperatingSystem [warning]: cannot fork/popen' errorPrintCR.
- ex return.
- ] do:[
- "have to fall back ..."
- command := 'cd "' , pathName , '"; pwd'.
- p := PipeStream readingFrom:command.
- ].
-
- (p isNil or:[p atEnd]) ifTrue:[
- ('UnixOperatingSystem [warning]: PipeStream for <' , command , '> failed') errorPrintCR.
- ] ifFalse:[
- path := p nextLine.
- p close.
- ]
- ].
- path isNil ifTrue:[
- "/
- "/ return the original - there is nothing else can we do
- "/
- path := pathName
- ].
- (SlowFork==true or:[ForkFailed==true]) ifTrue:[
- path := self compressPath:path
- ]
+ (self isValidPath:pathName) ifFalse:[
+ p := pathName.
+ [(p size > 1)
+ and:[p endsWith:(self fileSeparator)]
+ ] whileTrue:[
+ p := p copyWithoutLast:1.
+ ].
+ ^ p
+ ].
+
+ (SlowFork==true or:[PipeFailed==true]) ifFalse:[
+ PipeStream openErrorSignal handle:[:ex |
+ PipeFailed := true.
+ 'UnixOperatingSystem [warning]: cannot fork/popen' errorPrintCR.
+ ex return.
+ ] do:[
+ "have to fall back ..."
+ command := 'cd "' , pathName , '"; pwd'.
+ p := PipeStream readingFrom:command.
+ ].
+
+ (p isNil or:[p atEnd]) ifTrue:[
+ ('UnixOperatingSystem [warning]: PipeStream for <' , command , '> failed') errorPrintCR.
+ ] ifFalse:[
+ path := p nextLine.
+ p close.
+ ]
+ ].
+ path isNil ifTrue:[
+ "/
+ "/ return the original - there is nothing else can we do
+ "/
+ path := pathName
+ ].
+ (SlowFork==true or:[ForkFailed==true]) ifTrue:[
+ path := self compressPath:path
+ ]
].
^ path.
@@ -5019,28 +5072,31 @@
primIdOf:aPathName
"the actual code to return the fileNumber (i.e. inode number) of a file."
+ |encodedPathName|
+
+ encodedPathName := self encodePath:aPathName.
%{
struct stat buf;
int ret;
unsigned INT ino;
OBJ retVal;
- if (__isStringLike(aPathName)) {
+ if (__isStringLike(encodedPathName)) {
# ifdef TRACE_STAT_CALLS
- printf("stat on '%s' for id\n", __stringVal(aPathName));
-# endif
- __BEGIN_INTERRUPTABLE__
- do {
- ret = stat((char *) __stringVal(aPathName), &buf);
- } while (ret < 0 && errno == EINTR);
- __END_INTERRUPTABLE__
- if (ret >= 0) {
- ino = buf.st_ino;
- retVal = __MKUINT(ino);
- RETURN (retVal);
- }
- @global(LastErrorNumber) = __mkSmallInteger(errno);
- RETURN (nil);
+ printf("stat on '%s' for id\n", __stringVal(encodedPathName));
+# endif
+ __BEGIN_INTERRUPTABLE__
+ do {
+ ret = stat((char *) __stringVal(encodedPathName), &buf);
+ } while (ret < 0 && errno == EINTR);
+ __END_INTERRUPTABLE__
+ if (ret >= 0) {
+ ino = buf.st_ino;
+ retVal = __MKUINT(ino);
+ RETURN (retVal);
+ }
+ @global(LastErrorNumber) = __mkSmallInteger(errno);
+ RETURN (nil);
}
RETURN (nil);
%}.
@@ -5062,25 +5118,9 @@
Notice: if symbolic links are involved, the result may look different
from what you expect."
- |path|
-
%{ /* UNLIMITEDSTACK */
if (__isStringLike(pathName)) {
- if (strcmp(__stringVal(pathName), ".") == 0) {
- char nameBuffer[MAXPATHLEN + 1];
-
- if (@global(CurrentDirectory) == nil) {
- if (getcwd(nameBuffer, MAXPATHLEN)) {
- OBJ d;
-
- @global(CurrentDirectory) = d = __MKSTRING(nameBuffer);
- __GSTORE(d);
- }
- }
- RETURN (@global(CurrentDirectory));
- }
-
#ifdef HAS_REALPATH
{
char nameBuffer[MAXPATHLEN+1];
@@ -5088,7 +5128,6 @@
if (realpath(__stringVal(pathName), nameBuffer)) {
RETURN ( __MKSTRING(nameBuffer) );
}
- RETURN ( nil );
}
#endif /* ! HAS_REALPATH */
}
@@ -5101,28 +5140,31 @@
For nonexistent files, nil is returned."
"could be implemented as:
- (self infoOf:aPathName) accessed
- "
- |osSeconds i|
+ (self infoOf:aPathName) accessed
+ "
+ |osSeconds i encodedPathName|
+
+ encodedPathName := self encodePath:aPathName.
+
%{
struct stat buf;
time_t mtime;
int ret;
- if (__isStringLike(aPathName)) {
+ if (__isStringLike(encodedPathName)) {
# ifdef TRACE_STAT_CALLS
- printf("stat on '%s' for timeOfLastAccess\n", __stringVal(aPathName));
-# endif
- __BEGIN_INTERRUPTABLE__
- do {
- ret = stat((char *) __stringVal(aPathName), &buf);
- } while (ret < 0 && errno == EINTR);
- __END_INTERRUPTABLE__
- if (ret < 0) {
- @global(LastErrorNumber) = __mkSmallInteger(errno);
- RETURN (nil);
- }
- osSeconds = __MKUINT(buf.st_atime);
+ printf("stat on '%s' for timeOfLastAccess\n", __stringVal(encodedPathName));
+# endif
+ __BEGIN_INTERRUPTABLE__
+ do {
+ ret = stat((char *) __stringVal(encodedPathName), &buf);
+ } while (ret < 0 && errno == EINTR);
+ __END_INTERRUPTABLE__
+ if (ret < 0) {
+ @global(LastErrorNumber) = __mkSmallInteger(errno);
+ RETURN (nil);
+ }
+ osSeconds = __MKUINT(buf.st_atime);
}
%}.
osSeconds notNil ifTrue:[^ Timestamp fromOSTime:(osSeconds * 1000)].
@@ -5141,29 +5183,31 @@
For nonexistent files, nil is returned."
"could be implemented as:
- (self infoOf:aPathName) modified
- "
-
- |osSeconds i|
+ (self infoOf:aPathName) modified
+ "
+
+ |osSeconds i encodedPathName|
+
+ encodedPathName := self encodePath:aPathName.
%{
struct stat buf;
int ret;
time_t mtime;
- if (__isStringLike(aPathName)) {
+ if (__isStringLike(encodedPathName)) {
# ifdef TRACE_STAT_CALLS
- printf("stat on '%s' for timeOfLastChange\n", __stringVal(aPathName));
-# endif
- __BEGIN_INTERRUPTABLE__
- do {
- ret = stat((char *) __stringVal(aPathName), &buf);
- } while (ret < 0 && errno == EINTR);
- __END_INTERRUPTABLE__
- if (ret < 0) {
- @global(LastErrorNumber) = __mkSmallInteger(errno);
- RETURN ( nil );
- }
- osSeconds = __MKUINT(buf.st_mtime);
+ printf("stat on '%s' for timeOfLastChange\n", __stringVal(encodedPathName));
+# endif
+ __BEGIN_INTERRUPTABLE__
+ do {
+ ret = stat((char *) __stringVal(encodedPathName), &buf);
+ } while (ret < 0 && errno == EINTR);
+ __END_INTERRUPTABLE__
+ if (ret < 0) {
+ @global(LastErrorNumber) = __mkSmallInteger(errno);
+ RETURN ( nil );
+ }
+ osSeconds = __MKUINT(buf.st_mtime);
}
%}.
osSeconds notNil ifTrue:[^ Timestamp fromOSTime:(osSeconds * 1000)].
@@ -5182,11 +5226,13 @@
nil is returned.
Notice: for symbolic links, the type of the pointed-to file is returned."
- |i|
+ |i osSeconds encodedPathName|
+
+ encodedPathName := self encodePath:aPathName.
"
this could have been implemented as:
- (self infoOf:aPathName) type
+ (self infoOf:aPathName) type
but for huge directory searches the code below is faster
"
@@ -5194,47 +5240,47 @@
struct stat buf;
int ret;
- if (__isStringLike(aPathName)) {
+ if (__isStringLike(encodedPathName)) {
# ifdef TRACE_STAT_CALLS
- printf("stat on '%s' for type\n", __stringVal(aPathName));
-# endif
- __BEGIN_INTERRUPTABLE__
- do {
- ret = stat((char *) __stringVal(aPathName), &buf);
- } while (ret < 0 && errno == EINTR);
- __END_INTERRUPTABLE__
- if (ret < 0) {
- @global(LastErrorNumber) = __mkSmallInteger(errno);
- RETURN ( nil );
- }
- switch (buf.st_mode & S_IFMT) {
- case S_IFDIR:
- RETURN ( @symbol(directory) );
- case S_IFREG:
- RETURN ( @symbol(regular) );
+ printf("stat on '%s' for type\n", __stringVal(encodedPathName));
+# endif
+ __BEGIN_INTERRUPTABLE__
+ do {
+ ret = stat((char *) __stringVal(encodedPathName), &buf);
+ } while (ret < 0 && errno == EINTR);
+ __END_INTERRUPTABLE__
+ if (ret < 0) {
+ @global(LastErrorNumber) = __mkSmallInteger(errno);
+ RETURN ( nil );
+ }
+ switch (buf.st_mode & S_IFMT) {
+ case S_IFDIR:
+ RETURN ( @symbol(directory) );
+ case S_IFREG:
+ RETURN ( @symbol(regular) );
# ifdef S_IFCHR
- case S_IFCHR:
- RETURN ( @symbol(characterSpecial) );
+ case S_IFCHR:
+ RETURN ( @symbol(characterSpecial) );
# endif
# ifdef S_IFBLK
- case S_IFBLK:
- RETURN ( @symbol(blockSpecial) );
+ case S_IFBLK:
+ RETURN ( @symbol(blockSpecial) );
# endif
# ifdef S_IFLNK
- case S_IFLNK:
- RETURN ( @symbol(symbolicLink) );
+ case S_IFLNK:
+ RETURN ( @symbol(symbolicLink) );
# endif
# ifdef S_IFSOCK
- case S_IFSOCK:
- RETURN ( @symbol(socket) );
+ case S_IFSOCK:
+ RETURN ( @symbol(socket) );
# endif
# ifdef S_IFIFO
- case S_IFIFO:
- RETURN ( @symbol(fifo) );
-# endif
- default:
- RETURN ( @symbol(unknown) );
- }
+ case S_IFIFO:
+ RETURN ( @symbol(fifo) );
+# endif
+ default:
+ RETURN ( @symbol(unknown) );
+ }
}
%}.
i := self infoOf:aPathName.
@@ -8379,6 +8425,23 @@
!UnixOperatingSystem class methodsFor:'path queries'!
+decodePath:encodedPathName
+ "decode the pathName as returned by system calls.
+ E.g. linux system calls return sigle byte strings only,
+ so the pathName has been UTF-8 decoded."
+
+ "linux strings are in UTF8 (in contemporary linux versions)"
+ encodedPathName notNil ifTrue:[
+ [
+ ^ encodedPathName utf8Decoded.
+ ] on:InvalidEncodingError do:[:ex|
+ "maybe there are old filenames in ISO8859-x,
+ just keep them untranslated"
+ ].
+ ].
+ ^ encodedPathName
+!
+
defaultSystemPath
"add additional directories to the systemPath
(but only, if the major version is the same)"
@@ -8427,6 +8490,14 @@
"
OperatingSystem defaultSystemPath
"
+!
+
+encodePath:pathName
+ "encode the pathName for use with system calls.
+ E.g. linux system calls accept sigle byte strings only,
+ so the pathName has been UTF-8 encoded, before using it in a system call."
+
+ ^ pathName utf8Encoded
! !
!UnixOperatingSystem class methodsFor:'private'!
@@ -13292,11 +13363,11 @@
!UnixOperatingSystem class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic/UnixOperatingSystem.st,v 1.289 2012-12-13 11:13:51 stefan Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/UnixOperatingSystem.st,v 1.290 2012-12-13 13:20:12 stefan Exp $'
!
version_CVS
- ^ '$Header: /cvs/stx/stx/libbasic/UnixOperatingSystem.st,v 1.289 2012-12-13 11:13:51 stefan Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/UnixOperatingSystem.st,v 1.290 2012-12-13 13:20:12 stefan Exp $'
! !
UnixOperatingSystem initialize!