bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[bug-gnulib] new modules chdir-long, openat; also, save-cwd improvements


From: Paul Eggert
Subject: [bug-gnulib] new modules chdir-long, openat; also, save-cwd improvements
Date: Tue, 18 Jan 2005 14:03:01 -0800
User-agent: Gnus/5.1006 (Gnus v5.10.6) Emacs/21.3 (gnu/linux)

I installed the following patch, merged from coreutils.  It removes
PATH_MAX-related limitations on the length of the working directory.
Most of the original code is by Jim Meyering.

One interesting thing about this change is that we have a cycle of
module dependencies: chdir-long depends on open-at which depends on
save-cwd which depends on chdir-long.  Is this a bad thing?

2005-01-18  Paul Eggert  <address@hidden>

        Merge from coreutils.
        * modules/chdir-long, modules/openat: New files.
        * modules/save-cwd (Depends-on): Depend on chdir-long.
        (Makefile.am): Remove lib_SOURCES; now handled by AC_LIBSOURCES.

        * lib/save-cwd.c: Include "save-cwd.h" before other include files.
        (O_DIRECTORY): Remove; not needed here, since "." must be
        a directory.  All uses removed.
        (save_cwd): Use __sgi || __sun, not sun || __sun.  __sun is
        universal on Suns, and we also need to test for IRIX.
        Revamp code to use 'if' rather than '#if'.
        Avoid unnecessary comparison of cwd->desc to 0.

2005-01-18  Jim Meyering  <address@hidden>

        Change the name of the robust chdir function from chdir to chdir_long.
        * lib/save-cwd.c: Include chdir-long.h rather than chdir.h.
        (restore_cwd): Use chdir_long, not chdir.
        * lib/chdir-long.c: Renamed from chdir.c.
        * lib/chdir-long.h: Renamed from chdir.h.
        [!defined PATH_MAX]: Define chdir_long to chdir on systems like the 
Hurd.
        * m4/chdir-long.m4, m4/openat.m4: New files.
        * m4/save-cwd.m4 (gl_SAVE_CWD): Add AC_LIBSOURCES for save-cwd.c,
        save-cwd.h.  Add AC_LIBOBJ for save-cwd.

Index: lib/save-cwd.c
===================================================================
RCS file: /cvsroot/gnulib/gnulib/lib/save-cwd.c,v
retrieving revision 1.17
diff -p -u -r1.17 save-cwd.c
--- lib/save-cwd.c      7 Aug 2004 00:09:39 -0000       1.17
+++ lib/save-cwd.c      18 Jan 2005 21:55:50 -0000
@@ -21,6 +21,8 @@
 # include "config.h"
 #endif
 
+#include "save-cwd.h"
+
 #include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -37,11 +39,7 @@
 
 #include <errno.h>
 
-#ifndef O_DIRECTORY
-# define O_DIRECTORY 0
-#endif
-
-#include "save-cwd.h"
+#include "chdir-long.h"
 #include "xgetcwd.h"
 
 /* Record the location of the current working directory in CWD so that
@@ -64,48 +62,49 @@
 int
 save_cwd (struct saved_cwd *cwd)
 {
+#if !HAVE_FCHDIR
+# undef fchdir
+# define fchdir(x) (abort (), 0)
+  bool have_working_fchdir = false;
+  bool fchdir_needs_testing = false;
+#elif (__sgi || __sun)
   static bool have_working_fchdir = true;
+  bool fchdir_needs_testing = true;
+#else
+  bool have_working_fchdir = true;
+  bool fchdir_needs_testing = false;
+#endif
 
   cwd->desc = -1;
   cwd->name = NULL;
 
   if (have_working_fchdir)
     {
-#if HAVE_FCHDIR
-      cwd->desc = open (".", O_RDONLY | O_DIRECTORY);
-      if (cwd->desc < 0)
-       cwd->desc = open (".", O_WRONLY | O_DIRECTORY);
+      cwd->desc = open (".", O_RDONLY);
       if (cwd->desc < 0)
        {
-         cwd->name = xgetcwd ();
-         return cwd->name ? 0 : -1;
+         cwd->desc = open (".", O_WRONLY);
+         if (cwd->desc < 0)
+           {
+             cwd->name = xgetcwd ();
+             return cwd->name ? 0 : -1;
+           }
        }
 
-# if __sun__ || sun
       /* On SunOS 4 and IRIX 5.3, fchdir returns EINVAL when auditing
         is enabled, so we have to fall back to chdir.  */
