S6-FDHOLDER(7)
π S6-FDHOLDER(7) β the fdholder API, explained by your unix bestie
okay so this is the miscellaneous information manual page for s6-fdholder, and it's literally the API for clients who wanna talk to an s6-fdholderd(8) daemon. iykyk β¨
π¦ NAME
s6-fdholder β the API for clients that want to communicate with an s6-fdholderd(8) daemon. that's it, that's the whole name section, slay π
πΈ DESCRIPTION
bestie, go check the s6/s6-fdholder.h header for the exact function prototypes β that header is the source of truth, no cap π
π A programming example
the src/fdholder/s6-fdholder-*.c files in the s6 package? for instance, they show you exactly how to use the s6-fdholder library. iconic of them, honestly π«Ά
β° Synchronous functions with a specified maximum execution time
the explanation over in s6-ftrigr(7) applies here too, so listen up π
these functions are synchronous, but they can return early if the deadline is reached. and if that happens, you should close the connection to the server immediately, because at that point no protocol consistency is guaranteed. like, none. at all. π
the s6-fdholderd(8) server should be very quick to answer queries, so this whole mechanism is just a simple little security blanket against programming errors β for instance, connecting to the wrong daemon. been there π
π§ Starting and ending a session
s6_fdholder_t a = S6_FDHOLDER_ZERO ;
int fd = 6 ;
tain_now_g() ;
s6_fdholder_init(&a, fd) ;
(...)
s6_fdholder_free(&a) ;
s6_fdholder_init() assumes that fd is a socket that's already connected to an s6-fdholderd(8) daemon. and the a structure must be initialized to S6_FDHOLDER_ZERO before use β don't skip that step, bestie π
tain_now_g() initializes a global variable that keeps track of the current time, for use with later functions. timekeeping era β¨
s6_fdholder_free() frees the resources occupied by a. it does not, however, close fd. you gotta manually close it to end the connection to the server. and heads up: if your program has been started by s6-ipcclient(8), both fds 6 and 7 are open (and they refer to the same socket), so you should close both. yes, both. no cap π
alternatively, if your connection to s6-fdholderd(8) has not been created yet, you can use the following functions:
int s6_fdholder_start(s6_fdholder_t *a, char const *path, tain_t const *deadline, tain_t *stamp)β starts a session with ans6-fdholderd(8)instance listening on path.amust be initialized toS6_FDHOLDER_ZERObefore calling this function. on success, returns nonzero andacan be used as a handle for the nexts6_fdholder_*()function calls. on failure, returns0, and setserrno. πvoid s6_fdholder_end(s6_fdholder_t *a)β ends the current session and frees all allocated resources. if needed,ais immediately reusable for anothers6_fdholder_start()call. recycling queen π
π Storing an fd
int r ;
int fd ;
tain_t limit = TAIN_INFINITE ;
char const *id = "my_identifier" ;
r = s6_fdholder_store_g(&a, fd, id, &limit, &deadline) ;
s6_fdholder_store() (and its variant s6_fdholder_store_g() that uses the global timestamp variable) attempts to store a copy of descriptor fd into s6-fdholderd(8), using identifier id, with an expiration date of limit. in this example, limit is TAIN_INFINITE, which means no expiration date β it lives forever, main character energy β
the operation should return before deadline, else it will automatically return 0 ETIMEDOUT. the result is 1 on success and 0 on failure, with an appropriate errno code; refer to s6-fdholder-error-codes(7). π
π Deleting an fd
fd = s6_fdholder_delete_g(&a, id, &deadline);
s6_fdholder_delete() attempts to delete the file descriptor identified by id. it returns 1 on success and 0 on failure, with an appropriate errno code; refer to s6-fdholder-error-codes(7). bye bye descriptor π
π¦ Retrieving an fd
fd = s6_fdholder_retrieve_g(&a, id, &deadline);
s6_fdholder_retrieve() attempts to retrieve the file descriptor identified by id. it returns a valid fd number on success, and β1 on failure, with an appropriate errno code; refer to s6-fdholder-error-codes(7).
s6_fdholder_retrieve_delete() performs a retrieval and a deletion at the same time, if the client is authorized to do so. multitasking icon π₯
π Listing the identifiers held by the server
stralloc list = STRALLOC_ZERO ;
int n ;
n = s6_fdholder_list_g(&a, &list, &deadline) ;
s6_fdholder_list() gets the list of all identifiers currently held by the server. it stores it into the stralloc[1] list, as a series of null-terminated strings, one after the other. there are n such strings. the function returns n on success, or β1 on failure, with an appropriate errno code; refer to s6-fdholder-error-codes(7). a whole little roster, obsessed π
π Reading a dump
genalloc dump = GENALLOC_ZERO ;
r = s6_fdholder_getdump_g(&a, &dump, &deadline) ;
s6_fdholder_getdump() attempts to retrieve the whole set of descriptors from the server. it returns 1 on success, and 0 on failure, with an appropriate errno code; refer to s6-fdholder-error-codes(7). the set is stored into the genalloc[2] dump, which is to be interpreted as a stralloc containing an array of s6_fdholder_fd_t.
genalloc_s(s6_fdholder_fd_t, &dump) is a pointer to this array, and genalloc_len(s6_fdholder_fd_t, &dump) is the number of elements in the array. an s6_fdholder_fd_t contains at least a descriptor number, an identifier, and an expiration date; see the s6/s6-fdholder.h header file. go look, it's right there π
π§ Writing a dump
unsigned int dumplen ;
s6_fdholder_fd_t const *dumparray ;
r = s6_fdholder_setdump_g(&a, &dumparray, dumplen, &deadline) ;
s6_fdholder_setdump() attempts to send a set of descriptors to the server. the descriptors are contained in the array dumparray of length dumplen. the function returns 1 on success, and 0 on failure, with an appropriate errno code; refer to s6-fdholder-error-codes(7). sending it, periodt π
π SEE ALSO
[1] https://skarnet.org/software/skalibs/libstddjb/stralloc.html
[2] https://skarnet.org/software/skalibs/libstddjb/genalloc.html
this man page is ported from the authoritative documentation at: https://skarnet.org/software/s6/libs6/s6-fdholder.html π
π AUTHORS
- Laurent Bercot
- Alexis <flexibeast@gmail.com> (man page port)
ok that's the whole page, bestie, you ate that π«Ά
and a lil sign-off for the fine print: this is the Debian build of the page, dated September 29, 2021 β mwah, go store some fds πβ¨
π¦ where this page comes from
- nixpkgs unstable: s6 2.15.1.0
- nixpkgs unstable: s6-man-pages 2.14.0.1.4
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms