Merge branch 'master' into staging
[jackhill/guix/guix.git] / nix / libutil / util.hh
1 #pragma once
2
3 #include "types.hh"
4
5 #include <sys/types.h>
6 #include <sys/stat.h>
7 #include <dirent.h>
8 #include <unistd.h>
9 #include <signal.h>
10 #include <functional>
11
12 #include <cstdio>
13
14
15 namespace nix {
16
17
18 #define foreach(it_type, it, collection) \
19 for (it_type it = (collection).begin(); it != (collection).end(); ++it)
20
21 #define foreach_reverse(it_type, it, collection) \
22 for (it_type it = (collection).rbegin(); it != (collection).rend(); ++it)
23
24
25 /* Return an environment variable. */
26 string getEnv(const string & key, const string & def = "");
27
28 /* Return an absolutized path, resolving paths relative to the
29 specified directory, or the current directory otherwise. The path
30 is also canonicalised. */
31 Path absPath(Path path, Path dir = "");
32
33 /* Canonicalise a path by removing all `.' or `..' components and
34 double or trailing slashes. Optionally resolves all symlink
35 components such that each component of the resulting path is *not*
36 a symbolic link. */
37 Path canonPath(const Path & path, bool resolveSymlinks = false);
38
39 /* Return the directory part of the given canonical path, i.e.,
40 everything before the final `/'. If the path is the root or an
41 immediate child thereof (e.g., `/foo'), this means an empty string
42 is returned. */
43 Path dirOf(const Path & path);
44
45 /* Return the base name of the given canonical path, i.e., everything
46 following the final `/'. */
47 string baseNameOf(const Path & path);
48
49 /* Check whether a given path is a descendant of the given
50 directory. */
51 bool isInDir(const Path & path, const Path & dir);
52
53 /* Get status of `path'. */
54 struct stat lstat(const Path & path);
55
56 /* Return true iff the given path exists. */
57 bool pathExists(const Path & path);
58
59 /* Read the contents (target) of a symbolic link. The result is not
60 in any way canonicalised. */
61 Path readLink(const Path & path);
62
63 bool isLink(const Path & path);
64
65 /* Read the contents of a directory. The entries `.' and `..' are
66 removed. */
67 struct DirEntry
68 {
69 string name;
70 ino_t ino;
71 unsigned char type; // one of DT_*
72 DirEntry(const string & name, ino_t ino, unsigned char type)
73 : name(name), ino(ino), type(type) { }
74 };
75
76 typedef vector<DirEntry> DirEntries;
77
78 DirEntries readDirectory(const Path & path);
79
80 unsigned char getFileType(const Path & path);
81
82 /* Read the contents of a file into a string. */
83 string readFile(int fd);
84 string readFile(const Path & path, bool drain = false);
85
86 /* Write a string to a file. */
87 void writeFile(const Path & path, const string & s);
88
89 /* Read a line from a file descriptor. */
90 string readLine(int fd);
91
92 /* Write a line to a file descriptor. */
93 void writeLine(int fd, string s);
94
95 /* Delete a path; i.e., in the case of a directory, it is deleted
96 recursively. Don't use this at home, kids. The second variant
97 returns the number of bytes and blocks freed. */
98 void deletePath(const Path & path);
99
100 void deletePath(const Path & path, unsigned long long & bytesFreed);
101
102 /* Create a temporary directory. */
103 Path createTempDir(const Path & tmpRoot = "", const Path & prefix = "nix",
104 bool includePid = true, bool useGlobalCounter = true, mode_t mode = 0755);
105
106 /* Create a directory and all its parents, if necessary. Returns the
107 list of created directories, in order of creation. */
108 Paths createDirs(const Path & path);
109
110 /* Create a symlink. */
111 void createSymlink(const Path & target, const Path & link);
112
113
114 template<class T, class A>
115 T singleton(const A & a)
116 {
117 T t;
118 t.insert(a);
119 return t;
120 }
121
122
123 /* Messages. */
124
125
126 typedef enum {
127 ltPretty, /* nice, nested output */
128 ltEscapes, /* nesting indicated using escape codes (for log2xml) */
129 ltFlat /* no nesting */
130 } LogType;
131
132 extern LogType logType;
133 extern Verbosity verbosity; /* suppress msgs > this */
134
135 class Nest
136 {
137 private:
138 bool nest;
139 public:
140 Nest();
141 ~Nest();
142 void open(Verbosity level, const FormatOrString & fs);
143 void close();
144 };
145
146 void printMsg_(Verbosity level, const FormatOrString & fs);
147
148 #define startNest(varName, level, f) \
149 Nest varName; \
150 if (level <= verbosity) { \
151 varName.open(level, (f)); \
152 }
153
154 #define printMsg(level, f) \
155 do { \
156 if (level <= nix::verbosity) { \
157 nix::printMsg_(level, (f)); \
158 } \
159 } while (0)
160
161 #define debug(f) printMsg(lvlDebug, f)
162
163 void warnOnce(bool & haveWarned, const FormatOrString & fs);
164
165 void writeToStderr(const string & s);
166
167 extern void (*_writeToStderr) (const unsigned char * buf, size_t count);
168
169
170 /* Wrappers arount read()/write() that read/write exactly the
171 requested number of bytes. */
172 void readFull(int fd, unsigned char * buf, size_t count);
173 void writeFull(int fd, const unsigned char * buf, size_t count);
174 void writeFull(int fd, const string & s);
175
176 MakeError(EndOfFile, Error)
177
178
179 /* Read a file descriptor until EOF occurs. */
180 string drainFD(int fd);
181
182
183
184 /* Automatic cleanup of resources. */
185
186
187 template <class T>
188 struct AutoDeleteArray
189 {
190 T * p;
191 AutoDeleteArray(T * p) : p(p) { }
192 ~AutoDeleteArray()
193 {
194 delete [] p;
195 }
196 };
197
198
199 class AutoDelete
200 {
201 Path path;
202 bool del;
203 bool recursive;
204 public:
205 AutoDelete(const Path & p, bool recursive = true);
206 ~AutoDelete();
207 void cancel();
208 };
209
210
211 class AutoCloseFD
212 {
213 int fd;
214 public:
215 AutoCloseFD();
216 AutoCloseFD(int fd);
217 AutoCloseFD(const AutoCloseFD & fd);
218 ~AutoCloseFD();
219 void operator =(int fd);
220 operator int() const;
221 void close();
222 bool isOpen();
223 int borrow();
224 };
225
226
227 class Pipe
228 {
229 public:
230 AutoCloseFD readSide, writeSide;
231 void create();
232 };
233
234
235 class AutoCloseDir
236 {
237 DIR * dir;
238 public:
239 AutoCloseDir();
240 AutoCloseDir(DIR * dir);
241 ~AutoCloseDir();
242 void operator =(DIR * dir);
243 operator DIR *();
244 void close();
245 };
246
247
248 class Pid
249 {
250 pid_t pid;
251 bool separatePG;
252 int killSignal;
253 public:
254 Pid();
255 Pid(pid_t pid);
256 ~Pid();
257 void operator =(pid_t pid);
258 operator pid_t();
259 void kill(bool quiet = false);
260 int wait(bool block);
261 void setSeparatePG(bool separatePG);
262 void setKillSignal(int signal);
263 };
264
265
266 /* Kill all processes running under the specified uid by sending them
267 a SIGKILL. */
268 void killUser(uid_t uid);
269
270
271 /* Fork a process that runs the given function, and return the child
272 pid to the caller. */
273 pid_t startProcess(std::function<void()> fun, bool dieWithParent = true,
274 const string & errorPrefix = "error: ", bool runExitHandlers = false);
275
276
277 /* Run a program and return its stdout in a string (i.e., like the
278 shell backtick operator). */
279 string runProgram(Path program, bool searchPath = false,
280 const Strings & args = Strings());
281
282 MakeError(ExecError, Error)
283
284 /* Convert a list of strings to a null-terminated vector of char
285 *'s. The result must not be accessed beyond the lifetime of the
286 list of strings. */
287 std::vector<char *> stringsToCharPtrs(const Strings & ss);
288
289 /* Close all file descriptors except stdin, stdout, stderr, and those
290 listed in the given set. Good practice in child processes. */
291 void closeMostFDs(const set<int> & exceptions);
292
293 /* Set the close-on-exec flag for the given file descriptor. */
294 void closeOnExec(int fd);
295
296
297 /* User interruption. */
298
299 extern volatile sig_atomic_t _isInterrupted;
300
301 void _interrupted();
302
303 void inline checkInterrupt()
304 {
305 if (_isInterrupted) _interrupted();
306 }
307
308 MakeError(Interrupted, BaseError)
309
310
311 /* String tokenizer. */
312 template<class C> C tokenizeString(const string & s, const string & separators = " \t\n\r");
313
314
315 /* Concatenate the given strings with a separator between the
316 elements. */
317 string concatStringsSep(const string & sep, const Strings & ss);
318 string concatStringsSep(const string & sep, const StringSet & ss);
319
320
321 /* Remove trailing whitespace from a string. */
322 string chomp(const string & s);
323
324
325 /* Convert the exit status of a child as returned by wait() into an
326 error string. */
327 string statusToString(int status);
328
329 bool statusOk(int status);
330
331
332 /* Parse a string into an integer. */
333 template<class N> bool string2Int(const string & s, N & n)
334 {
335 std::istringstream str(s);
336 str >> n;
337 return str && str.get() == EOF;
338 }
339
340
341 /* Return true iff `s' ends in `suffix'. */
342 bool hasSuffix(const string & s, const string & suffix);
343
344
345 /* Read string `s' from stream `str'. */
346 void expect(std::istream & str, const string & s);
347
348 MakeError(FormatError, Error)
349
350
351 /* Read a C-style string from stream `str'. */
352 string parseString(std::istream & str);
353
354
355 /* Utility function used to parse legacy ATerms. */
356 bool endOfList(std::istream & str);
357
358
359 /* Exception handling in destructors: print an error message, then
360 ignore the exception. */
361 void ignoreException();
362
363
364 }