]> git.ipfire.org Git - thirdparty/git.git/blobdiff - unix-socket.c
Merge branch 'en/ort-perf-batch-9'
[thirdparty/git.git] / unix-socket.c
index 19ed48be9902f321285bfbec3feaf8357fd5e9b9..e0be1badb58dee8af8e28c4a4486bf0fdba18a9c 100644 (file)
@@ -1,13 +1,7 @@
 #include "cache.h"
 #include "unix-socket.h"
 
-static int unix_stream_socket(void)
-{
-       int fd = socket(AF_UNIX, SOCK_STREAM, 0);
-       if (fd < 0)
-               die_errno("unable to create socket");
-       return fd;
-}
+#define DEFAULT_UNIX_STREAM_LISTEN_BACKLOG (5)
 
 static int chdir_len(const char *orig, int len)
 {
@@ -36,16 +30,23 @@ static void unix_sockaddr_cleanup(struct unix_sockaddr_context *ctx)
 }
 
 static int unix_sockaddr_init(struct sockaddr_un *sa, const char *path,
-                             struct unix_sockaddr_context *ctx)
+                             struct unix_sockaddr_context *ctx,
+                             int disallow_chdir)
 {
        int size = strlen(path) + 1;
 
        ctx->orig_dir = NULL;
        if (size > sizeof(sa->sun_path)) {
-               const char *slash = find_last_dir_sep(path);
+               const char *slash;
                const char *dir;
                struct strbuf cwd = STRBUF_INIT;
 
+               if (disallow_chdir) {
+                       errno = ENAMETOOLONG;
+                       return -1;
+               }
+
+               slash = find_last_dir_sep(path);
                if (!slash) {
                        errno = ENAMETOOLONG;
                        return -1;
@@ -71,15 +72,18 @@ static int unix_sockaddr_init(struct sockaddr_un *sa, const char *path,
        return 0;
 }
 
-int unix_stream_connect(const char *path)
+int unix_stream_connect(const char *path, int disallow_chdir)
 {
-       int fd, saved_errno;
+       int fd = -1, saved_errno;
        struct sockaddr_un sa;
        struct unix_sockaddr_context ctx;
 
-       if (unix_sockaddr_init(&sa, path, &ctx) < 0)
+       if (unix_sockaddr_init(&sa, path, &ctx, disallow_chdir) < 0)
                return -1;
-       fd = unix_stream_socket();
+       fd = socket(AF_UNIX, SOCK_STREAM, 0);
+       if (fd < 0)
+               goto fail;
+
        if (connect(fd, (struct sockaddr *)&sa, sizeof(sa)) < 0)
                goto fail;
        unix_sockaddr_cleanup(&ctx);
@@ -87,28 +91,36 @@ int unix_stream_connect(const char *path)
 
 fail:
        saved_errno = errno;
+       if (fd != -1)
+               close(fd);
        unix_sockaddr_cleanup(&ctx);
-       close(fd);
        errno = saved_errno;
        return -1;
 }
 
-int unix_stream_listen(const char *path)
+int unix_stream_listen(const char *path,
+                      const struct unix_stream_listen_opts *opts)
 {
-       int fd, saved_errno;
+       int fd = -1, saved_errno;
+       int backlog;
        struct sockaddr_un sa;
        struct unix_sockaddr_context ctx;
 
        unlink(path);
 
-       if (unix_sockaddr_init(&sa, path, &ctx) < 0)
+       if (unix_sockaddr_init(&sa, path, &ctx, opts->disallow_chdir) < 0)
                return -1;
-       fd = unix_stream_socket();
+       fd = socket(AF_UNIX, SOCK_STREAM, 0);
+       if (fd < 0)
+               goto fail;
 
        if (bind(fd, (struct sockaddr *)&sa, sizeof(sa)) < 0)
                goto fail;
 
-       if (listen(fd, 5) < 0)
+       backlog = opts->listen_backlog_size;
+       if (backlog <= 0)
+               backlog = DEFAULT_UNIX_STREAM_LISTEN_BACKLOG;
+       if (listen(fd, backlog) < 0)
                goto fail;
 
        unix_sockaddr_cleanup(&ctx);
@@ -116,8 +128,9 @@ int unix_stream_listen(const char *path)
 
 fail:
        saved_errno = errno;
+       if (fd != -1)
+               close(fd);
        unix_sockaddr_cleanup(&ctx);
-       close(fd);
        errno = saved_errno;
        return -1;
 }