Unix.st
changeset 443 fae13c0f1512
parent 440 017c88672c98
child 445 61d040eafea7
--- a/Unix.st	Mon Oct 23 17:50:42 1995 +0100
+++ b/Unix.st	Mon Oct 23 17:55:03 1995 +0100
@@ -22,13 +22,13 @@
 COPYRIGHT (c) 1988 by Claus Gittinger
 	     All Rights Reserved
 
-$Header: /cvs/stx/stx/libbasic/Attic/Unix.st,v 1.58 1995-09-21 12:31:48 claus Exp $
+$Header: /cvs/stx/stx/libbasic/Attic/Unix.st,v 1.59 1995-10-23 16:54:54 cg Exp $
 '!
 
 !OperatingSystem primitiveDefinitions!
 
 %{
-#ifdef _AIX
+#if defined(_AIX)
 # ifndef WANT_REALPATH
 #  define WANT_REALPATH
 # endif
@@ -38,6 +38,7 @@
 # ifndef WANT_SYSTEM
 #  define WANT_SYSTEM
 # endif
+# define WANT_SHM
 #endif
 
 #ifdef WANT_REALPATH
@@ -49,9 +50,13 @@
 
 # include <sys/stat.h>
 # define _SYS_STAT_H_INCLUDED_
+
 #endif /* WANT_REALPATH */
 
 #ifdef WANT_SHM
+extern int shmctl(), shmget(), shmdt();
+extern char * shmat();
+
 # include <sys/types.h>
 # define _SYS_TYPES_H_INCLUDED_
 
@@ -254,6 +259,7 @@
  * is way too slow. Here is a realpath for the rest of us.
  * define WANT_REALPATH in the xxxIntern-file to get it.
  */
+
 #if defined(HAS_REALPATH)
 # undef WANT_REALPATH
 #endif
@@ -595,7 +601,7 @@
 
 version
 "
-$Header: /cvs/stx/stx/libbasic/Attic/Unix.st,v 1.58 1995-09-21 12:31:48 claus Exp $
+$Header: /cvs/stx/stx/libbasic/Attic/Unix.st,v 1.59 1995-10-23 16:54:54 cg Exp $
 "
 !
 
@@ -1099,9 +1105,9 @@
 	rel  = _MKSTRING(ubuff.release COMMA_CON);
 	ver  = _MKSTRING(ubuff.version COMMA_CON);
 	mach = _MKSTRING(ubuff.machine COMMA_CON);
-#ifdef LINUX
+# ifdef LINUX
 	dom  = _MKSTRING(ubuff.domainname COMMA_CON);
-#endif
+# endif
     }
 #else
 # ifdef mswindows
@@ -1339,8 +1345,7 @@
 	}
     }
 #endif
-%}
-.
+%}.
     ^ '? (' , aNumber printString , ')'
 
     "
@@ -1365,8 +1370,7 @@
 	}
     }
 #endif
-%}
-.
+%}.
     ^ '???'
 
     "
@@ -1395,8 +1399,13 @@
 
     uid = getuid();
     RETURN ( __MKSMALLINT(uid) );
-#endif
-%}
+#else
+# ifdef SYSTEM_HAS_USERS
+    /* ... */
+# endif
+#endif
+%}.
+    ^ 1 "just a dummy for systems which do not have userIDs"
 
     "
      OperatingSystem getUserID
@@ -1415,10 +1424,10 @@
 
     uid = geteuid();
     RETURN ( __MKSMALLINT(uid) );
-#else
+#endif
     /* --- return same as getUserID --- */
-#endif
-%}
+%}.
+    ^ self getUserID
 
     "
      OperatingSystem getEffectiveUserID
@@ -1438,11 +1447,10 @@
 #else
 # ifdef SYSTEM_HAS_GROUPS
     /* ... */
-# else
-    RETURN (__MKSMALLINT(1));
 # endif
 #endif
-%}
+%}.
+    ^ 1 "just a dummy for systems which do not have userIDs"
 
     "
      OperatingSystem getGroupID
@@ -1461,10 +1469,10 @@
 
     uid = getegid();
     RETURN ( __MKSMALLINT(uid) );
-#else
+#endif
     /* --- return same as getGroupID --- */
-#endif
-%}
+%}.
+    ^ self getGroupID
 
     "
      OperatingSystem getEffectiveGroupID
