MXVK Vulkan Framework 0.24.0
C++20 Vulkan rendering framework for practical 2D and 3D application development with SDL3.
Loading...
Searching...
No Matches
mxsocket.h File Reference
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>

Go to the source code of this file.

Classes

struct  MXSocket
 Cross-platform socket state used by the C API. More...
struct  MXSocketAddress

Macros

#define mx_close_socket(s)
#define MX_LEN(x)
#define mx_set_err(e)
#define NULL_SOCKET   -1
#define SOCK_EAGAIN   EAGAIN
#define SOCK_EBADF   EBADF
#define SOCK_ECONNABORTED   ECONNABORTED
#define SOCK_ECONNRESET   ECONNRESET
#define SOCK_EINTR   EINTR
#define SOCK_EINVAL   EINVAL
#define SOCK_ENOTSOCK   ENOTSOCK
#define SOCK_ERRNO   errno
#define SOCK_ESHUTDOWN   ESHUTDOWN
#define SOCK_EWOULDBLOCK   EWOULDBLOCK

Typedefs

typedef int mx_socket_fd

Functions

bool mx_socket_accept (const MXSocket *input, MXSocket *output)
 Accept an incoming connection.
bool mx_socket_bind (MXSocket *s, const char *port)
 Bind an Internet socket to a local port.
void mx_socket_close (MXSocket *s)
 Close a socket if it is open.
bool mx_socket_connect (MXSocket *s, const char *host, const char *port, int type)
 Connect an Internet socket to a remote host.
void mx_socket_ignore_pipe_signal ()
 Ignore SIGPIPE on platforms that require it.
bool mx_socket_init (MXSocket *s)
 Initialize a socket structure with default values.
bool mx_socket_ipv6_bind (MXSocket *s, const char *port)
 Bind an IPv6 Internet socket to a local port.
bool mx_socket_ipv6_connect (MXSocket *s, const char *host, const char *port, int type)
 Connect an IPv6 Internet socket to a remote host.
bool mx_socket_ipv6_listen (MXSocket *s, const char *port, int backlog, int type)
 Create and bind an IPv6 Internet socket for listening.
ssize_t mx_socket_ipv6_recvfrom (MXSocket *sock, void *buf, size_t bytes)
 Receive a datagram using an IPv6 Internet socket.
ssize_t mx_socket_ipv6_sendto (MXSocket *sock, const void *buf, size_t bytes)
 Send a datagram using an IPv6 Internet socket.
bool mx_socket_is_open (const MXSocket *s)
 Check whether the socket is open.
bool mx_socket_listen (MXSocket *s, const char *port, int backlog, int type)
 Create and bind an Internet socket for listening.
ssize_t mx_socket_read (MXSocket *s, void *data, size_t len, int flags)
 Read data from a socket.
ssize_t mx_socket_read_all (MXSocket *sock, void *buf, size_t bytes)
 Read the requested number of bytes from a socket.
bool mx_socket_readline (MXSocket *s, char **buffer, size_t *len)
 Read a line of text from a socket.
ssize_t mx_socket_recvfrom (MXSocket *sock, void *buf, size_t bytes)
 Receive a datagram using an Internet socket.
ssize_t mx_socket_recvfrom_address (MXSocket *sock, void *buf, size_t bytes, MXSocketAddress *address)
ssize_t mx_socket_send (MXSocket *s, const void *data, size_t len, int flags)
 Write data to a socket.
ssize_t mx_socket_sendto (MXSocket *sock, const void *buf, size_t bytes)
 Send a datagram using an Internet socket.
ssize_t mx_socket_sendto_address (MXSocket *sock, const void *buf, size_t bytes, const MXSocketAddress *address)
bool mx_socket_set_blocking (MXSocket *s, bool state)
 Toggle blocking mode for a socket.
bool mx_socket_unix_bind (MXSocket *s, const char *path)
 Bind a UNIX-domain socket to a local path.
bool mx_socket_unix_connect (MXSocket *s, const char *path, int type)
 Connect a UNIX-domain socket to a local path.
bool mx_socket_unix_listen (MXSocket *s, const char *path, int backlog, int type)
 Create and bind a UNIX-domain socket for listening.
