LCOV - code coverage report
Current view: top level - lib - savewd.h (source / functions) Hit Total Coverage
Test: coreutils.info Lines: 5 5 100.0 %
Date: 2018-01-30 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /* Save and restore the working directory, possibly using a subprocess.
       2             : 
       3             :    Copyright (C) 2006 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 <http://www.gnu.org/licenses/>.  */
      17             : 
      18             : /* Written by Paul Eggert.  */
      19             : 
      20             : #ifndef SAVEWD_H
      21             : # define SAVEWD_H 1
      22             : 
      23             : #include <stdbool.h>
      24             : #include <sys/types.h>
      25             : 
      26             : /* A saved working directory.  The member names and constants defined
      27             :    by this structure are private to the savewd module.  */
      28             : struct savewd
      29             : {
      30             :   /* The state of this object.  */
      31             :   enum
      32             :     {
      33             :       /* This object has been created but does not yet represent
      34             :          the working directory.  */
      35             :       INITIAL_STATE,
      36             : 
      37             :       /* val.fd is the original working directory's file descriptor.
      38             :          It is still the working directory.  */
      39             :       FD_STATE,
      40             : 
      41             :       /* Like FD_STATE, but the working directory has changed, so
      42             :          restoring it will require a fchdir.  */
      43             :       FD_POST_CHDIR_STATE,
      44             : 
      45             :       /* Fork and let the subprocess do the work.  val.child is 0 in a
      46             :          child, negative in a childless parent, and the child process
      47             :          ID in a parent with a child.  */
      48             :       FORKING_STATE,
      49             : 
      50             :       /* A serious problem argues against further efforts.  val.errnum
      51             :          contains the error number (e.g., EIO).  */
      52             :       ERROR_STATE,
      53             : 
      54             :       /* savewd_finish has been called, so the application no longer
      55             :          cares whether the working directory is saved, and there is no
      56             :          more work to do.  */
      57             :       FINAL_STATE
      58             :     } state;
      59             : 
      60             :   /* The object's value.  */
      61             :   union
      62             :   {
      63             :     int fd;
      64             :     int errnum;
      65             :     pid_t child;
      66             :   } val;
      67             : };
      68             : 
      69             : /* Initialize a saved working directory object.  */
      70             : static inline void
      71          95 : savewd_init (struct savewd *wd)
      72             : {
      73          95 :   wd->state = INITIAL_STATE;
      74          95 : }
      75             : 
      76             : 
      77             : /* Options for savewd_chdir.  */
      78             : enum
      79             :   {
      80             :     /* Do not follow symbolic links, if supported.  */
      81             :     SAVEWD_CHDIR_NOFOLLOW = 1,
      82             : 
      83             :     /* The directory should be readable, so fail if it happens to be
      84             :        discovered that the directory is not readable.  (Unreadable
      85             :        directories are not necessarily diagnosed, though.)  */
      86             :     SAVEWD_CHDIR_READABLE = 2,
      87             : 
      88             :     /* Do not chdir if the directory is readable; simply succeed
      89             :        without invoking chdir if the directory was opened.  */
      90             :     SAVEWD_CHDIR_SKIP_READABLE = 4
      91             :   };
      92             : 
      93             : /* Change the directory, and if successful, record into *WD the fact
      94             :    that the process chdired into DIR.  A process using this module
      95             :    should use savewd_chdir rather than chdir or fchdir.  Obey the
      96             :    options specified in OPTIONS.
      97             : 
      98             :    If OPEN_RESULT is not null, store into OPEN_RESULT[0] a file
      99             :    descriptor that accesses DIR if a file descriptor is successfully
     100             :    obtained.  Store -1 otherwise, setting OPEN_RESULT[1] to the error
     101             :    number.  Store through OPEN_RESULT regardless of whether the chdir
     102             :    is successful.  However, when -2 is returned, the contents of
     103             :    OPEN_RESULT are indeterminate since the file descriptor is closed
     104             :    in the parent.
     105             : 
     106             :    Return -2 if a subprocess was spun off to do the real work, -1
     107             :    (setting errno) if unsuccessful, 0 if successful.  */
     108             : int savewd_chdir (struct savewd *wd, char const *dir, int options,
     109             :                   int open_result[2]);
     110             : 
     111             : /* Restore the working directory from *WD.  STATUS indicates the exit
     112             :    status corresponding to the work done since the last save; this is
     113             :    used when the caller is in a subprocess.  Return 0 if successful,
     114             :    -1 (setting errno) on our failure, a positive subprocess exit
     115             :    status if the working directory was restored in the parent but the
     116             :    subprocess failed.  */
     117             : int savewd_restore (struct savewd *wd, int status);
     118             : 
     119             : /* Return WD's error number, or 0 if WD is not in an error state.  */
     120             : static inline int
     121          87 : savewd_errno (struct savewd const *wd)
     122             : {
     123          87 :   return (wd->state == ERROR_STATE ? wd->val.errnum : 0);
     124             : }
     125             : 
     126             : /* Deallocate any resources associated with WD.  A program that chdirs
     127             :    should restore before finishing.  */
     128             : void savewd_finish (struct savewd *wd);
     129             : 
     130             : /* Process N_FILES file names, FILE[0] through FILE[N_FILES - 1].
     131             :    For each file name F, call ACT (F, WD, OPTIONS); ACT should invoke
     132             :    savewd_chdir as needed, and should return an exit status.  WD
     133             :    represents the working directory; it may be in an error state when
     134             :    ACT is called.
     135             : 
     136             :    Save and restore the working directory as needed by the file name
     137             :    vector; assume that ACT does not require access to any relative
     138             :    file names other than its first argument, and that it is OK if the
     139             :    working directory is changed when this function returns.  Some
     140             :    actions may be applied in a subprocess.
     141             : 
     142             :    Return the maximum exit status that any call to ACT returned, or
     143             :    EXIT_SUCCESS (i.e., 0) if no calls were made.  */
     144             : int savewd_process_files (int n_files, char **file,
     145             :                           int (*act) (char *, struct savewd *, void *),
     146             :                           void *options);
     147             : 
     148             : #endif

Generated by: LCOV version 1.10