summaryrefslogtreecommitdiff
path: root/nix/libutil/util.cc
diff options
context:
space:
mode:
Diffstat (limited to 'nix/libutil/util.cc')
-rw-r--r--nix/libutil/util.cc101
1 files changed, 101 insertions, 0 deletions
diff --git a/nix/libutil/util.cc b/nix/libutil/util.cc
index e71e6c170a..327edf471f 100644
--- a/nix/libutil/util.cc
+++ b/nix/libutil/util.cc
@@ -14,6 +14,7 @@
#include <unistd.h>
#include <fcntl.h>
#include <limits.h>
+#include <sys/socket.h>
#ifdef __APPLE__
#include <sys/syscall.h>
@@ -62,6 +63,27 @@ string getEnv(const string & key, const string & def)
}
+string findProgram(const string & program)
+{
+ if(program.empty()) return "";
+
+ if(program[0] == '/') return pathExists(program) ? program : "";
+
+ char *path_ = getenv("PATH");
+ if(path_ == NULL) return "";
+ string path = path_;
+
+ Strings dirs = tokenizeString<Strings>(path, ":");
+ for (const auto& i : dirs) {
+ if(i == "") continue;
+ string f = i + "/" + program;
+ if(pathExists(f)) return f;
+ }
+
+ return "";
+}
+
+
Path absPath(Path path, Path dir)
{
if (path[0] != '/') {
@@ -857,6 +879,67 @@ void Pipe::create()
}
+void sendFD(int sock, int fd)
+{
+ ssize_t rc;
+ struct msghdr msg;
+ struct cmsghdr *cmsg;
+ char cmsgbuf[CMSG_SPACE(sizeof(fd))];
+ struct iovec iov;
+ char dummy = '\0';
+ memset(&msg, 0, sizeof(msg));
+ iov.iov_base = &dummy;
+ iov.iov_len = 1;
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = cmsgbuf;
+ msg.msg_controllen = sizeof(cmsgbuf);
+ cmsg = CMSG_FIRSTHDR(&msg);
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
+ memcpy(CMSG_DATA(cmsg), &fd, sizeof(fd));
+ msg.msg_controllen = cmsg->cmsg_len;
+ do
+ {
+ rc = sendmsg(sock, &msg, 0);
+ } while(rc < 0 && errno == EINTR);
+ if(rc < 0)
+ throw SysError("sending fd");
+}
+
+
+int receiveFD(int sock)
+{
+ int fd;
+ ssize_t rc;
+ struct msghdr msg;
+ struct cmsghdr *cmsg;
+ char cmsgbuf[CMSG_SPACE(sizeof(fd))];
+ struct iovec iov;
+ char dummy = '\0';
+ memset(&msg, 0, sizeof(msg));
+ iov.iov_base = &dummy;
+ iov.iov_len = 1;
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = cmsgbuf;
+ msg.msg_controllen = sizeof(cmsgbuf);
+ do
+ {
+ rc = recvmsg(sock, &msg, 0);
+ } while(rc < 0 && errno == EINTR);
+ if (rc < 0)
+ throw SysError("receiving fd");
+ if (rc == 0)
+ throw Error("received EOF (empty message) while receiving fd");
+
+ cmsg = CMSG_FIRSTHDR(&msg);
+ if (cmsg == NULL || cmsg->cmsg_type != SCM_RIGHTS)
+ throw Error("received message without an fd");
+ memcpy(&fd, CMSG_DATA(cmsg), sizeof(fd));
+ return fd;
+}
//////////////////////////////////////////////////////////////////////
@@ -1301,6 +1384,24 @@ bool endOfList(std::istream & str)
return false;
}
+string decodeOctalEscaped(const string & s)
+{
+ string r;
+ for (string::const_iterator i = s.begin(); i != s.end(); ) {
+ if (*i != '\\') { r += *(i++); continue; }
+ unsigned char c = 0;
+ ++i;
+ for(int j = 0; j < 3; j++) {
+ if(i == s.end() || *i < '0' || *i >= '8')
+ throw Error("malformed octal escape");
+ c = c * 8 + (*i - '0');
+ ++i;
+ }
+ r += c;
+ }
+ return r;
+}
+
void ignoreException()
{