ssize_t mx_socket_unix_recvfrom (MXSocket *sock, void *buf, size_t bytes)
 Receive a datagram using a UNIX-domain socket.
ssize_t mx_socket_unix_sendto (MXSocket *sock, const void *buf, size_t bytes)
 Send a datagram using a UNIX-domain socket.
bool mx_socket_valid (const MXSocket *s)
 Check whether the socket handle is valid.
ssize_t mx_socket_write_all (MXSocket *sock, const void *buf, size_t bytes)
 Write the requested number of bytes to a socket.

Macro Definition Documentation

◆ mx_close_socket

#define mx_close_socket ( s)
Value:
close(s)

Definition at line 49 of file mxsocket.h.

◆ MX_LEN

#define MX_LEN ( x)
Value:
(size_t)(x)

Definition at line 61 of file mxsocket.h.

◆ mx_set_err

#define mx_set_err ( e)
Value:
(errno = (e))

Definition at line 50 of file mxsocket.h.

◆ NULL_SOCKET

#define NULL_SOCKET   -1

Definition at line 62 of file mxsocket.h.

◆ SOCK_EAGAIN

#define SOCK_EAGAIN   EAGAIN

Definition at line 53 of file mxsocket.h.

◆ SOCK_EBADF

#define SOCK_EBADF   EBADF

Definition at line 57 of file mxsocket.h.

◆ SOCK_ECONNABORTED

#define SOCK_ECONNABORTED   ECONNABORTED

Definition at line 55 of file mxsocket.h.

◆ SOCK_ECONNRESET

#define SOCK_ECONNRESET   ECONNRESET

Definition at line 60 of file mxsocket.h.

◆ SOCK_EINTR

#define SOCK_EINTR   EINTR

Definition at line 52 of file mxsocket.h.

◆ SOCK_EINVAL

#define SOCK_EINVAL   EINVAL

Definition at line 56 of file mxsocket.h.

◆ SOCK_ENOTSOCK

#define SOCK_ENOTSOCK   ENOTSOCK

Definition at line 58 of file mxsocket.h.

◆ SOCK_ERRNO

#define SOCK_ERRNO   errno

Definition at line 51 of file mxsocket.h.

◆ SOCK_ESHUTDOWN

#define SOCK_ESHUTDOWN   ESHUTDOWN

Definition at line 59 of file mxsocket.h.

◆ SOCK_EWOULDBLOCK

#define SOCK_EWOULDBLOCK   EWOULDBLOCK

Definition at line 54 of file mxsocket.h.

Typedef Documentation

◆ mx_socket_fd

typedef int mx_socket_fd

Definition at line 48 of file mxsocket.h.

Function Documentation

◆ mx_socket_accept()

bool mx_socket_accept ( const MXSocket * input,
MXSocket * output )
nodiscard

Accept an incoming connection.

Parameters
inputListening socket.
outputNewly accepted socket state.
Returns
True on success.

Definition at line 278 of file mxsocket.c.

