UnixOperatingSystem.st
branchjv
changeset 21088 6f4535127ce6
parent 21024 8734987eb5c7
parent 21072 8c9b32a1d4a8
child 21247 9ee1206fc247
--- a/UnixOperatingSystem.st	Wed Nov 30 10:19:49 2016 +0000
+++ b/UnixOperatingSystem.st	Wed Nov 30 10:25:34 2016 +0000
@@ -1,3 +1,5 @@
+"{ Encoding: utf8 }"
+
 "
  COPYRIGHT (c) 1988 by Claus Gittinger
 	      All Rights Reserved
@@ -502,6 +504,7 @@
 # endif
 
 # if defined(HAS_SYSINFO)
+#  include <sys/sysinfo.h>
 #  include <sys/systeminfo.h>
 # endif
 
@@ -538,7 +541,7 @@
  * on some systems errno is a macro ... check for it here
  */
 #ifndef errno
- extern errno;
+ extern int errno;
 #endif
 
 /*
@@ -687,13 +690,15 @@
 
 # if !defined (__sigemptyset)
 #  define      __sigemptyset   sigemptyset
+# endif
+# if !defined (__sigaction)
 #  define      __sigaction     sigaction
 #  define      __sigaddset     sigaddset
 #  define      __sigprocmask   sigprocmask
 #  define      __execve        execve
 #  define      __wait          wait
 #  define      __waitpid       waitpid
-#  endif /* ! LINUX */
+# endif /* ! LINUX */
 
 # define      __sigprocmask   sigprocmask
 # define      __execve        execve
@@ -703,8 +708,7 @@
 
 
 static int
-mySystem(line)
-    register CONST char *line;
+mySystem(const char *line)
 {
     int status, save;
     pid_t pid;
@@ -3936,13 +3940,16 @@
 
 %{
 #if defined(HAS_SENDFILE)
+# include <sys/sendfile.h>
+
      if (__isSmallInteger(inFd)
       && __isSmallInteger(outFd)
       && __isSmallInteger(startIdx)
       && __isSmallInteger(count)) {
-	int nWritten;
-
-	nWritten = sendfile(__intVal(outFd), __intVal(inFd), __intVal(startIdx), __intVal(count));
+	off_t startOffset = __intVal(startIdx); 
+	ssize_t nWritten;
+
+	nWritten = sendfile(__intVal(outFd), __intVal(inFd), &startOffset, __intVal(count));
 	if (nWritten < 0) {
 	    @global(LastErrorNumber) = __mkSmallInteger(errno);
 	}
@@ -3972,25 +3979,31 @@
 createDirectory:aPathName withAccess:umask
     "create a new directory with name 'aPathName', which may be an absolute
      path, or relative to the current directory.
-     Return true if successful (or the directory existed already), false if failed.
+     Return nil if successful (or the directory existed already), an OsErrorHolder otherwise.
      This is a low-level entry - use Filename protocol for compatibility."
 
-    |encodedPathName|
+    |encodedPathName error|
 
     encodedPathName := self encodePath:aPathName.
 
 %{
     if (__isStringLike(encodedPathName) && __isSmallInteger(umask)) {
-	if (mkdir(__stringVal(encodedPathName), __smallIntegerVal(umask)) >= 0) {
-	    RETURN(true);
-	}
-	@global(LastErrorNumber) = __mkSmallInteger(errno);
+        if (mkdir(__stringVal(encodedPathName), __smallIntegerVal(umask)) >= 0) {
+            RETURN(nil);
+        }
+        error = __mkSmallInteger(errno);
     }
 %}.
     "/ could not create - if it already existed this is ok
 
-    (self isDirectory:aPathName) ifTrue:[^ true].
-    ^ false.
+    (self isDirectory:aPathName) ifTrue:[^ nil].
+
+    error notNil ifTrue:[
+        LastErrorNumber := error.
+        ^ self errorHolderForNumber:error.
+    ].
+
+    ^ self primitiveFailed
 
 
     "
@@ -4019,7 +4032,7 @@
     "link the file 'oldPath' to 'newPath'. The link will be a hard link.
      Return true if successful, false if not."
 
-    |encodedOldPathName encodedNewPathName|
+    |encodedOldPathName encodedNewPathName error|
 
     encodedOldPathName := self encodePath:oldPath.
     encodedNewPathName := self encodePath:newPath.
@@ -4028,18 +4041,23 @@
     int ret;
 
     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);
-    }
-%}.
+        __BEGIN_INTERRUPTABLE__
+        do {
+            ret = link((char *) __stringVal(encodedOldPathName), (char *) __stringVal(encodedNewPathName));
+        } while (ret < 0 && errno == EINTR);
+        __END_INTERRUPTABLE__
+        if (ret >= 0) {
+            RETURN (nil);
+        }
+        error = __mkSmallInteger(errno);
+    }
+%}.
+
+    error notNil ifTrue:[
+        LastErrorNumber := error.
+        ^ self errorHolderForNumber:error.
+    ].
+
     "/
     "/ bad argument(s) given
     "/
