2 #include "unix-socket.h"
4 static int chdir_len(const char *orig
, int len
)
6 char *path
= xmemdupz(orig
, len
);
12 struct unix_sockaddr_context
{
16 static void unix_sockaddr_cleanup(struct unix_sockaddr_context
*ctx
)
21 * If we fail, we can't just return an error, since we have
22 * moved the cwd of the whole process, which could confuse calling
23 * code. We are better off to just die.
25 if (chdir(ctx
->orig_dir
) < 0)
26 die("unable to restore original working directory");
30 static int unix_sockaddr_init(struct sockaddr_un
*sa
, const char *path
,
31 struct unix_sockaddr_context
*ctx
)
33 int size
= strlen(path
) + 1;
36 if (size
> sizeof(sa
->sun_path
)) {
37 const char *slash
= find_last_dir_sep(path
);
39 struct strbuf cwd
= STRBUF_INIT
;
48 size
= strlen(path
) + 1;
49 if (size
> sizeof(sa
->sun_path
)) {
53 if (strbuf_getcwd(&cwd
))
55 ctx
->orig_dir
= strbuf_detach(&cwd
, NULL
);
56 if (chdir_len(dir
, slash
- dir
) < 0)
60 memset(sa
, 0, sizeof(*sa
));
61 sa
->sun_family
= AF_UNIX
;
62 memcpy(sa
->sun_path
, path
, size
);
66 int unix_stream_connect(const char *path
)
68 int fd
= -1, saved_errno
;
69 struct sockaddr_un sa
;
70 struct unix_sockaddr_context ctx
;
72 if (unix_sockaddr_init(&sa
, path
, &ctx
) < 0)
74 fd
= socket(AF_UNIX
, SOCK_STREAM
, 0);
78 if (connect(fd
, (struct sockaddr
*)&sa
, sizeof(sa
)) < 0)
80 unix_sockaddr_cleanup(&ctx
);
87 unix_sockaddr_cleanup(&ctx
);
92 int unix_stream_listen(const char *path
)
94 int fd
= -1, saved_errno
;
95 struct sockaddr_un sa
;
96 struct unix_sockaddr_context ctx
;
100 if (unix_sockaddr_init(&sa
, path
, &ctx
) < 0)
102 fd
= socket(AF_UNIX
, SOCK_STREAM
, 0);
106 if (bind(fd
, (struct sockaddr
*)&sa
, sizeof(sa
)) < 0)
109 if (listen(fd
, 5) < 0)
112 unix_sockaddr_cleanup(&ctx
);
119 unix_sockaddr_cleanup(&ctx
);