278 {
279 if (input == nullptr || output == nullptr)
280 return false;
281
282 if (!mx_socket_valid(input))
283 return false;
284
285 mx_socket_fd newfd = accept(input->sockfd, 0, 0);
286#ifdef _WIN32
287 if (newfd == INVALID_SOCKET)
288 return false;
289 u_long mode = input->blocking ? 0 : 1;
290 if (ioctlsocket(newfd, FIONBIO, &mode) != 0) {
291 mx_close_socket(newfd);
292 return false;
293 }
294#else
295 if (newfd == NULL_SOCKET)
296 return false;
297
298 int flags = fcntl(newfd, F_GETFL);
299 if (flags == -1) {
300 close(newfd);
301 return false;
302 }
303 if (input->blocking)
304 flags &= ~O_NONBLOCK;
305 else
306 flags |= O_NONBLOCK;
307 if (fcntl(newfd, F_SETFL, flags) == -1) {
308 mx_close_socket(newfd);
309 return false;
310 }
311#endif
312 if (mx_socket_valid(output))
313 mx_socket_close(output);
314 output->sockfd = newfd;
315 output->addrlen = input->addrlen;
316 output->blocking = input->blocking;
317 output->sun = input->sun;
318 output->inet = input->inet;
319 output->inet6 = input->inet6;
320 return true;
321}
bool mx_socket_valid(const MXSocket *sock)
Check whether the socket handle is valid.
Definition mxsocket.c:416
void mx_socket_close(MXSocket *sock)
Close a socket if it is open.
Definition mxsocket.c:323
int mx_socket_fd
Definition mxsocket.h:48
#define mx_close_socket(s)
Definition mxsocket.h:49
#define NULL_SOCKET
Definition mxsocket.h:62
struct sockaddr_in6 inet6
IPv6 address storage.
Definition mxsocket.h:74
bool blocking
True when the socket is in blocking mode.
Definition mxsocket.h:71
struct sockaddr_in inet
IPv4 address storage.
Definition mxsocket.h:73
struct sockaddr_un sun
UNIX-domain address storage.
Definition mxsocket.h:72
mx_socket_fd sockfd
Underlying socket handle.
Definition mxsocket.h:69
socklen_t addrlen
Length of the active address structure.
Definition mxsocket.h:70

◆ mx_socket_bind()

bool mx_socket_bind ( MXSocket * s,
const char * port )
nodiscard

Bind an Internet socket to a local port.

Parameters
sSocket state to configure.
portService or port name.
Returns
True on success.

Definition at line 370 of file mxsocket.c.

370 {
371 return mx_socket_inet_bind(sock, port, AF_INET);
372}

◆ mx_socket_close()

void mx_socket_close ( MXSocket * s)

Close a socket if it is open.

Parameters
sSocket state to close.

Definition at line 323 of file mxsocket.c.

323 {
324 if (sock == nullptr)
325 return;
326 if (mx_socket_valid(sock))
327 mx_close_socket(sock->sockfd);
328 sock->sockfd = NULL_SOCKET;
329}

◆ mx_socket_connect()

bool mx_socket_connect ( MXSocket * s,
const char * host,
const char * port,
int type )
nodiscard

Connect an Internet socket to a remote host.

Parameters
sSocket state to configure.
hostRemote host name or address.
portRemote service or port name.
typeSocket kind, typically SOCK_STREAM or SOCK_DGRAM.
Returns
True on success.

Definition at line 362 of file mxsocket.c.

362 {
363 return mx_socket_inet_connect(sock, host, port, type, AF_INET);
364}

◆ mx_socket_ignore_pipe_signal()

void mx_socket_ignore_pipe_signal ( )

Ignore SIGPIPE on platforms that require it.

Definition at line 577 of file mxsocket.c.

577 {
578#ifndef _WIN32
579 signal(SIGPIPE, SIG_IGN);
580#endif
581}

◆ mx_socket_init()

bool mx_socket_init ( MXSocket * s)
nodiscard

Initialize a socket structure with default values.

Parameters
sSocket state to initialize.
Returns
True on success.

Definition at line 407 of file mxsocket.c.

407 {
408 if (sock == nullptr)
409 return false;
410 memset(sock, 0, sizeof(MXSocket));
411 sock->sockfd = NULL_SOCKET;
412 sock->blocking = true;
413 return true;
414}
Cross-platform socket state used by the C API.
Definition mxsocket.h:68

◆ mx_socket_ipv6_bind()

bool mx_socket_ipv6_bind ( MXSocket * s,
const char * port )
nodiscard

Bind an IPv6 Internet socket to a local port.

Parameters
sSocket state to configure.
portService or port name.
Returns
True on success.

Definition at line 374 of file mxsocket.c.

374 {
375 return mx_socket_inet_bind(sock, port, AF_INET6);
376}

◆ mx_socket_ipv6_connect()

bool mx_socket_ipv6_connect ( MXSocket * s,
const char * host,
const char * port,
int type )
nodiscard

Connect an IPv6 Internet socket to a remote host.

Parameters
sSocket state to configure.
hostRemote host name or address.
portRemote service or port name.
typeSocket kind, typically SOCK_STREAM or SOCK_DGRAM.
Returns
True on success.

Definition at line 366 of file mxsocket.c.

