util.cc 29 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238
  1. #include "config.h"
  2. #include "util.hh"
  3. #include "affinity.hh"
  4. #include <iostream>
  5. #include <cerrno>
  6. #include <cstdio>
  7. #include <cstdlib>
  8. #include <sstream>
  9. #include <cstring>
  10. #include <sys/wait.h>
  11. #include <unistd.h>
  12. #include <fcntl.h>
  13. #include <limits.h>
  14. #ifdef __APPLE__
  15. #include <sys/syscall.h>
  16. #endif
  17. #ifdef __linux__
  18. #include <sys/prctl.h>
  19. #endif
  20. extern char * * environ;
  21. namespace nix {
  22. BaseError::BaseError(const FormatOrString & fs, unsigned int status)
  23. : status(status)
  24. {
  25. err = fs.s;
  26. }
  27. BaseError & BaseError::addPrefix(const FormatOrString & fs)
  28. {
  29. prefix_ = fs.s + prefix_;
  30. return *this;
  31. }
  32. SysError::SysError(const FormatOrString & fs)
  33. : Error(format("%1%: %2%") % fs.s % strerror(errno))
  34. , errNo(errno)
  35. {
  36. }
  37. string getEnv(const string & key, const string & def)
  38. {
  39. char * value = getenv(key.c_str());
  40. return value ? string(value) : def;
  41. }
  42. Path absPath(Path path, Path dir)
  43. {
  44. if (path[0] != '/') {
  45. if (dir == "") {
  46. #ifdef __GNU__
  47. /* GNU (aka. GNU/Hurd) doesn't have any limitation on path
  48. lengths and doesn't define `PATH_MAX'. */
  49. char *buf = getcwd(NULL, 0);
  50. if (buf == NULL)
  51. #else
  52. char buf[PATH_MAX];
  53. if (!getcwd(buf, sizeof(buf)))
  54. #endif
  55. throw SysError("cannot get cwd");
  56. dir = buf;
  57. #ifdef __GNU__
  58. free(buf);
  59. #endif
  60. }
  61. path = dir + "/" + path;
  62. }
  63. return canonPath(path);
  64. }
  65. Path canonPath(const Path & path, bool resolveSymlinks)
  66. {
  67. string s;
  68. if (path[0] != '/')
  69. throw Error(format("not an absolute path: `%1%'") % path);
  70. string::const_iterator i = path.begin(), end = path.end();
  71. string temp;
  72. /* Count the number of times we follow a symlink and stop at some
  73. arbitrary (but high) limit to prevent infinite loops. */
  74. unsigned int followCount = 0, maxFollow = 1024;
  75. while (1) {
  76. /* Skip slashes. */
  77. while (i != end && *i == '/') i++;
  78. if (i == end) break;
  79. /* Ignore `.'. */
  80. if (*i == '.' && (i + 1 == end || i[1] == '/'))
  81. i++;
  82. /* If `..', delete the last component. */
  83. else if (*i == '.' && i + 1 < end && i[1] == '.' &&
  84. (i + 2 == end || i[2] == '/'))
  85. {
  86. if (!s.empty()) s.erase(s.rfind('/'));
  87. i += 2;
  88. }
  89. /* Normal component; copy it. */
  90. else {
  91. s += '/';
  92. while (i != end && *i != '/') s += *i++;
  93. /* If s points to a symlink, resolve it and restart (since
  94. the symlink target might contain new symlinks). */
  95. if (resolveSymlinks && isLink(s)) {
  96. if (++followCount >= maxFollow)
  97. throw Error(format("infinite symlink recursion in path `%1%'") % path);
  98. temp = absPath(readLink(s), dirOf(s))
  99. + string(i, end);
  100. i = temp.begin(); /* restart */
  101. end = temp.end();
  102. s = "";
  103. }
  104. }
  105. }
  106. return s.empty() ? "/" : s;
  107. }
  108. Path dirOf(const Path & path)
  109. {
  110. Path::size_type pos = path.rfind('/');
  111. if (pos == string::npos)
  112. throw Error(format("invalid file name `%1%'") % path);
  113. return pos == 0 ? "/" : Path(path, 0, pos);
  114. }
  115. string baseNameOf(const Path & path)
  116. {
  117. Path::size_type pos = path.rfind('/');
  118. if (pos == string::npos)
  119. throw Error(format("invalid file name `%1%'") % path);
  120. return string(path, pos + 1);
  121. }
  122. bool isInDir(const Path & path, const Path & dir)
  123. {
  124. return path[0] == '/'
  125. && string(path, 0, dir.size()) == dir
  126. && path.size() >= dir.size() + 2
  127. && path[dir.size()] == '/';
  128. }
  129. struct stat lstat(const Path & path)
  130. {
  131. struct stat st;
  132. if (lstat(path.c_str(), &st))
  133. throw SysError(format("getting status of `%1%'") % path);
  134. return st;
  135. }
  136. bool pathExists(const Path & path)
  137. {
  138. int res;
  139. #ifdef HAVE_STATX
  140. struct statx st;
  141. res = statx(AT_FDCWD, path.c_str(), AT_SYMLINK_NOFOLLOW, 0, &st);
  142. #else
  143. struct stat st;
  144. res = lstat(path.c_str(), &st);
  145. #endif
  146. if (!res) return true;
  147. if (errno != ENOENT && errno != ENOTDIR)
  148. throw SysError(format("getting status of %1%") % path);
  149. return false;
  150. }
  151. Path readLink(const Path & path)
  152. {
  153. checkInterrupt();
  154. struct stat st = lstat(path);
  155. if (!S_ISLNK(st.st_mode))
  156. throw Error(format("`%1%' is not a symlink") % path);
  157. char buf[st.st_size];
  158. ssize_t rlsize = readlink(path.c_str(), buf, st.st_size);
  159. if (rlsize == -1)
  160. throw SysError(format("reading symbolic link '%1%'") % path);
  161. else if (rlsize > st.st_size)
  162. throw Error(format("symbolic link ‘%1%’ size overflow %2% > %3%")
  163. % path % rlsize % st.st_size);
  164. return string(buf, st.st_size);
  165. }
  166. bool isLink(const Path & path)
  167. {
  168. struct stat st = lstat(path);
  169. return S_ISLNK(st.st_mode);
  170. }
  171. DirEntries readDirectory(const Path & path)
  172. {
  173. DirEntries entries;
  174. entries.reserve(64);
  175. AutoCloseDir dir = opendir(path.c_str());
  176. if (!dir) throw SysError(format("opening directory `%1%'") % path);
  177. struct dirent * dirent;
  178. while (errno = 0, dirent = readdir(dir)) { /* sic */
  179. checkInterrupt();
  180. string name = dirent->d_name;
  181. if (name == "." || name == "..") continue;
  182. entries.emplace_back(name, dirent->d_ino, dirent->d_type);
  183. }
  184. if (errno) throw SysError(format("reading directory `%1%'") % path);
  185. return entries;
  186. }
  187. unsigned char getFileType(const Path & path)
  188. {
  189. struct stat st = lstat(path);
  190. if (S_ISDIR(st.st_mode)) return DT_DIR;
  191. if (S_ISLNK(st.st_mode)) return DT_LNK;
  192. if (S_ISREG(st.st_mode)) return DT_REG;
  193. return DT_UNKNOWN;
  194. }
  195. string readFile(int fd)
  196. {
  197. struct stat st;
  198. if (fstat(fd, &st) == -1)
  199. throw SysError("statting file");
  200. unsigned char * buf = new unsigned char[st.st_size];
  201. AutoDeleteArray<unsigned char> d(buf);
  202. readFull(fd, buf, st.st_size);
  203. return string((char *) buf, st.st_size);
  204. }
  205. string readFile(const Path & path, bool drain)
  206. {
  207. AutoCloseFD fd = open(path.c_str(), O_RDONLY);
  208. if (fd == -1)
  209. throw SysError(format("reading file `%1%'") % path);
  210. return drain ? drainFD(fd) : readFile(fd);
  211. }
  212. void writeFile(const Path & path, const string & s)
  213. {
  214. AutoCloseFD fd = open(path.c_str(), O_WRONLY | O_TRUNC | O_CREAT, 0666);
  215. if (fd == -1)
  216. throw SysError(format("writing file '%1%'") % path);
  217. writeFull(fd, s);
  218. }
  219. string readLine(int fd)
  220. {
  221. string s;
  222. while (1) {
  223. checkInterrupt();
  224. char ch;
  225. ssize_t rd = read(fd, &ch, 1);
  226. if (rd == -1) {
  227. if (errno != EINTR)
  228. throw SysError("reading a line");
  229. } else if (rd == 0)
  230. throw EndOfFile("unexpected EOF reading a line");
  231. else {
  232. if (ch == '\n') return s;
  233. s += ch;
  234. }
  235. }
  236. }
  237. void writeLine(int fd, string s)
  238. {
  239. s += '\n';
  240. writeFull(fd, s);
  241. }
  242. static void _deletePath(const Path & path, unsigned long long & bytesFreed, size_t linkThreshold)
  243. {
  244. checkInterrupt();
  245. printMsg(lvlVomit, format("%1%") % path);
  246. #ifdef HAVE_STATX
  247. # define st_mode stx_mode
  248. # define st_size stx_size
  249. # define st_nlink stx_nlink
  250. struct statx st;
  251. if (statx(AT_FDCWD, path.c_str(),
  252. AT_SYMLINK_NOFOLLOW,
  253. STATX_SIZE | STATX_NLINK | STATX_MODE, &st) == -1)
  254. throw SysError(format("getting status of `%1%'") % path);
  255. #else
  256. struct stat st = lstat(path);
  257. #endif
  258. if (!S_ISDIR(st.st_mode) && st.st_nlink <= linkThreshold)
  259. bytesFreed += st.st_size;
  260. if (S_ISDIR(st.st_mode)) {
  261. /* Make the directory writable. */
  262. if (!(st.st_mode & S_IWUSR)) {
  263. if (chmod(path.c_str(), st.st_mode | S_IWUSR) == -1)
  264. throw SysError(format("making `%1%' writable") % path);
  265. }
  266. for (auto & i : readDirectory(path))
  267. _deletePath(path + "/" + i.name, bytesFreed, linkThreshold);
  268. }
  269. int ret;
  270. ret = S_ISDIR(st.st_mode) ? rmdir(path.c_str()) : unlink(path.c_str());
  271. if (ret == -1)
  272. throw SysError(format("cannot unlink `%1%'") % path);
  273. #undef st_mode
  274. #undef st_size
  275. #undef st_nlink
  276. }
  277. void deletePath(const Path & path)
  278. {
  279. unsigned long long dummy;
  280. deletePath(path, dummy);
  281. }
  282. void deletePath(const Path & path, unsigned long long & bytesFreed, size_t linkThreshold)
  283. {
  284. startNest(nest, lvlDebug,
  285. format("recursively deleting path `%1%'") % path);
  286. bytesFreed = 0;
  287. _deletePath(path, bytesFreed, linkThreshold);
  288. }
  289. static Path tempName(Path tmpRoot, const Path & prefix, bool includePid,
  290. int & counter)
  291. {
  292. tmpRoot = canonPath(tmpRoot.empty() ? getEnv("TMPDIR", "/tmp") : tmpRoot, true);
  293. if (includePid)
  294. return (format("%1%/%2%-%3%-%4%") % tmpRoot % prefix % getpid() % counter++).str();
  295. else
  296. return (format("%1%/%2%-%3%") % tmpRoot % prefix % counter++).str();
  297. }
  298. Path createTempDir(const Path & tmpRoot, const Path & prefix,
  299. bool includePid, bool useGlobalCounter, mode_t mode)
  300. {
  301. static int globalCounter = 0;
  302. int localCounter = 0;
  303. int & counter(useGlobalCounter ? globalCounter : localCounter);
  304. while (1) {
  305. checkInterrupt();
  306. Path tmpDir = tempName(tmpRoot, prefix, includePid, counter);
  307. if (mkdir(tmpDir.c_str(), mode) == 0) {
  308. /* Explicitly set the group of the directory. This is to
  309. work around around problems caused by BSD's group
  310. ownership semantics (directories inherit the group of
  311. the parent). For instance, the group of /tmp on
  312. FreeBSD is "wheel", so all directories created in /tmp
  313. will be owned by "wheel"; but if the user is not in
  314. "wheel", then "tar" will fail to unpack archives that
  315. have the setgid bit set on directories. */
  316. if (chown(tmpDir.c_str(), (uid_t) -1, getegid()) != 0)
  317. throw SysError(format("setting group of directory `%1%'") % tmpDir);
  318. return tmpDir;
  319. }
  320. if (errno != EEXIST)
  321. throw SysError(format("creating directory `%1%'") % tmpDir);
  322. }
  323. }
  324. Paths createDirs(const Path & path)
  325. {
  326. Paths created;
  327. if (path == "/") return created;
  328. struct stat st;
  329. if (lstat(path.c_str(), &st) == -1) {
  330. created = createDirs(dirOf(path));
  331. if (mkdir(path.c_str(), 0777) == -1 && errno != EEXIST)
  332. throw SysError(format("creating directory `%1%'") % path);
  333. st = lstat(path);
  334. created.push_back(path);
  335. }
  336. if (S_ISLNK(st.st_mode) && stat(path.c_str(), &st) == -1)
  337. throw SysError(format("statting symlink `%1%'") % path);
  338. if (!S_ISDIR(st.st_mode)) throw Error(format("`%1%' is not a directory") % path);
  339. return created;
  340. }
  341. void createSymlink(const Path & target, const Path & link)
  342. {
  343. if (symlink(target.c_str(), link.c_str()))
  344. throw SysError(format("creating symlink from `%1%' to `%2%'") % link % target);
  345. }
  346. LogType logType = ltPretty;
  347. Verbosity verbosity = lvlInfo;
  348. static int nestingLevel = 0;
  349. Nest::Nest()
  350. {
  351. nest = false;
  352. }
  353. Nest::~Nest()
  354. {
  355. close();
  356. }
  357. static string escVerbosity(Verbosity level)
  358. {
  359. return std::to_string((int) level);
  360. }
  361. void Nest::open(Verbosity level, const FormatOrString & fs)
  362. {
  363. if (level <= verbosity) {
  364. if (logType == ltEscapes)
  365. std::cerr << "\033[" << escVerbosity(level) << "p"
  366. << fs.s << "\n";
  367. else
  368. printMsg_(level, fs);
  369. nest = true;
  370. nestingLevel++;
  371. }
  372. }
  373. void Nest::close()
  374. {
  375. if (nest) {
  376. nestingLevel--;
  377. if (logType == ltEscapes)
  378. std::cerr << "\033[q";
  379. nest = false;
  380. }
  381. }
  382. void printMsg_(Verbosity level, const FormatOrString & fs)
  383. {
  384. checkInterrupt();
  385. if (level > verbosity) return;
  386. string prefix;
  387. if (logType == ltPretty)
  388. for (int i = 0; i < nestingLevel; i++)
  389. prefix += "| ";
  390. else if (logType == ltEscapes && level != lvlInfo)
  391. prefix = "\033[" + escVerbosity(level) + "s";
  392. string s = (format("%1%%2%\n") % prefix % fs.s).str();
  393. writeToStderr(s);
  394. }
  395. void warnOnce(bool & haveWarned, const FormatOrString & fs)
  396. {
  397. if (!haveWarned) {
  398. printMsg(lvlError, format("warning: %1%") % fs.s);
  399. haveWarned = true;
  400. }
  401. }
  402. void writeToStderr(const string & s)
  403. {
  404. try {
  405. if (_writeToStderr)
  406. _writeToStderr((const unsigned char *) s.data(), s.size());
  407. else
  408. writeFull(STDERR_FILENO, s);
  409. } catch (SysError & e) {
  410. /* Ignore failing writes to stderr if we're in an exception
  411. handler, otherwise throw an exception. We need to ignore
  412. write errors in exception handlers to ensure that cleanup
  413. code runs to completion if the other side of stderr has
  414. been closed unexpectedly. */
  415. if (!std::uncaught_exception()) throw;
  416. }
  417. }
  418. void (*_writeToStderr) (const unsigned char * buf, size_t count) = 0;
  419. void readFull(int fd, unsigned char * buf, size_t count)
  420. {
  421. while (count) {
  422. checkInterrupt();
  423. ssize_t res = read(fd, (char *) buf, count);
  424. if (res == -1) {
  425. if (errno == EINTR) continue;
  426. throw SysError("reading from file");
  427. }
  428. if (res == 0) throw EndOfFile("unexpected end-of-file");
  429. count -= res;
  430. buf += res;
  431. }
  432. }
  433. void writeFull(int fd, const unsigned char * buf, size_t count)
  434. {
  435. while (count) {
  436. checkInterrupt();
  437. ssize_t res = write(fd, (char *) buf, count);
  438. if (res == -1) {
  439. if (errno == EINTR) continue;
  440. throw SysError("writing to file");
  441. }
  442. count -= res;
  443. buf += res;
  444. }
  445. }
  446. void writeFull(int fd, const string & s)
  447. {
  448. writeFull(fd, (const unsigned char *) s.data(), s.size());
  449. }
  450. string drainFD(int fd)
  451. {
  452. string result;
  453. unsigned char buffer[4096];
  454. while (1) {
  455. checkInterrupt();
  456. ssize_t rd = read(fd, buffer, sizeof buffer);
  457. if (rd == -1) {
  458. if (errno != EINTR)
  459. throw SysError("reading from file");
  460. }
  461. else if (rd == 0) break;
  462. else result.append((char *) buffer, rd);
  463. }
  464. return result;
  465. }
  466. //////////////////////////////////////////////////////////////////////
  467. AutoDelete::AutoDelete(const string & p, bool recursive) : path(p)
  468. {
  469. del = true;
  470. this->recursive = recursive;
  471. }
  472. AutoDelete::~AutoDelete()
  473. {
  474. try {
  475. if (del) {
  476. if (recursive)
  477. deletePath(path);
  478. else {
  479. if (remove(path.c_str()) == -1)
  480. throw SysError(format("cannot unlink `%1%'") % path);
  481. }
  482. }
  483. } catch (...) {
  484. ignoreException();
  485. }
  486. }
  487. void AutoDelete::cancel()
  488. {
  489. del = false;
  490. }
  491. //////////////////////////////////////////////////////////////////////
  492. AutoCloseFD::AutoCloseFD()
  493. {
  494. fd = -1;
  495. }
  496. AutoCloseFD::AutoCloseFD(int fd)
  497. {
  498. this->fd = fd;
  499. }
  500. AutoCloseFD::AutoCloseFD(const AutoCloseFD & fd)
  501. {
  502. /* Copying an AutoCloseFD isn't allowed (who should get to close
  503. it?). But as an edge case, allow copying of closed
  504. AutoCloseFDs. This is necessary due to tiresome reasons
  505. involving copy constructor use on default object values in STL
  506. containers (like when you do `map[value]' where value isn't in
  507. the map yet). */
  508. this->fd = fd.fd;
  509. if (this->fd != -1) abort();
  510. }
  511. AutoCloseFD::~AutoCloseFD()
  512. {
  513. try {
  514. close();
  515. } catch (...) {
  516. ignoreException();
  517. }
  518. }
  519. void AutoCloseFD::operator =(int fd)
  520. {
  521. if (this->fd != fd) close();
  522. this->fd = fd;
  523. }
  524. AutoCloseFD::operator int() const
  525. {
  526. return fd;
  527. }
  528. void AutoCloseFD::close()
  529. {
  530. if (fd != -1) {
  531. if (::close(fd) == -1)
  532. /* This should never happen. */
  533. throw SysError(format("closing file descriptor %1%") % fd);
  534. fd = -1;
  535. }
  536. }
  537. bool AutoCloseFD::isOpen()
  538. {
  539. return fd != -1;
  540. }
  541. /* Pass responsibility for closing this fd to the caller. */
  542. int AutoCloseFD::borrow()
  543. {
  544. int oldFD = fd;
  545. fd = -1;
  546. return oldFD;
  547. }
  548. void Pipe::create()
  549. {
  550. int fds[2];
  551. if (pipe(fds) != 0) throw SysError("creating pipe");
  552. readSide = fds[0];
  553. writeSide = fds[1];
  554. closeOnExec(readSide);
  555. closeOnExec(writeSide);
  556. }
  557. //////////////////////////////////////////////////////////////////////
  558. AutoCloseDir::AutoCloseDir()
  559. {
  560. dir = 0;
  561. }
  562. AutoCloseDir::AutoCloseDir(DIR * dir)
  563. {
  564. this->dir = dir;
  565. }
  566. AutoCloseDir::~AutoCloseDir()
  567. {
  568. close();
  569. }
  570. void AutoCloseDir::operator =(DIR * dir)
  571. {
  572. this->dir = dir;
  573. }
  574. AutoCloseDir::operator DIR *()
  575. {
  576. return dir;
  577. }
  578. void AutoCloseDir::close()
  579. {
  580. if (dir) {
  581. closedir(dir);
  582. dir = 0;
  583. }
  584. }
  585. //////////////////////////////////////////////////////////////////////
  586. Pid::Pid()
  587. : pid(-1), separatePG(false), killSignal(SIGKILL)
  588. {
  589. }
  590. Pid::Pid(pid_t pid)
  591. : pid(pid), separatePG(false), killSignal(SIGKILL)
  592. {
  593. }
  594. Pid::~Pid()
  595. {
  596. kill();
  597. }
  598. void Pid::operator =(pid_t pid)
  599. {
  600. if (this->pid != pid) kill();
  601. this->pid = pid;
  602. killSignal = SIGKILL; // reset signal to default
  603. }
  604. Pid::operator pid_t()
  605. {
  606. return pid;
  607. }
  608. void Pid::kill(bool quiet)
  609. {
  610. if (pid == -1 || pid == 0) return;
  611. if (!quiet)
  612. printMsg(lvlError, format("killing process %1%") % pid);
  613. /* Send the requested signal to the child. If it has its own
  614. process group, send the signal to every process in the child
  615. process group (which hopefully includes *all* its children). */
  616. if (::kill(separatePG ? -pid : pid, killSignal) != 0)
  617. printMsg(lvlError, (SysError(format("killing process %1%") % pid).msg()));
  618. /* Wait until the child dies, disregarding the exit status. */
  619. int status;
  620. while (waitpid(pid, &status, 0) == -1) {
  621. checkInterrupt();
  622. if (errno != EINTR) {
  623. printMsg(lvlError,
  624. (SysError(format("waiting for process %1%") % pid).msg()));
  625. break;
  626. }
  627. }
  628. pid = -1;
  629. }
  630. int Pid::wait(bool block)
  631. {
  632. assert(pid != -1);
  633. while (1) {
  634. int status;
  635. int res = waitpid(pid, &status, block ? 0 : WNOHANG);
  636. if (res == pid) {
  637. pid = -1;
  638. return status;
  639. }
  640. if (res == 0 && !block) return -1;
  641. if (errno != EINTR)
  642. throw SysError("cannot get child exit status");
  643. checkInterrupt();
  644. }
  645. }
  646. void Pid::setSeparatePG(bool separatePG)
  647. {
  648. this->separatePG = separatePG;
  649. }
  650. void Pid::setKillSignal(int signal)
  651. {
  652. this->killSignal = signal;
  653. }
  654. void killUser(uid_t uid)
  655. {
  656. debug(format("killing all processes running under uid `%1%'") % uid);
  657. assert(uid != 0); /* just to be safe... */
  658. /* The system call kill(-1, sig) sends the signal `sig' to all
  659. users to which the current process can send signals. So we
  660. fork a process, switch to uid, and send a mass kill. */
  661. Pid pid = startProcess([&]() {
  662. if (setuid(uid) == -1)
  663. throw SysError("setting uid");
  664. while (true) {
  665. #ifdef __APPLE__
  666. /* OSX's kill syscall takes a third parameter that, among
  667. other things, determines if kill(-1, signo) affects the
  668. calling process. In the OSX libc, it's set to true,
  669. which means "follow POSIX", which we don't want here
  670. */
  671. if (syscall(SYS_kill, -1, SIGKILL, false) == 0) break;
  672. #elif __GNU__
  673. /* Killing all a user's processes using PID=-1 does currently
  674. not work on the Hurd. */
  675. if (kill(getpid(), SIGKILL) == 0) break;
  676. #else
  677. if (kill(-1, SIGKILL) == 0) break;
  678. #endif
  679. if (errno == ESRCH) break; /* no more processes */
  680. if (errno != EINTR)
  681. throw SysError(format("cannot kill processes for uid `%1%'") % uid);
  682. }
  683. _exit(0);
  684. });
  685. int status = pid.wait(true);
  686. #if __GNU__
  687. /* When the child killed itself, status = SIGKILL. */
  688. if (status == SIGKILL) return;
  689. #endif
  690. if (status != 0)
  691. throw Error(format("cannot kill processes for uid `%1%': %2%") % uid % statusToString(status));
  692. /* !!! We should really do some check to make sure that there are
  693. no processes left running under `uid', but there is no portable
  694. way to do so (I think). The most reliable way may be `ps -eo
  695. uid | grep -q $uid'. */
  696. }
  697. //////////////////////////////////////////////////////////////////////
  698. pid_t startProcess(std::function<void()> fun,
  699. bool dieWithParent, const string & errorPrefix, bool runExitHandlers)
  700. {
  701. pid_t pid = fork();
  702. if (pid == -1) throw SysError("unable to fork");
  703. if (pid == 0) {
  704. _writeToStderr = 0;
  705. try {
  706. #if __linux__
  707. if (dieWithParent && prctl(PR_SET_PDEATHSIG, SIGKILL) == -1)
  708. throw SysError("setting death signal");
  709. #endif
  710. restoreAffinity();
  711. fun();
  712. } catch (std::exception & e) {
  713. try {
  714. std::cerr << errorPrefix << e.what() << "\n";
  715. } catch (...) { }
  716. } catch (...) { }
  717. if (runExitHandlers)
  718. exit(1);
  719. else
  720. _exit(1);
  721. }
  722. return pid;
  723. }
  724. std::vector<char *> stringsToCharPtrs(const Strings & ss)
  725. {
  726. std::vector<char *> res;
  727. for (auto & s : ss) res.push_back((char *) s.c_str());
  728. res.push_back(0);
  729. return res;
  730. }
  731. string runProgram(Path program, bool searchPath, const Strings & args)
  732. {
  733. checkInterrupt();
  734. /* Create a pipe. */
  735. Pipe pipe;
  736. pipe.create();
  737. /* Fork. */
  738. Pid pid = startProcess([&]() {
  739. if (dup2(pipe.writeSide, STDOUT_FILENO) == -1)
  740. throw SysError("dupping stdout");
  741. Strings args_(args);
  742. args_.push_front(program);
  743. if (searchPath)
  744. execvp(program.c_str(), stringsToCharPtrs(args_).data());
  745. else
  746. execv(program.c_str(), stringsToCharPtrs(args_).data());
  747. throw SysError(format("executing `%1%'") % program);
  748. });
  749. pipe.writeSide.close();
  750. string result = drainFD(pipe.readSide);
  751. /* Wait for the child to finish. */
  752. int status = pid.wait(true);
  753. if (!statusOk(status))
  754. throw ExecError(format("program `%1%' %2%")
  755. % program % statusToString(status));
  756. return result;
  757. }
  758. void closeMostFDs(const set<int> & exceptions)
  759. {
  760. int maxFD = 0;
  761. maxFD = sysconf(_SC_OPEN_MAX);
  762. for (int fd = 0; fd < maxFD; ++fd)
  763. if (fd != STDIN_FILENO && fd != STDOUT_FILENO && fd != STDERR_FILENO
  764. && exceptions.find(fd) == exceptions.end())
  765. close(fd); /* ignore result */
  766. }
  767. void closeOnExec(int fd)
  768. {
  769. int prev;
  770. if ((prev = fcntl(fd, F_GETFD, 0)) == -1 ||
  771. fcntl(fd, F_SETFD, prev | FD_CLOEXEC) == -1)
  772. throw SysError("setting close-on-exec flag");
  773. }
  774. //////////////////////////////////////////////////////////////////////
  775. volatile sig_atomic_t _isInterrupted = 0;
  776. void _interrupted()
  777. {
  778. /* Block user interrupts while an exception is being handled.
  779. Throwing an exception while another exception is being handled
  780. kills the program! */
  781. if (!std::uncaught_exception()) {
  782. _isInterrupted = 0;
  783. throw Interrupted("interrupted by the user");
  784. }
  785. }
  786. //////////////////////////////////////////////////////////////////////
  787. template<class C> C tokenizeString(const string & s, const string & separators)
  788. {
  789. C result;
  790. string::size_type pos = s.find_first_not_of(separators, 0);
  791. while (pos != string::npos) {
  792. string::size_type end = s.find_first_of(separators, pos + 1);
  793. if (end == string::npos) end = s.size();
  794. string token(s, pos, end - pos);
  795. result.insert(result.end(), token);
  796. pos = s.find_first_not_of(separators, end);
  797. }
  798. return result;
  799. }
  800. template Strings tokenizeString(const string & s, const string & separators);
  801. template StringSet tokenizeString(const string & s, const string & separators);
  802. template vector<string> tokenizeString(const string & s, const string & separators);
  803. string concatStringsSep(const string & sep, const Strings & ss)
  804. {
  805. string s;
  806. foreach (Strings::const_iterator, i, ss) {
  807. if (s.size() != 0) s += sep;
  808. s += *i;
  809. }
  810. return s;
  811. }
  812. string concatStringsSep(const string & sep, const StringSet & ss)
  813. {
  814. string s;
  815. foreach (StringSet::const_iterator, i, ss) {
  816. if (s.size() != 0) s += sep;
  817. s += *i;
  818. }
  819. return s;
  820. }
  821. string chomp(const string & s)
  822. {
  823. size_t i = s.find_last_not_of(" \n\r\t");
  824. return i == string::npos ? "" : string(s, 0, i + 1);
  825. }
  826. string statusToString(int status)
  827. {
  828. if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
  829. if (WIFEXITED(status))
  830. return (format("failed with exit code %1%") % WEXITSTATUS(status)).str();
  831. else if (WIFSIGNALED(status)) {
  832. int sig = WTERMSIG(status);
  833. #if HAVE_STRSIGNAL
  834. const char * description = strsignal(sig);
  835. return (format("failed due to signal %1% (%2%)") % sig % description).str();
  836. #else
  837. return (format("failed due to signal %1%") % sig).str();
  838. #endif
  839. }
  840. else
  841. return "died abnormally";
  842. } else return "succeeded";
  843. }
  844. bool statusOk(int status)
  845. {
  846. return WIFEXITED(status) && WEXITSTATUS(status) == 0;
  847. }
  848. bool hasSuffix(const string & s, const string & suffix)
  849. {
  850. return s.size() >= suffix.size() && string(s, s.size() - suffix.size()) == suffix;
  851. }
  852. void expect(std::istream & str, const string & s)
  853. {
  854. char s2[s.size()];
  855. str.read(s2, s.size());
  856. if (string(s2, s.size()) != s)
  857. throw FormatError(format("expected string `%1%'") % s);
  858. }
  859. string parseString(std::istream & str)
  860. {
  861. string res;
  862. expect(str, "\"");
  863. int c;
  864. while ((c = str.get()) != '"')
  865. if (c == '\\') {
  866. c = str.get();
  867. if (c == 'n') res += '\n';
  868. else if (c == 'r') res += '\r';
  869. else if (c == 't') res += '\t';
  870. else res += c;
  871. }
  872. else res += c;
  873. return res;
  874. }
  875. bool endOfList(std::istream & str)
  876. {
  877. if (str.peek() == ',') {
  878. str.get();
  879. return false;
  880. }
  881. if (str.peek() == ']') {
  882. str.get();
  883. return true;
  884. }
  885. return false;
  886. }
  887. void ignoreException()
  888. {
  889. try {
  890. throw;
  891. } catch (std::exception & e) {
  892. printMsg(lvlError, format("error (ignored): %1%") % e.what());
  893. }
  894. }
  895. static const string pathNullDevice = "/dev/null";
  896. /* Common initialisation performed in child processes. */
  897. void commonChildInit(Pipe & logPipe)
  898. {
  899. /* Put the child in a separate session (and thus a separate
  900. process group) so that it has no controlling terminal (meaning
  901. that e.g. ssh cannot open /dev/tty) and it doesn't receive
  902. terminal signals. */
  903. if (setsid() == -1)
  904. throw SysError(format("creating a new session"));
  905. /* Dup the write side of the logger pipe into stderr. */
  906. if (dup2(logPipe.writeSide, STDERR_FILENO) == -1)
  907. throw SysError("cannot pipe standard error into log file");
  908. /* Dup stderr to stdout. */
  909. if (dup2(STDERR_FILENO, STDOUT_FILENO) == -1)
  910. throw SysError("cannot dup stderr into stdout");
  911. /* Reroute stdin to /dev/null. */
  912. int fdDevNull = open(pathNullDevice.c_str(), O_RDWR);
  913. if (fdDevNull == -1)
  914. throw SysError(format("cannot open `%1%'") % pathNullDevice);
  915. if (dup2(fdDevNull, STDIN_FILENO) == -1)
  916. throw SysError("cannot dup null device into stdin");
  917. close(fdDevNull);
  918. }
  919. //////////////////////////////////////////////////////////////////////
  920. Agent::Agent(const string &command, const Strings &args, const std::map<string, string> &env)
  921. {
  922. debug(format("starting agent '%1%'") % command);
  923. /* Create a pipe to get the output of the child. */
  924. fromAgent.create();
  925. /* Create the communication pipes. */
  926. toAgent.create();
  927. /* Create a pipe to get the output of the builder. */
  928. builderOut.create();
  929. /* Fork the hook. */
  930. pid = startProcess([&]() {
  931. commonChildInit(fromAgent);
  932. for (auto pair: env) {
  933. setenv(pair.first.c_str(), pair.second.c_str(), 1);
  934. }
  935. if (chdir("/") == -1) throw SysError("changing into `/");
  936. /* Dup the communication pipes. */
  937. if (dup2(toAgent.readSide, STDIN_FILENO) == -1)
  938. throw SysError("dupping to-hook read side");
  939. /* Use fd 4 for the builder's stdout/stderr. */
  940. if (dup2(builderOut.writeSide, 4) == -1)
  941. throw SysError("dupping builder's stdout/stderr");
  942. Strings allArgs;
  943. allArgs.push_back(command);
  944. allArgs.insert(allArgs.end(), args.begin(), args.end()); // append
  945. execv(command.c_str(), stringsToCharPtrs(allArgs).data());
  946. throw SysError(format("executing `%1%'") % command);
  947. });
  948. pid.setSeparatePG(true);
  949. fromAgent.writeSide.close();
  950. toAgent.readSide.close();
  951. }
  952. Agent::~Agent()
  953. {
  954. try {
  955. toAgent.writeSide.close();
  956. pid.kill(true);
  957. } catch (...) {
  958. ignoreException();
  959. }
  960. }
  961. }