@@ -1608,104 +1616,166 @@
 	    /*
 	     * POSIX errnos - these should be defined
 	     */
+#ifdef EPERM
 	    case EPERM:
 		msg = "Operation not permitted";
 		break;
+#endif
+#ifdef ENOENT
 	    case ENOENT:
 		msg = "No such file or directory";
 		break;
+#endif
+#ifdef ESRCH
 	    case ESRCH:
 		msg = "No such process";
 		break;
+#endif
+#ifdef EINTR
 	    case EINTR:
 		msg = "Interrupted system call";
 		break;
+#endif
+#ifdef EIO
 	    case EIO:
 		msg = "I/O error";
 		break;
+#endif
+#ifdef ENXIO
 	    case ENXIO:
 		msg = "No such device or address";
 		break;
+#endif
+#ifdef E2BIG
 	    case E2BIG:
 		msg = "Arg list too long";
 		break;
+#endif
+#ifdef ENOEXEC
 	    case ENOEXEC:
 		msg = "Exec format error";
 		break;
+#endif
+#ifdef EBADF
 	    case EBADF:
 		msg = "Bad file number";
 		break;
+#endif
+#ifdef ECHILD
 	    case ECHILD:
 		msg = "No child processes";
 		break;
+#endif
 #if !defined(EWOULDBLOCK) && defined(EAGAIN) && (EWOULDBLOCK != EAGAIN)
 	    case EAGAIN:
 		msg = "Try again";
 		break;
 #endif
+#ifdef ENOMEM
 	    case ENOMEM:
 		msg = "Out of memory";
 		break;
+#endif
+#ifdef EACCES
 	    case EACCES:
 		msg = "Permission denied";
 		break;
+#endif
+#ifdef EFAULT
 	    case EFAULT:
 		msg = "Bad address";
 		break;
+#endif
+#ifdef EBUSY
 	    case EBUSY:
 		msg = "Device or resource busy";
 		break;
+#endif
+#ifdef EEXIST
 	    case EEXIST:
 		msg = "File exists";
 		break;
+#endif
+#ifdef EXDEV
 	    case EXDEV:
 		msg = "Cross-device link";
 		break;
+#endif
+#ifdef ENODEV
 	    case ENODEV:
 		msg = "No such device";
 		break;
+#endif
+#ifdef ENOTDIR
 	    case ENOTDIR:
 		msg = "Not a directory";
 		break;
+#endif
+#ifdef EISDIR
 	    case EISDIR:
 		msg = "Is a directory";
 		break;
+#endif
+#ifdef EINVAL
 	    case EINVAL:
 		msg = "Invalid argument";
 		break;
+#endif
+#ifdef ENFILE
 	    case ENFILE:
 		msg = "File table overflow";
 		break;
+#endif
+#ifdef EMFILE
 	    case EMFILE:
 		msg = "Too many open files";
 		break;
+#endif
+#ifdef ENOTTY
 	    case ENOTTY:
 		msg = "Not a typewriter";
 		break;
+#endif
+#ifdef EFBIG
 	    case EFBIG:
 		msg = "File too large";
 		break;
+#endif
+#ifdef ENOSPC
 	    case ENOSPC:
 		msg = "No space left on device";
 		break;
+#endif
+#ifdef ESPIPE
 	    case ESPIPE:
 		msg = "Illegal seek";
 		break;
+#endif
+#ifdef EROFS
 	    case EROFS:
 		msg = "Read-only file system";
 		break;
+#endif
+#ifdef EMLINK
 	    case EMLINK:
 		msg = "Too many links";
 		break;
+#endif
+#ifdef EPIPE
 	    case EPIPE:
 		msg = "Broken pipe";
 		break;
+#endif
+#ifdef EDOM
 	    case EDOM:
 		msg = "Math argument out of domain";
 		break;
+#endif
+#ifdef ERANGE
 	    case ERANGE:
 		msg = "Math result not representable";
 		break;
+#endif
 #ifdef EDEADLK
 # if EDEADLK != EWOULDBLOCK
 	    case EDEADLK:
@@ -2717,16 +2787,30 @@
 #endif
 
     int sigNr;
+#if defined(SIGINT) || defined(SIGQUIT)
     extern void __signalUserInterrupt();
+#endif
+#ifdef SIGFPE
     extern void __signalFpExceptionInterrupt();