366 {
367 return mx_socket_inet_connect(sock, host, port, type, AF_INET6);
368}

◆ mx_socket_ipv6_listen()

bool mx_socket_ipv6_listen ( MXSocket * s,
const char * port,
int backlog,
int type )
nodiscard

Create and bind an IPv6 Internet socket for listening.

Parameters
sSocket state to configure.
portService or port name to bind.
backlogMaximum pending connection queue length.
typeSocket kind, typically SOCK_STREAM or SOCK_DGRAM.
Returns
True on success.

Definition at line 274 of file mxsocket.c.

274 {
275 return mx_socket_inet_listen(sock, port, backlog, type, AF_INET6);
276}

◆ mx_socket_ipv6_recvfrom()

ssize_t mx_socket_ipv6_recvfrom ( MXSocket * sock,
void * buf,
size_t bytes )

Receive a datagram using an IPv6 Internet socket.

Parameters
sockSocket state.
bufOutput buffer.
bytesMaximum number of bytes to receive.
Returns
Number of bytes received, or a negative error value.

Definition at line 632 of file mxsocket.c.

632 {
633 if (sock == nullptr || buf == nullptr || src_bytes == 0)
634 return -1;
635
636 ssize_t bytes = 0;
637 socklen_t len = (socklen_t)sizeof(struct sockaddr_storage);
638 struct sockaddr_storage caddr;
639 bytes = recvfrom(sock->sockfd, (char *)buf, MX_LEN(src_bytes), 0, (struct sockaddr *)&caddr, &len);
640 if (bytes >= 0)
641 mx_socket_store_inet_address(sock, (const struct sockaddr *)&caddr, len);
642 return bytes;
643}
#define MX_LEN(x)
Definition mxsocket.h:61

◆ mx_socket_ipv6_sendto()

ssize_t mx_socket_ipv6_sendto ( MXSocket * sock,
const void * buf,
size_t bytes )

Send a datagram using an IPv6 Internet socket.

Parameters
sockSocket state.
bufInput buffer.
bytesNumber of bytes to send.
Returns
Number of bytes sent, or a negative error value.

Definition at line 592 of file mxsocket.c.

592 {
593 if (sock == nullptr || buf == nullptr || src_bytes == 0)
594 return -1;
595
596 ssize_t bytes = 0;
597 bytes = sendto(sock->sockfd, (const char *)buf, MX_LEN(src_bytes), 0, (struct sockaddr *)&sock->inet6, sock->addrlen);
598 return bytes;
599}

◆ mx_socket_is_open()

bool mx_socket_is_open ( const MXSocket * s)
nodiscard

Check whether the socket is open.

Parameters
sSocket state to inspect.
Returns
True when the socket is open.

Definition at line 442 of file mxsocket.c.

442 {
443 if (sock == nullptr || !mx_socket_valid(sock))
444 return false;
445 char c = 0;
446#ifdef _WIN32
447 ssize_t r = recv(sock->sockfd, &c, 1, MSG_PEEK);
448#elif defined(MX_HAVE_MSG_DONTWAIT)
449 ssize_t r = recv(sock->sockfd, &c, 1, MSG_PEEK | MSG_DONTWAIT);
450#else
451 fd_set readfds;
452 FD_ZERO(&readfds);
453 FD_SET(sock->sockfd, &readfds);
454
455 struct timeval timeout = {0, 0};
456 const int ready = select((int)(sock->sockfd + 1), &readfds, nullptr, nullptr, &timeout);
457 if (ready < 0)
458 return false;
459 if (ready == 0)
460 return true;
461
462 ssize_t r = recv(sock->sockfd, &c, 1, MSG_PEEK);
463#endif
464 if (r == 0)
465 return false;
466 if (r > 0)
467 return true;
468 if (r < 0 && (SOCK_ERRNO == SOCK_EAGAIN || SOCK_ERRNO == SOCK_EWOULDBLOCK)) {
469 return true;
470 }
471 return false;
472}
#define SOCK_ERRNO
Definition mxsocket.h:51
#define SOCK_EWOULDBLOCK
Definition mxsocket.h:54
#define SOCK_EAGAIN
Definition mxsocket.h:53

