2.64 xs_unix_socket.h
 1/* copyright (c) 2022 - 2024 grunfink et al. / MIT license */
 2
 3#ifndef _XS_UNIX_SOCKET_H
 4
 5#define _XS_UNIX_SOCKET_H
 6
 7 int xs_unix_socket_server(const char *path, const char *grp);
 8 int xs_unix_socket_connect(const char *path);
 9
10
11#ifdef XS_IMPLEMENTATION
12
13#include <sys/stat.h>
14#include <sys/un.h>
15#include <grp.h>
16
17int xs_unix_socket_server(const char *path, const char *grp)
18/* opens a unix-type server socket */
19{
20    int rs = -1;
21
22    if ((rs = socket(AF_UNIX, SOCK_STREAM, 0)) != -1) {
23        struct sockaddr_un su = {0};
24        mode_t mode = 0666;
25
26        su.sun_family = AF_UNIX;
27        strncpy(su.sun_path, path, sizeof(su.sun_path));
28
29        unlink(path);
30
31        if (bind(rs, (struct sockaddr *)&su, sizeof(su)) == -1) {
32            close(rs);
33            return -1;
34        }
35
36        listen(rs, SOMAXCONN);
37
38        if (grp != NULL) {
39            struct group *g = NULL;
40
41            /* if there is a group name, get its gid_t */
42            g = getgrnam(grp);
43
44            if (g != NULL && chown(path, -1, g->gr_gid) != -1)
45                mode = 0660;
46        }
47
48        chmod(path, mode);
49    }
50
51    return rs;
52}
53
54
55int xs_unix_socket_connect(const char *path)
56/* connects to a unix-type socket */
57{
58    int d = -1;
59
60    if ((d = socket(AF_UNIX, SOCK_STREAM, 0)) != -1) {
61        struct sockaddr_un su = {0};
62
63        su.sun_family = AF_UNIX;
64        strncpy(su.sun_path, path, sizeof(su.sun_path));
65
66        if (connect(d, (struct sockaddr *)&su, sizeof(su)) == -1) {
67            close(d);
68            d = -1;
69        }
70    }
71
72    return d;
73}
74
75
76#endif /* XS_IMPLEMENTATION */
77
78#endif /* _XS_UNIX_SOCKET_H */