@@ -4053,9 +4071,9 @@
 createSymbolicLinkFrom:oldPath to:newPath
     "make a symbolic link for 'newPath' to the file 'oldPath'.
      The link will be a soft (symbolic) link.
-     Raise an error on error."
-
-    |error encodedOldPathName encodedNewPathName|
+     Answer nil on success and an OSErrorHolder on error."
+
+    |encodedOldPathName encodedNewPathName error|
 
     encodedOldPathName := self encodePath:oldPath.
     encodedNewPathName := self encodePath:newPath.
@@ -4064,32 +4082,35 @@
     int ret;
 
     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) {
-	    RETURN (true);
-	}
-	@global(LastErrorNumber) = error = __mkSmallInteger(errno);
-    }
-#endif
-%}.
+        __BEGIN_INTERRUPTABLE__
+        do {
+            ret = symlink((char *) __stringVal(encodedOldPathName), (char *) __stringVal(encodedNewPathName));
+        } while (ret < 0 && errno == EINTR);
+        __END_INTERRUPTABLE__
+        if (ret >= 0) {
+            RETURN (nil);
+        }
+        error = __mkSmallInteger(errno);
+    }
+#endif
+%}.
+
+    error notNil ifTrue:[
+        LastErrorNumber := error.
+        ^ self errorHolderForNumber:error.
+    ].
+
     (encodedOldPathName isString not or:[encodedNewPathName isString not]) ifTrue:[
-	"/
-	"/ bad argument(s) given
-	"/
-	^ self primitiveFailed
-    ].
-    error notNil ifTrue:[
-	(self errorHolderForNumber:error) reportError
+        "/
+        "/ bad argument(s) given
+        "/
+        ^ self primitiveFailed
     ].
 
     "/
     "/ this Unix does not seem to support symbolic links
     "/
-    ^ UnsupportedOperationSignal raise
+    ^ OSErrorHolder unsupportedOperation
 
     "
      OperatingSystem createSymbolicLinkFrom:'foo' to:'/tmp/bar'
@@ -4273,28 +4294,33 @@
      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 error|
 
     encodedPathName := self encodePath:fullPathName.
 %{
     int ret;
 
     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);
-    }
-%}.
+        __BEGIN_INTERRUPTABLE__
+        do {
+            ret = rmdir((char *) __stringVal(encodedPathName));
+        } while (ret < 0 && errno == EINTR);
+        __END_INTERRUPTABLE__
+
+        if (ret >= 0) {
+            RETURN (nil);
+        }
+        error = __mkSmallInteger(errno);
+    }
+%}.
+
+    error notNil ifTrue:[
+        LastErrorNumber := error.
+        ^ self errorHolderForNumber:error.
+    ].
+
     "/
-    "/ either not a string argument,
-    "/ or not supported by OS
+    "/ either not a string argument
     "/
     ^ self primitiveFailed
 
@@ -4308,25 +4334,32 @@
     "remove the file named 'fullPathName'; return true if successful.
      This is a lowLevel entry - use Filename protocol for compatibility."
 
-    |encodedPathName|
+    |encodedPathName error|
 
     encodedPathName := self encodePath:fullPathName.
 %{
     int ret;
 
     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);
-    }
-%}.
+        __BEGIN_INTERRUPTABLE__
+        do {
+            ret = unlink((char *) __stringVal(encodedPathName));
+        } while (ret < 0 && errno == EINTR);
+        __END_INTERRUPTABLE__
+
+        if (ret >= 0) {
+            RETURN (nil);
+        }
+        error = __mkSmallInteger(errno);
+    }
+%}.
+
+    error notNil ifTrue:[
+        LastErrorNumber := error.
+        ^ self errorHolderForNumber:error.
+    ].
+
+
     ^ self primitiveFailed
 !
 
@@ -4336,9 +4369,9 @@
      correct for the OS used - therefore, this should not be called
      directly. Instead, use Filename protocol to rename; this cares for
      any invalid names.
