util.hh 8.5 KB

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