1 #define DISABLE_SIGN_COMPARE_WARNINGS
3 #include "git-compat-util.h"
5 #include "unix-socket.h"
7 #define DEFAULT_UNIX_STREAM_LISTEN_BACKLOG (5)
9 static int chdir_len(const char *orig
, int len
)
11 char *path
= xmemdupz(orig
, len
);
17 struct unix_sockaddr_context
{
21 static void unix_sockaddr_cleanup(struct unix_sockaddr_context
*ctx
)
26 * If we fail, we can't just return an error, since we have
27 * moved the cwd of the whole process, which could confuse calling
28 * code. We are better off to just die.
30 if (chdir(ctx
->orig_dir
) < 0)
31 die("unable to restore original working directory");
35 static int unix_sockaddr_init(struct sockaddr_un
*sa
, const char *path
,
36 struct unix_sockaddr_context
*ctx
,
39 int size
= strlen(path
) + 1;
42 if (size
> sizeof(sa
->sun_path
)) {
45 struct strbuf cwd
= STRBUF_INIT
;
52 slash
= find_last_dir_sep(path
);
60 size
= strlen(path
) + 1;
61 if (size
> sizeof(sa
->sun_path
)) {
65 if (strbuf_getcwd(&cwd
))
67 ctx
->orig_dir
= strbuf_detach(&cwd
, NULL
);
68 if (chdir_len(dir
, slash
- dir
) < 0) {
69 FREE_AND_NULL(ctx
->orig_dir
);
74 memset(sa
, 0, sizeof(*sa
));
75 sa
->sun_family
= AF_UNIX
;
76 memcpy(sa
->sun_path
, path
, size
);
80 int unix_stream_connect(const char *path
, int disallow_chdir
)
82 int fd
= -1, saved_errno
;
83 struct sockaddr_un sa
;
84 struct unix_sockaddr_context ctx
;
86 if (unix_sockaddr_init(&sa
, path
, &ctx
, disallow_chdir
) < 0)
88 fd
= socket(AF_UNIX
, SOCK_STREAM
, 0);
92 if (connect(fd
, (struct sockaddr
*)&sa
, sizeof(sa
)) < 0)
94 unix_sockaddr_cleanup(&ctx
);
101 unix_sockaddr_cleanup(&ctx
);
106 int unix_stream_listen(const char *path
,
107 const struct unix_stream_listen_opts
*opts
)
109 int fd
= -1, saved_errno
;
111 struct sockaddr_un sa
;
112 struct unix_sockaddr_context ctx
;
116 if (unix_sockaddr_init(&sa
, path
, &ctx
, opts
->disallow_chdir
) < 0)
118 fd
= socket(AF_UNIX
, SOCK_STREAM
, 0);
122 if (bind(fd
, (struct sockaddr
*)&sa
, sizeof(sa
)) < 0)
125 backlog
= opts
->listen_backlog_size
;
127 backlog
= DEFAULT_UNIX_STREAM_LISTEN_BACKLOG
;
128 if (listen(fd
, backlog
) < 0)
131 unix_sockaddr_cleanup(&ctx
);
138 unix_sockaddr_cleanup(&ctx
);