--- a/Unix.st Thu May 12 04:07:15 1994 +0200
+++ b/Unix.st Tue May 17 12:09:46 1994 +0200
@@ -22,7 +22,7 @@
COPYRIGHT (c) 1988 by Claus Gittinger
All Rights Reserved
-$Header: /cvs/stx/stx/libbasic/Attic/Unix.st,v 1.13 1994-03-30 09:34:10 claus Exp $
+$Header: /cvs/stx/stx/libbasic/Attic/Unix.st,v 1.14 1994-05-17 10:09:37 claus Exp $
written 1988 by claus
'!
@@ -77,6 +77,13 @@
# define S_IXOTH (S_IEXEC>>6)
# endif
+# ifndef MAXPATHLEN
+# include <sys/param.h>
+# ifndef MAXPATHLEN
+# define MAXPATHLEN 1024
+# endif
+# endif
+
#endif
/*
@@ -205,105 +212,165 @@
|cpu|
- cpu := 'unknown'.
-
%{ /* NOCONTEXT */
-#ifdef vax
- cpu = _MKSTRING("vax" COMMA_CON);
-#endif
-#ifdef mips
- cpu = _MKSTRING("mips" COMMA_CON);
-#endif
-#ifdef i386
- cpu = _MKSTRING("i386" COMMA_CON);
-#endif
-#ifdef ns32k
- cpu = _MKSTRING("ns32k" COMMA_CON);
-#endif
-#ifdef mc68k
- cpu = _MKSTRING("mc68k" COMMA_CON);
-#endif
-#ifdef sparc
- cpu = _MKSTRING("sparc" COMMA_CON);
-#endif
-#ifdef hppa
- cpu = _MKSTRING("hppa" COMMA_CON);
-#endif
-#ifdef rs6000
- cpu = _MKSTRING("rs6000" COMMA_CON);
-#endif
-#ifdef alpha
- cpu = _MKSTRING("alpha" COMMA_CON);
-#endif
-#ifdef transputer
- cpu = _MKSTRING("transputer" COMMA_CON);
-#endif
+
+# ifdef vax
+# define CPU_STRING "vax"
+# endif
+# ifdef mips
+# define CPU_STRING "mips"
+# endif
+# ifdef i386
+# define CPU_STRING "i386"
+# endif
+# ifdef ns32k
+# define CPU_STRING "ns32k"
+# endif
+# ifdef mc68k
+# define CPU_STRING "mc68k"
+# endif
+# ifdef sparc
+# define CPU_STRING "sparc"
+# endif
+# ifdef hppa
+# define CPU_STRING "hppa"
+# endif
+# ifdef rs6000
+# define CPU_STRING "rs6000"
+# endif
+# ifdef alpha
+# define CPU_STRING "alpha"
+# endif
+# ifdef powerPC
+# define CPU_STRING "powerPC"
+# endif
+# ifdef transputer
+# define CPU_STRING "transputer"
+# endif
+
+# ifndef CPU_STRING
+# define CPU_STRING "unknown"
+# endif
+
+ cpu = _MKSTRING(CPU_STRING COMMA_CON);
+# undef CPU_STRING
%}
.
^ cpu
- "OperatingSystem getCPUType"
+ "
+ OperatingSystem getCPUType
+ "
+
+ "examples: are we running on a ss-10/solaris ?"
+ "
+ (OperatingSystem getCPUType = 'sparc')
+ and:[OperatingSystem getOSType = 'solaris']
+ "
+
+ "or on a pc/solaris ?"
+ "
+ (OperatingSystem getCPUType = 'i386')
+ and:[OperatingSystem getOSType = 'solaris']
+ "
!
getOSType
- "return a string giving the type of OS we're running on"
+ "return a string giving the type of OS we're running on.
+ This can be used to adapt programs to certain environment
+ differences (for example: mail-lock strategy ...)"
|os|
- os := 'unknown'.
-
%{ /* NOCONTEXT */
-#ifdef MSDOS
- os = _MKSTRING("msdos" COMMA_CON);
-#endif
-
-#ifdef sinix
- os = _MKSTRING("sinix" COMMA_CON);
-#endif
-
-#ifdef ultrix
- os = _MKSTRING("ultrix" COMMA_CON);
-#endif
-
-#ifdef sco
- os = _MKSTRING("sco" COMMA_CON);
-#endif
-
-#ifdef hpux
- os = _MKSTRING("hpux" COMMA_CON);
-#endif
-
-#ifdef LINUX
- os = _MKSTRING("linux" COMMA_CON);
-#endif
-
-#ifdef BSD
-# ifdef MACH
- os = _MKSTRING("mach" COMMA_CON);
-# endif
-
-# ifdef sunos
- os = _MKSTRING("sunos" COMMA_CON);
-# endif
-
-# ifdef IRIS
- os = _MKSTRING("irix" COMMA_CON);
-# endif
-
- if (os == nil) os = _MKSTRING("bsd" COMMA_CON);
-#endif
-
-#ifdef SYSV
-# ifdef SYSV3
- os = _MKSTRING("sys5.3" COMMA_CON);
-# else
-# ifdef SYSV4
- os = _MKSTRING("sys5.4" COMMA_CON);
-# else
- os = _MKSTRING("sys5" COMMA_CON);
-# endif
-# endif
-#endif
+
+# ifdef MSDOS
+# define OS_STRING "msdos"
+# endif
+
+# ifdef NT
+# define OS_STRING "nt"
+# endif
+
+# ifdef sinix
+# define OS_STRING "sinix"
+# endif
+
+# ifdef ultrix
+# define OS_STRING "ultrix"
+# endif
+
+# ifdef sco
+# define OS_STRING "sco"
+# endif
+
+# ifdef hpux
+# define OS_STRING "hpux"
+# endif
+
+# ifdef LINUX
+# define OS_STRING "linux"
+# endif
+
+# ifdef sunos
+# define OS_STRING "sunos"
+# endif
+
+# ifdef solaris
+# define OS_STRING "solaris"
+# endif
+
+# ifdef IRIS
+# define OS_STRING "irix"
+# endif
+
+ /*
+ * no concrete info; become somewhat vague ...
+ */
+# ifndef OS_STRING
+# ifdef MACH
+# define OS_STRING "mach"
+# endif
+# endif
+
+# ifndef OS_STRING
+# ifdef BSD
+# define OS_STRING "bsd"
+# endif
+
+# ifdef SYSV
+# ifdef SYSV3
+# define OS_STRING "sys5.3"
+# else
+# ifdef SYSV4
+# define OS_STRING "sys5.4"
+# else
+# define OS_STRING "sys5"
+# endif
+# endif
+# endif
+# endif
+
+ /*
+ * become very vague ...
+ */
+# ifndef OS_STRING
+# ifdef POSIX
+# define OS_STRING "posix"
+# endif
+# endif
+# ifndef OS_STRING
+# ifdef UNIX
+# define OS_STRING "unix"
+# endif
+# endif
+
+# ifndef OS_STRING
+# define OS_STRING "unknown"
+# endif
+
+ os = _MKSTRING(OS_STRING COMMA_CON);
+# undef OS_STRING
%}
.
^ os
@@ -316,76 +383,34 @@
This is almost the same as getOSType, but the returned string
is slightly different for some systems (i.e. iris vs. irix).
Dont depend on this - use getOSType. I dont really see a point
- here ..."
+ here ... (except for slight differences between next/mach and other
+ machs)"
|sys|
- sys := 'unknown'.
-
-%{ /* NOCONTEXT */
-#ifdef MSDOS
- sys = _MKSTRING("msdos" COMMA_CON);
-#endif
-
-#ifdef sinix
- sys = _MKSTRING("sinix" COMMA_CON);
-#endif
-
-#ifdef ultrix
- sys = _MKSTRING("ultrix" COMMA_CON);
-#endif
-
-#ifdef sco
- sys = _MKSTRING("sco" COMMA_CON);
-#endif
-
-#ifdef sunos
- sys = _MKSTRING("sunos" COMMA_CON);
-#endif
-
-#ifdef solaris
- sys = _MKSTRING("solaris" COMMA_CON);
-#endif
-
-#ifdef NEXT
- sys = _MKSTRING("next" COMMA_CON);
-#endif
-
-#ifdef IRIS
- sys = _MKSTRING("iris" COMMA_CON);
-#endif
-
-#ifdef LINUX
- sys = _MKSTRING("linux" COMMA_CON);
-#endif
-
-#ifdef hpux
- sys = _MKSTRING("hpux" COMMA_CON);
-#endif
-
-#ifdef BSD
-# ifdef MACH
- if (sys == nil) sys = _MKSTRING("mach" COMMA_CON);
-# endif
- if (sys == nil) sys = _MKSTRING("bsd" COMMA_CON);
-#endif
-
-#ifdef SYSV
-# ifdef SYSV3
- if (sys == nil) sys = _MKSTRING("sys5.3" COMMA_CON);
-# else
-# ifdef SYSV4
- if (sys == nil) sys = _MKSTRING("sys5.4" COMMA_CON);
-# else
- if (sys == nil) sys = _MKSTRING("sys5" COMMA_CON);
-# endif
-# endif
-#endif
+%{
+# ifdef NEXT
+# define SYS_STRING "next"
+# endif
+
+# ifdef IRIS
+# define SYS_STRING "iris"
+# endif
+
+# ifdef SYS_STRING
+ sys = _MKSTRING(SYS_STRING COMMA_CON);
+# undef SYS_STRING
+# endif
%}
.
+ sys isNil ifTrue:[
+ ^ self getOSType
+ ].
^ sys
- "OperatingSystem getSystemType"
+ "
+ OperatingSystem getSystemType
+ "
!
getHostName
@@ -398,9 +423,28 @@
^ HostName
].
name := self getEnvironment:'HOST'.
+%{
+#if defined(HAS_GETHOSTNAME)
+ char buffer[128];
+
+ if (gethostname(buffer, sizeof(buffer)) == 0) {
+ name = _MKSTRING(buffer COMMA_CON);
+ }
+#else
+# if defined(HAS_UNAME)
+# include <sys/utsname.h>
+
+ struct utsname ubuff;
+
+ if (uname(&ubuff) == 0) {
+ name = _MKSTRING(ubuff.nodename COMMA_CON);
+ }
+# endif
+#endif
+%}.
name isNil ifTrue:[
"since fork might be slow on some machines, give a warning ..."
- 'please set the HOST shell variable for faster startup' errorPrintNewline.
+ 'please set the HOST shell variable for faster startup' errorPrintNL.
p := PipeStream readingFrom:'hostname'.
p notNil ifTrue:[
@@ -409,10 +453,10 @@
]
].
name isNil ifTrue:[
- 'cannot find out hostname' errorPrintNewline.
+ 'cannot find out hostname' errorPrintNL.
].
HostName := name.
- ^name
+ ^ name
"
OperatingSystem getHostName
@@ -424,10 +468,7 @@
%{ /* NOCONTEXT */
-#ifdef BSD
- RETURN ( true );
-#endif
-#ifdef SYSV4
+#if defined(BSD) || defined(MACH) || defined(SYSV4)
RETURN ( true );
#endif
%}
@@ -437,22 +478,35 @@
maxFileNameLength
"return the max number of characters in a filename.
- this is no problem on 'real' unixes, but those instant
- ****-stations always make problems .."
+ This is no problem on 'real' unixes, but those
+ 'instant ****-stations' always make problems .."
%{ /* NOCONTEXT */
-#if defined(BSD) || defined(SYSV4) || defined(LONGFILENAMES)
- RETURN ( _MKSMALLINT(255) );
-#else
-# ifdef SYSV
- RETURN ( _MKSMALLINT(14) );
-# endif
-# ifdef MSDOS
- RETURN ( _MKSMALLINT(9) );
-# endif
-#endif
+
+ /*
+ * XXX: newer systems provide a query function for this ... use it
+ */
+# if defined(BSD) || defined(SYSV4) || defined(LONGFILENAMES)
+ RETURN ( _MKSMALLINT(255) );
+# endif
+
+# ifdef SYSV
+ RETURN ( _MKSMALLINT(14) );
+# endif
+
+# ifdef MSDOS
+ RETURN ( _MKSMALLINT(9) );
+# endif
+
+# ifdef NT
+ /*
+ * mhmh - depends on the filesystem type
+ */
+ RETURN ( _MKSMALLINT(9) );
+# endif
%}
.
+ "unix default"
^ 14
!
@@ -465,18 +519,18 @@
%{ /* NOCONTEXT */
#ifdef NOTDEF
-#if defined(SIGPOLL) || defined(SIGIO)
-# if defined(F_GETFL) && defined(F_SETFL)
-# if defined(FASYNC)
-/*
- * mhmh they seem to NOT work on NS2.1
- */
-# if !defined(NEXT)
- RETURN (true);
+# if defined(SIGPOLL) || defined(SIGIO)
+# if defined(F_GETFL) && defined(F_SETFL)
+# if defined(FASYNC)
+ /*
+ * mhmh they seem to NOT work on NS2.1
+ */
+# if !defined(NEXT)
+ RETURN (true);
+# endif
+# endif
+# endif
# endif
-# endif
-# endif
-#endif
#endif
%}
@@ -488,11 +542,11 @@
"return true, if the OS supports nonblocking IO."
%{ /* NOCONTEXT */
-#if defined(F_GETFL) && defined(F_SETFL)
-# if defined(FNDELAY)
- RETURN (true);
-# endif
-#endif
+# if defined(F_GETFL) && defined(F_SETFL)
+# if defined(FNDELAY)
+ RETURN (true);
+# endif
+# endif
%}
.
^ false
@@ -552,11 +606,12 @@
#endif
%}
.
- ^ '???'
+ ^ '? (' , aNumber printString , ')'
"
OperatingSystem getUserNameFromID:0
OperatingSystem getUserNameFromID:100
+ OperatingSystem getUserNameFromID:9991
"
!
@@ -627,87 +682,311 @@
(as returned by a system call).
Should be replaced by a resource lookup."
- |msg messages|
-
- (Language == #german) ifTrue:[
- messages := #('keine superuser Berechtigung'
- 'ungueltiger Datei- oder VerzeichnisName'
- nil "'ungueltige Prozessnummer' "
- nil "'unterbrochener systemcall' "
- 'E/A Fehler'
- nil "'Geraet existiert nicht' "
- 'zu viele Argumente'
- 'nicht ausfuehrbar'
- nil "'falscher FileDescriptor'"
- nil "'kein Kindprozess' "
- 'zu viele Prozesse oder zu wenig Speicher'
- 'zu wenig Speicher'
- 'keine ZugriffsBerechtigung'
- nil "'falsche Adresse' "
- nil "'kein Blockgeraet' "
- nil "'Platte noch im Zugriff' "
- 'Datei existiert bereits'
- nil "'Link ueber Plattengrenzen hinweg' "
- 'Geraet existiert nicht'
- 'ist kein Verzeichnis'
- 'ist ein Verzeichnis'
- nil "'ungueltiges Argument' "
- 'zu viele Dateien offen'
- 'zu viele Dateien offen'
- nil "'kein Terminalgeraet' "
- 'Datei wird gerade ausgefuehrt'
- 'Datei zu gross'
- 'Platte ist voll'
- 'ungueltige Positionierung'
- 'Platte ist schreibgeschuetzt'
- 'zu viele Links'
- 'Pipe unterbrochen'
- 'argument nicht im gueltigen Bereich'
- 'Ergebnis nicht im gueltigen Bereich')
- ] ifFalse:[
- messages := #('Not super-user'
- 'No such file or directory'
- nil "'No such process' "
- nil "'interrupted system call' "
- 'I/O error'
- nil "'No such device or address' "
- 'Arg list too long'
- 'Exec format error'
- nil "'Bad file number'"
- nil "'No children' "
- 'No more processes'
- 'Not enough core'
- 'Permission denied'
- nil "'Bad address' "
- nil "'Block device required' "
- nil "'Mount device busy' "
- 'File exists'
- nil "'Cross-device link' "
- 'No such device'
- 'Not a directory'
- 'Is a directory'
- nil 'Invalid argument'
- 'File table overflow'
- 'Too many open files'
- nil "'Not a typewriter' "
- 'Text file busy'
- 'File too large'
- 'No space left on device'
- 'Illegal seek'
- 'Read only file system'
- 'Too many links'
- 'Broken pipe'
- 'Math arg out of domain of func'
- 'Math result not representable')
- ].
-
- (errNr between:1 and:messages size) ifTrue:[
- msg := messages at:errNr
- ].
- msg isNil ifTrue:[
- ^ ('ErrorNr: ' , errNr printString)
- ].
- ^ msg
+%{
+ /* claus:
+ * I made this some primitive code, since errnos are not
+ * standard across unixes
+ */
+ char *msg = "unknown error";
+ char buffer[50];
+
+ if (_isSmallInteger(errNr)) {
+ switch (_intVal(errNr)) {
+ /*
+ * POSIX errnos - these should be defined
+ */
+ case EPERM:
+ msg = "Operation not permitted";
+ break;
+ case ENOENT:
+ msg = "No such file or directory";
+ break;
+ case ESRCH:
+ msg = "No such process";
+ break;
+ case EINTR:
+ msg = "Interrupted system call";
+ break;
+ case EIO:
+ msg = "I/O error";
+ break;
+ case ENXIO:
+ msg = "No such device or address";
+ break;
+ case E2BIG:
+ msg = "Arg list too long";
+ break;
+ case ENOEXEC:
+ msg = "Exec format error";
+ break;
+ case EBADF:
+ msg = "Bad file number";
+ break;
+ case ECHILD:
+ msg = "No child processes";
+ break;
+#if !defined(EWOULDBLOCK) && defined(EAGAIN) && (EWOULDBLOCK != EAGAIN)
+ case EAGAIN:
+ msg = "Try again";
+ break;
+#endif
+ case ENOMEM:
+ msg = "Out of memory";
+ break;
+ case EACCES:
+ msg = "Permission denied";
+ break;
+ case EFAULT:
+ msg = "Bad address";
+ break;
+ case EBUSY:
+ msg = "Device or resource busy";
+ break;
+ case EEXIST:
+ msg = "File exists";
+ break;
+ case EXDEV:
+ msg = "Cross-device link";
+ break;
+ case ENODEV:
+ msg = "No such device";
+ break;
+ case ENOTDIR:
+ msg = "Not a directory";
+ break;
+ case EISDIR:
+ msg = "Is a directory";
+ break;
+ case EINVAL:
+ msg = "Invalid argument";
+ break;
+ case ENFILE:
+ msg = "File table overflow";
+ break;
+ case EMFILE:
+ msg = "Too many open files";
+ break;
+ case ENOTTY:
+ msg = "Not a typewriter";
+ break;
+ case EFBIG:
+ msg = "File too large";
+ break;
+ case ENOSPC:
+ msg = "No space left on device";
+ break;
+ case ESPIPE:
+ msg = "Illegal seek";
+ break;
+ case EROFS:
+ msg = "Read-only file system";
+ break;
+ case EMLINK:
+ msg = "Too many links";
+ break;
+ case EPIPE:
+ msg = "Broken pipe";
+ break;
+ case EDOM:
+ msg = "Math argument out of domain";
+ break;
+ case ERANGE:
+ msg = "Math result not representable";
+ break;
+#ifdef EDEADLK
+ case EDEADLK:
+ msg = "Resource deadlock would occur";
+ break;
+#endif
+#ifdef ENAMETOOLONG
+ case ENAMETOOLONG:
+ msg = "File name too long";
+ break;
+#endif
+#ifdef ENOLCK
+ case ENOLCK:
+ msg = "No record locks available";
+ break;
+#endif
+#ifdef ENOSYS
+ case ENOSYS:
+ msg = "Function not implemented";
+ break;
+#endif
+#ifdef ENOTEMPTY
+ case ENOTEMPTY:
+ msg = "Directory not empty";
+ break;
+#endif
+#ifdef EILSEQ
+ case EILSEQ:
+ msg = "Illegal byte sequence";
+ break;
+#endif
+ /*
+ * XPG3 errnos - defined on most systems
+ */
+#ifdef ENOTBLK
+ case ENOTBLK:
+ msg = "Block device required";
+ break;
+#endif
+#ifdef ETXTBSY
+ case ETXTBSY:
+ msg = "Text file busy";
+ break;
+#endif
+ /*
+ * some others
+ */
+#ifdef EWOULDBLOCK
+ case EWOULDBLOCK:
+ msg = "Operation would block";
+ break;
+#endif
+#ifdef ENOMSG
+ case ENOMSG:
+ msg = "No message of desired type";
+ break;
+#endif
+#ifdef ELOOP
+ case ELOOP:
+ msg = "Too many levels of symbolic links";
+ break;
+#endif
+
+ /*
+ * some stream errors
+ */
+#ifdef ETIME
+ case ETIME:
+ msg = "Timer expired";
+ break;
+#endif
+#ifdef ENOSR
+ case ENOSR:
+ msg = "Out of streams resources";
+ break;
+#endif
+#ifdef ENOSTR
+ case ENOSTR:
+ msg = "Device not a stream";
+ break;
+#endif
+#ifdef ECOMM
+ case ECOMM:
+ msg = "Communication error on send";
+ break;
+#endif
+#ifdef EPROTO
+ case EPROTO:
+ msg = "Protocol error";
+ break;
+#endif
+ /*
+ * nfs errors
+ */
+#ifdef ESTALE
+ case ESTALE:
+ msg = "Stale NFS file handle";
+ break;
+#endif
+#ifdef EREMOTE
+ case EREMOTE:
+ msg = "Too many levels of remote in path";
+ break;
+#endif
+ /*
+ * some networking errors
+ */
+#ifdef EINPROGRESS
+ case EINPROGRESS:
+ msg = "Operation now in progress";
+ break;
+#endif
+#ifdef EALREADY
+ case EALREADY:
+ msg = "Operation already in progress";
+ break;
+#endif
+#ifdef ENOTSOCK
+ case ENOTSOCK:
+ msg = "Socket operation on non-socket";
+ break;
+#endif
+#ifdef EDESTADDRREQ
+ case EDESTADDRREQ:
+ msg = "Destination address required";
+ break;
+#endif
+#ifdef EMSGSIZE
+ case EMSGSIZE:
+ msg = "Message too long";
+ break;
+#endif
+#ifdef EPROTOTYPE
+ case EPROTOTYPE:
+ msg = "Protocol wrong type for socket";
+ break;
+#endif
+#ifdef ENOPROTOOPT
+ case ENOPROTOOPT:
+ msg = "Protocol not available";
+ break;
+#endif
+#ifdef EPROTONOSUPPORT
+ case EPROTONOSUPPORT:
+ msg = "Protocol not supported";
+ break;
+#endif
+#ifdef ESOCKTNOSUPPORT
+ case ESOCKTNOSUPPORT:
+ msg = "Socket type not supported";
+ break;
+#endif
+#ifdef EOPNOTSUPP
+ case EOPNOTSUPP:
+ msg = "Operation not supported on socket";
+ break;
+#endif
+#ifdef EPFNOSUPPORT
+ case EPFNOSUPPORT:
+ msg = "Protocol family not supported";
+ break;
+#endif
+#ifdef EAFNOSUPPORT
+ case EAFNOSUPPORT:
+ msg = "Address family not supported by protocol family";
+ break;
+#endif
+#ifdef EADDRINUSE
+ case EADDRINUSE:
+ msg = "Address already in use";
+ break;
+#endif
+#ifdef EADDRNOTAVAIL
+ case EADDRNOTAVAIL:
+ msg = "Can\'t assign requested address";
+ break;
+#endif
+#ifdef ETIMEDOUT
+ case ETIMEDOUT:
+ msg = "Connection timed out";
+ break;
+#endif
+#ifdef ECONNREFUSED
+ case ECONNREFUSED:
+ msg = "Connection refused";
+ break;
+#endif
+ default:
+ sprintf(buffer, "ErrorNr: %d", _intVal(errNr));
+ msg = buffer;
+ break;
+ }
+ }
+ RETURN (_MKSTRING(msg COMMA_CON));
+%}
! !
!OperatingSystem class methodsFor:'signal constants'!
@@ -1390,15 +1669,17 @@
^ self enableSignal:(self sigFP)
!
-enableSignalInterrupts
- "enable signal exception interrupts (trap, buserror & segm. violation).
+enableHardSignalInterrupts
+ "enable hard signal exception interrupts (trap, buserror & segm. violation).
after enabling, these exceptions will send the message
'signalInterrupt' to the SignalInterruptHandler object."
%{ /* NOCONTEXT */
extern void signalPIPEInterrupt();
+#ifdef SIGBUS
extern void signalBUSInterrupt();
+#endif
extern void signalSEGVInterrupt();
signal(SIGPIPE, signalPIPEInterrupt);
@@ -2197,7 +2478,7 @@
(i.e. OperatingSystem baseNameOf:'/usr/lib/st/file' -> 'file'
and OperatingSystem baseNameOf:'/usr/lib' -> lib).
This method does not check if the path is valid
- (i.e. if these directories really exist)."
+ (i.e. if these directories really exist & is readable)."
|prev index sep|
@@ -2214,9 +2495,12 @@
prev := index + 1
]
- "OperatingSystem baseNameOf:'/fee/foo/bar'"
- "OperatingSystem baseNameOf:'foo/bar'"
- "OperatingSystem baseNameOf:'../../foo/bar'"
+ "
+ OperatingSystem baseNameOf:'/fee/foo/bar'
+ OperatingSystem baseNameOf:'foo/bar'
+ OperatingSystem baseNameOf:'../../foo/bar'
+ OperatingSystem baseNameOf:'hello'
+ "
!
directoryNameOf:aPathString
@@ -2224,14 +2508,17 @@
- thats the name of the directory where aPath is
(i.e. OperatingSystem directoryNameOf:'/usr/lib/st/file' -> '/usr/lib/st'
and OperatingSystem directoryNameOf:'/usr/lib' -> /usr').
- This method does not check if the path is valid (i.e. if these directories
- really exist)."
+ This method does not check if the path is valid
+ (i.e. if these directories really exist & are readable)."
|last index sep sepString|
sep := self fileSeparator.
sepString := sep asString.
(aPathString = sepString) ifTrue:[
+ "
+ the trivial '/' case
+ "
^ aPathString
].
(aPathString startsWith:sepString) ifFalse:[
@@ -2243,15 +2530,75 @@
[true] whileTrue:[
index := aPathString indexOf:sep startingAt:(last + 1).
index == 0 ifTrue:[
- (last == 1) ifTrue:[^ sepString].
+ (last == 1) ifTrue:[
+ (aPathString startsWith:sepString) ifTrue:[
+ ^ sepString
+ ].
+ ^ '.'
+ ].
+"
+ (aPathString startsWith:sepString) ifFalse:[
+ (aPathString startsWith:('..' , sepString)) ifFalse:[
+ ^ './' , (aPathString copyTo:(last - 1))
+ ]
+ ].
+"
^ aPathString copyTo:(last - 1)
].
last := index.
]
- "OperatingSystem directoryNameOf:'/fee/foo/bar'"
- "OperatingSystem directoryNameOf:'foo/bar'"
- "OperatingSystem directoryNameOf:'../../foo/bar'"
+ "
+ OperatingSystem directoryNameOf:'/fee/foo/bar'
+ OperatingSystem directoryNameOf:'foo/bar'
+ OperatingSystem directoryNameOf:'../../foo/bar'
+ OperatingSystem directoryNameOf:'bar'
+ OperatingSystem directoryNameOf:'/bar'
+ "
+!
+
+pathNameOf:pathName
+ "return the pathName of the argument, aPathString,
+ - thats the full pathname of the directory, starting at '/'.
+ This method needs the path to be valid
+ (i.e. all directories must exist, be readable and executable).
+ Notice: if symbolic links are involved, the result may look different
+ from what you expect."
+
+ |p path|
+
+ "some have a convenient function for this ..."
+%{ /* STACK: 16000 */
+#ifdef HAS_REALPATH
+ char nameBuffer[MAXPATHLEN + 1];
+
+ if (__isString(pathName)) {
+ if (realpath(_stringVal(pathName), nameBuffer)) {
+ path = _MKSTRING(nameBuffer COMMA_CON);
+ }
+ }
+#endif
+%}
+.
+ path isNil ifTrue:[
+ "have to fall back ..."
+
+ p := PipeStream readingFrom:'cd ' , pathName , '; pwd'.
+ p isNil ifTrue:[
+ path := pathName
+ ] ifFalse:[
+ path := p nextLine.
+ p close.
+ ].
+ ].
+ ^ path.
+
+ "
+ OperatingSystem pathNameOf:'.'
+ OperatingSystem pathNameOf:'../smalltalk/../smalltalk'
+ OperatingSystem pathNameOf:'../../..'
+ OperatingSystem pathNameOf:'..'
+ "
!
isValidPath:aPathName
@@ -2365,15 +2712,6 @@
|info type mode uid gid size id atimeLow atimeHi mtimeLow mtimeHi|
- "{ Symbol: directory }"
- "{ Symbol: regular }"
- "{ Symbol: characterSpecial }"
- "{ Symbol: blockSpecial }"
- "{ Symbol: fifo }"
- "{ Symbol: socket }"
- "{ Symbol: symbolicLink }"
- "{ Symbol: unknown }"
-
%{
struct stat buf;
int ret;
@@ -2389,34 +2727,34 @@
}
switch (buf.st_mode & S_IFMT) {
case S_IFDIR:
- type = _directory;
+ type = @symbol(directory);
break;
case S_IFCHR:
- type = _characterSpecial;
+ type = @symbol(characterSpecial);
break;
case S_IFBLK:
- type = _blockSpecial;
+ type = @symbol(blockSpecial);
break;
case S_IFREG:
- type = _regular;
+ type = @symbol(regular);
break;
#ifdef S_IFLNK
case S_IFLNK:
- type = _symbolicLink;
+ type = @symbol(symbolicLink);
break;
#endif
#ifdef S_IFSOCK
case S_IFSOCK:
- type = _socket;
+ type = @symbol(socket);
break;
#endif
#ifdef S_IFIFO
case S_IFIFO:
- type = _fifo;
+ type = @symbol(fifo);
break;
#endif
default:
- type = _unknown;
+ type = @symbol(unknown);
break;
}
mode = _MKSMALLINT(buf.st_mode & 0777);
@@ -2726,7 +3064,7 @@
%{ /* NOCONTEXT */
if (__isString(oldPath) && __isString(newPath)) {
-#if defined(BSD)
+#if defined(HAS_RENAME)
if (rename((char *) _stringVal(oldPath), (char *) _stringVal(newPath)) >= 0) {
RETURN ( true );
}