aio_write(), aio_write64()

Updated: April 19, 2023

Asynchronously write to a file

Synopsis:

#include <aio.h>

int aio_write( struct aiocb * aiocbptr );
int aio_write64( struct aiocb64 * aiocbptr );

Arguments:

aiocbptr
A pointer to an asynchronous I/O control block of type aiocb or aiocb64 that defines how much data to write, and where to write it.

Library:

libc

Use the -l c option to qcc to link against this library. This library is usually included automatically.

Description:

The aio_write() function asynchronously writes aiocbptr->aio_nbytes to the file associated with aiocbptr->aio_filedes from the buffer that aiocbptr->aio_buf points to. The function returns when the write request has been initiated or, at a minimum, queued to the file or device. The aio_write64() function is a large-file support version of aio_write().

Note: In QNX Neutrino 6.6 or later, the large-file support functions and data types appear in the name space only if you define _LARGEFILE64_SOURCE when you compile your code. For more information, see Classification in What's in a Function Description?

The asynchronous operation is submitted at the scheduling priority of the thread minus aiocbptr->aio_reqprio.

You can use the aiocbptr argument as an argument to aio_error() and aio_return() to determine the error status and return status of the asynchronous operation while it's in progress.

If O_APPEND isn't set for the file descriptor aio_filedes, then the requested operation takes place at the absolute position in the file as given by aio_offset, as if lseek() were called immediately before the operation with an offset of aio_offset and a whence of SEEK_SET.

If O_APPEND is set for the file descriptor, write operations append to the file in the same order as the calls were made.

If synchronized I/O is enabled on the file associated with aiocbptr->aio_filedes, these functions behave in accordance with the definitions of synchronized I/O data integrity completion and synchronized I/O file integrity completion.

The following conditions may be detected synchronously at the time of the call to aio_write() or aio_write64(), or asynchronously. If any of these conditions are detected synchronously, these functions return -1 and set errno to the corresponding value. If any of these conditions are detected asynchronously, the return status of the asynchronous operation is set to -1, and the error status of the asynchronous operation is set to the corresponding value:

EBADF
The aiocbptr->aio_filedes argument isn't a valid file descriptor that's open for writing.
EINVAL
The file offset value implied by aiocbptr->aio_offset would be invalid, aiocbptr->aio_reqprio isn't a valid value, or aiocbptr->aio_nbytes is invalid.

If aio_write() or aio_write64() successfully queues the I/O operation, but the operation is subsequently canceled or encounters an error, the return status of the asynchronous operation is one of the values normally returned by write(). In addition, the error status of the asynchronous operation is set to one of the error statuses normally set by write(), or one of the following:

EBADF
The aiocbptr->aio_filedes isn't a valid file descriptor that's open for writing.
ECANCELED
The requested I/O was canceled before the I/O was completed, due to an explicit aio_cancel(), request.
EINVAL
The file offset value implied by aiocbptr->aio_offset would be invalid.

The following condition may be detected synchronously or asynchronously:

EOVERFLOW
The file is a regular file, aiocbptr->aio_nbytes is greater than 0, and the starting offset in aiocbptr->aio_offset is at or beyond the offset maximum in the open file description associated with aiocbptr->aio_filedes.

Returns:

0 if the I/O operation was successfully queued, or -1 if an error occurred (errno is set).

Errors:

EAGAIN
The requested asynchronous I/O operation wasn't queued because of system resource limitations.

Classification:

aio_write() is POSIX 1003.1; aio_write64() is Large-file support

Safety:  
Cancellation point No
Interrupt handler No
Signal handler Yes
Thread Yes

Caveats:

The first time you call an aio_* function, a thread pool is created, making your process multithreaded if it isn't already. Because of this, after a fork() the child can not use any of the aio_*() functions if the parent used any aio_*() functions before the fork(). The thread pool isn't destroyed until your process ends.