-      if (fchdir (cwd->desc))
+      if (fchdir_needs_testing && fchdir (cwd->desc) != 0)
        {
-         if (errno == EINVAL)
-           {
-             close (cwd->desc);
-             cwd->desc = -1;
-             have_working_fchdir = false;
-           }
-         else
+         int saved_errno = errno;
+         close (cwd->desc);
+         cwd->desc = -1;
+         if (saved_errno != EINVAL)
            {
-             int saved_errno = errno;
-             close (cwd->desc);
-             cwd->desc = -1;
              errno = saved_errno;
              return -1;
            }
+         have_working_fchdir = false;
        }
-# endif /* __sun__ || sun */
-#else
-# define fchdir(x) (abort (), 0)
-      have_working_fchdir = false;
-#endif
     }
 
   if (!have_working_fchdir)
@@ -127,7 +126,7 @@ restore_cwd (const struct saved_cwd *cwd
   if (0 <= cwd->desc)
     return fchdir (cwd->desc);
   else
-    return chdir (cwd->name);
+    return chdir_long (cwd->name);
 }
 
 void
Index: m4/save-cwd.m4
===================================================================
RCS file: /cvsroot/gnulib/gnulib/m4/save-cwd.m4,v
retrieving revision 1.2
diff -p -u -r1.2 save-cwd.m4
--- m4/save-cwd.m4      10 Sep 2003 06:53:45 -0000      1.2
+++ m4/save-cwd.m4      18 Jan 2005 21:55:50 -0000
@@ -1,5 +1,5 @@
-# save-cwd.m4 serial 2
-dnl Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+# save-cwd.m4 serial 3
+dnl Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
 dnl This file is free software, distributed under the terms of the GNU
 dnl General Public License.  As a special exception to the GNU General
 dnl Public License, this file may be distributed as part of a program
