1/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
2/* If you are missing that file, acquire a complete release at teeworlds.com. */
3
4/*
5 Title: OS Abstraction
6*/
7
8#ifndef BASE_SYSTEM_H
9#define BASE_SYSTEM_H
10
11#include "dbg.h"
12#include "detect.h"
13#include "fs.h"
14#include "mem.h"
15#include "str.h"
16#include "time.h"
17#include "types.h"
18
19#include <chrono>
20#include <cinttypes>
21#include <cstdarg>
22#include <cstdint>
23#include <cstring>
24#include <ctime>
25#include <functional>
26#include <mutex>
27#include <optional>
28#include <string>
29
30#ifdef __MINGW32__
31#undef PRId64
32#undef PRIu64
33#undef PRIX64
34#define PRId64 "I64d"
35#define PRIu64 "I64u"
36#define PRIX64 "I64X"
37#define PRIzu "Iu"
38#else
39#define PRIzu "zu"
40#endif
41
42#ifdef CONF_FAMILY_UNIX
43#include <sys/un.h>
44#endif
45
46#ifdef CONF_PLATFORM_LINUX
47#include <netinet/in.h>
48#include <sys/socket.h>
49#endif
50
51/**
52 * File I/O related operations.
53 *
54 * @defgroup File-IO File I/O
55 */
56
57/**
58 * @ingroup File-IO
59 */
60enum
61{
62 /**
63 * Open file for reading.
64 *
65 * @see io_open
66 */
67 IOFLAG_READ = 1,
68 /**
69 * Open file for writing.
70 *
71 * @see io_open
72 */
73 IOFLAG_WRITE = 2,
74 /**
75 * Open file for appending at the end.
76 *
77 * @see io_open
78 */
79 IOFLAG_APPEND = 4,
80};
81
82/**
83 * @ingroup File-IO
84 */
85enum ESeekOrigin
86{
87 /**
88 * Start seeking from the beginning of the file.
89 *
90 * @see io_seek
91 */
92 IOSEEK_START = 0,
93 /**
94 * Start seeking from the current position.
95 *
96 * @see io_seek
97 */
98 IOSEEK_CUR = 1,
99 /**
100 * Start seeking from the end of the file.
101 *
102 * @see io_seek
103 */
104 IOSEEK_END = 2,
105};
106
107/**
108 * Opens a file.
109 *
110 * @ingroup File-IO
111 *
112 * @param filename File to open.
113 * @param flags A set of IOFLAG flags.
114 *
115 * @see IOFLAG_READ, IOFLAG_WRITE, IOFLAG_APPEND.
116 *
117 * @return A handle to the file on success, or `nullptr` on failure.
118 */
119IOHANDLE io_open(const char *filename, int flags);
120
121/**
122 * Reads data into a buffer from a file.
123 *
124 * @ingroup File-IO
125 *
126 * @param io Handle to the file to read data from.
127 * @param buffer Pointer to the buffer that will receive the data.
128 * @param size Number of bytes to read from the file.
129 *
130 * @return Number of bytes read.
131 */
132unsigned io_read(IOHANDLE io, void *buffer, unsigned size);
133
134/**
135 * Reads the rest of the file into a buffer.
136 *
137 * @ingroup File-IO
138 *
139 * @param io Handle to the file to read data from.
140 * @param result Receives the file's remaining contents.
141 * @param result_len Receives the file's remaining length.
142 *
143 * @return `true` on success, `false` on failure.
144 *
145 * @remark Does NOT guarantee that there are no internal null bytes.
146 * @remark The result must be freed after it has been used.
147 * @remark The function will fail if more than 1 GiB of memory would
148 * have to be allocated. Large files should not be loaded into memory.
149 */
150bool io_read_all(IOHANDLE io, void **result, unsigned *result_len);
151
152/**
153 * Reads the rest of the file into a null-terminated buffer with
154 * no internal null bytes.
155 *
156 * @ingroup File-IO
157 *
158 * @param io Handle to the file to read data from.
159 *
160 * @return The file's remaining contents, or `nullptr` on failure.
161 *
162 * @remark Guarantees that there are no internal null bytes.
163 * @remark Guarantees that result will contain null-termination.
164 * @remark The result must be freed after it has been used.
165 * @remark The function will fail if more than 1 GiB of memory would
166 * have to be allocated. Large files should not be loaded into memory.
167 */
168char *io_read_all_str(IOHANDLE io);
169
170/**
171 * Skips data in a file.
172 *
173 * @ingroup File-IO
174 *
175 * @param io Handle to the file.
176 * @param size Number of bytes to skip.
177 *
178 * @return `0` on success.
179 */
180int io_skip(IOHANDLE io, int64_t size);
181
182/**
183 * Seeks to a specified offset in the file.
184 *
185 * @ingroup File-IO
186 *
187 * @param io Handle to the file.
188 * @param offset Offset from position to search.
189 * @param origin Position to start searching from.
190 *
191 * @return `0` on success.
192 */
193int io_seek(IOHANDLE io, int64_t offset, ESeekOrigin origin);
194
195/**
196 * Gets the current position in the file.
197 *
198 * @ingroup File-IO
199 *
200 * @param io Handle to the file.
201 *
202 * @return The current position, or `-1` on failure.
203 */
204int64_t io_tell(IOHANDLE io);
205
206/**
207 * Gets the total length of the file. Resets cursor to the beginning.
208 *
209 * @ingroup File-IO
210 *
211 * @param io Handle to the file.
212 *
213 * @return The total size, or `-1` on failure.
214 */
215int64_t io_length(IOHANDLE io);
216
217/**
218 * Writes data from a buffer to a file.
219 *
220 * @ingroup File-IO
221 *
222 * @param io Handle to the file.
223 * @param buffer Pointer to the data that should be written.
224 * @param size Number of bytes to write.
225 *
226 * @return Number of bytes written.
227 */
228unsigned io_write(IOHANDLE io, const void *buffer, unsigned size);
229
230/**
231 * Writes a platform dependent newline to a file.
232 *
233 * @ingroup File-IO
234 *
235 * @param io Handle to the file.
236 *
237 * @return `true` on success, `false` on failure.
238 */
239bool io_write_newline(IOHANDLE io);
240
241/**
242 * Closes a file.
243 *
244 * @ingroup File-IO
245 *
246 * @param io Handle to the file.
247 *
248 * @return `0` on success.
249 */
250int io_close(IOHANDLE io);
251
252/**
253 * Empties all buffers and writes all pending data.
254 *
255 * @ingroup File-IO
256 *
257 * @param io Handle to the file.
258 *
259 * @return `0` on success.
260 */
261int io_flush(IOHANDLE io);
262
263/**
264 * Synchronize file changes to disk.
265 *
266 * @ingroup File-IO
267 *
268 * @param io Handle to the file.
269 *
270 * @return `0` on success.
271 */
272int io_sync(IOHANDLE io);
273
274/**
275 * Checks whether an error occurred during I/O with the file.
276 *
277 * @ingroup File-IO
278 *
279 * @param io Handle to the file.
280 *
281 * @return `0` on success, or non-`0` on error.
282 */
283int io_error(IOHANDLE io);
284
285/**
286 * Returns a handle for the standard input.
287 *
288 * @ingroup File-IO
289 *
290 * @return An @link IOHANDLE @endlink for the standard input.
291 *
292 * @remark The handle must not be closed.
293 */
294IOHANDLE io_stdin();
295
296/**
297 * Returns a handle for the standard output.
298 *
299 * @ingroup File-IO
300 *
301 * @return An @link IOHANDLE @endlink for the standard output.
302 *
303 * @remark The handle must not be closed.
304 */
305IOHANDLE io_stdout();
306
307/**
308 * Returns a handle for the standard error.
309 *
310 * @ingroup File-IO
311 *
312 * @return An @link IOHANDLE @endlink for the standard error.
313 *
314 * @remark The handle must not be closed.
315 */
316IOHANDLE io_stderr();
317
318/**
319 * Returns a handle for the current executable.
320 *
321 * @ingroup File-IO
322 *
323 * @return An @link IOHANDLE @endlink for the current executable.
324 */
325IOHANDLE io_current_exe();
326
327/**
328 * Wrapper for asynchronously writing to an @link IOHANDLE @endlink.
329 *
330 * @ingroup File-IO
331 */
332typedef struct ASYNCIO ASYNCIO;
333
334/**
335 * Wraps a @link IOHANDLE @endlink for asynchronous writing.
336 *
337 * @ingroup File-IO
338 *
339 * @param io Handle to the file.
340 *
341 * @return The handle for asynchronous writing.
342 */
343ASYNCIO *aio_new(IOHANDLE io);
344
345/**
346 * Locks the `ASYNCIO` structure so it can't be written into by
347 * other threads.
348 *
349 * @ingroup File-IO
350 *
351 * @param aio Handle to the file.
352 */
353void aio_lock(ASYNCIO *aio);
354
355/**
356 * Unlocks the `ASYNCIO` structure after finishing the contiguous
357 * write.
358 *
359 * @ingroup File-IO
360 *
361 * @param aio Handle to the file.
362 */
363void aio_unlock(ASYNCIO *aio);
364
365/**
366 * Queues a chunk of data for writing.
367 *
368 * @ingroup File-IO
369 *
370 * @param aio Handle to the file.
371 * @param buffer Pointer to the data that should be written.
372 * @param size Number of bytes to write.
373 */
374void aio_write(ASYNCIO *aio, const void *buffer, unsigned size);
375
376/**
377 * Queues a newline for writing.
378 *
379 * @ingroup File-IO
380 *
381 * @param aio Handle to the file.
382 */
383void aio_write_newline(ASYNCIO *aio);
384
385/**
386 * Queues a chunk of data for writing. The `ASYNCIO` struct must be
387 * locked using @link aio_lock @endlink first.
388 *
389 * @ingroup File-IO
390 *
391 * @param aio Handle to the file.
392 * @param buffer Pointer to the data that should be written.
393 * @param size Number of bytes to write.
394 */
395void aio_write_unlocked(ASYNCIO *aio, const void *buffer, unsigned size);
396
397/**
398 * Queues a newline for writing. The `ASYNCIO` struct must be locked
399 * using @link aio_lock @endlink first.
400 *
401 * @ingroup File-IO
402 *
403 * @param aio Handle to the file.
404 */
405void aio_write_newline_unlocked(ASYNCIO *aio);
406
407/**
408 * Checks whether errors have occurred during the asynchronous writing.
409 *
410 * Call this function regularly to see if there are errors. Call this
411 * function after @link aio_wait @endlink to see if the process of writing
412 * to the file succeeded.
413 *
414 * @ingroup File-IO
415 *
416 * @param aio Handle to the file.
417 *
418 * @return `0` on success, or non-`0` on error.
419 */
420int aio_error(ASYNCIO *aio);
421
422/**
423 * Queues file closing.
424 *
425 * @ingroup File-IO
426 *
427 * @param aio Handle to the file.
428 */
429void aio_close(ASYNCIO *aio);
430
431/**
432 * Wait for the asynchronous operations to complete.
433 *
434 * @ingroup File-IO
435 *
436 * @param aio Handle to the file.
437 */
438void aio_wait(ASYNCIO *aio);
439
440/**
441 * Frees the resources associated with the asynchronous file handle.
442 *
443 * @ingroup File-IO
444 *
445 * @param aio Handle to the file.
446 */
447void aio_free(ASYNCIO *aio);
448
449/**
450 * Threading related functions.
451 *
452 * @defgroup Threads Threading
453 *
454 * @see Locks
455 * @see Semaphore
456 */
457
458/**
459 * Creates a new thread.
460 *
461 * @ingroup Threads
462 *
463 * @param threadfunc Entry point for the new thread.
464 * @param user Pointer to pass to the thread.
465 * @param name Name describing the use of the thread.
466 *
467 * @return Handle for the new thread.
468 */
469void *thread_init(void (*threadfunc)(void *), void *user, const char *name);
470
471/**
472 * Waits for a thread to be done or destroyed.
473 *
474 * @ingroup Threads
475 *
476 * @param thread Thread to wait for.
477 */
478void thread_wait(void *thread);
479
480/**
481 * Yield the current thread's execution slice.
482 *
483 * @ingroup Threads
484 */
485void thread_yield();
486
487/**
488 * Puts the thread in the detached state, guaranteeing that
489 * resources of the thread will be freed immediately when the
490 * thread terminates.
491 *
492 * @ingroup Threads
493 *
494 * @param thread Thread to detach.
495 */
496void thread_detach(void *thread);
497
498/**
499 * Creates a new thread and detaches it.
500 *
501 * @ingroup Threads
502 *
503 * @param threadfunc Entry point for the new thread.
504 * @param user Pointer to pass to the thread.
505 * @param name Name describing the use of the thread.
506 */
507void thread_init_and_detach(void (*threadfunc)(void *), void *user, const char *name);
508
509/**
510 * @defgroup Semaphore Semaphores
511 *
512 * @see Threads
513 */
514
515#if defined(CONF_FAMILY_WINDOWS)
516typedef void *SEMAPHORE;
517#elif defined(CONF_PLATFORM_MACOS)
518#include <semaphore.h>
519typedef sem_t *SEMAPHORE;
520#elif defined(CONF_FAMILY_UNIX)
521#include <semaphore.h>
522typedef sem_t SEMAPHORE;
523#else
524#error not implemented on this platform
525#endif
526
527/**
528 * @ingroup Semaphore
529 */
530void sphore_init(SEMAPHORE *sem);
531/**
532 * @ingroup Semaphore
533 */
534void sphore_wait(SEMAPHORE *sem);
535/**
536 * @ingroup Semaphore
537 */
538void sphore_signal(SEMAPHORE *sem);
539/**
540 * @ingroup Semaphore
541 */
542void sphore_destroy(SEMAPHORE *sem);
543
544/**
545 * @defgroup Network Networking
546 */
547
548/**
549 * @defgroup Network-General General networking
550 *
551 * @ingroup Network
552 */
553
554/**
555 * @ingroup Network-General
556 */
557extern const NETADDR NETADDR_ZEROED;
558
559#ifdef CONF_FAMILY_UNIX
560/**
561 * @ingroup Network-General
562 */
563typedef int UNIXSOCKET;
564/**
565 * @ingroup Network-General
566 */
567typedef struct sockaddr_un UNIXSOCKETADDR;
568#endif
569
570/**
571 * Initiates network functionality.
572 *
573 * @ingroup Network-General
574 *
575 * @remark You must call this function before using any other network functions.
576 */
577void net_init();
578
579/**
580 * Looks up the ip of a hostname.
581 *
582 * @ingroup Network-General
583 *
584 * @param hostname Host name to look up.
585 * @param addr The output address to write to.
586 * @param types The type of IP that should be returned.
587 *
588 * @return `0` on success.
589 */
590int net_host_lookup(const char *hostname, NETADDR *addr, int types);
591
592/**
593 * Compares two network addresses.
594 *
595 * @ingroup Network-General
596 *
597 * @param a Address to compare.
598 * @param b Address to compare to.
599 *
600 * @return `< 0` if address a is less than address b.
601 * @return `0` if address a is equal to address b.
602 * @return `> 0` if address a is greater than address b.
603 */
604int net_addr_comp(const NETADDR *a, const NETADDR *b);
605
606/**
607 * Compares two network addresses ignoring port.
608 *
609 * @ingroup Network-General
610 *
611 * @param a Address to compare.
612 * @param b Address to compare to.
613 *
614 * @return `< 0` if address a is less than address b.
615 * @return `0` if address a is equal to address b.
616 * @return `> 0` if address a is greater than address b.
617 */
618int net_addr_comp_noport(const NETADDR *a, const NETADDR *b);
619
620/**
621 * Turns a network address into a representative string.
622 *
623 * @ingroup Network-General
624 *
625 * @param addr Address to turn into a string.
626 * @param string Buffer to fill with the string.
627 * @param max_length Maximum size of the string.
628 * @param add_port Whether to add the port to the string.
629 *
630 * @remark The string will always be null-terminated.
631 */
632void net_addr_str(const NETADDR *addr, char *string, int max_length, bool add_port);
633
634/**
635 * Turns url string into a network address struct.
636 * The url format is tw-0.6+udp://{ipaddr}[:{port}]
637 * ipaddr: can be ipv4 or ipv6
638 * port: is a optional internet protocol port
639 *
640 * This format is used for parsing the master server, be careful before changing it.
641 *
642 * Examples:
643 * tw-0.6+udp://127.0.0.1
644 * tw-0.6+udp://127.0.0.1:8303
645 *
646 * @ingroup Network-General
647 *
648 * @param addr Address to fill in.
649 * @param string String to parse.
650 * @param host_buf Pointer to a buffer to write the host to
651 * It will include the port if one is included in the url
652 * It can also be set to `nullptr` then it will be ignored.
653 * @param host_buf_size Size of the host buffer or 0 if no host_buf pointer is given.
654 *
655 * @return `0` on success.
656 * @return `> 0` if the input wasn't a valid DDNet URL,
657 * @return `< 0` if the input is a valid DDNet URL but the host part was not a valid IPv4/IPv6 address
658 */
659int net_addr_from_url(NETADDR *addr, const char *string, char *host_buf, size_t host_buf_size);
660
661/**
662 * Checks if an address is local.
663 *
664 * @ingroup Network-General
665 *
666 * @param addr Address to check.
667 *
668 * @return `true` if the address is local, `false` otherwise.
669 */
670bool net_addr_is_local(const NETADDR *addr);
671
672/**
673 * Turns string into a network address.
674 *
675 * @ingroup Network-General
676 *
677 * @param addr Address to fill in.
678 * @param string String to parse.
679 *
680 * @return `0` on success.
681 */
682int net_addr_from_str(NETADDR *addr, const char *string);
683
684/**
685 * Make a socket not block on operations
686 *
687 * @ingroup Network-General
688 *
689 * @param sock The socket to set the mode on.
690 *
691 * @returns `0` on success.
692 */
693int net_set_non_blocking(NETSOCKET sock);
694
695/**
696 * Make a socket block on operations.
697 *
698 * @param sock The socket to set the mode on.
699 *
700 * @returns `0` on success.
701 */
702int net_set_blocking(NETSOCKET sock);
703
704/**
705 * If a network operation failed, the error code.
706 *
707 * @ingroup Network-General
708 *
709 * @returns The error code.
710 */
711int net_errno();
712
713/**
714 * If a network operation failed, the platform-specific error code and string.
715 *
716 * @ingroup Network-General
717 *
718 * @returns The error code and string combined into one string.
719 */
720std::string net_error_message();
721
722/**
723 * Determines whether a network operation would block.
724 *
725 * @ingroup Network-General
726 *
727 * @returns `0` if wouldn't block, `1` if would block.
728 */
729int net_would_block();
730
731/**
732 * Waits for a socket to have data available to receive up the specified timeout duration.
733 *
734 * @ingroup Network-General
735 *
736 * @param sock Socket to wait on.
737 * @param nanoseconds Timeout duration to wait.
738 *
739 * @return `1` if data was received within the timeout duration, `0` otherwise.
740 */
741int net_socket_read_wait(NETSOCKET sock, std::chrono::nanoseconds nanoseconds);
742
743/**
744 * @defgroup Network-UDP UDP Networking
745 *
746 * @ingroup Network
747 */
748
749/**
750 * Determine a socket's type.
751 *
752 * @ingroup Network-General
753 *
754 * @param sock Socket whose type should be determined.
755 *
756 * @return The socket type, a bitset of `NETTYPE_IPV4`, `NETTYPE_IPV6`, `NETTYPE_WEBSOCKET_IPV4`
757 * and `NETTYPE_WEBSOCKET_IPV6`, or `NETTYPE_INVALID` if the socket is invalid.
758 */
759int net_socket_type(NETSOCKET sock);
760
761/**
762 * Creates a UDP socket and binds it to a port.
763 *
764 * @ingroup Network-UDP
765 *
766 * @param bindaddr Address to bind the socket to.
767 *
768 * @return On success it returns an handle to the socket. On failure it returns `nullptr`.
769 */
770NETSOCKET net_udp_create(NETADDR bindaddr);
771
772/**
773 * Sends a packet over an UDP socket.
774 *
775 * @ingroup Network-UDP
776 *
777 * @param sock Socket to use.
778 * @param addr Where to send the packet.
779 * @param data Pointer to the packet data to send.
780 * @param size Size of the packet.
781 *
782 * @return On success it returns the number of bytes sent. Returns `-1` on error.
783 */
784int net_udp_send(NETSOCKET sock, const NETADDR *addr, const void *data, int size);
785
786/**
787 * Receives a packet over an UDP socket.
788 *
789 * @ingroup Network-UDP
790 *
791 * @param sock Socket to use.
792 * @param addr Pointer to an NETADDR that will receive the address.
793 * @param data Received data. Will be invalidated when this function is called again.
794 *
795 * @return On success it returns the number of bytes received. Returns `-1` on error.
796 */
797int net_udp_recv(NETSOCKET sock, NETADDR *addr, unsigned char **data);
798
799/**
800 * Closes an UDP socket.
801 *
802 * @ingroup Network-UDP
803 *
804 * @param sock Socket to close.
805 */
806void net_udp_close(NETSOCKET sock);
807
808/**
809 * @defgroup Network-TCP TCP Networking
810 *
811 * @ingroup Network
812 */
813
814/**
815 * Creates a TCP socket.
816 *
817 * @ingroup Network-TCP
818 *
819 * @param bindaddr Address to bind the socket to.
820 *
821 * @return On success it returns an handle to the socket. On failure it returns `nullptr`.
822 */
823NETSOCKET net_tcp_create(NETADDR bindaddr);
824
825/**
826 * Makes the socket start listening for new connections.
827 *
828 * @ingroup Network-TCP
829 *
830 * @param sock Socket to start listen to.
831 * @param backlog Size of the queue of incoming connections to keep.
832 *
833 * @return `0` on success.
834 */
835int net_tcp_listen(NETSOCKET sock, int backlog);
836
837/**
838 * Polls a listening socket for a new connection.
839 *
840 * @ingroup Network-TCP
841 *
842 * @param sock Listening socket to poll.
843 * @param new_sock Pointer to a socket to fill in with the new socket.
844 * @param addr Pointer to an address that will be filled in the remote address, can be `nullptr`.
845 *
846 * @return A non-negative integer on success. Negative integer on failure.
847 */
848int net_tcp_accept(NETSOCKET sock, NETSOCKET *new_sock, NETADDR *addr);
849
850/**
851 * Connects one socket to another.
852 *
853 * @ingroup Network-TCP
854 *
855 * @param sock Socket to connect.
856 * @param addr Address to connect to.
857 *
858 * @return `0` on success.
859 *
860 */
861int net_tcp_connect(NETSOCKET sock, const NETADDR *addr);
862
863/**
864 * Connect a socket to a TCP address without blocking.
865 *
866 * @ingroup Network-TCP
867 *
868 * @param sock The socket to connect with.
869 * @param bindaddr The address to connect to.
870 *
871 * @returns `0` on success.
872 */
873int net_tcp_connect_non_blocking(NETSOCKET sock, NETADDR bindaddr);
874
875/**
876 * Sends data to a TCP stream.
877 *
878 * @ingroup Network-TCP
879 *
880 * @param sock Socket to send data to.
881 * @param data Pointer to the data to send.
882 * @param size Size of the data to send.
883 *
884 * @return Number of bytes sent. Negative value on failure.
885 */
886int net_tcp_send(NETSOCKET sock, const void *data, int size);
887
888/**
889 * Receives data from a TCP stream.
890 *
891 * @ingroup Network-TCP
892 *
893 * @param sock Socket to recvive data from.
894 * @param data Pointer to a buffer to write the data to.
895 * @param maxsize Maximum of data to write to the buffer.
896 *
897 * @return Number of bytes recvived. Negative value on failure. When in
898 * non-blocking mode, it returns 0 when there is no more data to be fetched.
899 */
900int net_tcp_recv(NETSOCKET sock, void *data, int maxsize);
901
902/**
903 * Closes a TCP socket.
904 *
905 * @ingroup Network-TCP
906 *
907 * @param sock Socket to close.
908 */
909void net_tcp_close(NETSOCKET sock);
910
911#if defined(CONF_FAMILY_UNIX)
912/**
913 * @defgroup Network-Unix-Sockets UNIX Socket Networking
914 *
915 * @ingroup Network
916 */
917
918/**
919 * Creates an unnamed unix datagram socket.
920 *
921 * @ingroup Network-Unix-Sockets
922 *
923 * @return On success it returns a handle to the socket. On failure it returns `-1`.
924 */
925UNIXSOCKET net_unix_create_unnamed();
926
927/**
928 * Sends data to a Unix socket.
929 *
930 * @ingroup Network-Unix-Sockets
931 *
932 * @param sock Socket to use.
933 * @param addr Where to send the packet.
934 * @param data Pointer to the packet data to send.
935 * @param size Size of the packet.
936 *
937 * @return Number of bytes sent. Negative value on failure.
938 */
939int net_unix_send(UNIXSOCKET sock, UNIXSOCKETADDR *addr, void *data, int size);
940
941/**
942 * Sets the unixsocketaddress for a path to a socket file.
943 *
944 * @ingroup Network-Unix-Sockets
945 *
946 * @param addr Pointer to the `UNIXSOCKETADDR` to fill.
947 * @param path Path to the (named) unix socket.
948 */
949void net_unix_set_addr(UNIXSOCKETADDR *addr, const char *path);
950
951/**
952 * Closes a Unix socket.
953 *
954 * @ingroup Network-Unix-Sockets
955 *
956 * @param sock Socket to close.
957 */
958void net_unix_close(UNIXSOCKET sock);
959
960#endif
961
962/**
963 * String related functions.
964 *
965 * @defgroup Strings Strings
966 */
967
968/**
969 * Performs printf formatting into a buffer.
970 *
971 * @ingroup Strings
972 *
973 * @param buffer Pointer to the buffer to receive the formatted string.
974 * @param buffer_size Size of the buffer.
975 * @param format printf formatting string.
976 * @param args The variable argument list.
977 *
978 * @return Length of written string, even if it has been truncated.
979 *
980 * @remark See the C manual for syntax for the printf formatting string.
981 * @remark The strings are treated as null-terminated strings.
982 * @remark Guarantees that buffer string will contain null-termination.
983 */
984[[gnu::format(printf, 3, 0)]] int str_format_v(char *buffer, int buffer_size, const char *format, va_list args);
985
986/**
987 * Performs printf formatting into a buffer.
988 *
989 * @ingroup Strings
990 *
991 * @param buffer Pointer to the buffer to receive the formatted string.
992 * @param buffer_size Size of the buffer.
993 * @param format printf formatting string.
994 * @param ... Parameters for the formatting.
995 *
996 * @return Length of written string, even if it has been truncated.
997 *
998 * @remark See the C manual for syntax for the printf formatting string.
999 * @remark The strings are treated as null-terminated strings.
1000 * @remark Guarantees that buffer string will contain null-termination.
1001 */
1002[[gnu::format(printf, 3, 4)]] int str_format(char *buffer, int buffer_size, const char *format, ...);
1003
1004#if !defined(CONF_DEBUG)
1005int str_format_int(char *buffer, size_t buffer_size, int value);
1006
1007template<typename... Args>
1008int str_format_opt(char *buffer, int buffer_size, const char *format, Args... args)
1009{
1010 static_assert(sizeof...(args) > 0, "Use str_copy instead of str_format without format arguments");
1011 return str_format(buffer, buffer_size, format, args...);
1012}
1013
1014template<>
1015inline int str_format_opt(char *buffer, int buffer_size, const char *format, int val) // NOLINT(readability-inconsistent-declaration-parameter-name)
1016{
1017 if(strcmp(format, "%d") == 0)
1018 {
1019 return str_format_int(buffer, buffer_size, val);
1020 }
1021 else
1022 {
1023 return str_format(buffer, buffer_size, format, val);
1024 }
1025}
1026
1027#define str_format str_format_opt
1028#endif
1029
1030/**
1031 * Computes the edit distance between two strings.
1032 *
1033 * @param a First string for the edit distance.
1034 * @param b Second string for the edit distance.
1035 *
1036 * @return The edit distance between the both strings.
1037 *
1038 * @remark The strings are treated as null-terminated strings.
1039 */
1040int str_utf8_dist(const char *a, const char *b);
1041
1042/**
1043 * Computes the edit distance between two strings, allows buffers
1044 * to be passed in.
1045 *
1046 * @ingroup Strings
1047 *
1048 * @param a First string for the edit distance.
1049 * @param b Second string for the edit distance.
1050 * @param buf Buffer for the function.
1051 * @param buf_len Length of the buffer, must be at least as long as
1052 * twice the length of both strings combined plus two.
1053 *
1054 * @return The edit distance between the both strings.
1055 *
1056 * @remark The strings are treated as null-terminated strings.
1057 */
1058int str_utf8_dist_buffer(const char *a, const char *b, int *buf, int buf_len);
1059
1060/**
1061 * Computes the edit distance between two strings, allows buffers
1062 * to be passed in.
1063 *
1064 * @ingroup Strings
1065 *
1066 * @param a First string for the edit distance.
1067 * @param a_len Length of the first string.
1068 * @param b Second string for the edit distance.
1069 * @param b_len Length of the second string.
1070 * @param buf Buffer for the function.
1071 * @param buf_len Length of the buffer, must be at least as long as
1072 * the length of both strings combined plus two.
1073 *
1074 * @return The edit distance between the both strings.
1075 *
1076 * @remark The strings are treated as null-terminated strings.
1077 */
1078int str_utf32_dist_buffer(const int *a, int a_len, const int *b, int b_len, int *buf, int buf_len);
1079
1080/**
1081 * Utilities for accessing the file system.
1082 *
1083 * @defgroup Filesystem Filesystem
1084 */
1085
1086/**
1087 * Lists the files and folders in a directory.
1088 *
1089 * @ingroup Filesystem
1090 *
1091 * @param dir Directory to list.
1092 * @param cb Callback function to call for each entry.
1093 * @param type Type of the directory.
1094 * @param user Pointer to give to the callback.
1095 *
1096 * @remark The strings are treated as null-terminated strings.
1097 */
1098void fs_listdir(const char *dir, FS_LISTDIR_CALLBACK cb, int type, void *user);
1099
1100/**
1101 * Lists the files and folders in a directory and gets additional file information.
1102 *
1103 * @ingroup Filesystem
1104 *
1105 * @param dir Directory to list.
1106 * @param cb Callback function to call for each entry.
1107 * @param type Type of the directory.
1108 * @param user Pointer to give to the callback.
1109 *
1110 * @remark The strings are treated as null-terminated strings.
1111 */
1112void fs_listdir_fileinfo(const char *dir, FS_LISTDIR_CALLBACK_FILEINFO cb, int type, void *user);
1113
1114/**
1115 * Recursively creates parent directories for a file or directory.
1116 *
1117 * @ingroup Filesystem
1118 *
1119 * @param path File or directory for which to create parent directories.
1120 *
1121 * @return `0` on success. Negative value on failure.
1122 *
1123 * @remark The strings are treated as null-terminated strings.
1124 */
1125int fs_makedir_rec_for(const char *path);
1126
1127/**
1128 * Fetches per user configuration directory.
1129 *
1130 * @ingroup Filesystem
1131 *
1132 * @param appname Name of the application.
1133 * @param path Buffer that will receive the storage path.
1134 * @param max Size of the buffer.
1135 *
1136 * @return `0` on success. Negative value on failure.
1137 *
1138 * @remark Returns ~/.appname on UNIX based systems.
1139 * @remark Returns ~/Library/Applications Support/appname on macOS.
1140 * @remark Returns %APPDATA%/Appname on Windows based systems.
1141 *
1142 * @remark The strings are treated as null-terminated strings.
1143 */
1144int fs_storage_path(const char *appname, char *path, int max);
1145
1146/**
1147 * Checks if a file exists.
1148 *
1149 * @ingroup Filesystem
1150 *
1151 * @param path The path to check.
1152 *
1153 * @return `1` if a file with the given path exists.
1154 * @return `0` on failure or if the file does not exist.
1155 *
1156 * @remark The strings are treated as null-terminated strings.
1157 */
1158int fs_is_file(const char *path);
1159
1160/**
1161 * Checks if a folder exists.
1162 *
1163 * @ingroup Filesystem
1164 *
1165 * @param path The path to check.
1166 *
1167 * @return `1` if a folder with the given path exists.
1168 * @return `0` on failure or if the folder does not exist.
1169 *
1170 * @remark The strings are treated as null-terminated strings.
1171 */
1172int fs_is_dir(const char *path);
1173
1174/**
1175 * Checks whether a given path is relative or absolute.
1176 *
1177 * @ingroup Filesystem
1178 *
1179 * @param path Path to check.
1180 *
1181 * @return `1` if relative, `0` if absolute.
1182 *
1183 * @remark The strings are treated as null-terminated strings.
1184 */
1185int fs_is_relative_path(const char *path);
1186
1187/**
1188 * Changes the current working directory.
1189 *
1190 * @ingroup Filesystem
1191 *
1192 * @param path New working directory path.
1193 *
1194 * @return `0` on success. `1` on failure.
1195 *
1196 * @remark The strings are treated as null-terminated strings.
1197 */
1198int fs_chdir(const char *path);
1199
1200/**
1201 * Gets the current working directory.
1202 *
1203 * @ingroup Filesystem
1204 *
1205 * @param buffer Buffer that will receive the current working directory.
1206 * @param buffer_size Size of the buffer.
1207 *
1208 * @return Pointer to the buffer on success, `nullptr` on failure.
1209 *
1210 * @remark The strings are treated as null-terminated strings.
1211 */
1212char *fs_getcwd(char *buffer, int buffer_size);
1213
1214/**
1215 * Gets the name of a file or folder specified by a path,
1216 * i.e. the last segment of the path.
1217 *
1218 * @ingroup Filesystem
1219 *
1220 * @param path Path from which to retrieve the filename.
1221 *
1222 * @return Filename of the path.
1223 *
1224 * @remark Supports forward and backward slashes as path segment separator.
1225 * @remark No distinction between files and folders is being made.
1226 * @remark The strings are treated as null-terminated strings.
1227 */
1228const char *fs_filename(const char *path);
1229
1230/**
1231 * Splits a filename into name (without extension) and file extension.
1232 *
1233 * @ingroup Filesystem
1234 *
1235 * @param filename The filename to split.
1236 * @param name Buffer that will receive the name without extension, may be nullptr.
1237 * @param name_size Size of the name buffer (ignored if name is nullptr).
1238 * @param extension Buffer that will receive the extension, may be nullptr.
1239 * @param extension_size Size of the extension buffer (ignored if extension is nullptr).
1240 *
1241 * @remark Does NOT handle forward and backward slashes.
1242 * @remark No distinction between files and folders is being made.
1243 * @remark The strings are treated as null-terminated strings.
1244 */
1245void fs_split_file_extension(const char *filename, char *name, size_t name_size, char *extension = nullptr, size_t extension_size = 0);
1246
1247/**
1248 * Normalizes the given path: replaces backslashes with regular slashes
1249 * and removes trailing slashes.
1250 *
1251 * @ingroup Filesystem
1252 *
1253 * @param path Path to normalize.
1254 *
1255 * @remark The strings are treated as null-terminated strings.
1256 */
1257void fs_normalize_path(char *path);
1258
1259/**
1260 * Get the parent directory of a directory.
1261 *
1262 * @ingroup Filesystem
1263 *
1264 * @param path Path of the directory. The parent will be store in this buffer as well.
1265 *
1266 * @return `0` on success. `1` on failure.
1267 *
1268 * @remark The strings are treated as null-terminated strings.
1269 */
1270int fs_parent_dir(char *path);
1271
1272/**
1273 * Deletes a file.
1274 *
1275 * @ingroup Filesystem
1276 *
1277 * @param filename Path of the file to delete.
1278 *
1279 * @return `0` on success. `1` on failure.
1280 *
1281 * @remark The strings are treated as null-terminated strings.
1282 * @remark Returns an error if the path specifies a directory name.
1283 */
1284int fs_remove(const char *filename);
1285
1286/**
1287 * Renames the file or directory. If the paths differ the file will be moved.
1288 *
1289 * @ingroup Filesystem
1290 *
1291 * @param oldname The current path of a file or directory.
1292 * @param newname The new path for the file or directory.
1293 *
1294 * @return `0` on success. `1` on failure.
1295 *
1296 * @remark The strings are treated as null-terminated strings.
1297 */
1298int fs_rename(const char *oldname, const char *newname);
1299
1300/**
1301 * Gets the creation and the last modification date of a file or directory.
1302 *
1303 * @ingroup Filesystem
1304 *
1305 * @param name Path of a file or directory.
1306 * @param created Pointer where the creation time will be stored.
1307 * @param modified Pointer where the modification time will be stored.
1308 *
1309 * @return `0` on success. non-zero on failure.
1310 *
1311 * @remark The strings are treated as null-terminated strings.
1312 * @remark Returned time is in seconds since UNIX Epoch.
1313 */
1314int fs_file_time(const char *name, time_t *created, time_t *modified);
1315
1316/**
1317 * Swaps the endianness of data. Each element is swapped individually by reversing its bytes.
1318 *
1319 * @param data Pointer to data to be swapped.
1320 * @param elem_size Size in bytes of each element.
1321 * @param num Number of elements.
1322 *
1323 * @remark The caller must ensure that the data is at least `elem_size * num` bytes in size.
1324 */
1325void swap_endian(void *data, unsigned elem_size, unsigned num);
1326
1327void net_stats(NETSTATS *stats);
1328
1329int str_utf8_to_skeleton(const char *str, int *buf, int buf_len);
1330
1331/**
1332 * Checks if two strings only differ by confusable characters.
1333 *
1334 * @ingroup Strings
1335 *
1336 * @param str1 String to compare.
1337 * @param str2 String to compare.
1338 *
1339 * @return `0` if the strings are confusables.
1340 */
1341int str_utf8_comp_confusable(const char *str1, const char *str2);
1342
1343/**
1344 * Converts the given Unicode codepoint to lowercase (locale insensitive).
1345 *
1346 * @ingroup Strings
1347 *
1348 * @param code Unicode codepoint to convert.
1349 *
1350 * @return Lowercase codepoint, or the original codepoint if there is no lowercase version.
1351 */
1352int str_utf8_tolower_codepoint(int code);
1353
1354/**
1355 * Packs 4 big endian bytes into an unsigned.
1356 *
1357 * @param bytes Pointer to an array of bytes that will be packed.
1358 *
1359 * @return The packed unsigned.
1360 *
1361 * @remark Assumes the passed array is least 4 bytes in size.
1362 * @remark Assumes unsigned is 4 bytes in size.
1363 *
1364 * @see uint_to_bytes_be
1365 */
1366unsigned bytes_be_to_uint(const unsigned char *bytes);
1367
1368/**
1369 * Packs an unsigned into 4 big endian bytes.
1370 *
1371 * @param bytes Pointer to an array where the bytes will be stored.
1372 * @param value The values that will be packed into the array.
1373 *
1374 * @remark Assumes the passed array is least 4 bytes in size.
1375 * @remark Assumes unsigned is 4 bytes in size.
1376 *
1377 * @see bytes_be_to_uint
1378 */
1379void uint_to_bytes_be(unsigned char *bytes, unsigned value);
1380
1381/**
1382 * Shell, process management, OS specific functionality.
1383 *
1384 * @defgroup Shell Shell
1385 */
1386
1387/**
1388 * Returns the ID of the current process.
1389 *
1390 * @ingroup Shell
1391 *
1392 * @return PID of the current process.
1393 */
1394int pid();
1395
1396/**
1397 * Fixes the command line arguments to be encoded in UTF-8 on all systems.
1398 *
1399 * @ingroup Shell
1400 *
1401 * @param argc A pointer to the argc parameter that was passed to the main function.
1402 * @param argv A pointer to the argv parameter that was passed to the main function.
1403 *
1404 * @remark You need to call @link cmdline_free @endlink once you're no longer using the results.
1405 */
1406void cmdline_fix(int *argc, const char ***argv);
1407
1408/**
1409 * Frees memory that was allocated by @link cmdline_fix @endlink.
1410 *
1411 * @ingroup Shell
1412 *
1413 * @param argc The argc obtained from `cmdline_fix`.
1414 * @param argv The argv obtained from `cmdline_fix`.
1415 */
1416void cmdline_free(int argc, const char **argv);
1417
1418#if !defined(CONF_PLATFORM_ANDROID)
1419/**
1420 * Determines the initial window state when using @link shell_execute @endlink
1421 * to execute a process.
1422 *
1423 * @ingroup Shell
1424 *
1425 * @remark Currently only supported on Windows.
1426 */
1427enum class EShellExecuteWindowState
1428{
1429 /**
1430 * The process window is opened in the foreground and activated.
1431 */
1432 FOREGROUND,
1433
1434 /**
1435 * The process window is opened in the background without focus.
1436 */
1437 BACKGROUND,
1438};
1439
1440/**
1441 * Executes a given file.
1442 *
1443 * @ingroup Shell
1444 *
1445 * @param file The file to execute.
1446 * @param window_state The window state how the process window should be shown.
1447 * @param arguments Optional array of arguments to pass to the process.
1448 * @param num_arguments The number of arguments.
1449 *
1450 * @return Handle of the new process, or @link INVALID_PROCESS @endlink on error.
1451 */
1452PROCESS shell_execute(const char *file, EShellExecuteWindowState window_state, const char **arguments = nullptr, size_t num_arguments = 0);
1453
1454/**
1455 * Sends kill signal to a process.
1456 *
1457 * @ingroup Shell
1458 *
1459 * @param process Handle of the process to kill.
1460 *
1461 * @return `1` on success, `0` on error.
1462 */
1463int kill_process(PROCESS process);
1464
1465/**
1466 * Checks if a process is alive.
1467 *
1468 * @ingroup Shell
1469 *
1470 * @param process Handle/PID of the process.
1471 *
1472 * @return `true` if the process is currently running,
1473 * @return `false` if the process is not running (dead).
1474 */
1475bool is_process_alive(PROCESS process);
1476
1477/**
1478 * Opens a link in the browser.
1479 *
1480 * @ingroup Shell
1481 *
1482 * @param link The link to open in a browser.
1483 *
1484 * @return `1` on success, `0` on failure.
1485 *
1486 * @remark The strings are treated as null-terminated strings.
1487 * @remark This may not be called with untrusted input or it'll result in arbitrary code execution, especially on Windows.
1488 */
1489int open_link(const char *link);
1490
1491/**
1492 * Opens a file or directory with the default program.
1493 *
1494 * @ingroup Shell
1495 *
1496 * @param path The file or folder to open with the default program.
1497 *
1498 * @return `1` on success, `0` on failure.
1499 *
1500 * @remark The strings are treated as null-terminated strings.
1501 * @remark This may not be called with untrusted input or it'll result in arbitrary code execution, especially on Windows.
1502 */
1503int open_file(const char *path);
1504#endif // !defined(CONF_PLATFORM_ANDROID)
1505
1506/**
1507 * Secure random number generation.
1508 *
1509 * @defgroup Secure-Random Secure Random
1510 */
1511
1512/**
1513 * Generates a null-terminated password of length `2 * random_length`.
1514 *
1515 * @ingroup Secure-Random
1516 *
1517 * @param buffer Pointer to the start of the output buffer.
1518 * @param length Length of the buffer.
1519 * @param random Pointer to a randomly-initialized array of shorts.
1520 * @param random_length Length of the short array.
1521 */
1522void generate_password(char *buffer, unsigned length, const unsigned short *random, unsigned random_length);
1523
1524/**
1525 * Fills the buffer with the specified amount of random password characters.
1526 *
1527 * @ingroup Secure-Random
1528 *
1529 * @param buffer Pointer to the start of the buffer.
1530 * @param length Length of the buffer.
1531 * @param pw_length Length of the desired password.
1532 *
1533 * @remark The desired password length must be greater or equal to 6,
1534 * even and smaller or equal to 128.
1535 */
1536void secure_random_password(char *buffer, unsigned length, unsigned pw_length);
1537
1538/**
1539 * Fills the buffer with the specified amount of random bytes.
1540 *
1541 * @ingroup Secure-Random
1542 *
1543 * @param bytes Pointer to the start of the buffer.
1544 * @param length Length of the buffer.
1545 */
1546void secure_random_fill(void *bytes, unsigned length);
1547
1548/**
1549 * Returns random `int`.
1550 *
1551 * @ingroup Secure-Random
1552 *
1553 * @return Random int.
1554 *
1555 * @remark Can be used as a replacement for the `rand` function.
1556 */
1557int secure_rand();
1558
1559/**
1560 * Returns a random nonnegative integer below the given number,
1561 * with a uniform distribution.
1562 *
1563 * @ingroup Secure-Random
1564 *
1565 * @param below Upper limit (exclusive) of integers to return.
1566 *
1567 * @return Random nonnegative below the given number.
1568 */
1569int secure_rand_below(int below);
1570
1571/**
1572 * Returns a human-readable version string of the operating system.
1573 *
1574 * @ingroup Shell
1575 *
1576 * @param version Buffer to use for the output.
1577 * @param length Length of the output buffer.
1578 *
1579 * @return `true` on success, `false` on failure.
1580 */
1581bool os_version_str(char *version, size_t length);
1582
1583/**
1584 * Returns a string of the preferred locale of the user / operating system.
1585 * The string conforms to [RFC 3066](https://www.ietf.org/rfc/rfc3066.txt)
1586 * and only contains the characters `a`-`z`, `A`-`Z`, `0`-`9` and `-`.
1587 * If the preferred locale could not be determined this function
1588 * falls back to the locale `"en-US"`.
1589 *
1590 * @ingroup Shell
1591 *
1592 * @param locale Buffer to use for the output.
1593 * @param length Length of the output buffer.
1594 *
1595 * @remark The strings are treated as null-terminated strings.
1596 */
1597void os_locale_str(char *locale, size_t length);
1598
1599/**
1600 * @defgroup Crash-Dumping Crash Dumping
1601 */
1602
1603/**
1604 * Initializes the crash dumper and sets the filename to write the crash dump
1605 * to, if support for crash logging was compiled in. Otherwise does nothing.
1606 *
1607 * @ingroup Crash-Dumping
1608 *
1609 * @param log_file_path Absolute path to which crash log file should be written.
1610 */
1611void crashdump_init_if_available(const char *log_file_path);
1612
1613/**
1614 * Fixes the command line arguments to be encoded in UTF-8 on all systems.
1615 * This is a RAII wrapper for @link cmdline_fix @endlink and @link cmdline_free @endlink.
1616 *
1617 * @ingroup Shell
1618 */
1619class CCmdlineFix
1620{
1621 int m_Argc;
1622 const char **m_ppArgv;
1623
1624public:
1625 CCmdlineFix(int *pArgc, const char ***pppArgv)
1626 {
1627 cmdline_fix(argc: pArgc, argv: pppArgv);
1628 m_Argc = *pArgc;
1629 m_ppArgv = *pppArgv;
1630 }
1631 ~CCmdlineFix()
1632 {
1633 cmdline_free(argc: m_Argc, argv: m_ppArgv);
1634 }
1635 CCmdlineFix(const CCmdlineFix &) = delete;
1636};
1637
1638#endif
1639