vaszprintf-posix tests: Fix a gcc warning.
[gnulib.git] / lib / savewd.h
blobe74ba82d9412e905b4c340ff97f21020ffc73d47
1 /* Save and restore the working directory, possibly using a subprocess.
3 Copyright (C) 2006, 2009-2024 Free Software Foundation, Inc.
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.
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.
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/>. */
18 /* Written by Paul Eggert. */
20 #ifndef SAVEWD_H
21 #define SAVEWD_H 1
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
28 #include <sys/types.h>
30 _GL_INLINE_HEADER_BEGIN
31 #ifndef SAVEWD_INLINE
32 # define SAVEWD_INLINE _GL_INLINE
33 #endif
35 #ifdef __cplusplus
36 extern "C" {
37 #endif
40 /* A saved working directory. The member names and constants defined
41 by this structure are private to the savewd module. */
42 struct savewd
44 /* The state of this object. */
45 enum
47 /* This object has been created but does not yet represent
48 the working directory. */
49 INITIAL_STATE,
51 /* val.fd is the original working directory's file descriptor.
52 It is still the working directory. */
53 FD_STATE,
55 /* Like FD_STATE, but the working directory has changed, so
56 restoring it will require a fchdir. */
57 FD_POST_CHDIR_STATE,
59 /* Fork and let the subprocess do the work. val.child is 0 in a
60 child, negative in a childless parent, and the child process
61 ID in a parent with a child. */
62 FORKING_STATE,
64 /* A serious problem argues against further efforts. val.errnum
65 contains the error number (e.g., EIO). */
66 ERROR_STATE,
68 /* savewd_finish has been called, so the application no longer
69 cares whether the working directory is saved, and there is no
70 more work to do. */
71 FINAL_STATE
72 } state;
74 /* The object's value. */
75 union
77 int fd;
78 int errnum;
79 pid_t child;
80 } val;
83 /* Initialize a saved working directory object. */
84 SAVEWD_INLINE void
85 savewd_init (struct savewd *wd)
87 wd->state = INITIAL_STATE;
91 /* Options for savewd_chdir. Can be ORed together. */
92 enum
94 /* Do not follow symbolic links, if supported. */
95 SAVEWD_CHDIR_NOFOLLOW = 1,
97 /* Do not chdir if the directory is readable; simply succeed
98 without invoking chdir if the directory was opened. */
99 SAVEWD_CHDIR_SKIP_READABLE = 2
102 /* Change the directory, and if successful, record into *WD the fact
103 that the process chdired into DIR. A process using this module
104 should use savewd_chdir rather than chdir or fchdir. Obey the
105 options specified in OPTIONS.
107 If OPEN_RESULT is not null, store into OPEN_RESULT[0] a file
108 descriptor that accesses DIR if a file descriptor is successfully
109 obtained. Store -1 otherwise, setting OPEN_RESULT[1] to the error
110 number. Store through OPEN_RESULT regardless of whether the chdir
111 is successful. However, when -2 is returned, the contents of
112 OPEN_RESULT are indeterminate since the file descriptor is closed
113 in the parent.
115 Return -2 if a subprocess was spun off to do the real work, -1
116 (setting errno) if unsuccessful, 0 if successful. */
117 int savewd_chdir (struct savewd *wd, char const *dir, int options,
118 int open_result[2]);
120 /* Restore the working directory from *WD. STATUS indicates the exit
121 status corresponding to the work done since the last save; this is
122 used when the caller is in a subprocess. Return 0 if successful,
123 -1 (setting errno) on our failure, a positive subprocess exit
124 status if the working directory was restored in the parent but the
125 subprocess failed. */
126 int savewd_restore (struct savewd *wd, int status);
128 /* Return WD's error number, or 0 if WD is not in an error state. */
129 SAVEWD_INLINE int _GL_ATTRIBUTE_PURE
130 savewd_errno (struct savewd const *wd)
132 return (wd->state == ERROR_STATE ? wd->val.errnum : 0);
135 /* Deallocate any resources associated with WD. A program that chdirs
136 should restore before finishing. */
137 void savewd_finish (struct savewd *wd);
139 /* Process N_FILES file names, FILE[0] through FILE[N_FILES - 1].
140 For each file name F, call ACT (F, WD, OPTIONS); ACT should invoke
141 savewd_chdir as needed, and should return an exit status. WD
142 represents the working directory; it may be in an error state when
143 ACT is called.
145 Save and restore the working directory as needed by the file name
146 vector; assume that ACT does not require access to any relative
147 file names other than its first argument, and that it is OK if the
148 working directory is changed when this function returns. Some
149 actions may be applied in a subprocess.
151 Return the maximum exit status that any call to ACT returned, or
152 EXIT_SUCCESS (i.e., 0) if no calls were made. */
153 int savewd_process_files (int n_files, char **file,
154 int (*act) (char *, struct savewd *, void *),
155 void *options);
158 #ifdef __cplusplus
160 #endif
162 _GL_INLINE_HEADER_END
164 #endif