]> Zhao Yanbai Git Server - minix.git/commitdiff
Add dirname function
authorErik van der Kouwe <erik@minix3.org>
Mon, 25 Jan 2010 18:12:28 +0000 (18:12 +0000)
committerErik van der Kouwe <erik@minix3.org>
Mon, 25 Jan 2010 18:12:28 +0000 (18:12 +0000)
lib/other/dirname.c [new file with mode: 0755]
man/man3/dirname.3 [new file with mode: 0755]
test/test43.c

diff --git a/lib/other/dirname.c b/lib/other/dirname.c
new file mode 100755 (executable)
index 0000000..1a578ae
--- /dev/null
@@ -0,0 +1,29 @@
+#include <libgen.h>
+#include <string.h>
+
+/* based on http://www.opengroup.org/onlinepubs/009695399/functions/dirname.html */
+char *dirname(char *path)
+{
+       char *pathend;
+
+       /* remove leading slash(es) except root */
+       pathend = path + strlen(path) - 1;
+       while (pathend > path && *pathend == '/')
+               pathend--;
+       
+       /* remove last path component */
+       while (pathend >= path && *pathend != '/')
+               pathend--;
+
+       /* remove slash(es) before last path component except root */
+       while (pathend > path && *pathend == '/')
+               pathend--;
+
+       /* special case: no slashes */
+       if (pathend < path)
+               return ".";
+
+       /* truncate and return string */
+       pathend[1] = 0;
+       return path;
+}
diff --git a/man/man3/dirname.3 b/man/man3/dirname.3
new file mode 100755 (executable)
index 0000000..30c9c0a
--- /dev/null
@@ -0,0 +1,19 @@
+.TH DIRNAME 3
+.SH NAME
+dirname \- determine name of containing directory
+.SH SYNOPSIS
+.nf
+.ft B
+#include <libgen.h>
+
+char *dirname(char *\fIpath\fP);
+.SH DESCRIPTION
+The dirname function returns the name of the directory containing \fIpath\fP.
+If the path does not contain slashes, the string "." is returned. Trailing 
+slashes are ignored.
+.SH "SEE ALSO"
+.BR basename (3).
+.SH NOTES
+This function may, but need not, overwrite the buffer passed to it.
+Although MINIX' implementation of this function is re-entrant, POSIX does not
+guarantee this property and portable programs should not rely on it.
index 8ff3534eb37fc17d9c46fa36661300d26be42c2a..0e4d509ab5dadc0744f2c5428dcb28b6f847fe9c 100644 (file)
@@ -3,6 +3,7 @@
 #include <assert.h>
 #include <dirent.h>
 #include <errno.h>
+#include <libgen.h>
 #include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -328,6 +329,36 @@ static void cleanup(const char *path)
        if (rmdir(path) < 0) ERR;
 }
 
+static void test_dirname(const char *path, const char *exp)
+{
+       char buffer[PATH_MAX];
+       int i, j;
+       size_t pathlen = strlen(path);
+       char *pathout;
+
+       assert(pathlen + 3 < PATH_MAX);
+
+       /* try with no, one or two trailing slashes */
+       for (i = 0; i < 3; i++)
+       {
+               /* no trailing slashes for empty string */
+               if (pathlen < 1 && i > 0)
+                       continue;
+                       
+               /* prepare buffer */
+               strcpy(buffer, path);
+               for (j = 0; j < i; j++)
+                       buffer[pathlen + j] = '/';
+       
+               buffer[pathlen + i] = 0;
+       
+               /* perform test */
+               pathout = dirname(buffer);
+               if (strcmp(pathout, exp) != 0)
+                       ERR;
+       }
+}
+
 int main(int argc, char **argv)
 {
        char buffer1[PATH_MAX + 1], buffer2[PATH_MAX + 1];
@@ -358,6 +389,36 @@ int main(int argc, char **argv)
        /* delete the symlinks */
        cleanup(addbasepath(buffer1, PATH_BASE));
 
+       /* also test dirname */
+       test_dirname("", ".");  
+       test_dirname(".", "."); 
+       test_dirname("..", ".");        
+       test_dirname("x", "."); 
+       test_dirname("xy", ".");        
+       test_dirname("x/y", "x");       
+       test_dirname("xy/z", "xy");     
+       test_dirname("x/yz", "x");      
+       test_dirname("ab/cd", "ab");    
+       test_dirname("x//y", "x");      
+       test_dirname("xy//z", "xy");    
+       test_dirname("x//yz", "x");     
+       test_dirname("ab//cd", "ab");   
+       test_dirname("/", "/"); 
+       test_dirname("/x", "/");        
+       test_dirname("/xy", "/");       
+       test_dirname("/x/y", "/x");     
+       test_dirname("/xy/z", "/xy");   
+       test_dirname("/x/yz", "/x");    
+       test_dirname("/ab/cd", "/ab");  
+       test_dirname("/x//y", "/x");    
+       test_dirname("/xy//z", "/xy");  
+       test_dirname("/x//yz", "/x");   
+       test_dirname("/ab//cd", "/ab"); 
+       test_dirname("/usr/src", "/usr");       
+       test_dirname("/usr/src/test", "/usr/src");      
+       test_dirname("usr/src", "usr"); 
+       test_dirname("usr/src/test", "usr/src");        
+
        /* done */
        quit();
        return(-1);     /* impossible */