+#endif
+#ifdef SIGIO
     extern void __signalIoInterrupt();
+#endif
 #ifdef CHILD_SIGNAL
     extern void __signalChildInterrupt();
 #endif
+#ifdef SIGPIPE
     extern void __signalPIPEInterrupt();
+#endif
+#ifdef SIGBUS
     extern void __signalBUSInterrupt();
+#endif
+#ifdef SIGSEGV
     extern void __signalSEGVInterrupt();
+#endif
+#ifdef SIGALRM
     extern void __signalTimerInterrupt();
+#endif
     extern void __signalInterrupt();
     void (*handler)();
 #ifdef HAS_SIGACTION
@@ -2745,26 +2829,38 @@
 	    sigNr = SIGIO;
 #endif
 	switch (sigNr) {
+#ifdef SIGINT
 	    case SIGINT:
+#endif
+#ifdef SIGQUIT
 	    case SIGQUIT:
+#endif
+#if defined(SIGINT) || defined(SIGQUIT)
 		handler = __signalUserInterrupt;
 		break;
-
+#endif
+
+#ifdef SIGFPE
 	    case SIGFPE:
 		handler = __signalFpExceptionInterrupt;
 		break;
-
+#endif
+
+#ifdef SIGPIPE
 	    case SIGPIPE:
 		handler = __signalPIPEInterrupt;
 		break;
+#endif
 #ifdef SIGBUS
 	    case SIGBUS:
 		handler = __signalBUSInterrupt;
 		break;
 #endif
+#ifdef SIGSEGV
 	    case SIGSEGV:
 		handler = __signalSEGVInterrupt;
 		break;
+#endif
 #ifdef SIGIO
 	    case SIGIO:
 		handler = __signalIoInterrupt;
@@ -2776,9 +2872,11 @@
 		handler = __signalChildInterrupt;
 		break;
 #endif
+#ifdef SIGALRM
 	    case SIGALRM:
 		handler = __signalTimerInterrupt;
 		break;
+#endif
 
 	    default:
 		handler = __signalInterrupt;
@@ -2817,13 +2915,22 @@
 !
 
 enableQuitInterrupts
-    "enable quitInterrupt (usually ^\) handling, and make it a userinterrupt.
+    "enable quitInterrupt (usually ^\) handling, and make it a userInterrupt.
      (the default will dump core and exit - which is not a good idea for
       end-user applications ...)"
 
     ^ self enableSignal:(self sigQUIT)
 !
 
+enableAbortInterrupts
+    "enable abort signalhandling, and make it a regular signalInterrupt.
+     (the default will dump core and exit - which is not a good idea for
+      end-user applications ...).
+     This is especially useful, if linked-in C-libraries call abort() ..."
+
+    ^ self enableSignal:(self sigABRT)
+!
+
 disableUserInterrupts
     "disable userInterrupt processing;
      when disabled, no ^C processing takes place.
@@ -2850,17 +2957,25 @@
 
 %{  /* NOCONTEXT */
 
+#ifdef SIGPIPE
     extern void __signalPIPEInterrupt();
+#endif
 #ifdef SIGBUS
     extern void __signalBUSInterrupt();
 #endif
+#ifdef SIGSEGV
     extern void __signalSEGVInterrupt();
-
+#endif
+
+#ifdef SIGPIPE
     signal(SIGPIPE, __signalPIPEInterrupt);
+#endif
 #ifdef SIGBUS
     signal(SIGBUS,  __signalBUSInterrupt);
 #endif
+#ifdef SIGSEGV
     signal(SIGSEGV, __signalSEGVInterrupt);
+#endif
 %}
 !
 
@@ -4059,15 +4174,10 @@
 
     "
      OperatingSystem compressPath:'./..'    
-
      OperatingSystem compressPath:'/foo/bar/baz/..'  
-
      OperatingSystem compressPath:'foo/bar/baz/..'  
-
      OperatingSystem compressPath:'foo/bar/baz/../'  
-
      OperatingSystem compressPath:'foo/bar/baz/..///' 
-
      OperatingSystem compressPath:'///foo/bar/baz/..///' 
     "
 !
@@ -4357,15 +4467,19 @@
 	    case S_IFDIR:
 		type = @symbol(directory);
 		break;
+	    case S_IFREG:
+		type = @symbol(regular);
+		break;
+#ifdef S_IFCHR
 	    case S_IFCHR:
 		type = @symbol(characterSpecial);
 		break;
+#endif
+#ifdef S_IFBLK
 	    case S_IFBLK:
 		type = @symbol(blockSpecial);
 		break;
-	    case S_IFREG:
-		type = @symbol(regular);
-		break;
+#endif
 #ifdef S_IFLNK
 	    case S_IFLNK:
 		type = @symbol(symbolicLink);
@@ -4539,7 +4653,8 @@
 !
 
 timeOfLastChange:aPathName
-    "return the time, when the file was last changed"
+    "return the time, when the file was last changed. 
+     For nonexistent files, nil is returned."
 
     "could be implemented as:
 	(self infoOf:aPathName) at:#modified
@@ -4555,11 +4670,12 @@
 	do {
 	    ret = stat((char *) _stringVal(aPathName), &buf);
 	} while (ret < 0 && errno == EINTR);
-	if (ret >= 0) {
-	    timeLow = _MKSMALLINT(buf.st_mtime & 0xFFFF);
-	    timeHi = _MKSMALLINT((buf.st_mtime >> 16) & 0xFFFF);
+	if (ret < 0) {
+	    OperatingSystem_LastErrorNumber = _MKSMALLINT(errno);
+	    RETURN ( nil );
 	}
-	OperatingSystem_LastErrorNumber = _MKSMALLINT(errno);
+	timeLow = _MKSMALLINT(buf.st_mtime & 0xFFFF);
+	timeHi = _MKSMALLINT((buf.st_mtime >> 16) & 0xFFFF);
     }
 %}
 .