@@ -8,6 +8,8 @@ dnl the same distribution terms as the r
 
 AC_DEFUN([gl_SAVE_CWD],
 [
+  AC_LIBSOURCES([save-cwd.c, save-cwd.h])
+  AC_LIBOBJ([save-cwd])
   dnl Prerequisites for lib/save-cwd.c.
   AC_CHECK_HEADERS_ONCE(fcntl.h unistd.h)
   AC_CHECK_FUNCS(fchdir)
Index: modules/save-cwd
===================================================================
RCS file: /cvsroot/gnulib/gnulib/modules/save-cwd,v
retrieving revision 1.6
diff -p -u -r1.6 save-cwd
--- modules/save-cwd    22 Sep 2004 15:11:04 -0000      1.6
+++ modules/save-cwd    18 Jan 2005 21:55:50 -0000
@@ -7,13 +7,13 @@ lib/save-cwd.c
 m4/save-cwd.m4
 
 Depends-on:
+chdir-long
 xgetcwd
 
 configure.ac:
 gl_SAVE_CWD
 
 Makefile.am:
-lib_SOURCES += save-cwd.h save-cwd.c
 
 Include:
 "save-cwd.h"
--- /dev/null   2003-03-18 13:55:57 -0800
+++ lib/chdir-long.c    2005-01-18 13:31:32 -0800
@@ -0,0 +1,338 @@
+/* provide a chdir function that tries not to fail due to ENAMETOOLONG
+   Copyright (C) 2004 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
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+/* written by Jim Meyering */
+
+#include <config.h>
+
+#include "chdir-long.h"
+
+#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdio.h>
+#include <assert.h>
+#include <limits.h>
+
+#include "mempcpy.h"
+#include "openat.h"
+
+#ifndef O_DIRECTORY
+# define O_DIRECTORY 0
+#endif
+
+#ifndef MIN
+# define MIN(a, b) ((a) < (b) ? (a) : (b))
+#endif
+
+#ifndef PATH_MAX
+# error "compile this file only if your system defines PATH_MAX"
+#endif
+
+/* FIXME: this use of `MIN' is our sole concession to arbitrary limitations.
+   If, for some system, PATH_MAX is larger than 8191 and you call
+   chdir_long with a directory name that is longer than PATH_MAX,
+   yet that contains a single component that is more than 8191 bytes
+   long, then this function will fail.  */
+#define MAX_COMPONENT_LENGTH MIN (PATH_MAX - 1, 8 * 1024)
+
+struct cd_buf
+{
+  /* FIXME maybe allocate this via malloc, rather than using the stack.
+     But that would be the sole use of malloc.  Is it worth it to
+     let chdir_long fail due to a low-memory condition?
+     But when using malloc, and assuming we remove the `concession'
+     above, we'll still have to avoid allocating 2^31 bytes on
+     systems that define PATH_MAX to very large number.
+     Ideally, we'd allocate enough to deal with most names, and
+     dynamically increase the buffer size only when necessary.  */
+  char buffer[MAX_COMPONENT_LENGTH + 1];
+  char *avail;
+  int fd;
+};
+
+/* Like memchr, but return the number of bytes from MEM
+   to the first occurrence of C thereafter.  Search only
+   LEN bytes.  Return LEN if C is not found.  */
+static inline size_t
+memchrcspn (char const *mem, int c, size_t len)
+{
+  char const *found = memchr (mem, c, len);
+  if (!found)
+    return len;
+
+  len = found - mem;
+  return len;
+}
+
+static void
+cdb_init (struct cd_buf *cdb)
+{
+  cdb->avail = cdb->buffer;
+  cdb->fd = AT_FDCWD;
+}
+
+static inline bool
+cdb_empty (struct cd_buf const *cdb)
+{
+  return cdb->avail == cdb->buffer;
+}
+
+static inline int
+cdb_fchdir (struct cd_buf const *cdb)
+{
+  return fchdir (cdb->fd);
+}
+
+static int
+cdb_advance_fd (struct cd_buf *cdb, char const *dir)
+{
+  int new_fd = openat (cdb->fd, dir, O_RDONLY | O_DIRECTORY);
+  if (new_fd < 0)
+    {
+      new_fd = openat (cdb->fd, dir, O_WRONLY | O_DIRECTORY);
+      if (new_fd < 0)
+       return -1;
+    }
+
+  if (cdb->fd != AT_FDCWD)
+    close (cdb->fd);
+  cdb->fd = new_fd;
+
+  return 0;
+}
+
+static int
+cdb_flush (struct cd_buf *cdb)
+{
+  if (cdb_empty (cdb))
+    return 0;
+
+  cdb->avail[0] = '\0';
+  if (cdb_advance_fd (cdb, cdb->buffer) != 0)
+    return -1;
+
+  cdb->avail = cdb->buffer;
+
+  return 0;
+}
+
+static void
+cdb_free (struct cd_buf *cdb)
+{
+  if (0 <= cdb->fd && close (cdb->fd) != 0)
+    abort ();
+}
+
+static int
+cdb_append (struct cd_buf *cdb, char const *s, size_t len)
+{
+  char const *end = cdb->buffer + sizeof cdb->buffer;
+
+  /* Insert a slash separator if there is a preceding byte
+     and it's not a slash.  */
+  bool need_slash = (cdb->buffer < cdb->avail && cdb->avail[-1] != '/');
+  size_t n_free;
+
+  if (sizeof cdb->buffer < len + 1)
+    {
+      /* This single component is too long.  */
+      errno = ENAMETOOLONG;
+      return -1;
+    }
+
+  /* See if there's enough room for the `/', the new component and
+     a trailing NUL.  */
+  n_free = end - cdb->avail;
+  if (n_free < need_slash + len + 1)
+    {
+      if (cdb_flush (cdb) != 0)
+       return -1;
+      need_slash = false;
+    }
+
+  if (need_slash)
+    *(cdb->avail)++ = '/';
+
+  cdb->avail = mempcpy (cdb->avail, s, len);
+  return 0;
+}
+
+/* This is a wrapper around chdir that works even on PATH_MAX-limited
+   systems.  It handles an arbitrarily long directory name by extracting
+   and processing manageable portions of the name.  On systems without
+   the openat syscall, this means changing the working directory to
+   more and more `distant' points along the long directory name and
+   then restoring the working directory.
+   If any of those attempts to change or restore the working directory
+   fails, this function exits nonzero.
+
+   Note that this function may still fail with errno == ENAMETOOLONG,
+   but only if the specified directory name contains a component that
+   is long enough to provoke such a failure all by itself (e.g. if the
+   component is longer than PATH_MAX on systems that define PATH_MAX).  */
+
+int
+chdir_long (char const *dir)
+{
+  int e = chdir (dir);
+  if (e == 0 || errno != ENAMETOOLONG)
+    return e;
+
+  {
+    size_t len = strlen (dir);
+    char const *dir_end = dir + len;
+    char const *d;
+    struct cd_buf cdb;
+
+    cdb_init (&cdb);
+
+    /* If DIR is the empty string, then the chdir above
+       must have failed and set errno to ENOENT.  */
+    assert (0 < len);
+
+    if (*dir == '/')
+      {
+       /* Names starting with exactly two slashes followed by at least
+          one non-slash are special --
+          for example, in some environments //Hostname/file may
+          denote a file on a different host.
+          Preserve those two leading slashes.  Treat all other
+          sequences of slashes like a single one.  */
+       if (3 <= len && dir[1] == '/' && dir[2] != '/')
+         {
+           size_t name_len = 1 + strcspn (dir + 3, "/");
+           if (cdb_append (&cdb, dir, 2 + name_len) != 0)
+             goto Fail;
+           /* Advance D to next slash or to end of string. */
+           d = dir + 2 + name_len;
+           assert (*d == '/' || *d == '\0');
+         }
+       else
+         {
+           if (cdb_append (&cdb, "/", 1) != 0)
+             goto Fail;
+           d = dir + 1;
+         }
+      }
+    else
+      {
+       d = dir;
+      }
+
+    while (1)
+      {
+       /* Skip any slashes to find start of next component --
+          or the end of DIR. */
+       char const *start = d + strspn (d, "/");
+       if (*start == '\0')
+         {
+           if (cdb_flush (&cdb) != 0)
+             goto Fail;
+           break;
+         }
+       /* If the remaining portion is no longer than PATH_MAX, then
+          flush anything that is buffered and do the rest in one chunk.  */
+       if (dir_end - start <= PATH_MAX)
+         {
+           if (cdb_flush (&cdb) != 0
+               || cdb_advance_fd (&cdb, start) != 0)
+             goto Fail;
+           break;
+         }
+
+       len = memchrcspn (start, '/', dir_end - start);
+       assert (len == strcspn (start, "/"));
+       d = start + len;
+       if (cdb_append (&cdb, start, len) != 0)
+         goto Fail;
+      }
+
+    if (cdb_fchdir (&cdb) != 0)
+      goto Fail;
+
+    cdb_free (&cdb);
+    return 0;
+
+   Fail:
+    {
+      int saved_errno = errno;
+      cdb_free (&cdb);
+      errno = saved_errno;
+      return -1;
+    }
+  }
+}
+
+#if TEST_CHDIR
+
+# include <stdio.h>
+# include "closeout.h"
+# include "error.h"
+
+char *program_name;
+
+int
+main (int argc, char *argv[])
+{
+  char *line = NULL;
+  size_t n = 0;
+  int len;
+
+  program_name = argv[0];
+  atexit (close_stdout);
+
+  len = getline (&line, &n, stdin);
+  if (len < 0)
+    {
+      int saved_errno = errno;
+      if (feof (stdin))
+       exit (0);
+
+      error (EXIT_FAILURE, saved_errno,
+            "reading standard input");
+    }
+  else if (len == 0)
+    exit (0);
+
+  if (line[len-1] == '\n')
+    line[len-1] = '\0';
+
+  if (chdir_long (line) != 0)
+    error (EXIT_FAILURE, errno,
+          "chdir_long failed: %s", line);
+
+  {
+    /* Using `pwd' here makes sense only if it is a robust implementation,
+       like the one in coreutils after the 2004-04-19 changes.  */
+    char const *cmd = "pwd";
+    execlp (cmd, (char *) NULL);
+    error (EXIT_FAILURE, errno, "%s", cmd);
+  }
+
+  /* not reached */
+  abort ();
+}
+#endif
+
+/*
+Local Variables:
+compile-command: "gcc -DTEST_CHDIR=1 -DHAVE_CONFIG_H -I.. -g -O -W -Wall 
chdir-long.c libfetish.a"
+End:
+*/
--- /dev/null   2003-03-18 13:55:57 -0800
+++ lib/chdir-long.h    2005-01-18 13:31:32 -0800
@@ -0,0 +1,35 @@
+/* provide a chdir function that tries not to fail due to ENAMETOOLONG
+   Copyright (C) 2004 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
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+/* Written by Jim Meyering.  */
+
+#include <unistd.h>
+#include <limits.h>
+
+#ifndef PATH_MAX
+# ifdef        MAXPATHLEN
+#  define PATH_MAX MAXPATHLEN
+# endif
+#endif
+
+/* On systems without PATH_MAX, presume that chdir accepts
+   arbitrarily long directory names.  */
+#ifndef PATH_MAX
+# define chdir_long(Dir) chdir (Dir)
+#else
+int chdir_long (char const *dir);
+#endif
--- /dev/null   2003-03-18 13:55:57 -0800
+++ lib/openat.c        2005-01-18 13:31:10 -0800
@@ -0,0 +1,91 @@
+/* provide a replacement openat function
+   Copyright (C) 2004 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
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+/* written by Jim Meyering */
+
+#include <config.h>
+
+#include "openat.h"
+
+#include <stdlib.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include "error.h"
+#include "exitfail.h"
+#include "save-cwd.h"
+
+#include "gettext.h"
+#define _(msgid) gettext (msgid)
+
+/* Replacement for Solaris' openat function.
+   <http://www.google.com/search?q=openat+site:docs.sun.com>
+   Simulate it by doing save_cwd/fchdir/open/restore_cwd.
+   If either the save_cwd or the restore_cwd fails (relatively unlikely,
+   and usually indicative of a problem that deserves close attention),
+   then give a diagnostic and exit nonzero.
+   Otherwise, upon failure, set errno and return -1, as openat does.
+   Upon successful completion, return a file descriptor.  */
+int
+rpl_openat (int fd, char const *filename, int flags, ...)
+{
+  struct saved_cwd saved_cwd;
+  int saved_errno;
+  int new_fd;
+  mode_t mode = 0;
+
+  if (flags & O_CREAT)
+    {
+      va_list arg;
+      va_start (arg, flags);
+
+      /* Assume that mode_t is passed compatibly with mode_t's type
+        after argument promotion.  */
+      mode = va_arg (arg, mode_t);
+
+      va_end (arg);
+    }
+
+  if (fd == AT_FDCWD || *filename == '/')
+    return open (filename, flags, mode);
+
+  if (save_cwd (&saved_cwd) != 0)
+    error (exit_failure, errno,
+          _("openat: unable to record current working directory"));
+
+  if (fchdir (fd) != 0)
+    {
+      saved_errno = errno;
+      free_cwd (&saved_cwd);
+      errno = saved_errno;
+      return -1;
+    }
+
+  new_fd = open (filename, flags, mode);
+  saved_errno = errno;
+
+  if (restore_cwd (&saved_cwd) != 0)
+    error (exit_failure, errno,
+          _("openat: unable to restore working directory"));
+
+  free_cwd (&saved_cwd);
+
+  errno = saved_errno;
+  return new_fd;
+}
--- /dev/null   2003-03-18 13:55:57 -0800
+++ lib/openat.h        2005-01-18 13:31:10 -0800
@@ -0,0 +1,35 @@
+/* provide a replacement openat function
+   Copyright (C) 2004 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
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+/* written by Jim Meyering */
+
+#if HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+
+#ifndef AT_FDCWD
+# define AT_FDCWD (-3041965) /* same value as Solaris 9 */
+
+# ifdef __OPENAT_PREFIX
+#  undef openat
+#  define __OPENAT_CONCAT(x, y) x ## y
+#  define __OPENAT_XCONCAT(x, y) __OPENAT_CONCAT (x, y)
+#  define __OPENAT_ID(y) __OPENAT_XCONCAT (__OPENAT_PREFIX, y)
+#  define openat __OPENAT_ID (openat)
+int openat (int fd, char const *filename, int flags, /* mode_t mode */ ...);
+# endif
+#endif
--- /dev/null   2003-03-18 13:55:57 -0800
+++ m4/chdir-long.m4    2005-01-18 13:35:16 -0800
@@ -0,0 +1,41 @@
+#serial 4
+
+# Use Gnulib's robust chdir function.
+# It can handle arbitrarily long directory names, which means
+# that when it is given the name of an existing directory, it
+# never fails with ENAMETOOLONG.
+# Arrange to compile chdir-long.c only on systems that define PATH_MAX.
+
+dnl Copyright (C) 2004 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+# Written by Jim Meyering.
+
+AC_DEFUN([gl_FUNC_CHDIR_LONG],
+[
+  AC_LIBSOURCES([chdir-long.c, chdir-long.h])
+  AC_CACHE_CHECK([whether this system has a definition of PATH_MAX],
+    gl_have_path_max_definition,
+    [AC_EGREP_CPP([have_path_max_definition],
+                  [#include <unistd.h>
+#include <limits.h>
+#ifdef PATH_MAX
+have_path_max_definition
+#endif],
+    gl_have_path_max_definition=yes,
+    gl_have_path_max_definition=no)])
+
+  if test $gl_have_path_max_definition; then
+    AC_LIBOBJ([chdir-long])
+    gl_PREREQ_CHDIR_LONG
+  fi
+])
+
+AC_DEFUN([gl_PREREQ_CHDIR_LONG],
+[
+  AM_STDBOOL_H
+  gl_FUNC_MEMPCPY
+  gl_FUNC_OPENAT
+])
--- /dev/null   2003-03-18 13:55:57 -0800
+++ m4/openat.m4        2005-01-18 13:33:12 -0800
@@ -0,0 +1,28 @@
+#serial 3
+# See if we need to use our replacement for Solaris' openat function.
+
+dnl Copyright (C) 2004 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+# Written by Jim Meyering.
+
+AC_DEFUN([gl_FUNC_OPENAT],
+[
+  AC_LIBSOURCES([openat.c, openat.h])
+  AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
+  AC_REPLACE_FUNCS(openat)
+  case $ac_cv_func_openat in
+  yes) ;;
+  *)
+    AC_DEFINE([__OPENAT_PREFIX], [[rpl_]],
+      [Define to rpl_ if the openat replacement function should be used.])
+    gl_PREREQ_OPENAT;;
+  esac
+])
+
+AC_DEFUN([gl_PREREQ_OPENAT],
+[
+  AC_REQUIRE([gl_SAVE_CWD])
+])
--- /dev/null   2003-03-18 13:55:57 -0800
+++ modules/chdir-long  2005-01-18 13:30:01 -0800
@@ -0,0 +1,25 @@
+Description:
+chdir-like function that tries not to fail due to ENAMETOOLONG
+
+Files:
+lib/chdir-long.h
+lib/chdir-long.c
+m4/chdir-long.m4
+
+Depends-on:
+openat
+mempcpy
+
+configure.ac:
+gl_FUNC_CHDIR_LONG
+
+Makefile.am:
+
+Include:
+"chdir-long.h"
+
+License:
+GPL
+
+Maintainer:
+Jim Meyering
--- /dev/null   2003-03-18 13:55:57 -0800
+++ modules/openat      2005-01-18 13:28:22 -0800
@@ -0,0 +1,27 @@
+Description:
+Open a file at a directory.
+
+Files:
+lib/openat.c
+lib/openat.h
+m4/openat.m4
+
+Depends-on:
+save-cwd
+gettext
+error
+exitfail
+
+configure.ac:
+gl_FUNC_OPENAT
+
+Makefile.am:
+
+Include:
+"openat.h"
+
+License:
+GPL
+
+Maintainer:
+Jim Meyering




reply via email to

[Prev in Thread] Current Thread [Next in Thread]