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 : /* Return an environment variable. */
16 : string getEnv(const string & key, const string & def = "");
17 :
18 : /* Return an absolutized path, resolving paths relative to the
19 : specified directory, or the current directory otherwise. The path
20 : is also canonicalised. */
21 : Path absPath(Path path, Path dir = "");
22 :
23 : /* Canonicalise a path by removing all `.' or `..' components and
24 : double or trailing slashes. Optionally resolves all symlink
25 : components such that each component of the resulting path is *not*
26 : a symbolic link. */
27 : Path canonPath(const Path & path, bool resolveSymlinks = false);
28 :
29 : /* Return the directory part of the given canonical path, i.e.,
30 : everything before the final `/'. If the path is the root or an
31 : immediate child thereof (e.g., `/foo'), this means an empty string
32 : is returned. */
33 : Path dirOf(const Path & path);
34 :
35 : /* Return the base name of the given canonical path, i.e., everything
36 : following the final `/'. */
37 : string baseNameOf(const Path & path);
38 :
39 : /* Return true iff the given path exists. */
40 : bool pathExists(const Path & path);
41 :
42 : /* Read the contents (target) of a symbolic link. The result is not
43 : in any way canonicalised. */
44 : Path readLink(const Path & path);
45 :
46 : bool isLink(const Path & path);
47 :
48 : /* Read the contents of a directory. The entries `.' and `..' are
49 : removed. */
50 : Strings readDirectory(const Path & path);
51 :
52 : /* Read the contents of a file into a string. */
53 : string readFile(int fd);
54 : string readFile(const Path & path);
55 :
56 : /* Write a string to a file. */
57 : void writeFile(const Path & path, const string & s);
58 :
59 : /* Delete a path; i.e., in the case of a directory, it is deleted
60 : recursively. Don't use this at home, kids. The second variant
61 : returns the number of bytes freed. */
62 : void deletePath(const Path & path);
63 :
64 : void deletePath(const Path & path, unsigned long long & bytesFreed);
65 :
66 : /* Make a path read-only recursively. */
67 : void makePathReadOnly(const Path & path);
68 :
69 : /* Create a temporary directory. */
70 : Path createTempDir();
71 :
72 : /* Create a directory and all its parents, if necessary. */
73 : void createDirs(const Path & path);
74 :
75 : /* Create a file and write the given text to it. The file is written
76 : in binary mode (i.e., no end-of-line conversions). The path should
77 : not already exist. */
78 : void writeStringToFile(const Path & path, const string & s);
79 :
80 : template<class T, class A>
81 : T singleton(const A & a)
82 297 : {
83 297 : T t;
84 297 : t.insert(a);
85 297 : return t;
86 : }
87 :
88 :
89 : /* Messages. */
90 :
91 :
92 : typedef enum {
93 : ltPretty, /* nice, nested output */
94 : ltEscapes, /* nesting indicated using escape codes (for log2xml) */
95 : ltFlat /* no nesting */
96 : } LogType;
97 :
98 : extern LogType logType;
99 : extern Verbosity verbosity; /* suppress msgs > this */
100 :
101 : class Nest
102 : {
103 : private:
104 : bool nest;
105 : public:
106 : Nest();
107 : ~Nest();
108 : void open(Verbosity level, const format & f);
109 : void close();
110 : };
111 :
112 : void printMsg_(Verbosity level, const format & f);
113 :
114 : #define startNest(varName, level, f) \
115 : Nest varName; \
116 : if (level <= verbosity) { \
117 : varName.open(level, (f)); \
118 : }
119 :
120 : #define printMsg(level, f) \
121 : do { \
122 : if (level <= verbosity) { \
123 : printMsg_(level, (f)); \
124 : } \
125 : } while (0)
126 :
127 : #define debug(f) printMsg(lvlDebug, f)
128 :
129 : void warnOnce(bool & haveWarned, const format & f);
130 :
131 :
132 : /* Wrappers arount read()/write() that read/write exactly the
133 : requested number of bytes. */
134 : void readFull(int fd, unsigned char * buf, size_t count);
135 : void writeFull(int fd, const unsigned char * buf, size_t count);
136 :
137 :
138 : /* Read a file descriptor until EOF occurs. */
139 : string drainFD(int fd);
140 :
141 :
142 :
143 : /* Automatic cleanup of resources. */
144 :
145 : class AutoDelete
146 : {
147 : string path;
148 : bool del;
149 : public:
150 : AutoDelete(const string & p);
151 : ~AutoDelete();
152 : void cancel();
153 : };
154 :
155 :
156 : class AutoCloseFD
157 : {
158 : int fd;
159 : public:
160 : AutoCloseFD();
161 : AutoCloseFD(int fd);
162 : AutoCloseFD(const AutoCloseFD & fd);
163 : ~AutoCloseFD();
164 : void operator =(int fd);
165 : operator int() const;
166 : void close();
167 : bool isOpen();
168 : int borrow();
169 : };
170 :
171 :
172 : class Pipe
173 : {
174 : public:
175 : AutoCloseFD readSide, writeSide;
176 : void create();
177 : };
178 :
179 :
180 : class AutoCloseDir
181 : {
182 : DIR * dir;
183 : public:
184 : AutoCloseDir();
185 : AutoCloseDir(DIR * dir);
186 : ~AutoCloseDir();
187 : void operator =(DIR * dir);
188 : operator DIR *();
189 : };
190 :
191 :
192 : class Pid
193 : {
194 : pid_t pid;
195 : bool separatePG;
196 : public:
197 : Pid();
198 : ~Pid();
199 : void operator =(pid_t pid);
200 : operator pid_t();
201 : void kill();
202 : int wait(bool block);
203 : void setSeparatePG(bool separatePG);
204 : };
205 :
206 :
207 : /* Run a program and return its stdout in a string (i.e., like the
208 : shell backtick operator). */
209 : string runProgram(Path program);
210 :
211 : /* Wrapper around _exit() on Unix and ExitProcess() on Windows. (On
212 : Cygwin, _exit() doesn't seem to do the right thing.) */
213 : void quickExit(int status);
214 :
215 :
216 : /* User interruption. */
217 :
218 : extern volatile sig_atomic_t _isInterrupted;
219 :
220 : void _interrupted();
221 :
222 : void inline checkInterrupt()
223 121289 : {
224 121289 : if (_isInterrupted) _interrupted();
225 : }
226 :
227 :
228 : /* String packing / unpacking. */
229 : string packStrings(const Strings & strings);
230 : Strings unpackStrings(const string & s);
231 :
232 :
233 : /* String tokenizer. */
234 : Strings tokenizeString(const string & s, const string & separators = " \t\n\r");
235 :
236 :
237 : /* Convert the exit status of a child as returned by wait() into an
238 : error string. */
239 : string statusToString(int status);
240 :
241 : bool statusOk(int status);
242 :
243 :
244 : /* Parse a string into an integer. */
245 : string int2String(int n);
246 : bool string2Int(const string & s, int & n);
247 :
248 :
249 : /* Setuid support. */
250 : struct SwitchToOriginalUser
251 : {
252 : SwitchToOriginalUser();
253 : ~SwitchToOriginalUser();
254 : };
255 :
256 : void switchToNixUser();
257 :
258 :
259 : }
260 :
261 :
262 : #endif /* !__UTIL_H */
|