dirname: add library-safe mdir_name
[gnulib.git] / lib / dirname.c
index c27e5b5..20dcaf5 100644 (file)
@@ -1,7 +1,7 @@
 /* dirname.c -- return all but the last element in a file name
 
-   Copyright (C) 1990, 1998, 2000, 2001, 2003, 2004, 2005, 2006 Free Software
-   Foundation, Inc.
+   Copyright (C) 1990, 1998, 2000, 2001, 2003, 2004, 2005, 2006, 2009
+   Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -20,6 +20,7 @@
 
 #include "dirname.h"
 
+#include <stdlib.h>
 #include <string.h>
 #include "xalloc.h"
 
@@ -57,9 +58,9 @@ dir_len (char const *file)
    since it has different meanings in different environments.
    In some environments the builtin `dirname' modifies its argument.
 
-   Return the leading directories part of FILE, allocated with xmalloc.
+   Return the leading directories part of FILE, allocated with malloc.
    Works properly even if there are trailing slashes (by effectively
-   ignoring them).  Unlike POSIX dirname(), FILE cannot be NULL.
+   ignoring them).  Return NULL on failure.
 
    If lstat (FILE) would succeed, then { chdir (dir_name (FILE));
    lstat (base_name (FILE)); } will access the same file.  Likewise,
@@ -68,17 +69,32 @@ dir_len (char const *file)
    to "foo" in the same directory FILE was in.  */
 
 char *
-dir_name (char const *file)
+mdir_name (char const *file)
 {
   size_t length = dir_len (file);
   bool append_dot = (length == 0
                     || (FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE
                         && length == FILE_SYSTEM_PREFIX_LEN (file)
                         && file[2] != '\0' && ! ISSLASH (file[2])));
-  char *dir = xmalloc (length + append_dot + 1);
+  char *dir = malloc (length + append_dot + 1);
+  if (!dir)
+    return NULL;
   memcpy (dir, file, length);
   if (append_dot)
     dir[length++] = '.';
   dir[length] = '\0';
   return dir;
 }
+
+/* Just like mdir_name, above, except, rather than
+   returning NULL upon malloc failure, here, we report the
+   "memory exhausted" condition and exit.  */
+
+char *
+dir_name (char const *file)
+{
+  char *result = mdir_name (file);
+  if (!result)
+    xalloc_die ();
+  return result;
+}