From 6849e5b4db50598867050596155c24a9ab51e69a Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Sat, 30 May 2026 11:51:39 +0800 Subject: [PATCH] opt: more reasonable method to set scoket flag --- src/ipc/ipc.h | 55 ++++++++++++++++++++++++++++++++------------------- src/mango.c | 9 ++++++++- 2 files changed, 43 insertions(+), 21 deletions(-) diff --git a/src/ipc/ipc.h b/src/ipc/ipc.h index 5bbffcc3..1694eb8b 100644 --- a/src/ipc/ipc.h +++ b/src/ipc/ipc.h @@ -217,7 +217,7 @@ static cJSON *build_monitor_tags_response(Monitor *m) { static void send_static_json(int fd, const char *json_str) { size_t len = strlen(json_str); - send(fd, json_str, len, MSG_NOSIGNAL); + send(fd, json_str, len, 0); } /* ---------- 一次性命令处理 ---------- */ @@ -413,7 +413,7 @@ static void handle_command(int client_fd, const char *cmd_raw) { char *msg = malloc(len + 2); if (msg) { snprintf(msg, len + 2, "%s\n", json_str); - send(client_fd, msg, len + 1, MSG_NOSIGNAL); + send(client_fd, msg, len + 1, 0); free(msg); } free(json_str); @@ -434,7 +434,7 @@ static void ipc_notify_json_to_fd(int fd, cJSON *json) { return; } snprintf(msg, len + 2, "%s\n", str); - if (send(fd, msg, len + 1, MSG_NOSIGNAL) < 0) { + if (send(fd, msg, len + 1, 0) < 0) { struct ipc_watch_client *wc, *tmp; wl_list_for_each_safe(wc, tmp, &watch_clients, link) { if (wc->fd == fd) { @@ -462,7 +462,7 @@ static int ipc_watch_data_handler(int fd, uint32_t mask, void *data) { } if (mask & WL_EVENT_READABLE) { char buf[64]; - ssize_t n = recv(fd, buf, sizeof(buf), MSG_DONTWAIT); + ssize_t n = recv(fd, buf, sizeof(buf), 0); if (n == 0 || (n < 0 && errno != EAGAIN && errno != EWOULDBLOCK)) { ipc_remove_watch_client(wc); } @@ -643,8 +643,7 @@ static int ipc_handle_client_data(int fd, uint32_t mask, void *data) { available = client->buf_cap - client->buf_len; } - ssize_t n = recv(fd, client->buf + client->buf_len, available - 1, - MSG_DONTWAIT); + ssize_t n = recv(fd, client->buf + client->buf_len, available - 1, 0); if (n <= 0) goto cleanup; @@ -683,8 +682,12 @@ static int ipc_handle_connection(int fd, uint32_t mask, void *data) { if (client_fd < 0) return 0; + // 设置 O_NONBLOCK int flags = fcntl(client_fd, F_GETFL, 0); fcntl(client_fd, F_SETFL, flags | O_NONBLOCK); + // 设置 FD_CLOEXEC + flags = fcntl(client_fd, F_GETFD, 0); + fcntl(client_fd, F_SETFD, flags | FD_CLOEXEC); struct ipc_client_state *client = calloc(1, sizeof(*client)); client->fd = client_fd; @@ -715,7 +718,7 @@ void ipc_notify_monitor(Monitor *m) { snprintf(json_str, len + 2, "%s\n", raw); free(raw); } - if (send(wc->fd, json_str, len + 1, MSG_NOSIGNAL) < 0) + if (send(wc->fd, json_str, len + 1, 0) < 0) ipc_remove_watch_client(wc); } } @@ -731,10 +734,8 @@ void ipc_notify_last_surface_ws_name(Monitor *m) { if (wc->type != IPC_WATCH_LAST_OPEN_SURFACE) continue; - /* 匹配具体 monitor 名称,或空名称表示默认 selmon */ bool match = false; if (wc->target.monitor.name[0] == '\0') { - /* 订阅的是 selmon */ if (m == selmon) match = true; } else { @@ -759,7 +760,7 @@ void ipc_notify_last_surface_ws_name(Monitor *m) { snprintf(json_str, len + 2, "%s\n", raw); free(raw); } - if (send(wc->fd, json_str, len + 1, MSG_NOSIGNAL) < 0) + if (send(wc->fd, json_str, len + 1, 0) < 0) ipc_remove_watch_client(wc); } free(json_str); @@ -790,7 +791,7 @@ void ipc_notify_focusing_client(void) { snprintf(json_str, len + 2, "%s\n", raw); free(raw); } - if (send(wc->fd, json_str, len + 1, MSG_NOSIGNAL) < 0) + if (send(wc->fd, json_str, len + 1, 0) < 0) ipc_remove_watch_client(wc); } } @@ -814,7 +815,7 @@ void ipc_notify_client(Client *c) { snprintf(json_str, len + 2, "%s\n", raw); free(raw); } - if (send(wc->fd, json_str, len + 1, MSG_NOSIGNAL) < 0) + if (send(wc->fd, json_str, len + 1, 0) < 0) ipc_remove_watch_client(wc); } } @@ -840,7 +841,7 @@ void ipc_notify_tags(Monitor *m) { snprintf(json_str, len + 2, "%s\n", raw); free(raw); } - if (send(wc->fd, json_str, len + 1, MSG_NOSIGNAL) < 0) + if (send(wc->fd, json_str, len + 1, 0) < 0) ipc_remove_watch_client(wc); } } @@ -870,7 +871,7 @@ void ipc_notify_all_monitors(void) { snprintf(json_str, len + 2, "%s\n", raw); free(raw); } - if (send(wc->fd, json_str, len + 1, MSG_NOSIGNAL) < 0) + if (send(wc->fd, json_str, len + 1, 0) < 0) ipc_remove_watch_client(wc); } } @@ -900,7 +901,7 @@ void ipc_notify_all_clients(void) { snprintf(json_str, len + 2, "%s\n", raw); free(raw); } - if (send(wc->fd, json_str, len + 1, MSG_NOSIGNAL) < 0) + if (send(wc->fd, json_str, len + 1, 0) < 0) ipc_remove_watch_client(wc); } } @@ -925,7 +926,7 @@ void ipc_notify_all_tags(void) { snprintf(json_str, len + 2, "%s\n", raw); free(raw); } - if (send(wc->fd, json_str, len + 1, MSG_NOSIGNAL) < 0) + if (send(wc->fd, json_str, len + 1, 0) < 0) ipc_remove_watch_client(wc); } } @@ -951,7 +952,7 @@ void ipc_notify_keymode(void) { snprintf(json_str, len + 2, "%s\n", raw); free(raw); } - if (send(wc->fd, json_str, len + 1, MSG_NOSIGNAL) < 0) + if (send(wc->fd, json_str, len + 1, 0) < 0) ipc_remove_watch_client(wc); } } @@ -977,7 +978,7 @@ void ipc_notify_kb_layout(void) { snprintf(json_str, len + 2, "%s\n", raw); free(raw); } - if (send(wc->fd, json_str, len + 1, MSG_NOSIGNAL) < 0) + if (send(wc->fd, json_str, len + 1, 0) < 0) ipc_remove_watch_client(wc); } } @@ -1000,11 +1001,25 @@ void ipc_init(struct wl_event_loop *event_loop) { snprintf(ipc_socket_path, sizeof(ipc_socket_path), "%s/mango-%d.sock", xdg_runtime, getpid()); - ipc_sock_fd = - socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0); + ipc_sock_fd = socket(AF_UNIX, SOCK_STREAM, 0); if (ipc_sock_fd < 0) return; + // 设置 FD_CLOEXEC + int flags = fcntl(ipc_sock_fd, F_GETFD, 0); + if (flags == -1 || fcntl(ipc_sock_fd, F_SETFD, flags | FD_CLOEXEC) == -1) { + wlr_log(WLR_ERROR, "failed to set FD_CLOEXEC on IPC socket"); + close(ipc_sock_fd); + return; + } + // 设置 O_NONBLOCK + flags = fcntl(ipc_sock_fd, F_GETFL, 0); + if (flags == -1 || fcntl(ipc_sock_fd, F_SETFL, flags | O_NONBLOCK) == -1) { + wlr_log(WLR_ERROR, "failed to set O_NONBLOCK on IPC socket"); + close(ipc_sock_fd); + return; + } + struct sockaddr_un addr = {.sun_family = AF_UNIX}; strncpy(addr.sun_path, ipc_socket_path, sizeof(addr.sun_path) - 1); diff --git a/src/mango.c b/src/mango.c index 4d08abd5..0b55dfa1 100644 --- a/src/mango.c +++ b/src/mango.c @@ -5805,13 +5805,20 @@ void setup(void) { } init_baked_points(); - int32_t drm_fd, i, sig[] = {SIGCHLD, SIGINT, SIGTERM, SIGPIPE}; + int32_t drm_fd, i; + int32_t sig[] = {SIGCHLD, SIGINT, + SIGTERM}; // 不设置SIGPIPE,因为ipc发送失败不应该影响主程序 struct sigaction sa = {.sa_flags = SA_RESTART, .sa_handler = handlesig}; sigemptyset(&sa.sa_mask); for (i = 0; i < LENGTH(sig); i++) sigaction(sig[i], &sa, NULL); + // 单独为 SIGPIPE 设置忽略 + struct sigaction sa_pipe = {.sa_flags = 0, .sa_handler = SIG_IGN}; + sigemptyset(&sa_pipe.sa_mask); + sigaction(SIGPIPE, &sa_pipe, NULL); + wlr_log_init(config.log_level, NULL); /* The Wayland display is managed by libwayland. It handles accepting