Back to index

glibc  2.9
dirname.c
Go to the documentation of this file.
00001 /* dirname - return directory part of PATH.
00002    Copyright (C) 1996, 2000, 2001, 2002 Free Software Foundation, Inc.
00003    This file is part of the GNU C Library.
00004    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
00005 
00006    The GNU C Library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Lesser General Public
00008    License as published by the Free Software Foundation; either
00009    version 2.1 of the License, or (at your option) any later version.
00010 
00011    The GNU C Library is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014    Lesser General Public License for more details.
00015 
00016    You should have received a copy of the GNU Lesser General Public
00017    License along with the GNU C Library; if not, write to the Free
00018    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00019    02111-1307 USA.  */
00020 
00021 #include <libgen.h>
00022 #include <string.h>
00023 
00024 
00025 char *
00026 dirname (char *path)
00027 {
00028   static const char dot[] = ".";
00029   char *last_slash;
00030 
00031   /* Find last '/'.  */
00032   last_slash = path != NULL ? strrchr (path, '/') : NULL;
00033 
00034   if (last_slash != NULL && last_slash != path && last_slash[1] == '\0')
00035     {
00036       /* Determine whether all remaining characters are slashes.  */
00037       char *runp;
00038 
00039       for (runp = last_slash; runp != path; --runp)
00040        if (runp[-1] != '/')
00041          break;
00042 
00043       /* The '/' is the last character, we have to look further.  */
00044       if (runp != path)
00045        last_slash = __memrchr (path, '/', runp - path);
00046     }
00047 
00048   if (last_slash != NULL)
00049     {
00050       /* Determine whether all remaining characters are slashes.  */
00051       char *runp;
00052 
00053       for (runp = last_slash; runp != path; --runp)
00054        if (runp[-1] != '/')
00055          break;
00056 
00057       /* Terminate the path.  */
00058       if (runp == path)
00059        {
00060          /* The last slash is the first character in the string.  We have to
00061             return "/".  As a special case we have to return "//" if there
00062             are exactly two slashes at the beginning of the string.  See
00063             XBD 4.10 Path Name Resolution for more information.  */
00064          if (last_slash == path + 1)
00065            ++last_slash;
00066          else
00067            last_slash = path + 1;
00068        }
00069       else
00070        last_slash = runp;
00071 
00072       last_slash[0] = '\0';
00073     }
00074   else
00075     /* This assignment is ill-designed but the XPG specs require to
00076        return a string containing "." in any case no directory part is
00077        found and so a static and constant string is required.  */
00078     path = (char *) dot;
00079 
00080   return path;
00081 }