-     Returns true if successful, false if not"
-
-    |encodedOldPathName encodedNewPathName|
+     Returns nil if successful, an OsErrorHolder if not"
+
+    |encodedOldPathName encodedNewPathName error|
 
     encodedOldPathName := self encodePath:oldPath.
     encodedNewPathName := self encodePath:newPath.
@@ -4347,29 +4380,34 @@
 
     if (__isStringLike(encodedOldPathName) && __isStringLike(encodedNewPathName)) {
 #if defined(HAS_RENAME)
-	__BEGIN_INTERRUPTABLE__
-	do {
-	    ret = rename((char *) __stringVal(encodedOldPathName), (char *) __stringVal(encodedNewPathName));
-	} 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(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);
-    }
-%}.
+        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) {
+            RETURN (nil);
+        }
+        error = __mkSmallInteger(errno);
+    }
+%}.
+
+    error notNil ifTrue:[
+        LastErrorNumber := error.
+        ^ self errorHolderForNumber:error.
+    ].
+
     ^ self primitiveFailed
 
     "
@@ -4382,9 +4420,8 @@
 
 %{
     sync();
-    RETURN (self);
-%}.
-    ^ self primitiveFailed
+%}.
+    ^ nil
 !
 
 syncFileSystem:handle
@@ -4417,12 +4454,12 @@
 !
 
 truncateFile:aPathName to:newSize
-    "change a files size return true on success, false on failure.
+    "change a files size return nil on success, an OSErrorHolder on failure.
      This may not be supported on all architectures.
 
      This is a low-level entry - use Filename protocol."
 
-    |encodedPathName|
+    |encodedPathName error|
 
     encodedPathName := self encodePath:aPathName.
 
@@ -4432,62 +4469,70 @@
     off_t truncateSize;
 
     if (!__isStringLike(encodedPathName))
-	goto getOutOfHere;
+        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(encodedPathName), truncateSize);
-	} while (ret < 0 && errno == EINTR);
-	__END_INTERRUPTABLE__
-#else
-# ifdef HAS_FTRUNCATE
+        __BEGIN_INTERRUPTABLE__
+        do {
+            ret = truncate((char *) __stringVal(encodedPathName), truncateSize);
+        } while (ret < 0 && errno == EINTR);
+        __END_INTERRUPTABLE__
+
+#elif defined(HAS_FTRUNCATE)
     {
-	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 );
-    }
-    RETURN (true);
+        int fd;
+
+        do {
+            fd = ret = open((char *) __stringVal(encodedPathName), 2);
+        } while (fd < 0 && errno == EINTR);
+        if (fd >= 0) {
+            ret = ftruncate(fd, truncateSize);
+            close(fd);
+        }
+    }
+#endif /* HAS_FTRUNCATE */
+        if (ret >= 0) {
+            RETURN (nil);
+        }
+        error = __mkSmallInteger(errno);
+
 getOutOfHere:;
-#endif
-%}.
+#else
+        error = __mkSmallInteger(ENOTSUP);
+#endif
+%}.
+
+    error notNil ifTrue:[
+        LastErrorNumber := error.
+        ^ self errorHolderForNumber:error.
+    ].
+
     ^ self primitiveFailed
+
+    "
+        self truncateFile:'foo' to:2222222
+    "
 ! !
 
 !UnixOperatingSystem class methodsFor:'file access rights'!
@@ -4563,17 +4608,17 @@
 
 accessModeOf:aPathName
     "return a number representing access rights rwxrwxrwx for owner,
-     group and others. Return nil if such a file does not exist.
+     group and others. Return an OSErrorHolder if such a file does not exist.
      Notice that the returned number is OS dependent - use the
      modeMasks as returned by OperatingSystem>>accessMaskFor:"
 
     "
      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 error|
 
     encodedPathName := self encodePath:aPathName.
 %{
@@ -4582,21 +4627,26 @@
 
     if (__isStringLike(encodedPathName)) {
 #ifdef TRACE_STAT_CALLS
-	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) );
-    }
-%}.
+        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) {
+            RETURN ( __mkSmallInteger(buf.st_mode & 0777) );
+        }
+        error = __mkSmallInteger(errno);
+    }
+%}.
+
+    error notNil ifTrue:[
+        LastErrorNumber := error.
+        ^ self errorHolderForNumber:error.
+    ].
+
    ^ self primitiveFailed
 
    "
@@ -4610,32 +4660,39 @@
      Notice that the returned number is OS dependent - use the
      modeMasks as returned by OperatingSystem>>accessMaskFor:"
 
