Line data Source code
1 : #ifndef HEADER_fd_src_app_fdctl_utility_h
2 : #define HEADER_fd_src_app_fdctl_utility_h
3 :
4 : #include "fdctl.h"
5 :
6 : #include <stdlib.h>
7 :
8 : /* mkdir_all() is like `mkdir -p`, it creates all directories
9 : needed as part of the path. Logs an error and exits the process
10 : if anything goes wrong. Directories that did not already
11 : exist will be created with the given uid and gid. */
12 : void
13 : mkdir_all( const char * path,
14 : uid_t uid,
15 : gid_t gid );
16 :
17 : /* Recursively remove an entire directory. If remove_root is true, will
18 : also remove the root directory as well, otherwise it is left empty. */
19 :
20 : void
21 : rmtree( char const * path,
22 : int remove_root );
23 :
24 : /* read_uint_file() reads a uint from the given path, or exits the
25 : program with an error if any error was encountered. If the path
26 : cannot be opened due to ENOENT, the error message is prefixed
27 : with the string provided in errmsg_enoent. */
28 : uint
29 : read_uint_file( const char * path,
30 : const char * errmsg_enoent );
31 :
32 : /* write_uint_file() writes a uint to the given path, or exits the
33 : program with an error if any error was encountered. */
34 : void
35 : write_uint_file( const char * path,
36 : uint value );
37 :
38 : void
39 : exit_group( int status );
40 :
41 : /* internet_routing_interface() returns the interface index which
42 : routes to the public internet (8.8.8.8). If multiple interfaces
43 : route there, the first one returned by rtnetlink is returned.
44 :
45 : If no interface routes to 8.8.8.8, -1 is returned. */
46 : int internet_routing_interface( void );
47 :
48 : /* nanosleep1() sleeps the calling thread for the provided number of
49 : nanoseconds, ensuring it continues to sleep if it is interrupted.
50 : The function will log error and exit() if the sleep cannot be
51 : performed. */
52 : void nanosleep1( uint secs, uint nanos );
53 :
54 : /* current_executable_path() retrieves the full path of the current
55 : executable into the path. Path should be a buffer with at least
56 : PATH_MAX elements or calling this is undefined behavior. Logs error
57 : and exits if the current executable cannot be determined. */
58 : void
59 : current_executable_path( char path[ PATH_MAX ] );
60 :
61 : /* RUN() executes the given string and formatting arguments as a
62 : subprocess, and waits for the child to complete. If the child does
63 : not exit successfully with code 0, the calling program is aborted. */
64 0 : #define RUN(...) do { \
65 0 : char cmd[ 4096 ]; \
66 0 : FD_TEST( fd_cstr_printf_check( cmd, \
67 0 : sizeof(cmd), \
68 0 : NULL, \
69 0 : __VA_ARGS__ ) ); \
70 0 : int ret = system( cmd ); \
71 0 : if( FD_UNLIKELY( ret ) ) \
72 0 : FD_LOG_ERR(( "running command `%s` failed exit code=%d (%i-%s)", \
73 0 : cmd, \
74 0 : ret, \
75 0 : errno, \
76 0 : fd_io_strerror( errno ) )); \
77 0 : } while( 0 )
78 :
79 : /* OUTPUT() executes the given string and formatting arguments as a
80 : subprocess, and waits for the child to complete. The output stdout of
81 : the child process is captured into the `output` argument. If the
82 : child does not exit successfully with code 0, or the output of the
83 : child would overflow the provided output buffer, the calling program
84 : is aborted. */
85 : #define OUTPUT(output, ...) do { \
86 : char cmd[ 4096 ]; \
87 : FD_TEST( fd_cstr_printf_check( cmd, \
88 : sizeof(cmd), \
89 : NULL, \
90 : __VA_ARGS__ ) ); \
91 : FILE * process = popen( cmd, "r" ); \
92 : if( FD_UNLIKELY( !process ) ) \
93 : FD_LOG_ERR(( "popen of command `%s` failed (%i-%s)", \
94 : cmd, \
95 : errno, \
96 : fd_io_strerror( errno ) )); \
97 : size_t output_len = sizeof( output ); \
98 : size_t printed = fread( output, \
99 : 1, \
100 : output_len, \
101 : process ); \
102 : if( FD_UNLIKELY( ferror( process ) ) ) \
103 : FD_LOG_ERR(( "fread of command `%s` failed (%i-%s)", \
104 : cmd, \
105 : errno, \
106 : fd_io_strerror( errno ) )); \
107 : if( FD_UNLIKELY( printed >= output_len ) ) \
108 : FD_LOG_ERR(( "fread of command `%s` truncated", cmd )); \
109 : output[ printed ] = '\0'; \
110 : if( FD_UNLIKELY( pclose( process ) == -1 ) ) \
111 : FD_LOG_ERR(( "pclose of command `%s` failed (%i-%s)", \
112 : cmd, \
113 : errno, \
114 : fd_io_strerror( errno ) )); \
115 : } while( 0 )
116 :
117 : #endif /* HEADER_fd_src_app_fdctl_utility_h */
|