◆ mx_socket_listen()

bool mx_socket_listen ( MXSocket * s,
const char * port,
int backlog,
int type )
nodiscard

Create and bind an Internet socket for listening.

Parameters
sSocket state to configure.
portService or port name to bind.
backlogMaximum pending connection queue length.
typeSocket kind, typically SOCK_STREAM or SOCK_DGRAM.
Returns
True on success.

Definition at line 270 of file mxsocket.c.

270 {
271 return mx_socket_inet_listen(sock, port, backlog, type, AF_INET);
272}

◆ mx_socket_read()

ssize_t mx_socket_read ( MXSocket * s,
void * data,
size_t len,
int flags )

Read data from a socket.

Parameters
sSocket state.
dataOutput buffer.
lenNumber of bytes to read.
flagsPlatform socket flags.
Returns
Number of bytes read, or a negative error value.

Definition at line 422 of file mxsocket.c.

422 {
423 if (sock == nullptr || buf == nullptr || len == 0)
424 return -1;
425 if (!mx_socket_valid(sock)) {
426 mx_set_err(EBADF);
427 return -1;
428 }
429 return recv(sock->sockfd, (char *)buf, MX_LEN(len), flags);
430}
#define mx_set_err(e)
Definition mxsocket.h:50

◆ mx_socket_read_all()

ssize_t mx_socket_read_all ( MXSocket * sock,
void * buf,
size_t bytes )

Read the requested number of bytes from a socket.

Parameters
sockSocket state.
bufOutput buffer.
bytesNumber of bytes to read.
Returns
Number of bytes read, or a negative error value.

Definition at line 555 of file mxsocket.c.

555 {
556 if (sock == nullptr || buf == nullptr || bytes == 0)
557 return -1;
558
559 char *ptr = (char *)buf;
560 size_t left = bytes;
561 while (left > 0) {
562 ssize_t bytes_read = recv(sock->sockfd, (char *)ptr, MX_LEN(left), 0);
563 if (bytes_read == -1) {
564 if (SOCK_ERRNO == SOCK_EINTR) {
565 continue;
566 }
567 return -1;
568 }
569 if (bytes_read == 0)
570 break;
571 left -= (size_t)bytes_read;
572 ptr += bytes_read;
573 }
574 return (ssize_t)(bytes - left);
575}
#define SOCK_EINTR
Definition mxsocket.h:52

◆ mx_socket_readline()

bool mx_socket_readline ( MXSocket * s,
char ** buffer,
size_t * len )
nodiscard

Read a line of text from a socket.

Parameters
sSocket state.
bufferOutput buffer pointer.
lenOutput length.
Returns
True on success.

Definition at line 474 of file mxsocket.c.

474 {
475 if (sock == nullptr || buffer == nullptr || size == nullptr)
476 return false;
477
478 if (!mx_socket_valid(sock)) {
479 mx_set_err(EBADF);
480 return false;
481 }
482
483 *buffer = nullptr;
484 *size = 0;
485
486 size_t init_size = 4096;
487 char *temp = (char *)malloc(init_size + 1);
488 if (temp == nullptr)
489 return false;
490 char c = 0;
491 size_t index = 0;
492 while (1) {
493 ssize_t read_val = recv(sock->sockfd, &c, 1, 0);
494 if (read_val > 0) {
495 if (c == '\n')
496 break;
497 if (index >= init_size) {
498 size_t new_init_size = init_size * 2;
499 char *t = (char *)realloc(temp, new_init_size + 1);
500 if (t == nullptr) {
501 free(temp);
502 return false;
503 }
504 temp = t;
505 init_size = new_init_size;
506 }
507 temp[index++] = c;
508 continue;
509 }
510 if (read_val == 0) {
511 if (index == 0) {
512 free(temp);
513 return false;
514 }
515 break;
516 }
517
518 if (SOCK_ERRNO == SOCK_EINTR)
519 continue;
520
522 if (!sock->blocking)
523 break;
524 continue;
525 }
526 free(temp);
527 return false;
528 }
529 temp[index] = 0;
530 *buffer = temp;
531 *size = index;
532 return true;
533}

