Copyright (C) 2006, 2009-2010 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
#ifndef SAVEWD_H
# define SAVEWD_H 1
#include <stdbool.h>
#include <sys/types.h>
by this structure are private to the savewd module. */
struct savewd
{
enum
{
the working directory. */
INITIAL_STATE,
It is still the working directory. */
FD_STATE,
restoring it will require a fchdir. */
FD_POST_CHDIR_STATE,
child, negative in a childless parent, and the child process
ID in a parent with a child. */
FORKING_STATE,
contains the error number (e.g., EIO). */
ERROR_STATE,
cares whether the working directory is saved, and there is no
more work to do. */
FINAL_STATE
} state;
union
{
int fd;
int errnum;
pid_t child;
} val;
};
static inline void
savewd_init (struct savewd *wd)
{
wd->state = INITIAL_STATE;
}
enum
{
SAVEWD_CHDIR_NOFOLLOW = 1,
discovered that the directory is not readable. (Unreadable
directories are not necessarily diagnosed, though.) */
SAVEWD_CHDIR_READABLE = 2,
without invoking chdir if the directory was opened. */
SAVEWD_CHDIR_SKIP_READABLE = 4
};
that the process chdired into DIR. A process using this module
should use savewd_chdir rather than chdir or fchdir. Obey the
options specified in OPTIONS.
If OPEN_RESULT is not null, store into OPEN_RESULT[0] a file
descriptor that accesses DIR if a file descriptor is successfully
obtained. Store -1 otherwise, setting OPEN_RESULT[1] to the error
number. Store through OPEN_RESULT regardless of whether the chdir
is successful. However, when -2 is returned, the contents of
OPEN_RESULT are indeterminate since the file descriptor is closed
in the parent.
Return -2 if a subprocess was spun off to do the real work, -1
(setting errno) if unsuccessful, 0 if successful. */
int savewd_chdir (struct savewd *wd, char const *dir, int options,
int open_result[2]);
status corresponding to the work done since the last save; this is
used when the caller is in a subprocess. Return 0 if successful,
-1 (setting errno) on our failure, a positive subprocess exit
status if the working directory was restored in the parent but the
subprocess failed. */
int savewd_restore (struct savewd *wd, int status);
static inline int
savewd_errno (struct savewd const *wd)
{
return (wd->state == ERROR_STATE ? wd->val.errnum : 0);
}
should restore before finishing. */
void savewd_finish (struct savewd *wd);
For each file name F, call ACT (F, WD, OPTIONS); ACT should invoke
savewd_chdir as needed, and should return an exit status. WD
represents the working directory; it may be in an error state when
ACT is called.
Save and restore the working directory as needed by the file name
vector; assume that ACT does not require access to any relative
file names other than its first argument, and that it is OK if the
working directory is changed when this function returns. Some
actions may be applied in a subprocess.
Return the maximum exit status that any call to ACT returned, or
EXIT_SUCCESS (i.e., 0) if no calls were made. */
int savewd_process_files (int n_files, char **file,
int (*act) (char *, struct savewd *, void *),
void *options);
#endif