UnixOperatingSystem.st
changeset 15157 a04922c5376b
parent 15155 e6df51948b20
child 15175 1239f9959ed8
child 18054 56594a8c6b83
--- a/UnixOperatingSystem.st	Thu Apr 25 15:06:28 2013 +0200
+++ b/UnixOperatingSystem.st	Thu Apr 25 15:08:04 2013 +0200
@@ -720,7 +720,7 @@
 
 /*
  * some systems do not have realpath();
- * the alternative of reading from a 'pwp'-pipe
+ * the alternative of reading from a 'pwd'-pipe
  * is way too slow. Here is a realpath for the rest of us.
  * define WANT_REALPATH in the xxxIntern-file to get it.
  */
@@ -744,19 +744,20 @@
 #  define MAXPATHLEN     1024
 # endif
 
-static
-char *
-realpath(path, resolved_path)
-    char *path;
-    char resolved_path [];
+static char *
+realpath(const char *path, char *resolved_path)
 {
 	char copy_path[MAXPATHLEN];
 	char link_path[MAXPATHLEN];
-	char *new_path = resolved_path;
-	char *max_path;
+	char *new_path, *max_path, *mallocedPath;
 	int readlinks = 0;
 	int n;
 
+	if (resolved_path == NULL) {
+	    mallocedPath = resolved_path = malloc(MAXPATHLEN+1);
+	}
+	new_path = resolved_path;
+
 	/* Make a copy of the source path since we may need to modify it. */
 	strcpy(copy_path, path);
 	path = copy_path;
@@ -768,8 +769,10 @@
 #else
 		new_path = getwd(new_path);
 #endif
-		if (new_path == NULL)
+		if (new_path == NULL) {
+		    if (mallocedPath) free(mallocedPath);
 		    return(NULL);
+		}
 
 		new_path += strlen(new_path);
 		if (new_path[-1] != '/')
@@ -808,24 +811,28 @@
 		/* Safely copy the next pathname component. */
 		while (*path != '\0' && *path != '/') {
 			if (path > max_path) {
-				errno = ENAMETOOLONG;
-				return NULL;
+		    	    if (mallocedPath) free(mallocedPath);
+			    errno = ENAMETOOLONG;
+			    return NULL;
 			}
 			*new_path++ = *path++;
 		}
 #ifdef S_IFLNK
 		/* Protect against infinite loops. */
 		if (readlinks++ > MAX_READLINKS) {
-			errno = ELOOP;
-			return NULL;
+		    if (mallocedPath) free(mallocedPath);
+		    errno = ELOOP;
+		    return NULL;
 		}
 		/* See if latest pathname component is a symlink. */
 		*new_path = '\0';
 		n = readlink(resolved_path, link_path, MAXPATHLEN - 1);
 		if (n < 0) {
 			/* EINVAL means the file exists but isn't a symlink. */
-			if (errno != EINVAL)
-				return NULL;
+			if (errno != EINVAL) {
+		    	    if (mallocedPath) free(mallocedPath);
+			    return NULL;
+			}
 		}
 		else {
 			/* Note: readlink doesn't add the null byte. */
@@ -839,8 +846,9 @@
 					;
 			/* Safe sex check. */
 			if (strlen(path) + n >= MAXPATHLEN) {
-				errno = ENAMETOOLONG;
-				return NULL;
+		    	    if (mallocedPath) free(mallocedPath);
+			    errno = ENAMETOOLONG;
+			    return NULL;
 			}
 			/* Insert symlink contents into path. */
 			strcat(link_path, path);
@@ -5034,7 +5042,7 @@
             [(p size > 1)
              and:[p endsWith:(self fileSeparator)]
             ] whileTrue:[
-                p := p copyWithoutLast:1.
+                p := p copyButLast:1.
             ].
             ^ p
         ].
@@ -5174,17 +5182,20 @@
 
     if (__isStringLike(pathName)) {
 #ifdef HAS_REALPATH
-        char *nameP = realpath(__stringVal(pathName), NULL);
+        // POSIX-2008 says, that a NULL namebuffer causes realPath to malloc()
+        // the required memory. But this does not work as of 2013-04
+        char nameBuffer[MAXPATHLEN+1];
+        char *nameP = realpath(__stringVal(pathName), nameBuffer);
         if (nameP) {
             OBJ ret = __MKSTRING(nameP);
-            free(nameP);
+            // free(nameP);
             RETURN ( ret );
         }
+        // fprintf(stderr, "stx[warning]: realpath(\"%s\") failed: %s\n", __stringVal(pathName), strerror(errno));
 #endif /* ! HAS_REALPATH */
     } else {
         error = @symbol(argument);     // argument is not a string
     }
-    fprintf(stderr, "stx[warning]: realpath(\"%s\") failed\n", __stringVal(pathName));
 %}.
 "/ Does not work as of 2013-04 (UNLIMITEDSTACK problem?)
 "/    error notNil ifTrue:[
