comparison seobeo/s_network.c @ 231:09a96dcb2b4c hg-web

[merge] Join existing hg-web branch head
author MrJuneJune <me@mrjunejune.com>
date Sun, 02 Aug 2026 16:50:48 -0700
parents 0e7b9464248d
children b8aa08503378
comparison
equal deleted inserted replaced
217:7ef4c9d2a72d 231:09a96dcb2b4c
1 #include "seobeo/seobeo.h" 1 #include "seobeo/seobeo.h"
2 2
3 static pthread_once_t g_sigpipe_once = PTHREAD_ONCE_INIT;
4
5 static void Seobeo_Process_Ignore_Sigpipe(void)
6 {
7 signal(SIGPIPE, SIG_IGN);
8 }
9
10 static void Seobeo_Socket_Disable_Sigpipe(int socket_fd)
11 {
12 #ifdef SO_NOSIGPIPE
13 int enabled = 1;
14 setsockopt(socket_fd, SOL_SOCKET, SO_NOSIGPIPE, &enabled, sizeof(enabled));
15 #else
16 (void)socket_fd;
17 #endif
18 }
19
20 static ssize_t Seobeo_Socket_Write(
21 int socket_fd,
22 const void *buffer,
23 size_t length)
24 {
25 #ifdef MSG_NOSIGNAL
26 return send(socket_fd, buffer, length, MSG_NOSIGNAL);
27 #else
28 return send(socket_fd, buffer, length, 0);
29 #endif
30 }
3 31
4 Seobeo_Handle *Seobeo_Stream_Handle_Server_Create(const char *host, const char* port) 32 Seobeo_Handle *Seobeo_Stream_Handle_Server_Create(const char *host, const char* port)
5 { 33 {
34 pthread_once(&g_sigpipe_once, Seobeo_Process_Ignore_Sigpipe);
6 Seobeo_Handle *p_handle; 35 Seobeo_Handle *p_handle;
7 struct addrinfo hints, *server_infos, *free_server_info; 36 struct addrinfo hints, *server_infos, *free_server_info;
8 int32 socket_fd, yes = 1; // Need this for setsockopt 37 int32 socket_fd, yes = 1; // Need this for setsockopt
9 38
10 memset(&hints, 0, sizeof hints); 39 memset(&hints, 0, sizeof hints);
24 ) 53 )
25 { 54 {
26 if((socket_fd = socket(free_server_info->ai_family, 55 if((socket_fd = socket(free_server_info->ai_family,
27 free_server_info->ai_socktype, free_server_info->ai_protocol)) == -1) 56 free_server_info->ai_socktype, free_server_info->ai_protocol)) == -1)
28 { perror("socket"); continue; } 57 { perror("socket"); continue; }
58 Seobeo_Socket_Disable_Sigpipe(socket_fd);
29 59
30 if (setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) == -1) 60 if (setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) == -1)
31 { perror("setsockopt SO_REUSEADDR"); continue; } 61 { perror("setsockopt SO_REUSEADDR"); continue; }
32 62
33 #ifdef SO_REUSEPORT 63 #ifdef SO_REUSEPORT
79 } 109 }
80 110
81 111
82 Seobeo_Handle *Seobeo_Stream_Handle_Client_Create(const char *host, const char* port, boolean use_tls) 112 Seobeo_Handle *Seobeo_Stream_Handle_Client_Create(const char *host, const char* port, boolean use_tls)
83 { 113 {
114 pthread_once(&g_sigpipe_once, Seobeo_Process_Ignore_Sigpipe);
84 Seobeo_Handle *p_handle; 115 Seobeo_Handle *p_handle;
85 p_handle = malloc(sizeof(*p_handle)); 116 p_handle = malloc(sizeof(*p_handle));
86 117
87 struct addrinfo hints, *server_infos; 118 struct addrinfo hints, *server_infos;
88 int32 socket_fd; // Need this for setsockopt 119 int32 socket_fd; // Need this for setsockopt
96 127
97 128
98 if((socket_fd = socket(server_infos->ai_family, 129 if((socket_fd = socket(server_infos->ai_family,
99 server_infos->ai_socktype, server_infos->ai_protocol)) == -1) 130 server_infos->ai_socktype, server_infos->ai_protocol)) == -1)
100 { perror("socket"); return NULL; } 131 { perror("socket"); return NULL; }
132 Seobeo_Socket_Disable_Sigpipe(socket_fd);
101 133
102 if (connect(socket_fd, server_infos->ai_addr, server_infos->ai_addrlen) != 0) 134 if (connect(socket_fd, server_infos->ai_addr, server_infos->ai_addrlen) != 0)
103 { perror("connect"); return NULL; } 135 { perror("connect"); return NULL; }
104 freeaddrinfo(server_infos); 136 freeaddrinfo(server_infos);
105 137
152 inet_ntop( 184 inet_ntop(
153 addr.ss_family, 185 addr.ss_family,
154 Seobeo_Get_IP4_Or_IP6((struct sockaddr *)&addr), 186 Seobeo_Get_IP4_Or_IP6((struct sockaddr *)&addr),
155 client_inet_addr, sizeof client_inet_addr); 187 client_inet_addr, sizeof client_inet_addr);
156 if (client_fd == -1) return NULL; 188 if (client_fd == -1) return NULL;
189 Seobeo_Socket_Disable_Sigpipe(client_fd);
157 190
158 // Set non blocking... 191 // Set non blocking...
159 int flags = fcntl(client_fd, F_GETFL, 0); 192 int flags = fcntl(client_fd, F_GETFL, 0);
160 if (flags == -1) return NULL; 193 if (flags == -1) return NULL;
161 fcntl(client_fd, F_SETFL, flags | O_NONBLOCK); 194 fcntl(client_fd, F_SETFL, flags | O_NONBLOCK);
234 if (n == 0) return 0; // would block 267 if (n == 0) return 0; // would block
235 sent += (uint32)n; 268 sent += (uint32)n;
236 }else 269 }else
237 { 270 {
238 Seobeo_Log(SEOBEO_DEBUG, "Flushing socket: %d\n", p_handle->socket); 271 Seobeo_Log(SEOBEO_DEBUG, "Flushing socket: %d\n", p_handle->socket);
239 ssize_t n = write( 272 ssize_t n = Seobeo_Socket_Write(
240 p_handle->socket, 273 p_handle->socket,
241 p_handle->write_buffer + sent, 274 p_handle->write_buffer + sent,
242 total - sent 275 total - sent
243 ); 276 );
244 if (n < 0) { 277 if (n < 0) {
266 if (data_size > p_handle->write_buffer_capacity) 299 if (data_size > p_handle->write_buffer_capacity)
267 { 300 {
268 uint32 offset = 0; 301 uint32 offset = 0;
269 while (offset < data_size) 302 while (offset < data_size)
270 { 303 {
271 ssize_t n = write(p_handle->socket, 304 ssize_t n;
272 data + offset, 305 if (p_handle->ssl)
273 data_size - offset); 306 {
307 n = Seobeo_SSL_Write(p_handle, data + offset, data_size - offset);
308 }
309 else
310 {
311 n = Seobeo_Socket_Write(
312 p_handle->socket,
313 data + offset,
314 data_size - offset);
315 }
316
274 if (n==0) 317 if (n==0)
275 { 318 {
276 // DEBUG 319 // DEBUG
277 Seobeo_Log(SEOBEO_DEBUG, "Write offset: %d\n", offset); 320 Seobeo_Log(SEOBEO_DEBUG, "Write offset: %d\n", offset);
278 break; 321 break;