(root)/
coreutils-9.4/
lib/
savewd.h
       1  /* Save and restore the working directory, possibly using a subprocess.
       2  
       3     Copyright (C) 2006, 2009-2023 Free Software Foundation, Inc.
       4  
       5     This program is free software: you can redistribute it and/or modify
       6     it under the terms of the GNU General Public License as published by
       7     the Free Software Foundation, either version 3 of the License, or
       8     (at your option) any later version.
       9  
      10     This program is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13     GNU General Public License for more details.
      14  
      15     You should have received a copy of the GNU General Public License
      16     along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
      17  
      18  /* Written by Paul Eggert.  */
      19  
      20  #ifndef SAVEWD_H
      21  #define SAVEWD_H 1
      22  
      23  /* This file uses _GL_INLINE_HEADER_BEGIN, _GL_INLINE, _GL_ATTRIBUTE_PURE.  */
      24  #if !_GL_CONFIG_H_INCLUDED
      25   #error "Please include config.h first."
      26  #endif
      27  
      28  #include <sys/types.h>
      29  
      30  _GL_INLINE_HEADER_BEGIN
      31  #ifndef SAVEWD_INLINE
      32  # define SAVEWD_INLINE _GL_INLINE
      33  #endif
      34  
      35  /* A saved working directory.  The member names and constants defined
      36     by this structure are private to the savewd module.  */
      37  struct savewd
      38  {
      39    /* The state of this object.  */
      40    enum
      41      {
      42        /* This object has been created but does not yet represent
      43           the working directory.  */
      44        INITIAL_STATE,
      45  
      46        /* val.fd is the original working directory's file descriptor.
      47           It is still the working directory.  */
      48        FD_STATE,
      49  
      50        /* Like FD_STATE, but the working directory has changed, so
      51           restoring it will require a fchdir.  */
      52        FD_POST_CHDIR_STATE,
      53  
      54        /* Fork and let the subprocess do the work.  val.child is 0 in a
      55           child, negative in a childless parent, and the child process
      56           ID in a parent with a child.  */
      57        FORKING_STATE,
      58  
      59        /* A serious problem argues against further efforts.  val.errnum
      60           contains the error number (e.g., EIO).  */
      61        ERROR_STATE,
      62  
      63        /* savewd_finish has been called, so the application no longer
      64           cares whether the working directory is saved, and there is no
      65           more work to do.  */
      66        FINAL_STATE
      67      } state;
      68  
      69    /* The object's value.  */
      70    union
      71    {
      72      int fd;
      73      int errnum;
      74      pid_t child;
      75    } val;
      76  };
      77  
      78  /* Initialize a saved working directory object.  */
      79  SAVEWD_INLINE void
      80  savewd_init (struct savewd *wd)
      81  {
      82    wd->state = INITIAL_STATE;
      83  }
      84  
      85  
      86  /* Options for savewd_chdir.  Can be ORed together.  */
      87  enum
      88    {
      89      /* Do not follow symbolic links, if supported.  */
      90      SAVEWD_CHDIR_NOFOLLOW = 1,
      91  
      92      /* Do not chdir if the directory is readable; simply succeed
      93         without invoking chdir if the directory was opened.  */
      94      SAVEWD_CHDIR_SKIP_READABLE = 2
      95    };
      96  
      97  /* Change the directory, and if successful, record into *WD the fact
      98     that the process chdired into DIR.  A process using this module
      99     should use savewd_chdir rather than chdir or fchdir.  Obey the
     100     options specified in OPTIONS.
     101  
     102     If OPEN_RESULT is not null, store into OPEN_RESULT[0] a file
     103     descriptor that accesses DIR if a file descriptor is successfully
     104     obtained.  Store -1 otherwise, setting OPEN_RESULT[1] to the error
     105     number.  Store through OPEN_RESULT regardless of whether the chdir
     106     is successful.  However, when -2 is returned, the contents of
     107     OPEN_RESULT are indeterminate since the file descriptor is closed
     108     in the parent.
     109  
     110     Return -2 if a subprocess was spun off to do the real work, -1
     111     (setting errno) if unsuccessful, 0 if successful.  */
     112  int savewd_chdir (struct savewd *wd, char const *dir, int options,
     113                    int open_result[2]);
     114  
     115  /* Restore the working directory from *WD.  STATUS indicates the exit
     116     status corresponding to the work done since the last save; this is
     117     used when the caller is in a subprocess.  Return 0 if successful,
     118     -1 (setting errno) on our failure, a positive subprocess exit
     119     status if the working directory was restored in the parent but the
     120     subprocess failed.  */
     121  int savewd_restore (struct savewd *wd, int status);
     122  
     123  /* Return WD's error number, or 0 if WD is not in an error state.  */
     124  SAVEWD_INLINE int _GL_ATTRIBUTE_PURE
     125  savewd_errno (struct savewd const *wd)
     126  {
     127    return (wd->state == ERROR_STATE ? wd->val.errnum : 0);
     128  }
     129  
     130  /* Deallocate any resources associated with WD.  A program that chdirs
     131     should restore before finishing.  */
     132  void savewd_finish (struct savewd *wd);
     133  
     134  /* Process N_FILES file names, FILE[0] through FILE[N_FILES - 1].
     135     For each file name F, call ACT (F, WD, OPTIONS); ACT should invoke
     136     savewd_chdir as needed, and should return an exit status.  WD
     137     represents the working directory; it may be in an error state when
     138     ACT is called.
     139  
     140     Save and restore the working directory as needed by the file name
     141     vector; assume that ACT does not require access to any relative
     142     file names other than its first argument, and that it is OK if the
     143     working directory is changed when this function returns.  Some
     144     actions may be applied in a subprocess.
     145  
     146     Return the maximum exit status that any call to ACT returned, or
     147     EXIT_SUCCESS (i.e., 0) if no calls were made.  */
     148  int savewd_process_files (int n_files, char **file,
     149                            int (*act) (char *, struct savewd *, void *),
     150                            void *options);
     151  
     152  _GL_INLINE_HEADER_END
     153  
     154  #endif