+    |error|
+
 %{
     struct stat buf;
     int ret;
 
     if (__isSmallInteger(aFileDescriptor)) {
 # ifdef TRACE_STAT_CALLS
-	printf("fstat on '%d' for accessMode\n", __smallIntegerVal(aFileDescriptor));
-# endif
-	__BEGIN_INTERRUPTABLE__
-	do {
-	    ret = fstat(__smallIntegerVal(aFileDescriptor), &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
+        printf("fstat on '%d' for accessMode\n", __smallIntegerVal(aFileDescriptor));
+# endif
+        __BEGIN_INTERRUPTABLE__
+        do {
+            ret = fstat(__smallIntegerVal(aFileDescriptor), &buf);
+        } while ((ret < 0) && (errno == EINTR));
+        __END_INTERRUPTABLE__
+
+        if (ret >= 0) {
+            RETURN ( __mkSmallInteger(buf.st_mode & 0777) );
+        }
+        error = __mkSmallInteger(errno);
+    }
+%}.
+
+    error notNil ifTrue:[
+        LastErrorNumber := error.
+        ^ self errorHolderForNumber:error.
+    ].
+
+    ^ self primitiveFailed
 
    "
     '/' asFilename readingFileDo:[:s|
-	(OperatingSystem accessModeOfFd:s fileDescriptor) printStringRadix:8
+        (OperatingSystem accessModeOfFd:s fileDescriptor) printStringRadix:8
     ].
    "
 !
@@ -4643,54 +4700,72 @@
 changeAccessModeOf:aPathName to:modeBits
     "change the access rights of aPathName to the OS dependent modeBits.
      You should construct this mask using accessMaskFor, to be OS
-     independent. Return true if changed,
-     false if such a file does not exist or change was not allowd."
-
-    |encodedPathName|
+     independent. Return nil if changed,
+     anOSErrorHolder if such a file does not exist or change was not allowd."
+
+    |encodedPathName error|
 
     encodedPathName := self encodePath:aPathName.
 %{
     int ret;
 
     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 );
-    }
-%}.
+        __BEGIN_INTERRUPTABLE__
+        do {
+            ret = chmod((char *)__stringVal(encodedPathName), __intVal(modeBits));
+        } while (ret < 0 && errno == EINTR);
+        __END_INTERRUPTABLE__
+
+        if (ret >= 0) {
+            RETURN (nil);
+        }
+        error = __mkSmallInteger(errno);
+    }
+%}.
+
+    error notNil ifTrue:[
+        LastErrorNumber := error.
+        ^ self errorHolderForNumber:error.
+    ].
+
     ^ self primitiveFailed
+
+    "
+        self changeAccessModeOf:'foo' to:8r666
+    "
 !
 
 changeAccessModeOfFd:aFileDescriptor to:modeBits
     "change the access rights of the file referenced by aFileDescriptor
      to the OS dependent modeBits.
      You should construct this mask using accessMaskFor, to be OS
-     independent. Return true if changed,
-     false if such a file does not exist or change was not allowd."
+     independent. Return nil if changed,
+     an OSErrorHolder if such a file does not exist or change was not allowed."
+
+    |error|
 
 %{
     int ret;
 
     if (__isSmallInteger(aFileDescriptor) && __isSmallInteger(modeBits)) {
-	__BEGIN_INTERRUPTABLE__
-	do {
-	    ret = fchmod(__smallIntegerVal(aFileDescriptor), __intVal(modeBits));
-	} while (ret < 0 && errno == EINTR);
-	__END_INTERRUPTABLE__
-	if (ret < 0) {
-	    @global(LastErrorNumber) = __mkSmallInteger(errno);
-	    RETURN ( false );
-	}
-	RETURN ( true );
-    }
-%}.
+        __BEGIN_INTERRUPTABLE__
+        do {
+            ret = fchmod(__smallIntegerVal(aFileDescriptor), __intVal(modeBits));
+        } while (ret < 0 && errno == EINTR);
+        __END_INTERRUPTABLE__
+
+        if (ret >= 0) {
+            RETURN (nil);
+        }
+        error = __mkSmallInteger(errno);
+    }
+%}.
+
+    error notNil ifTrue:[
+        LastErrorNumber := error.
+        ^ self errorHolderForNumber:error.
+    ].
+
     ^ self primitiveFailed
 ! !
 
@@ -4788,29 +4863,12 @@
     ^ false
 !
 