◆ mx_socket_recvfrom()

ssize_t mx_socket_recvfrom ( MXSocket * sock,
void * buf,
size_t bytes )

Receive a datagram using an Internet socket.

Parameters
sockSocket state.
bufOutput buffer.
bytesMaximum number of bytes to receive.
Returns
Number of bytes received, or a negative error value.

Definition at line 601 of file mxsocket.c.

601 {
602 if (sock == nullptr || buf == nullptr || src_bytes == 0)
603 return -1;
604
605 ssize_t bytes = 0;
606 socklen_t len = (socklen_t)sizeof(struct sockaddr_storage);
607 struct sockaddr_storage caddr;
608 bytes = recvfrom(sock->sockfd, (char *)buf, MX_LEN(src_bytes), 0, (struct sockaddr *)&caddr, &len);
609 if (bytes >= 0)
610 mx_socket_store_inet_address(sock, (const struct sockaddr *)&caddr, len);
611 return bytes;
612}

◆ mx_socket_recvfrom_address()

ssize_t mx_socket_recvfrom_address ( MXSocket * sock,
void * buf,
size_t bytes,
MXSocketAddress * address )

Definition at line 614 of file mxsocket.c.

614 {
615 if (sock == nullptr || buf == nullptr || src_bytes == 0 || address == nullptr)
616 return -1;
617 address->length = (socklen_t)sizeof(address->storage);
618 ssize_t bytes = recvfrom(sock->sockfd, (char *)buf, MX_LEN(src_bytes), 0,
619 (struct sockaddr *)&address->storage, &address->length);
620 if (bytes >= 0)
621 mx_socket_store_inet_address(sock, (const struct sockaddr *)&address->storage, address->length);
622 return bytes;
623}
socklen_t length
Definition mxsocket.h:79
struct sockaddr_storage storage
Definition mxsocket.h:78

◆ mx_socket_send()

ssize_t mx_socket_send ( MXSocket * s,
const void * data,
size_t len,
int flags )

Write data to a socket.

Parameters
sSocket state.
dataInput buffer.
lenNumber of bytes to send.
flagsPlatform socket flags.
Returns
Number of bytes written, or a negative error value.

Definition at line 432 of file mxsocket.c.

432 {
433 if (sock == nullptr || buf == nullptr || len == 0)
434 return -1;
435 if (!mx_socket_valid(sock)) {
436 mx_set_err(EBADF);
437 return -1;
438 }
439 return send(sock->sockfd, (const char *)buf, MX_LEN(len), flags);
440}

◆ mx_socket_sendto()

ssize_t mx_socket_sendto ( MXSocket * sock,
const void * buf,
size_t bytes )

Send a datagram using an Internet socket.

Parameters
sockSocket state.
bufInput buffer.
bytesNumber of bytes to send.
Returns
Number of bytes sent, or a negative error value.

Definition at line 583 of file mxsocket.c.

583 {
584 if (sock == nullptr || buf == nullptr || src_bytes == 0)
585 return -1;
586
587 ssize_t bytes = 0;
588 bytes = sendto(sock->sockfd, (const char *)buf, MX_LEN(src_bytes), 0, (struct sockaddr *)&sock->inet, sock->addrlen);
589 return bytes;
590}

◆ mx_socket_sendto_address()

ssize_t mx_socket_sendto_address ( MXSocket * sock,
const void * buf,
size_t bytes,
const MXSocketAddress * address )

Definition at line 625 of file mxsocket.c.

625 {
626 if (sock == nullptr || buf == nullptr || src_bytes == 0 || address == nullptr || address->length == 0)
627 return -1;
628 return sendto(sock->sockfd, (const char *)buf, MX_LEN(src_bytes), 0,
629 (const struct sockaddr *)&address->storage, address->length);
630}

◆ mx_socket_set_blocking()

bool mx_socket_set_blocking ( MXSocket * s,
bool state )
nodiscard

Toggle blocking mode for a socket.

Parameters
sSocket state to update.
stateDesired blocking state.
Returns
True on success.

Definition at line 331 of file mxsocket.c.

