lio_listio(3)
β¨ lio_listio β initiate a list of I/O requests β¨
okay bestie, so lio_listio(3) is a library function and it lives in the Real-time library β that's librt, so you link it with -lrt. π
π SYNOPSIS π
#include <aio.h>
int lio_listio(int n;
int mode,
struct aiocb *restrict const aiocb_list[restrict n],
int n, struct sigevent *restrict sevp);
πΈ DESCRIPTION πΈ
So basically, lio_listio() kicks off a whole list of I/O operations β the ones described by the array aiocb_list. Like, an entire group chat of I/O requests, all at once. π
The mode argument (yes, the manpage calls it "the mode operation", we move) takes one of these values:
LIO_WAITβ the call just... blocks. Sits there. Stays seated until every single operation is done. And thesevpargument? Ignored. Not even looked at. πLIO_NOWAITβ the I/O operations get queued up for processing and the call returns immediately, no waiting around, we are booked and busy. Then when all of the I/O operations complete, asynchronous notification occurs, exactly as specified by thesevpargument β go checksigevent(3type)for the deets. And ifsevpisNULL, then no asynchronous notification happens at all. Silence. Nothing. π¦
The aiocb_list argument is an array of pointers to aiocb structures that describe the I/O operations. And heads up: these operations are executed in an unspecified order β so do not come for me about ordering, it's giving chaos and that's on purpose. The n argument says how big the aiocb_list array is. And null pointers in aiocb_list? Ignored. Not our problem, we skip right past them. β¨
Now, inside each control block in aiocb_list, there's a field called aio_lio_opcode and it tells you which I/O operation to initiate, like this:
LIO_READβ initiate a read operation. It gets queued exactly like a call toaio_read(3)with this control block. πLIO_WRITEβ initiate a write operation. It gets queued exactly like a call toaio_write(3)with this control block. βοΈLIO_NOPβ ignore this control block entirely. Nothing to see here, moving on. π
All the other fields in each control block mean the same things they mean for aio_read(3) and aio_write(3). And the aio_sigevent fields of each control block can be used to specify notifications for the individual I/O operations β see sigevent(7) for that. π
π₯ RETURN VALUE π₯
If mode is LIO_NOWAIT, lio_listio() returns 0 when all the I/O operations are successfully queued. Otherwise it returns -1, and errno gets set to tell you what went wrong. π
If mode is LIO_WAIT, lio_listio() returns 0 when all of the I/O operations have completed successfully. Otherwise, again, -1 is returned and errno is set to indicate the error.
β οΈ Now listen, this part matters: the return status fromlio_listio()gives you info only about the call itself, not about the individual I/O operations. One or more of the I/O operations may fail, and that does not stop the other operations from completing. So if you wanna know the status of the individual operations inaiocb_list, useaio_error(3). And once an operation has completed, you get its return status withaio_return(3). Individual I/O operations can fail for all the reasons described over inaio_read(3)andaio_write(3). fr fr. π«Ά
π ERRORS π
lio_listio() may fail for these reasons:
EAGAINβ out of resources. π΅EAGAINβ the number of I/O operations specified bynwould blow past the limitAIO_MAX. (yes it's listed twice, both are real, don't @ me)EINTRβmodewasLIO_WAITand a signal got caught before all the I/O operations completed; seesignal(7). And the drama? This may even be one of the signals used for asynchronous I/O completion notification. πEINVALβmodeis invalid, ornexceeds the limitAIO_LISTIO_MAX. π«EIOβ one or more of the operations specified byaiocb_listfailed. The application can check the status of each operation usingaio_return(3). π
β οΈ Important caveat time: iflio_listio()fails with the errorEAGAIN,EINTR, orEIO, then some of the operations inaiocb_listmay have been initiated. Iflio_listio()fails for any other reason, then none of the I/O operations has been initiated. So like, know which one you're in. π
β ATTRIBUTES β
For an explanation of the terms used in this section, see attributes(7).
- Interface:
lio_listio() - Attribute: Thread safety
- Value:
MT-Safe
(That's your vibe check passed: it's thread-safe, slay. π)
π STANDARDS π
POSIX.1-2008. periodt.
π¦ HISTORY π¦
- glibc
2.1. POSIX.1-2001.
we stan a legacy icon. π
π NOTES π
- It is a good idea to zero out the control blocks before use. do it. please. π
- The control blocks must not be changed while the I/O operations are in progress. hands off, bestie. β
- The buffer areas being read into or written from must not be accessed during the operations, or undefined results may occur. Do not touch. Do not look at it. Do not think about it. π
- The memory areas involved must remain valid. keep them alive, keep them valid. πΈ
- Simultaneous I/O operations specifying the same
aiocbstructure produce undefined results. Just don't. π
π SEE ALSO π
and that's the whole page, babe π this came from Linux man-pages 6.20, dated 2026-02-08, and it's the lio_listio(3) manual β go forth and queue your I/O, you've got this. π«Άβ¨
π¦ where this page comes from
- arch rolling: man-pages 6.20-1 Β· BSD-2-Clause AND BSD-3-Clause AND BSD-4.3TAHOE AND BSD-4-Clause-UC AND GPL-1.0-or-later AND GPL-2.0-only AND GPL-2.0-or-later AND GPL-3.0-or-later AND LGPL-3.0-linking-exception AND LGPL-3.0-or-later AND LicenseRef-Public-Domain AND LicenseRef-UltraPermissive AND Linux-man-pages-1-para AND Linux-man-pages-copyleft AND Linux-man-pages-copyleft-2-para AND Linux-man-pages-copyleft-var AND MIT AND Spencer-94
- nixpkgs unstable: man-pages 6.20
- π the page's license: GPL-2.0-or-later
- Copyright 2010, Michael Kerrisk <mtk.manpages@gmail.com>
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms