From 5ebb3b4832d6370128b87c6b5e2b56f10b096ccc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Tarl=C3=A1=20Cardoso=20Lemos?= Date: Sun, 14 Nov 2010 23:01:04 -0200 Subject: [PATCH] Port the IPC socket creation code from -next. --- src/ipc.c | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/src/ipc.c b/src/ipc.c index eed63bd4..b8409a92 100644 --- a/src/ipc.c +++ b/src/ipc.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -38,6 +39,34 @@ static void set_nonblock(int sockfd) { err(-1, "Could not set O_NONBLOCK"); } +/* + * Emulates mkdir -p (creates any missing folders) + * + */ +static bool mkdirp(const char *path) { + if (mkdir(path, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) == 0) + return true; + if (errno != ENOENT) { + ELOG("mkdir(%s) failed: %s\n", path, strerror(errno)); + return false; + } + char *copy = strdup(path); + /* strip trailing slashes, if any */ + while (copy[strlen(copy)-1] == '/') + copy[strlen(copy)-1] = '\0'; + + char *sep = strrchr(copy, '/'); + if (sep == NULL) + return false; + *sep = '\0'; + bool result = false; + if (mkdirp(copy)) + result = mkdirp(path); + free(copy); + + return result; +} + static void ipc_send_message(int fd, const unsigned char *payload, int message_type, int message_size) { int buffer_size = strlen("i3-ipc") + sizeof(uint32_t) + @@ -555,11 +584,20 @@ void ipc_new_client(EV_P_ struct ev_io *w, int revents) { int ipc_create_socket(const char *filename) { int sockfd; + char *resolved = resolve_tilde(filename); + DLOG("Creating IPC-socket at %s\n", resolved); + char *copy = sstrdup(resolved); + const char *dir = dirname(copy); + if (!path_exists(dir)) + mkdirp(dir); + free(copy); + /* Unlink the unix domain socket before */ unlink(filename); if ((sockfd = socket(AF_LOCAL, SOCK_STREAM, 0)) < 0) { perror("socket()"); + free(resolved); return -1; } @@ -568,12 +606,14 @@ int ipc_create_socket(const char *filename) { struct sockaddr_un addr; memset(&addr, 0, sizeof(struct sockaddr_un)); addr.sun_family = AF_LOCAL; - strcpy(addr.sun_path, filename); + strncpy(addr.sun_path, resolved, sizeof(addr.sun_path) - 1); if (bind(sockfd, (struct sockaddr*)&addr, sizeof(struct sockaddr_un)) < 0) { perror("bind()"); + free(resolved); return -1; } + free(resolved); set_nonblock(sockfd); if (listen(sockfd, 5) < 0) {