331 {
332 if (sock == nullptr)
333 return false;
334 if (mx_socket_valid(sock)) {
335#ifdef _WIN32
336 u_long mode = state ? 0 : 1;
337 if (ioctlsocket(sock->sockfd, FIONBIO, &mode) != 0) {
338 fprintf(stderr, "Error setting flags for: %d\n", (int)sock->sockfd);
339 return false;
340 }
341#else
342 int flags = fcntl(sock->sockfd, F_GETFL);
343 if (flags == -1) {
344 fprintf(stderr, "Error getting flags for: %d\n", sock->sockfd);
345 return false;
346 }
347 if (state)
348 flags &= ~O_NONBLOCK;
349 else
350 flags |= O_NONBLOCK;
351 if (fcntl(sock->sockfd, F_SETFL, flags) == -1) {
352 fprintf(stderr, "Error setting flags for: %d\n", sock->sockfd);
353 return false;
354 }
355#endif
356 sock->blocking = state;
357 } else
358 return false;
359 return true;
360}

◆ mx_socket_unix_bind()

bool mx_socket_unix_bind ( MXSocket * s,
const char * path )
nodiscard

Bind a UNIX-domain socket to a local path.

Parameters
sSocket state to configure.
pathFilesystem path for the socket.
Returns
True on success.

Definition at line 378 of file mxsocket.c.

