From 854ebf64dc7dae95a43a4e139e075156d2add805 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Sun, 14 Jan 2007 11:32:10 +0000 Subject: [PATCH] New module 'fchdir'. --- ChangeLog | 33 ++++++ MODULES.html.sh | 1 + lib/backupfile.c | 5 + lib/chown.c | 5 + lib/clean-temp.c | 7 ++ lib/copy-file.c | 6 ++ lib/dirent_.h | 42 ++++++++ lib/dup-safer.c | 2 +- lib/execute.c | 5 + lib/fchdir.c | 277 ++++++++++++++++++++++++++++++++++++++++++++++++++ lib/fcntl_.h | 19 ++++ lib/fsusage.c | 5 + lib/gc-gnulib.c | 5 + lib/getcwd.c | 5 + lib/glob.c | 5 + lib/javacomp.c | 5 + lib/mountlist.c | 10 ++ lib/openat-proc.c | 5 + lib/pagealign_alloc.c | 5 + lib/pipe.c | 5 + lib/progreloc.c | 5 + lib/savedir.c | 5 + lib/unistd_.h | 52 ++++++++++ lib/utime.c | 5 + m4/fchdir.m4 | 29 ++++++ m4/unistd_h.m4 | 18 +++- modules/fchdir | 41 ++++++++ modules/unistd | 12 ++- 28 files changed, 612 insertions(+), 7 deletions(-) create mode 100644 lib/dirent_.h create mode 100644 lib/fchdir.c create mode 100644 lib/unistd_.h create mode 100644 m4/fchdir.m4 create mode 100644 modules/fchdir diff --git a/ChangeLog b/ChangeLog index 688ac0569..eff0b42f2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,36 @@ +2006-12-30 Bruno Haible + + * modules/fchdir: New file. + * modules/unistd (Files): Add lib/unistd_.h. + (Makefile.am): Generate unistd.h from unistd_.h. + * lib/fchdir.c: New file. + * lib/dirent_.h: New file. + * lib/unistd_.h: New file. + * lib/fcntl_.h (open) [FCHDIR_REPLACEMENT]: New replacement. + * m4/fchdir.m4: New file. + * m4/unistd_h.m4 (gl_PREREQ_UNISTD): New macro. + (gl_HEADER_UNISTD): Invoke it. + * lib/dup-safer.c (dup_safer) [FCHDIR_REPLACEMENT]: Use the dup + function. + * lib/backupfile.c (opendir, closedir): Undefine. + * lib/chown.c (open, close): Undefine. + * lib/clean-temp.c (open, close): Undefine. + * lib/copy-file.c (open, close): Undefine. + * lib/execute.c (open, close): Undefine. + * lib/fsusage.c (open, close): Undefine. + * lib/gc-gnulib.c (open, close): Undefine. + * lib/getcwd.c (opendir, closedir): Undefine. + * lib/glob.c (opendir, closedir): Undefine. + * lib/javacomp.c (open, close): Undefine. + * lib/mountlist.c (open, close, opendir, closedir): Undefine. + * lib/openat-proc.c (open, close): Undefine. + * lib/pagealign_alloc.c (open, close): Undefine. + * lib/pipe.c (open, close): Undefine. + * lib/progreloc.c (open, close): Undefine. + * lib/savedir.c (opendir, closedir): Undefine. + * lib/utime.c (open, close): Undefine. + * MODULES.html.sh (Support for systems lacking POSIX:2001): Add fchdir. + 2007-01-10 Bruno Haible * lib/striconv.c (mem_cd_iconv): Align the temporary buffer. diff --git a/MODULES.html.sh b/MODULES.html.sh index 5836e3431..68a3152ba 100755 --- a/MODULES.html.sh +++ b/MODULES.html.sh @@ -1921,6 +1921,7 @@ func_all_modules () func_begin_table func_module chown func_module dup2 + func_module fchdir func_module ftruncate func_module getaddrinfo func_module getcwd diff --git a/lib/backupfile.c b/lib/backupfile.c index 5875d3a11..adfc0e541 100644 --- a/lib/backupfile.c +++ b/lib/backupfile.c @@ -82,6 +82,11 @@ of `digit' even when the host does not conform to POSIX. */ #define ISDIGIT(c) ((unsigned int) (c) - '0' <= 9) +/* The results of opendir() in this file are not used with dirfd and fchdir, + therefore save some unnecessary work in fchdir.c. */ +#undef opendir +#undef closedir + /* The extension added to file names to produce a simple (as opposed to numbered) backup file name. */ char const *simple_backup_suffix = "~"; diff --git a/lib/chown.c b/lib/chown.c index 1301aa6ad..2da2c80ab 100644 --- a/lib/chown.c +++ b/lib/chown.c @@ -33,6 +33,11 @@ #include #include +/* The results of open() in this file are not used with fchdir, + therefore save some unnecessary work in fchdir.c. */ +#undef open +#undef close + /* Provide a more-closely POSIX-conforming version of chown on systems with one or both of the following problems: - chown doesn't treat an ID of -1 as meaning diff --git a/lib/clean-temp.c b/lib/clean-temp.c index aa82974a1..7acc68857 100644 --- a/lib/clean-temp.c +++ b/lib/clean-temp.c @@ -67,6 +67,13 @@ # define uintptr_t unsigned long #endif +#if !GNULIB_FCNTL_SAFER +/* The results of open() in this file are not used with fchdir, + therefore save some unnecessary work in fchdir.c. */ +# undef open +# undef close +#endif + /* The use of 'volatile' in the types below (and ISO C 99 section 5.1.2.3.(5)) ensure that while constructing or modifying the data structures, the field diff --git a/lib/copy-file.c b/lib/copy-file.c index 4314f4c6d..5a5dcf72c 100644 --- a/lib/copy-file.c +++ b/lib/copy-file.c @@ -46,6 +46,12 @@ #define _(str) gettext (str) +/* The results of open() in this file are not used with fchdir, + therefore save some unnecessary work in fchdir.c. */ +#undef open +#undef close + + void copy_file_preserving (const char *src_filename, const char *dest_filename) { diff --git a/lib/dirent_.h b/lib/dirent_.h new file mode 100644 index 000000000..cadc267f8 --- /dev/null +++ b/lib/dirent_.h @@ -0,0 +1,42 @@ +/* Wrapper around . + Copyright (C) 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef _GL_DIRENT_H +#define _GL_DIRENT_H + +#include @ABSOLUTE_DIRENT_H@ + + +/* Declare overridden functions. */ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef FCHDIR_REPLACEMENT +# define opendir rpl_opendir +extern DIR * opendir (const char *); +# define closedir rpl_closedir +extern int closedir (DIR *); +#endif + +#ifdef __cplusplus +} +#endif + + +#endif /* _GL_DIRENT_H */ diff --git a/lib/dup-safer.c b/lib/dup-safer.c index d0606eeb4..7b12b615c 100644 --- a/lib/dup-safer.c +++ b/lib/dup-safer.c @@ -35,7 +35,7 @@ int dup_safer (int fd) { -#ifdef F_DUPFD +#if defined F_DUPFD && !defined FCHDIR_REPLACEMENT return fcntl (fd, F_DUPFD, STDERR_FILENO + 1); #else /* fd_safer calls us back, but eventually the recursion unwinds and diff --git a/lib/execute.c b/lib/execute.c index cb72343f8..ea9388034 100644 --- a/lib/execute.c +++ b/lib/execute.c @@ -70,6 +70,11 @@ extern char **environ; # define STDERR_FILENO 2 #endif +/* The results of open() in this file are not used with fchdir, + therefore save some unnecessary work in fchdir.c. */ +#undef open +#undef close + #ifdef EINTR diff --git a/lib/fchdir.c b/lib/fchdir.c new file mode 100644 index 000000000..c05a9f314 --- /dev/null +++ b/lib/fchdir.c @@ -0,0 +1,277 @@ +/* fchdir replacement. + Copyright (C) 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "canonicalize.h" +#include "dirfd.h" +#include "strdup.h" + +/* This replacement assumes that a directory is not renamed while opened + through a file descriptor. */ + +/* Array of file descriptors opened. If it points to a directory, it stores + info about this directory; otherwise it stores an errno value of ENOTDIR. */ +typedef struct +{ + char *name; /* Absolute name of the directory, or NULL. */ + int saved_errno; /* If name == NULL: The error code describing the failure + reason. */ +} dir_info_t; +static dir_info_t *dirs; +static size_t dirs_allocated; + +/* Try to ensure dirs has enough room for a slot at index fd. */ +static void +ensure_dirs_slot (size_t fd) +{ + if (fd >= dirs_allocated) + { + size_t new_allocated; + dir_info_t *new_dirs; + size_t i; + + new_allocated = 2 * dirs_allocated + 1; + if (new_allocated <= fd) + new_allocated = fd + 1; + new_dirs = + (dirs != NULL + ? (dir_info_t *) realloc (dirs, new_allocated * sizeof (dir_info_t)) + : (dir_info_t *) malloc (new_allocated * sizeof (dir_info_t))); + if (new_dirs != NULL) + { + for (i = dirs_allocated; i < new_allocated; i++) + { + new_dirs[i].name = NULL; + new_dirs[i].saved_errno = ENOTDIR; + } + dirs = new_dirs; + dirs_allocated = new_allocated; + } + } +} + +/* Override open() and close(), to keep track of the open file descriptors. */ + +int +close (int fd) +#undef close +{ + int retval = close (fd); + + if (retval >= 0 && fd >= 0 && fd < dirs_allocated) + { + if (dirs[fd].name != NULL) + free (dirs[fd].name); + dirs[fd].name = NULL; + dirs[fd].saved_errno = ENOTDIR; + } + return retval; +} + +int +open (const char *filename, int flags, ...) +#undef open +{ + mode_t mode; + int fd; + struct stat statbuf; + + mode = 0; + if (flags & O_CREAT) + { + va_list arg; + va_start (arg, flags); + + /* If mode_t is narrower than int, use the promoted type (int), + not mode_t. Use sizeof to guess whether mode_t is narrower; + we don't know of any practical counterexamples. */ + mode = (sizeof (mode_t) < sizeof (int) + ? va_arg (arg, int) + : va_arg (arg, mode_t)); + + va_end (arg); + } + fd = open (filename, flags, mode); + if (fd >= 0) + { + ensure_dirs_slot (fd); + if (fd < dirs_allocated + && fstat (fd, &statbuf) >= 0 && S_ISDIR (statbuf.st_mode)) + { + dirs[fd].name = canonicalize_file_name (filename); + if (dirs[fd].name == NULL) + dirs[fd].saved_errno = errno; + } + } + return fd; +} + +/* Override opendir() and closedir(), to keep track of the open file + descriptors. Needed because there is a function dirfd(). */ + +int +closedir (DIR *dp) +#undef closedir +{ + int fd = dirfd (dp); + int retval = closedir (dp); + + if (retval >= 0 && fd >= 0 && fd < dirs_allocated) + { + if (dirs[fd].name != NULL) + free (dirs[fd].name); + dirs[fd].name = NULL; + dirs[fd].saved_errno = ENOTDIR; + } + return retval; +} + +DIR * +opendir (const char *filename) +#undef opendir +{ + DIR *dp; + + dp = opendir (filename); + if (dp != NULL) + { + int fd = dirfd (dp); + if (fd >= 0) + { + ensure_dirs_slot (fd); + if (fd < dirs_allocated) + { + dirs[fd].name = canonicalize_file_name (filename); + if (dirs[fd].name == NULL) + dirs[fd].saved_errno = errno; + } + } + } + return dp; +} + +/* Override dup() and dup2(), to keep track of open file descriptors. */ + +int +dup (int oldfd) +#undef dup +{ + int newfd = dup (oldfd); + + if (oldfd >= 0 && newfd >= 0) + { + ensure_dirs_slot (newfd); + if (newfd < dirs_allocated) + { + if (oldfd < dirs_allocated) + { + if (dirs[oldfd].name != NULL) + { + dirs[newfd].name = strdup (dirs[oldfd].name); + if (dirs[newfd].name == NULL) + dirs[newfd].saved_errno = ENOMEM; + } + else + { + dirs[newfd].name = NULL; + dirs[newfd].saved_errno = dirs[oldfd].saved_errno; + } + } + else + { + dirs[newfd].name = NULL; + dirs[newfd].saved_errno = ENOMEM; + } + } + } + return newfd; +} + +int +dup2 (int oldfd, int newfd) +#undef dup2 +{ + int retval = dup2 (oldfd, newfd); + + if (retval >= 0 && oldfd >= 0 && newfd >= 0 && newfd != oldfd) + { + ensure_dirs_slot (newfd); + if (newfd < dirs_allocated) + { + if (oldfd < dirs_allocated) + { + if (dirs[oldfd].name != NULL) + { + dirs[newfd].name = strdup (dirs[oldfd].name); + if (dirs[newfd].name == NULL) + dirs[newfd].saved_errno = ENOMEM; + } + else + { + dirs[newfd].name = NULL; + dirs[newfd].saved_errno = dirs[oldfd].saved_errno; + } + } + else + { + dirs[newfd].name = NULL; + dirs[newfd].saved_errno = ENOMEM; + } + } + } + return retval; +} + +/* Implement fchdir() in terms of chdir(). */ + +int +fchdir (int fd) +{ + if (fd >= 0) + { + if (fd < dirs_allocated) + { + if (dirs[fd].name != NULL) + return chdir (dirs[fd].name); + else + { + errno = dirs[fd].saved_errno; + return -1; + } + } + else + { + errno = ENOMEM; + return -1; + } + } + else + { + errno = EBADF; + return -1; + } +} diff --git a/lib/fcntl_.h b/lib/fcntl_.h index 5c2857cae..e16ad54af 100644 --- a/lib/fcntl_.h +++ b/lib/fcntl_.h @@ -26,6 +26,25 @@ #include #include @ABSOLUTE_FCNTL_H@ + +/* Declare overridden functions. */ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef FCHDIR_REPLACEMENT +# define open rpl_open +extern int open (const char *, int, ...); +#endif + +#ifdef __cplusplus +} +#endif + + +/* Fix up the O_* macros. */ + #if !defined O_DIRECT && defined O_DIRECTIO /* Tru64 spells it `O_DIRECTIO'. */ # define O_DIRECT O_DIRECTIO diff --git a/lib/fsusage.c b/lib/fsusage.c index a305979ba..337bf5315 100644 --- a/lib/fsusage.c +++ b/lib/fsusage.c @@ -56,6 +56,11 @@ # include "full-read.h" #endif +/* The results of open() in this file are not used with fchdir, + therefore save some unnecessary work in fchdir.c. */ +#undef open +#undef close + /* Many space usage primitives use all 1 bits to denote a value that is not applicable or unknown. Propagate this information by returning a uintmax_t value that is all 1 bits if X is all 1 bits, even if X diff --git a/lib/gc-gnulib.c b/lib/gc-gnulib.c index 5ce31c150..f414f433e 100644 --- a/lib/gc-gnulib.c +++ b/lib/gc-gnulib.c @@ -68,6 +68,11 @@ # include "rijndael-api-fst.h" #endif +/* The results of open() in this file are not used with fchdir, + therefore save some unnecessary work in fchdir.c. */ +#undef open +#undef close + Gc_rc gc_init (void) { diff --git a/lib/getcwd.c b/lib/getcwd.c index 292bc19a3..f13da4dcc 100644 --- a/lib/getcwd.c +++ b/lib/getcwd.c @@ -97,6 +97,11 @@ # define __opendir opendir # define __readdir readdir #endif + +/* The results of opendir() in this file are not used with dirfd and fchdir, + therefore save some unnecessary recursion in fchdir.c. */ +#undef opendir +#undef closedir /* Get the name of the current working directory, and put it in SIZE bytes of BUF. Returns NULL if the directory couldn't be determined or diff --git a/lib/glob.c b/lib/glob.c index 6f8641aad..edef095e6 100644 --- a/lib/glob.c +++ b/lib/glob.c @@ -162,6 +162,11 @@ static const char *next_brace_sub (const char *begin, int flags) __THROW; #endif /* !defined _LIBC || !defined GLOB_ONLY_P */ +/* The results of opendir() in this file are not used with dirfd and fchdir, + therefore save some unnecessary work in fchdir.c. */ +#undef opendir +#undef closedir + static int glob_in_dir (const char *pattern, const char *directory, int flags, int (*errfunc) (const char *, int), glob_t *pglob); diff --git a/lib/javacomp.c b/lib/javacomp.c index ba0f43700..5d3d60be4 100644 --- a/lib/javacomp.c +++ b/lib/javacomp.c @@ -53,6 +53,11 @@ #define _(str) gettext (str) +/* The results of open() in this file are not used with fchdir, + therefore save some unnecessary work in fchdir.c. */ +#undef open +#undef close + /* Survey of Java compilers. diff --git a/lib/mountlist.c b/lib/mountlist.c index d70a1a208..bb01f91ef 100644 --- a/lib/mountlist.c +++ b/lib/mountlist.c @@ -143,6 +143,16 @@ char *strstr (); # define SIZE_MAX ((size_t) -1) #endif +/* The results of open() in this file are not used with fchdir, + therefore save some unnecessary work in fchdir.c. */ +#undef open +#undef close + +/* The results of opendir() in this file are not used with dirfd and fchdir, + therefore save some unnecessary work in fchdir.c. */ +#undef opendir +#undef closedir + #ifndef ME_DUMMY # define ME_DUMMY(Fs_name, Fs_type) \ (strcmp (Fs_type, "autofs") == 0 \ diff --git a/lib/openat-proc.c b/lib/openat-proc.c index 87293a46f..ff2fff003 100644 --- a/lib/openat-proc.c +++ b/lib/openat-proc.c @@ -34,6 +34,11 @@ #include "same-inode.h" #include "xalloc.h" +/* The results of open() in this file are not used with fchdir, + therefore save some unnecessary work in fchdir.c. */ +#undef open +#undef close + #define PROC_SELF_FD_FORMAT "/proc/self/fd/%d/%s" #define PROC_SELF_FD_NAME_SIZE_BOUND(len) \ diff --git a/lib/pagealign_alloc.c b/lib/pagealign_alloc.c index cbbe76346..c06dd0da4 100644 --- a/lib/pagealign_alloc.c +++ b/lib/pagealign_alloc.c @@ -52,6 +52,11 @@ # endif #endif +/* The results of open() in this file are not used with fchdir, + therefore save some unnecessary work in fchdir.c. */ +#undef open +#undef close + #if HAVE_MMAP || ! HAVE_POSIX_MEMALIGN diff --git a/lib/pipe.c b/lib/pipe.c index 19feaf4e7..521872be6 100644 --- a/lib/pipe.c +++ b/lib/pipe.c @@ -69,6 +69,11 @@ extern char **environ; # define STDERR_FILENO 2 #endif +/* The results of open() in this file are not used with fchdir, + therefore save some unnecessary work in fchdir.c. */ +#undef open +#undef close + #ifdef EINTR diff --git a/lib/progreloc.c b/lib/progreloc.c index e9fb64705..cb9795999 100644 --- a/lib/progreloc.c +++ b/lib/progreloc.c @@ -77,6 +77,11 @@ # define FILE_SYSTEM_PREFIX_LEN(P) 0 #endif +/* The results of open() in this file are not used with fchdir, + therefore save some unnecessary work in fchdir.c. */ +#undef open +#undef close + #undef set_program_name diff --git a/lib/savedir.c b/lib/savedir.c index 12084ee90..d930fb4af 100644 --- a/lib/savedir.c +++ b/lib/savedir.c @@ -43,6 +43,11 @@ # define NAME_SIZE_DEFAULT 512 #endif +/* The results of opendir() in this file are not used with dirfd and fchdir, + therefore save some unnecessary work in fchdir.c. */ +#undef opendir +#undef closedir + /* Return a freshly allocated string containing the file names in directory DIRP, separated by '\0' characters; the end is marked by two '\0' characters in a row. diff --git a/lib/unistd_.h b/lib/unistd_.h new file mode 100644 index 000000000..36fa67312 --- /dev/null +++ b/lib/unistd_.h @@ -0,0 +1,52 @@ +/* Substitute for and wrapper around . + Copyright (C) 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef _GL_UNISTD_H +#define _GL_UNISTD_H + +#if HAVE_UNISTD_H +# include @ABSOLUTE_UNISTD_H@ +#endif + + +/* Declare overridden functions. */ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef FCHDIR_REPLACEMENT + +/* Change the process' current working directory to the directory on which + the given file descriptor is open. */ +extern int fchdir (int /*fd*/); + +# define close rpl_close +extern int close (int); +# define dup rpl_dup +extern int dup (int); +# define dup2 rpl_dup2 +extern int dup2 (int, int); + +#endif + +#ifdef __cplusplus +} +#endif + + +#endif /* _GL_UNISTD_H */ diff --git a/lib/utime.c b/lib/utime.c index 421a7cc58..273a5fb31 100644 --- a/lib/utime.c +++ b/lib/utime.c @@ -47,6 +47,11 @@ struct utimbuf }; #endif +/* The results of open() in this file are not used with fchdir, + therefore save some unnecessary work in fchdir.c. */ +#undef open +#undef close + /* Emulate utime (file, NULL) for systems (like 4.3BSD) that do not interpret it to set the access and modification times of FILE to the current time. Return 0 if successful, -1 if not. */ diff --git a/m4/fchdir.m4 b/m4/fchdir.m4 new file mode 100644 index 000000000..caebfcbe0 --- /dev/null +++ b/m4/fchdir.m4 @@ -0,0 +1,29 @@ +# fchdir.m4 serial 1 +dnl Copyright (C) 2006 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. + +AC_DEFUN([gl_FUNC_FCHDIR], +[ + AC_CHECK_FUNCS_ONCE([fchdir]) + if test $ac_cv_func_fchdir = no; then + AC_LIBOBJ([fchdir]) + gl_PREREQ_FCHDIR + AC_DEFINE([FCHDIR_REPLACEMENT], 1, + [Define if gnulib's fchdir() replacement is used.]) + gl_ABSOLUTE_HEADER([dirent.h]) + ABSOLUTE_DIRENT_H=\"$gl_cv_absolute_dirent_h\" + DIRENT_H='dirent.h' + UNISTD_H2='unistd.h' + else + DIRENT_H= + UNISTD_H2= + fi + AC_SUBST([ABSOLUTE_DIRENT_H]) + AC_SUBST([DIRENT_H]) + AC_SUBST([UNISTD_H2]) +]) + +# Prerequisites of lib/fchdir.c. +AC_DEFUN([gl_PREREQ_FCHDIR], [:]) diff --git a/m4/unistd_h.m4 b/m4/unistd_h.m4 index 9c77f9bd0..9d499dfe8 100644 --- a/m4/unistd_h.m4 +++ b/m4/unistd_h.m4 @@ -1,4 +1,4 @@ -# unistd_h.m4 serial 2 +# unistd_h.m4 serial 3 dnl Copyright (C) 2006 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -8,11 +8,25 @@ dnl Written by Simon Josefsson AC_DEFUN([gl_HEADER_UNISTD], [ - dnl Prerequisites of lib/unistd.h. AC_CHECK_HEADERS([unistd.h], [ UNISTD_H='' ], [ UNISTD_H='unistd.h' ]) AC_SUBST(UNISTD_H) + dnl This module decides to build unistd.h if it is missing. + dnl The fchdir module decides to build unistd.h if fchdir() is missing. + dnl Therefore check for the prerequisites of lib/unistd.h always. + gl_PREREQ_UNISTD +]) + +dnl Prerequisites of lib/unistd.h. +AC_DEFUN([gl_PREREQ_UNISTD], +[ + AC_CHECK_HEADERS_ONCE([unistd.h]) + if test $ac_cv_header_unistd_h = yes; then + gl_ABSOLUTE_HEADER([unistd.h]) + ABSOLUTE_UNISTD_H=\"$gl_cv_absolute_unistd_h\" + fi + AC_SUBST([ABSOLUTE_UNISTD_H]) ]) diff --git a/modules/fchdir b/modules/fchdir new file mode 100644 index 000000000..b8fa65108 --- /dev/null +++ b/modules/fchdir @@ -0,0 +1,41 @@ +Description: +fchdir() function: change current directory, given an open file descriptor. + +Files: +lib/fchdir.c +lib/dirent_.h +m4/fchdir.m4 + +Depends-on: +fcntl +unistd +canonicalize-lgpl +dirfd +strdup + +configure.ac: +gl_FUNC_FCHDIR + +Makefile.am: +BUILT_SOURCES += $(DIRENT_H) $(UNISTD_H2) + +# We need the following in order to create when the system +# doesn't have one that works with the given compiler. +dirent.h: dirent_.h + rm -f $@-t $@ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + sed -e 's|@''ABSOLUTE_DIRENT_H''@|$(ABSOLUTE_DIRENT_H)|g' \ + < $(srcdir)/dirent_.h; \ + } > $@-t + mv $@-t $@ +MOSTLYCLEANFILES += dirent.h dirent.h-t + +Include: +#include + +License: +LGPL + +Maintainer: +Bruno Haible + diff --git a/modules/unistd b/modules/unistd index 177b95ce1..d04c80c2a 100644 --- a/modules/unistd +++ b/modules/unistd @@ -3,6 +3,7 @@ A for systems lacking it. Files: m4/unistd_h.m4 +lib/unistd_.h Depends-on: @@ -14,11 +15,14 @@ BUILT_SOURCES += $(UNISTD_H) # We need the following in order to create an empty placeholder for # when the system doesn't have one. -unistd.h: +unistd.h: unistd_.h + rm -f $@-t $@ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - echo '/* Empty placeholder for $@. */'; \ - } > $@ -MOSTLYCLEANFILES += unistd.h + sed -e 's|@''ABSOLUTE_UNISTD_H''@|$(ABSOLUTE_UNISTD_H)|g' \ + < $(srcdir)/unistd_.h; \ + } > $@-t + mv $@-t $@ +MOSTLYCLEANFILES += unistd.h unistd.h-t Include: #include -- 2.11.0