-supportsFileLinks
-    "return true, if the OS supports file links (hard links).
-     Typically, only unix returns true here."
-
-    ^ true
-
-    "Modified: / 5.6.1998 / 18:35:01 / cg"
-!
-
 supportsFileLocks
     "return true, if the OS supports file locking"
 
 %{ /* NOCONTEXT */
-#if defined(F_SETLK)
-    RETURN (true);
-#else
-# if defined(LOCK_EX) && defined(LOCK_UN)
+#if defined(F_SETLK) || (defined(LOCK_EX) && defined(LOCK_UN)) || defined(F_LOCK) && defined(F_UNLOCK)
     RETURN (true);
-# else
-#  if defined(F_LOCK) && defined(F_UNLOCK)
-    RETURN (true);
-#  endif
-# endif
 #endif
 %}.
     ^ false
@@ -4825,12 +4883,8 @@
      (i.e. with immediate return instead of waiting for the lock)"
 
 %{ /* NOCONTEXT */
-#if defined(F_SETLK) && defined(F_SETLKW)
+#if (defined(F_SETLK) && defined(F_SETLKW)) || (defined(LOCK_EX) && defined(LOCK_UN) && defined(LOCK_NB))
     RETURN (true);
-#else
-# if defined(LOCK_EX) && defined(LOCK_UN) && defined(LOCK_NB)
-    RETURN (true);
-# endif
 #endif
 %}.
     ^ false
@@ -7003,7 +7057,9 @@
 #if defined(HAS_UNIX98_PTY)
     int _fdM, _fdS;
     char *slaveName;
-    extern char *ptsname();     /* also in #include <stdlib.h> */
+    extern char *ptsname(int);     /* also in #include <stdlib.h> */
+    extern int grantpt(int);
+    extern int unlockpt(int);
 
     _fdM = open("/dev/ptmx", O_RDWR | O_NOCTTY);
 
@@ -8479,8 +8535,8 @@
      instructionSets extendedInstructions platform|
 
 %{  /* STACK: 4096 */
-#ifdef LINUX
-# ifdef ELF /* old a.out unixes do not have this ... */
+#if defined(linux) && defined(ELF)  /* old a.out unixes do not have this ... */
+# include <sys/sysinfo.h>
     /*
      * additional info available ...
      */
@@ -8493,7 +8549,6 @@
 	swapSize  = __MKUINT(infoBuffer.totalswap);
 	freeSwap  = __MKUINT(infoBuffer.freeswap);
     }
-# endif
 #endif /* LINUX */
 
 #if defined(hpux) && !defined(__GNUC__)
@@ -9615,6 +9670,15 @@
     "
 !
 
+supportsFileLinks
+    "return true, if the OS supports file links (hard links).
+     Typically, only unix returns true here."
+
+    ^ true
+
+    "Modified: / 5.6.1998 / 18:35:01 / cg"
+!
+
 supportsIOInterrupts
     "return true, if the OS supports IO availability interrupts
      (i.e. SIGPOLL/SIGIO).
@@ -9843,7 +9907,7 @@
      Codeset := #'utf8-mac'.
      CodesetEncoder := nil.
      OperatingSystem getCodesetEncoder
-     OperatingSystem encodePath:''
+     OperatingSystem encodePath:'äöü'
     "
 
     "Modified: / 23-01-2013 / 10:00:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
@@ -10200,7 +10264,7 @@
     unsigned INT t = 0;
 
 # if defined(_POSIX_MONOTONIC_CLOCK) && defined(CLOCK_MONOTONIC) && !defined(NO_CLOCK_GETTIME)
-    static has_clock_gettime = 1;
+    static int has_clock_gettime = 1;
     struct timespec ts;
 
     if (has_clock_gettime) {
@@ -10739,7 +10803,7 @@
 
 %{  /* NOCONTEXT */
     static char cachedName[128];
-    static firstCall = 1;
+    static int firstCall = 1;
     extern char *getenv();
     extern char *getlogin();
 
@@ -13363,8 +13427,10 @@
             domain:#'AF_INET' type:nil protocol:nil flags:nil
      self getAddressInfo:'www.exept.de' serviceName:nil
             domain:#'AF_INET6' type:nil protocol:nil flags:nil
-     self getAddressInfo:'www.baden-wrttemberg.de' serviceName:nil
+     self getAddressInfo:'www.baden-württemberg.de' serviceName:nil
             domain:#'AF_INET' type:#stream protocol:nil flags:nil
+     self getAddressInfo:'www.baden-württemberg.de' serviceName:nil
+	    domain:#'AF_INET6' type:#stream protocol:nil flags:nil
     "
 !