| ... | @@ -7056,3 +7056,48 @@ pub fn timerfd_gettime(fd: i32) TimerFdGetError!linux.itimerspec { | ... | @@ -7056,3 +7056,48 @@ pub fn timerfd_gettime(fd: i32) TimerFdGetError!linux.itimerspec { |
| 7056 | else => |err| return unexpectedErrno(err), | 7056 | else => |err| return unexpectedErrno(err), |
| 7057 | }; | 7057 | }; |
| 7058 | } | 7058 | } |
| | 7059 | |
| | 7060 | /// Whether or not the current target support SIGPIPE |
| | 7061 | pub const have_sigpipe_support = switch (builtin.os.tag) { |
| | 7062 | .linux, |
| | 7063 | .macos, |
| | 7064 | .netbsd, |
| | 7065 | .solaris, |
| | 7066 | .freebsd, |
| | 7067 | .openbsd, |
| | 7068 | => true, |
| | 7069 | else => false, |
| | 7070 | }; |
| | 7071 | |
| | 7072 | pub const keep_sigpipe: bool = if (@hasDecl(root, "keep_sigpipe")) |
| | 7073 | root.keep_sigpipe |
| | 7074 | else |
| | 7075 | false; |
| | 7076 | |
| | 7077 | /// This function will tell the kernel to ignore SIGPIPE rather than terminate |
| | 7078 | /// the process. This function is automatically called in `start.zig` before |
| | 7079 | /// `main`. This behavior can be disabled by adding this to your root module: |
| | 7080 | /// |
| | 7081 | /// pub const keep_sigpipe = true; |
| | 7082 | /// |
| | 7083 | /// SIGPIPE is triggered when a process attempts to write to a broken pipe. |
| | 7084 | /// By default, SIGPIPE will terminate the process without giving the program |
| | 7085 | /// an opportunity to handle the situation. Unlike a segfault, it doesn't |
| | 7086 | /// trigger the panic handler so all the developer sees is that the program |
| | 7087 | /// terminated with no indication as to why. |
| | 7088 | /// |
| | 7089 | /// By telling the kernel to instead ignore SIGPIPE, writes to broken pipes |
| | 7090 | /// will return the EPIPE error (error.BrokenPipe) and the program can handle |
| | 7091 | /// it like any other error. |
| | 7092 | pub fn maybeIgnoreSigpipe() void { |
| | 7093 | if (have_sigpipe_support and !keep_sigpipe) { |
| | 7094 | const act = Sigaction{ |
| | 7095 | .handler = .{ .sigaction = SIG.IGN }, |
| | 7096 | .mask = empty_sigset, |
| | 7097 | .flags = SA.SIGINFO, |
| | 7098 | }; |
| | 7099 | sigaction(SIG.PIPE, &act, null) catch |err| std.debug.panic("ignore SIGPIPE failed with '{s}'" ++ |
| | 7100 | ", add `pub const keep_sigpipe = true;` to your root module" ++ |
| | 7101 | " or adjust have_sigpipe_support in std/os.zig", .{@errorName(err)}); |
| | 7102 | } |
| | 7103 | } |