@@ -5194,6 +5205,7 @@
 
     "
         self primPathNameOf:'.'
+        self primPathNameOf:'/murks/quatsch/bla/.'
         self primPathNameOf:5555
     "
 !
@@ -6375,36 +6387,36 @@
 closeLeftOverFiles
     "a bad bad kludge and workaround for a big bug in the linux
      getAddrInfo implementation:
-	if it gets interrupted (via a timer, for example), its domain-name
-	socket remains open and is NEVER closed.
-	These open files collect up and lead to no-more-files eventually.
+        if it gets interrupted (via a timer, for example), its domain-name
+        socket remains open and is NEVER closed.
+        These open files collect up and lead to no-more-files eventually.
      Invoking this method helps in this situation."
 
     |p|
 
     p := PipeStream
-	    readingFrom:('lsof -p ' , (OperatingSystem getProcessId printString)).
+            readingFrom:('lsof -p ' , (OperatingSystem getProcessId printString)).
 
     p linesDo:[:line |
-	|words fd|
-
-	words := line asCollectionOfWords.
-	"/ COMMAND PID USER   FD   TYPE     DEVICE    SIZE    NODE NAME
-	words first = 'stx' ifTrue:[
-	    words second = (OperatingSystem getProcessId printString) ifTrue:[
-		(words fourth endsWith:'u') ifTrue:[
-		    (words fifth = 'IPv4') ifTrue:[
-			(words seventh = 'UDP') ifTrue:[
-			    (words last endsWith:'domain') ifTrue:[
-				fd := Number readFrom:(words fourth copyWithoutLast:1).
+        |words fd|
+
+        words := line asCollectionOfWords.
+        "/ COMMAND PID USER   FD   TYPE     DEVICE    SIZE    NODE NAME
+        words first = 'stx' ifTrue:[
+            words second = (OperatingSystem getProcessId printString) ifTrue:[
+                (words fourth endsWith:'u') ifTrue:[
+                    (words fifth = 'IPv4') ifTrue:[
+                        (words seventh = 'UDP') ifTrue:[
+                            (words last endsWith:'domain') ifTrue:[
+                                fd := Number readFrom:(words fourth copyButLast:1).
 Transcript showCR:line.
-				OperatingSystem closeFd:fd.
-			    ]
-			]
-		    ]
-		]
-	    ]
-	]
+                                OperatingSystem closeFd:fd.
+                            ]
+                        ]
+                    ]
+                ]
+            ]
+        ]
     ].
     p close.
 
@@ -13522,11 +13534,11 @@
 !UnixOperatingSystem class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic/UnixOperatingSystem.st,v 1.313 2013-04-25 11:42:17 stefan Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/UnixOperatingSystem.st,v 1.314 2013-04-25 13:08:04 stefan Exp $'
 !
 
 version_CVS
-    ^ '$Header: /cvs/stx/stx/libbasic/UnixOperatingSystem.st,v 1.313 2013-04-25 11:42:17 stefan Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/UnixOperatingSystem.st,v 1.314 2013-04-25 13:08:04 stefan Exp $'
 ! !