commit 6db1ccc
wf
·
2026-03-28 12:59:48 +0000 UTC
parent 97031e7
IPC bug(fix)
4 files changed,
+80,
-50
M
README
+1,
-2
1@@ -13,8 +13,7 @@ dependencies
2 todo
3 ----
4
5- - fix IPC socket deadloop
6- - configuration
7+ - fix client segfault
8 - document IPC interface
9
10 [1]: https://git.sr.ht/~shrub900/neuswc
M
client.c
+9,
-9
1@@ -14,18 +14,18 @@ ipc_msg(char **cmd) {
2 char msg[256];
3
4 memset(&addr, 0, sizeof(struct sockaddr_un));
5- addr.sun_family = AF_LOCAL;
6+ addr.sun_family = AF_UNIX;
7 strncpy(addr.sun_path, SOCK_PATH, sizeof(addr.sun_path) - 1);
8
9- csock = socket(AF_LOCAL, SOCK_STREAM, 0);
10- if (csock == -1) {
11- perror("couldn't open client socket");
12+ cfd = socket(AF_UNIX, SOCK_STREAM, 0);
13+ if (cfd == -1) {
14+ perror("couldn't open IPC socket");
15 return;
16 }
17
18- if (connect(csock, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) == -1) {
19+ if (connect(cfd, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) == -1) {
20 perror("couldn't connect to IPC socket");
21- close(csock);
22+ close(cfd);
23 return;
24 }
25
26@@ -35,11 +35,11 @@ ipc_msg(char **cmd) {
27 strcat(msg, cmd[i]);
28 }
29
30- if (send(csock, msg, strlen(msg), 0) == -1) {
31+ if (send(cfd, msg, strlen(msg), 0) == -1) {
32 perror("couldn't send IPC message");
33 }
34
35- close(csock);
36+ close(cfd);
37 }
38
39 int
40@@ -52,7 +52,7 @@ main(int argc, char **argv) {
41 int u_argc = argc - 2;
42 char **u_argv = argv + 2;
43
44- for (int i = 0; i < (int)(sizeof commands / sizeof commands[0]); i++) {
45+ for (int i = 0; i < (sizeof commands / sizeof commands[0]); i++) {
46 if (strcmp(commands[i].name, argv[1]) == 0) {
47 if (commands[i].argc != u_argc) {
48 fprintf(stderr, "wrong number of arguments for %s (need %d)\n", commands[i].name, commands[i].argc);
M
howl.c
+68,
-36
1@@ -4,6 +4,7 @@
2 #include <errno.h>
3 #include <signal.h>
4 #include <unistd.h>
5+#include <fcntl.h>
6 #include <getopt.h>
7 #include <sys/socket.h>
8 #include <sys/un.h>
9@@ -42,67 +43,97 @@ static struct swc_screen_handler scr_handler = {
10
11 static int
12 handler(int fd, uint32_t mask, void *data) {
13- UNUSED(mask);
14 UNUSED(data);
15
16- _inf("handling :333333333333333333");
17-
18- char buf[MAXSIZE];
19- ssize_t res = read(fd, buf, sizeof(buf) - 1);
20+ if (mask & WL_EVENT_HANGUP) {
21+ /* conn. closed */
22+ _wrn("IPC socket connection closed prematurely: %s", strerror(errno));
23+ return 0;
24+ }
25
26- if (res < 0) {
27- _wrn("couldn't read from IPC socket: %s", strerror(errno));
28- return 1;
29+ if (mask & WL_EVENT_ERROR) {
30+ /* conn. error */
31+ _wrn("IPC socket connection error: %s", strerror(errno));
32+ return 0;
33 }
34- buf[res] = '\0';
35
36- _inf("read bullshit from socket: %s", buf);
37+ if (mask & WL_EVENT_READABLE) {
38+ if (fd == sfd) {
39+ int afd = accept(sfd, NULL, NULL);
40+ if (afd == -1) {
41+ _wrn("couldn't accept incoming connection on IPC socket: %s", strerror(errno));
42+ return 0;
43+ }
44
45- char *tok;
46- int argc = 0;
47- char **argv;
48+ char buf[MAXSIZE];
49+ ssize_t n;
50
51- tok = strtok(buf, " ");
52- argv[argc] = tok;
53- argc++;
54+ if ((n = read(afd, buf, sizeof(buf) - 1)) < 0) {
55+ /* read error */
56+ _wrn("couldn't read from IPC socket: %s", strerror(errno));
57+ return 0;
58+ }
59
60- while (tok != NULL) {
61- argv[argc] = tok;
62- argc++;
63- tok = strtok(NULL, " ");
64- }
65+ if (n == 0) {
66+ /* EOF */
67+ _wrn("unexpected EOF on IPC socket: %s", strerror(errno));
68+ return 0;
69+ }
70
71- for (int i = 0; i < (sizeof commands / sizeof commands[0]); i++) {
72- if (strcmp(commands[i].name, argv[0]) == 0) {
73- argv++;
74- commands[i].fn(argv);
75- if (commands[i].config) reload_config();
76+ if (n > 0) {
77+ int argc = 0;
78+ char *argv[64], *tok = NULL;
79+
80+ buf[n] = '\0';
81+ while (buf[n-1] == '\r' || buf[n-1] == '\n' || buf[n-1] == ' ')
82+ buf[n-1] = '\0';
83+
84+ tok = strtok(buf, " ");
85+ while (tok != NULL && argc < 63) {
86+ argv[argc++] = tok;
87+ tok = strtok(NULL, " ");
88+ }
89+ argv[argc] = NULL;
90+
91+ if (argc == 0) return 0;
92+
93+ for (int i = 0; i < (sizeof commands / sizeof commands[0]); i++) {
94+ if (strcmp(commands[i].name, argv[0]) == 0) {
95+ commands[i].fn(argv + 1);
96+ if (commands[i].config) reload_config();
97+ return 0;
98+ }
99+ }
100+ _wrn("no such command %s", argv[0]);
101+ }
102+ close(afd);
103+ return 0;
104 }
105 }
106
107- return 0;
108+ return 0; /* NOTREACHED */
109 }
110
111 static void
112 setup_ipc(void) {
113 struct sockaddr_un addr;
114
115- ssock = socket(AF_LOCAL, SOCK_STREAM, 0);
116- if (ssock == -1)
117+ sfd = socket(AF_UNIX, SOCK_STREAM, 0);
118+ if (sfd == -1)
119 _err(1, "couldn't open IPC socket: %s", strerror(errno));
120
121 memset(&addr, 0, sizeof(addr));
122- addr.sun_family = AF_LOCAL;
123+ addr.sun_family = AF_UNIX;
124 strncpy(addr.sun_path, SOCK_PATH, sizeof(addr.sun_path) - 1);
125
126 unlink(SOCK_PATH);
127- if (bind(ssock, (struct sockaddr *)&addr, sizeof(addr)) == -1)
128+ if (bind(sfd, (struct sockaddr *)&addr, sizeof(addr)) == -1)
129 _err(1, "couldn't bind IPC socket: %s", strerror(errno));
130
131- if (listen(ssock, 5) == -1)
132+ if (listen(sfd, 5) == -1)
133 _err(1, "couldn't listen on IPC socket: %s", strerror(errno));
134
135- wl_event_loop_add_fd(wm.loop, ssock, WL_EVENT_READABLE, handler, NULL);
136+ wl_event_loop_add_fd(wm.loop, sfd, WL_EVENT_READABLE | WL_EVENT_HANGUP | WL_EVENT_ERROR, handler, NULL);
137
138 _inf("set up IPC socket");
139 }
140@@ -113,8 +144,6 @@ sig_handler(int s) {
141 if (wm.dpy) {
142 swc_finalize();
143 wl_display_terminate(wm.dpy);
144- close(ssock);
145- unlink(SOCK_PATH);
146 }
147 }
148
149@@ -199,13 +228,16 @@ setup(void) {
150 signal(SIGINT, sig_handler);
151 signal(SIGTERM, sig_handler);
152 signal(SIGQUIT, sig_handler);
153+
154+ free(conf_path);
155 }
156
157 static void
158 cleanup(void) {
159 swc_finalize();
160 wl_display_destroy(wm.dpy);
161- close(ssock);
162+ close(sfd);
163+ unlink(SOCK_PATH);
164 }
165
166 static void
+2,
-3
1@@ -7,9 +7,8 @@
2 #define SOCK_PATH "/tmp/.howl.sock"
3 #define MAXSIZE 256
4
5-/* IPC socket */
6-static int ssock;
7-static int csock;
8+static int sfd;
9+static int cfd;
10
11 extern void _inf(const char *, ...);
12 extern void _wrn(const char *, ...);