1 #include "git-compat-util.h"
3 #include "unix-socket.h"
5 #define DEFAULT_UNIX_STREAM_LISTEN_BACKLOG (5)
7 static int chdir_len(const char *orig
, int len
)
9 char *path
= xmemdupz(orig
, len
);
15 struct unix_sockaddr_context
{
19 static void unix_sockaddr_cleanup(struct unix_sockaddr_context
*ctx
)
24 * If we fail, we can't just return an error, since we have
25 * moved the cwd of the whole process, which could confuse calling
26 * code. We are better off to just die.
28 if (chdir(ctx
->orig_dir
) < 0)
29 die("unable to restore original working directory");
33 static int unix_sockaddr_init(struct sockaddr_un
*sa
, const char *path
,
34 struct unix_sockaddr_context
*ctx
,
37 int size
= strlen(path
) + 1;
40 if (size
> sizeof(sa
->sun_path
)) {
43 struct strbuf cwd
= STRBUF_INIT
;
50 slash
= find_last_dir_sep(path
);
58 size
= strlen(path
) + 1;
59 if (size
> sizeof(sa
->sun_path
)) {
63 if (strbuf_getcwd(&cwd
))
65 ctx
->orig_dir
= strbuf_detach(&cwd
, NULL
);
66 if (chdir_len(dir
, slash
- dir
) < 0)
70 memset(sa
, 0, sizeof(*sa
));
71 sa
->sun_family
= AF_UNIX
;
72 memcpy(sa
->sun_path
, path
, size
);
76 int unix_stream_connect(const char *path
, int disallow_chdir
)
78 int fd
= -1, saved_errno
;
79 struct sockaddr_un sa
;
80 struct unix_sockaddr_context ctx
;
82 if (unix_sockaddr_init(&sa
, path
, &ctx
, disallow_chdir
) < 0)
84 fd
= socket(AF_UNIX
, SOCK_STREAM
, 0);
88 if (connect(fd
, (struct sockaddr
*)&sa
, sizeof(sa
)) < 0)
90 unix_sockaddr_cleanup(&ctx
);
97 unix_sockaddr_cleanup(&ctx
);
102 int unix_stream_listen(const char *path
,
103 const struct unix_stream_listen_opts
*opts
)
105 int fd
= -1, saved_errno
;
107 struct sockaddr_un sa
;
108 struct unix_sockaddr_context ctx
;
112 if (unix_sockaddr_init(&sa
, path
, &ctx
, opts
->disallow_chdir
) < 0)
114 fd
= socket(AF_UNIX
, SOCK_STREAM
, 0);
118 if (bind(fd
, (struct sockaddr
*)&sa
, sizeof(sa
)) < 0)
121 backlog
= opts
->listen_backlog_size
;
123 backlog
= DEFAULT_UNIX_STREAM_LISTEN_BACKLOG
;
124 if (listen(fd
, backlog
) < 0)
127 unix_sockaddr_cleanup(&ctx
);
134 unix_sockaddr_cleanup(&ctx
);