@@ -4572,7 +4688,8 @@
 !
 
 timeOfLastAccess:aPathName
-    "return the time, when the file was last accessed"
+    "return the time, when the file was last accessed.
+     For nonexistent files, nil is returned."
 
     "could be implemented as:
 	(self infoOf:aPathName) at:#accessed 
@@ -4587,11 +4704,12 @@
 	do {
 	    ret = stat((char *) _stringVal(aPathName), &buf);
 	} while (ret < 0 && errno == EINTR);
-	if (ret >= 0) {
-	    timeLow = _MKSMALLINT(buf.st_atime & 0xFFFF);
-	    timeHi = _MKSMALLINT((buf.st_atime >> 16) & 0xFFFF);
+	if (ret < 0) {
+	    OperatingSystem_LastErrorNumber = _MKSMALLINT(errno);
+	    RETURN (nil);
 	}
-	OperatingSystem_LastErrorNumber = _MKSMALLINT(errno);
+	timeLow = _MKSMALLINT(buf.st_atime & 0xFFFF);
+	timeHi = _MKSMALLINT((buf.st_atime >> 16) & 0xFFFF);
     }
 %}
 .
@@ -4625,6 +4743,7 @@
 	    RETURN (_MKSMALLINT(buf.st_ino));
 	}
 	OperatingSystem_LastErrorNumber = _MKSMALLINT(errno);
+	RETURN (nil);
     }
 %}
 .
@@ -4658,12 +4777,16 @@
 	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) );
+#endif
+#ifdef S_IFBLK
 	    case S_IFBLK:
 		RETURN ( @symbol(blockSpecial) );
-	    case S_IFREG:
-		RETURN ( @symbol(regular) );
+#endif
 #ifdef S_IFLNK
 	    case S_IFLNK:
 		RETURN ( @symbol(symbolicLink) );
@@ -4838,9 +4961,9 @@
     void *address, *shmaddr;
     int shmflg, shmid;
 
-    if (__isInteger(addr)
+    if (__isSmallInteger(addr)
      && __bothSmallInteger(flags, id)) {
-	shmaddr = __longIntVal(addr);
+	shmaddr = (void *) __intVal(addr);
 	shmflg = __intVal(flags);
 	shmid = __intVal(id);
 
@@ -4862,11 +4985,11 @@
     void *shmaddr;
     int rslt;
 
-    if (__isInteger(addr)) {
-	shmaddr = __longIntVal(addr);
+    if (__isSmallInteger(addr)) {
+	shmaddr = (void *) __intVal(addr);
 
 	rslt = shmdt(shmaddr);
-	if (address != (void *)-1) {
+	if (rslt != -1) {
 	    RETURN (true);
 	}
 	OperatingSystem_LastErrorNumber = _MKSMALLINT(errno);