1 : #ifndef __UTIL_H
2 : #define __UTIL_H
3 :
4 : #include "types.hh"
5 :
6 : #include <sys/types.h>
7 : #include <dirent.h>
8 : #include <unistd.h>
9 : #include <signal.h>
10 :
11 :
12 : namespace nix {
13 :
14 :
15 : #define foreach(it_type, it, collection) \
16 : for (it_type it = collection.begin(); it != collection.end(); ++it)
17 :
18 :
19 : /* Return an environment variable. */
20 : string getEnv(const string & key, const string & def = "");
21 :
22 : /* Return an absolutized path, resolving paths relative to the
23 : specified directory, or the current directory otherwise. The path
24 : is also canonicalised. */
25 : Path absPath(Path path, Path dir = "");
26 :
27 : /* Canonicalise a path by removing all `.' or `..' components and
28 : double or trailing slashes. Optionally resolves all symlink
29 : components such that each component of the resulting path is *not*
30 : a symbolic link. */
31 : Path canonPath(const Path & path, bool resolveSymlinks = false);
32 :
33 : /* Return the directory part of the given canonical path, i.e.,
34 : everything before the final `/'. If the path is the root or an
35 : immediate child thereof (e.g., `/foo'), this means an empty string
36 : is returned. */
37 : Path dirOf(const Path & path);
38 :
39 : /* Return the base name of the given canonical path, i.e., everything
40 : following the final `/'. */
41 : string baseNameOf(const Path & path);
42 :
43 : /* Return true iff the given path exists. */
44 : bool pathExists(const Path & path);
45 :
46 : /* Read the contents (target) of a symbolic link. The result is not
47 : in any way canonicalised. */
48 : Path readLink(const Path & path);
49 :
50 : bool isLink(const Path & path);
51 :
52 : /* Read the contents of a directory. The entries `.' and `..' are
53 : removed. */
54 : Strings readDirectory(const Path & path);
55 :
56 : /* Read the contents of a file into a string. */
57 : string readFile(int fd);
58 : string readFile(const Path & path);
59 :
60 : /* Write a string to a file. */
61 : void writeFile(const Path & path, const string & s);
62 :
63 : /* Compute the sum of the sizes of all files in `path'. */
64 : void computePathSize(const Path & path,
65 : unsigned long long & bytes, unsigned long long & blocks);
66 :
67 : /* Delete a path; i.e., in the case of a directory, it is deleted
68 : recursively. Don't use this at home, kids. The second variant
69 : returns the number of bytes and blocks freed. */
70 : void deletePath(const Path & path);
71 :
72 : void deletePath(const Path & path, unsigned long long & bytesFreed,
73 : unsigned long long & blocksFreed);
74 :
75 : /* Make a path read-only recursively. */
76 : void makePathReadOnly(const Path & path);
77 :
78 : /* Create a temporary directory. */
79 : Path createTempDir(const Path & tmpRoot = "", const Path & prefix = "nix",
80 : bool includePid = true, bool useGlobalCounter = true);
81 :
82 : /* Create a directory and all its parents, if necessary. Returns the
83 : list of created directories, in order of creation. */
84 : Paths createDirs(const Path & path);
85 :
86 : /* Create a file and write the given text to it. The file is written
87 : in binary mode (i.e., no end-of-line conversions). The path should
88 : not already exist. */
89 : void writeStringToFile(const Path & path, const string & s);
90 :
91 : template<class T, class A>
92 3675 : T singleton(const A & a)
93 : {
94 3675 : T t;
95 3675 : t.insert(a);
96 0 : return t;
97 : }
98 :
99 :
100 : /* Messages. */
101 :
102 :
103 : typedef enum {
104 : ltPretty, /* nice, nested output */
105 : ltEscapes, /* nesting indicated using escape codes (for log2xml) */
106 : ltFlat /* no nesting */
107 : } LogType;
108 :
109 : extern LogType logType;
110 : extern Verbosity verbosity; /* suppress msgs > this */
111 :
112 : class Nest
113 : {
114 : private:
115 : bool nest;
116 : public:
117 : Nest();
118 : ~Nest();
119 : void open(Verbosity level, const format & f);
120 : void close();
121 : };
122 :
123 : void printMsg_(Verbosity level, const format & f);
124 :
125 : #define startNest(varName, level, f) \
126 : Nest varName; \
127 : if (level <= verbosity) { \
128 : varName.open(level, (f)); \
129 : }
130 :
131 : #define printMsg(level, f) \
132 : do { \
133 : if (level <= verbosity) { \
134 : printMsg_(level, (f)); \
135 : } \
136 : } while (0)
137 :
138 : #define debug(f) printMsg(lvlDebug, f)
139 :
140 : void warnOnce(bool & haveWarned, const format & f);
141 :
142 : extern void (*writeToStderr) (const unsigned char * buf, size_t count);
143 :
144 :
145 : /* Wrappers arount read()/write() that read/write exactly the
146 : requested number of bytes. */
147 : void readFull(int fd, unsigned char * buf, size_t count);
148 : void writeFull(int fd, const unsigned char * buf, size_t count);
149 :
150 184 : MakeError(EndOfFile, Error)
151 :
152 :
153 : /* Read a file descriptor until EOF occurs. */
154 : string drainFD(int fd);
155 :
156 :
157 :
158 : /* Automatic cleanup of resources. */
159 :
160 :
161 : template <class T>
162 : struct AutoDeleteArray
163 : {
164 : T * p;
165 14045 : AutoDeleteArray(T * p) : p(p) { }
166 14045 : ~AutoDeleteArray()
167 : {
168 14045 : delete [] p;
169 : }
170 : };
171 :
172 :
173 : class AutoDelete
174 : {
175 : Path path;
176 : bool del;
177 : bool recursive;
178 : public:
179 : AutoDelete(const Path & p, bool recursive = true);
180 : ~AutoDelete();
181 : void cancel();
182 : };
183 :
184 :
185 : class AutoCloseFD
186 : {
187 : int fd;
188 : public:
189 : AutoCloseFD();
190 : AutoCloseFD(int fd);
191 : AutoCloseFD(const AutoCloseFD & fd);
192 : ~AutoCloseFD();
193 : void operator =(int fd);
194 : operator int() const;
195 : void close();
196 : bool isOpen();
197 : int borrow();
198 : };
199 :
200 :
201 : class Pipe
202 2652 : {
203 : public:
204 : AutoCloseFD readSide, writeSide;
205 : void create();
206 : };
207 :
208 :
209 : class AutoCloseDir
210 : {
211 : DIR * dir;
212 : public:
213 : AutoCloseDir();
214 : AutoCloseDir(DIR * dir);
215 : ~AutoCloseDir();
216 : void operator =(DIR * dir);
217 : operator DIR *();
218 : };
219 :
220 :
221 : class Pid
222 : {
223 : pid_t pid;
224 : bool separatePG;
225 : int killSignal;
226 : public:
227 : Pid();
228 : ~Pid();
229 : void operator =(pid_t pid);
230 : operator pid_t();
231 : void kill();
232 : int wait(bool block);
233 : void setSeparatePG(bool separatePG);
234 : void setKillSignal(int signal);
235 : };
236 :
237 :
238 : /* Kill all processes running under the specified uid by sending them
239 : a SIGKILL. */
240 : void killUser(uid_t uid);
241 :
242 :
243 : /* Run a program and return its stdout in a string (i.e., like the
244 : shell backtick operator). */
245 : string runProgram(Path program, bool searchPath = false,
246 : const Strings & args = Strings());
247 :
248 : /* Close all file descriptors except stdin, stdout, stderr, and those
249 : listed in the given set. Good practice in child processes. */
250 : void closeMostFDs(const set<int> & exceptions);
251 :
252 : /* Wrapper around _exit() on Unix and ExitProcess() on Windows. (On
253 : Cygwin, _exit() doesn't seem to do the right thing.) */
254 : void quickExit(int status);
255 :
256 : /* Common initialisation for setuid programs: clear the environment,
257 : sanitize file handles 0, 1 and 2. */
258 : void setuidCleanup();
259 :
260 :
261 : /* User interruption. */
262 :
263 : extern volatile sig_atomic_t _isInterrupted;
264 :
265 : void _interrupted();
266 :
267 286014 : void inline checkInterrupt()
268 : {
269 286014 : if (_isInterrupted) _interrupted();
270 286014 : }
271 :
272 0 : MakeError(Interrupted, BaseError)
273 :
274 :
275 : /* String packing / unpacking. */
276 : string packStrings(const Strings & strings);
277 : Strings unpackStrings(const string & s);
278 :
279 :
280 : /* String tokenizer. */
281 : Strings tokenizeString(const string & s, const string & separators = " \t\n\r");
282 :
283 :
284 : /* Convert the exit status of a child as returned by wait() into an
285 : error string. */
286 : string statusToString(int status);
287 :
288 : bool statusOk(int status);
289 :
290 :
291 : /* Parse a string into an integer. */
292 : string int2String(int n);
293 : bool string2Int(const string & s, int & n);
294 : bool string2Int(const string & s, long long & n);
295 :
296 :
297 : /* Return true iff `s' ends in `suffix'. */
298 : bool hasSuffix(const string & s, const string & suffix);
299 :
300 :
301 : /* Exception handling in destructors: print an error message, then
302 : ignore the exception. */
303 : void ignoreException();
304 :
305 :
306 : /* STL functions such as sort() pass a binary function object around
307 : by value, so it gets cloned a lot. This is bad if the function
308 : object has state or is simply large. This adapter wraps the
309 : function object to simulate passing by reference. */
310 : template<class F>
311 : struct binary_function_ref_adapter
312 : {
313 : F * p;
314 :
315 0 : binary_function_ref_adapter(F * _p)
316 : {
317 0 : p = _p;
318 : }
319 :
320 : typename F::result_type operator () (
321 : const typename F::first_argument_type & x,
322 0 : const typename F::second_argument_type & y)
323 : {
324 0 : return (*p)(x, y);
325 : }
326 : };
327 :
328 :
329 : }
330 :
331 :
332 : #endif /* !__UTIL_H */
|