378 {
379 if (!mx_socket_init(s) || path == nullptr)
380 return false;
381
382 mx_socket_fd sockfd = socket(AF_UNIX, SOCK_DGRAM, 0);
383#ifdef _WIN32
384 if (sockfd == INVALID_SOCKET) {
385#else
386 if (sockfd == -1) {
387#endif
388 perror("socket");
389 return false;
390 }
391 remove(path);
392 struct sockaddr_un caddy;
393 memset(&caddy, 0, sizeof(struct sockaddr_un));
394 caddy.sun_family = AF_UNIX;
395 strncpy(caddy.sun_path, path, sizeof(caddy.sun_path) - 1);
396 if (bind(sockfd, (struct sockaddr *)&caddy, sizeof(caddy)) == -1) {
397 perror("bind");
398 mx_close_socket(sockfd);
399 return false;
400 }
401 s->sun = caddy;
402 s->addrlen = sizeof(caddy);
403 s->sockfd = sockfd;
404 return true;
405}
bool mx_socket_init(MXSocket *sock)
Initialize a socket structure with default values.
Definition mxsocket.c:407

◆ mx_socket_unix_connect()

bool mx_socket_unix_connect ( MXSocket * s,
const char * path,
int type )
nodiscard

Connect a UNIX-domain socket to a local path.

Parameters
sSocket state to configure.
pathFilesystem path for the socket.
typeSocket kind, typically SOCK_STREAM or SOCK_DGRAM.
Returns
True on success.

Definition at line 241 of file mxsocket.c.

241 {
242 if (path == nullptr)
243 return false;
244 if (!mx_socket_init(sock))
245 return false;
246 mx_socket_fd sockfd = NULL_SOCKET;
247 struct sockaddr_un addr;
248 memset(&addr, 0, sizeof(struct sockaddr_un));
249 addr.sun_family = AF_UNIX;
250 sockfd = socket(AF_UNIX, type, 0);
251#ifdef _WIN32
252 if (sockfd == INVALID_SOCKET) {
253#else
254 if (sockfd == -1) {
255#endif
256 perror("socket");
257 return false;
258 }
259 strncpy(addr.sun_path, path, sizeof(addr.sun_path) - 1);
260 if (connect(sockfd, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) == -1) {
261 perror("connect");
262 mx_close_socket(sockfd);
263 return false;
264 }
265 sock->sockfd = sockfd;
266 sock->sun = addr;
267 return true;
268}

◆ mx_socket_unix_listen()

bool mx_socket_unix_listen ( MXSocket * s,
const char * path,
int backlog,
int type )
nodiscard

Create and bind a UNIX-domain socket for listening.

Parameters
sSocket state to configure.
pathFilesystem path for the socket.
backlogMaximum pending connection queue length.
typeSocket kind, typically SOCK_STREAM or SOCK_DGRAM.
Returns
True on success.

Definition at line 202 of file mxsocket.c.

202 {
203 if (path == nullptr)
204 return false;
205 if (!mx_socket_init(sock))
206 return false;
207 struct sockaddr_un addr;
208 mx_socket_fd sockfd = socket(AF_UNIX, type, 0);
209#ifdef _WIN32
210 if (sockfd == INVALID_SOCKET) {
211#else
212 if (sockfd == -1) {
213#endif
214 perror("socket");
215 return false;
216 }
217 if (remove(path) == -1 && errno == ENOENT) {
218 perror("remove");
219 mx_close_socket(sockfd);
220 return false;
221 }
222 memset(&addr, 0, sizeof(struct sockaddr_un));
223 strncpy(addr.sun_path, path, sizeof(addr.sun_path) - 1);
224 addr.sun_family = AF_UNIX;
225 if (bind(sockfd, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) == -1) {
226 perror("bind");
227 mx_close_socket(sockfd);
228 return false;
229 }
230
231 if (listen(sockfd, backlog) == -1) {
232 perror("listen");
233 mx_close_socket(sockfd);
234 return false;
235 }
236 sock->sockfd = sockfd;
237 sock->sun = addr;
238 return true;
239}

◆ mx_socket_unix_recvfrom()

ssize_t mx_socket_unix_recvfrom ( MXSocket * sock,
void * buf,
size_t bytes )

Receive a datagram using a UNIX-domain socket.

Parameters
sockSocket state.
bufOutput buffer.
bytesMaximum number of bytes to receive.
Returns
Number of bytes received, or a negative error value.

Definition at line 653 of file mxsocket.c.

653 {
654 if (sock == nullptr || buf == nullptr || src_bytes == 0)
655 return -1;
656
657 ssize_t bytes = 0;
658 socklen_t len = (socklen_t)sizeof(struct sockaddr_storage);
659 struct sockaddr_storage caddr;
660 bytes = recvfrom(sock->sockfd, (char *)buf, MX_LEN(src_bytes), 0, (struct sockaddr *)&caddr, &len);
661 return bytes;
662}

◆ mx_socket_unix_sendto()

ssize_t mx_socket_unix_sendto ( MXSocket * sock,
const void * buf,
size_t bytes )

Send a datagram using a UNIX-domain socket.

Parameters
sockSocket state.
bufInput buffer.
bytesNumber of bytes to send.
Returns
Number of bytes sent, or a negative error value.

Definition at line 645 of file mxsocket.c.

645 {
646 if (sock == nullptr || buf == nullptr || src_bytes == 0)
647 return -1;
648
649 ssize_t bytes = 0;
650 bytes = sendto(sock->sockfd, (const char *)buf, MX_LEN(src_bytes), 0, (struct sockaddr *)&sock->sun, sock->addrlen);
651 return bytes;
652}

◆ mx_socket_valid()

bool mx_socket_valid ( const MXSocket * s)
nodiscard

Check whether the socket handle is valid.

Parameters
sSocket state to inspect.
Returns
True when the handle is valid.

Definition at line 416 of file mxsocket.c.

416 {
417 if (sock == nullptr)
418 return false;
419 return sock->sockfd != NULL_SOCKET;
420}

◆ mx_socket_write_all()

ssize_t mx_socket_write_all ( MXSocket * sock,
const void * buf,
size_t bytes )

Write the requested number of bytes to a socket.

Parameters
sockSocket state.
bufInput buffer.
bytesNumber of bytes to write.
Returns
Number of bytes written, or a negative error value.

Definition at line 535 of file mxsocket.c.

535 {
536 if (sock == nullptr || buf == nullptr || bytes == 0)
537 return -1;
538
539 const char *ptr = (const char *)buf;
540 size_t left = bytes;
541 while (left > 0) {
542 ssize_t written = send(sock->sockfd, (const char *)ptr, MX_LEN(left), 0);
543 if (written == -1) {
544 if (SOCK_ERRNO == SOCK_EINTR) {
545 continue;
546 }
547 return -1;
548 }
549 left -= (size_t)written;
550 ptr += written;
551 }
552 return (ssize_t)bytes;
553}