fdholder.html (7226B)
1 <html> 2 <head> 3 <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 4 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 5 <meta http-equiv="Content-Language" content="en" /> 6 <title>s6: the s6-fdholder library interface</title> 7 <meta name="Description" content="s6: the s6-fdholder library interface" /> 8 <meta name="Keywords" content="s6 fdholder file descriptor fd holding fd-passing library interface" /> 9 <!-- <link rel="stylesheet" type="text/css" href="//skarnet.org/default.css" /> --> 10 </head> 11 <body> 12 13 <p> 14 <a href="index.html">libs6</a><br /> 15 <a href="../">s6</a><br /> 16 <a href="//skarnet.org/software/">Software</a><br /> 17 <a href="//skarnet.org/">skarnet.org</a> 18 </p> 19 20 <h1> The <tt>fdholder</tt> library interface </h1> 21 22 <p> 23 The <tt>fdholder</tt> library provides an API for clients 24 wanting to communicate with a 25 <a href="../s6-fdholderd.html">s6-fdholderd</a> daemon. 26 </p> 27 28 <h2> Programming </h2> 29 30 <p> 31 Check the <tt>s6/fdholder.h</tt> header for the 32 exact function prototypes. 33 </p> 34 35 <h3> A programming example </h3> 36 37 <p> 38 The <tt>src/fdholder/s6-fdholder-*.c</tt> files in the s6 package, 39 for instance, illustrate how to use the fdholder library. 40 </p> 41 42 <h3> Synchronous functions with a specified maximum execution time </h3> 43 44 <p> 45 The explanation given 46 <a href="ftrigr.html#synctimed">there</a> applies here too: the 47 functions documented in this page are synchronous, but can return 48 early if the deadline is reached, in which case the connection to the 49 server should be closed immediately because no protocol consistency is 50 guaranteed. 51 </p> 52 53 <p> 54 The <a href="../s6-fdholderd.html">s6-fdholderd</a> server should be 55 very quick to answer queries, so this mechanism is provided as a simple 56 security against programming errors - for instance, connecting to the 57 wrong daemon. 58 </p> 59 60 <h3> Starting and ending a session </h3> 61 62 <pre> 63 s6_fdholder_t a = S6_FDHOLDER_ZERO ; 64 int fd = 6 ; 65 66 tain_now_g() ; 67 68 s6_fdholder_init(&a, fd) ; 69 (...) 70 s6_fdholder_free(&a) ; 71 </pre> 72 73 <p> 74 <tt>s6_fdholder_init</tt> assumes that <em>fd</em> is a socket already 75 connected to an s6-fdholderd daemon. The <em>a</em> structure must be 76 initialized to <tt>S6_FDHOLDER_ZERO</tt> before use. 77 </p> 78 79 <p> 80 <a href="//skarnet.org/software/skalibs/libstddjb/tai.html">tain_now_g()</a> 81 initializes a global variable that keeps track of the current time, for 82 use with later functions. 83 </p> 84 85 <p> 86 <tt>s6_fdholder_free</tt> frees the resources occupied by <em>a</em>. 87 It does not, however, close <em>fd</em>. You should manually close it 88 to end the connection to the server. Note that if your program has been 89 started by <a href="../s6-ipcclient.html">s6-ipcclient</a>, both fds 6 90 and 7 are open (and refer to the same socket), so you should close both. 91 </p> 92 93 <p> 94 Alternatively, if your connection to s6-fdholderd has not been created yet, 95 you can use the following functions: 96 </p> 97 98 <h4> <code> int s6_fdholder_start (s6_fdholder_t *a, char const *path, tain_t const *deadline, tain_t *stamp) </code> </h4> 99 100 <p> 101 Starts a session with a <a href="../s6-fdholderd.html">s6-fdholderd</a> 102 instance listening on <em>path</em>. <em>a</em> must be initialized to 103 S6_FDHOLDER_ZERO before calling this function. On success, returns nonzero 104 and <em>a</em> can be used as a handle for the next <tt>s6_fdholder_*</tt> 105 function calls. On failure, returns 0, and sets errno. 106 </p> 107 108 <h4> <code> void s6_fdholder_end (s6_fdholder_t *a) </code> </h4> 109 110 <p> 111 Ends the current session and frees all allocated resources. If needed, 112 <em>a</em> is immediately reusable for another <tt>s6_fdholder_start</tt> call. 113 </p> 114 115 <h3> Storing a fd </h3> 116 117 <pre> 118 int r ; 119 int fd ; 120 tain_t limit = TAIN_INFINITE ; 121 char const *id = "my_identifier" ; 122 r = s6_fdholder_store_g(&a, fd, id, &limit, &deadline) ; 123 </pre> 124 125 <p> 126 <tt>s6_fdholder_store</tt> (and its variant <tt>s6_fdholder_store_g</tt> 127 that uses the global timestamp variable) attempts to store a copy of 128 descriptor <em>fd</em> into s6-fdholderd, using identifier <em>id</em>, 129 with an expiration date of <em>limit</em>. In this example, <em>limit</em> 130 is TAIN_INFINITE, which means no expiration date. The operation should 131 return before <em>deadline</em>, else it will automatically return 132 0 ETIMEDOUT. The result is 1 on success and 0 on failure, with an 133 <a href="../s6-fdholder-errorcodes.html">appropriate</a> errno code. 134 </p> 135 136 <h3> Deleting a fd </h3> 137 138 <pre> 139 fd = s6_fdholder_delete_g(&a, id, &deadline) ; 140 </pre> 141 142 <p> 143 <tt>s6_fdholder_delete</tt> attempts to delete the file descriptor 144 identified by <em>id</em>. It returns 1 on success and 0 on failure, 145 with an 146 <a href="../s6-fdholder-errorcodes.html">appropriate</a> errno code. 147 </p> 148 149 <h3> Retrieving a fd </h3> 150 151 <pre> 152 fd = s6_fdholder_retrieve_g(&a, id, &deadline) ; 153 </pre> 154 155 <p> 156 <tt>s6_fdholder_retrieve</tt> attempts to retrieve the file descriptor 157 identified by <em>id</em>. It returns a valid fd number on success, and 158 -1 on failure, with an 159 <a href="../s6-fdholder-errorcodes.html">appropriate</a> errno code. 160 </p> 161 162 <p> 163 <tt>s6_fdholder_retrieve_delete()</tt> performs a retrieval and a 164 deletion at the same time, if the client is authorized to do so. 165 </p> 166 167 <h3> Listing the identifiers held by the server </h3> 168 169 <pre> 170 stralloc list = STRALLOC_ZERO ; 171 int n ; 172 n = s6_fdholder_list_g(&a, &list, &deadline) ; 173 </pre> 174 175 <p> 176 <tt>s6_fdholder_list</tt> gets the list of all identifiers currently 177 held by the server. It stores it into the 178 <a href="//skarnet.org/software/skalibs/libstddjb/stralloc.html">stralloc</a> 179 <em>list</em>, as a series of null-terminated strings, one after the other. 180 There are <em>n</em> such strings. The function returns <em>n</em> on 181 success, or -1 on failure, with an 182 <a href="../s6-fdholder-errorcodes.html">appropriate</a> errno code. 183 </p> 184 185 186 <h3> Reading a dump </h3> 187 188 <pre> 189 genalloc dump = GENALLOC_ZERO ; 190 r = s6_fdholder_getdump_g(&a, &dump, &deadline) ; 191 </pre> 192 193 <p> 194 <tt>s6_fdholder_getdump</tt> attempts to retrieve the whole set of 195 descriptors from the server. 196 It returns 1 on success, and 0 on failure, with an 197 <a href="../s6-fdholder-errorcodes.html">appropriate</a> errno code. 198 The set is stored into the 199 <a href="//skarnet.org/software/skalibs/libstddjb/genalloc.html">genalloc</a> 200 <em>dump</em>, which is to be interpreted as a stralloc containing an array 201 of <tt>s6_fdholder_fd_t</tt>. 202 </p> 203 204 <p> 205 <tt>genalloc_s(s6_fdholder_fd_t, &dump)</tt> is a pointer to this array, and 206 <tt>genalloc_len(s6_fdholder_fd_t, &dump)</tt> is the number of elements 207 in the array. A <tt>s6_fdholder_fd_t</tt> contains at least a descriptor 208 number, an identifier, and an expiration date, see the 209 <tt>s6/fdholder.h</tt> header file. 210 </p> 211 212 <h3> Writing a dump </h3> 213 214 <pre> 215 unsigned int dumplen ; 216 s6_fdholder_fd_t const *dumparray ; 217 r = s6_fdholder_setdump_g(&a, &dumparray, dumplen, &deadline) ; 218 </pre> 219 220 <p> 221 <tt>s6_fdholder_setdump</tt> attempts to send a set of descriptors to the 222 server. The descriptors are contained in the array <em>dumparray</em> of 223 length <em>dumplen</em>. The function 224 returns 1 on success, and 0 on failure, with an 225 <a href="../s6-fdholder-errorcodes.html">appropriate</a> errno code. 226 </p> 227 228 </body> 229 </html>