What is EAGAIN?

EAGAIN (Error Again) — errno 11 — means the resource is temporarily unavailable. Try again later. This commonly occurs with non-blocking I/O operations.

On Linux, EAGAIN and EWOULDBLOCK are the same value (11), but on some systems they differ.

Quick Fix: Retry the operation, use blocking mode, or implement proper I/O multiplexing with select(), poll(), or epoll().

Common Causes

  • Non-blocking socket has no data to read
  • Non-blocking pipe is full when writing
  • Process limit reached (fork() failed)
  • File descriptor limit exceeded

How to Fix

1. Retry the Operation

#include <errno.h>
#include <unistd.h>

ssize_t safe_write(int fd, const void *buf, size_t count) {
    size_t written = 0;
    while (written < count) {
        ssize_t result = write(fd, (const char *)buf + written, count - written);
        if (result > 0) {
            written += result;
        } else if (result == -1) {
            if (errno == EAGAIN || errno == EWOULDBLOCK) {
                // Resource temporarily unavailable, retry
                usleep(1000); // 1ms delay
                continue;
            }
            return -1; // Real error
        }
    }
    return written;
}

2. Use select() or poll()

#include <sys/select.h>
#include <errno.h>

int wait_for_writable(int fd, int timeout_ms) {
    fd_set write_fds;
    struct timeval tv;

    FD_ZERO(&write_fds);
    FD_SET(fd, &write_fds);

    tv.tv_sec = timeout_ms / 1000;
    tv.tv_usec = (timeout_ms % 1000) * 1000;

    int result = select(fd + 1, NULL, &write_fds, NULL, &tv);
    if (result > 0) {
        return 0; // fd is writable
    } else if (result == 0) {
        return -2; // Timeout
    }
    return -1; // Error
}

3. Use epoll for High-Performance

#include <sys/epoll.h>

int epoll_wait_for_events(int epfd, struct epoll_event *events, int maxevents) {
    int nfds = epoll_wait(epfd, events, maxevents, 5000); // 5 second timeout
    if (nfds == -1) {
        if (errno == EAGAIN) {
            // No events ready, continue waiting
            return 0;
        }
        perror("epoll_wait");
        return -1;
    }
    return nfds;
}

4. Set Non-Blocking Mode

#include <fcntl.h>

int set_nonblocking(int fd) {
    int flags = fcntl(fd, F_GETFL, 0);
    if (flags == -1) return -1;
    return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
}

Examples

Socket Example

#include <sys/socket.h>
#include <errno.h>

int recv_nonblocking(int sockfd, char *buf, size_t len) {
    ssize_t n = recv(sockfd, buf, len, 0);
    if (n == -1) {
        if (errno == EAGAIN || errno == EWOULDBLOCK) {
            printf("No data available yet\n");
            return 0;
        }
        perror("recv");
        return -1;
    }
    return n;
}

Pipe Example

#include <unistd.h>
#include <errno.h>

void write_to_pipe(int pipefd, const char *data) {
    while (1) {
        ssize_t n = write(pipefd, data, strlen(data));
        if (n == -1) {
            if (errno == EAGAIN) {
                // Pipe is full, wait and retry
                usleep(10000); // 10ms
                continue;
            }
            perror("write");
            break;
        }
        break;
    }
}

Quick Command Reference

CommandDescription
errno 11Show EAGAIN description
man errnoList all errno values
strace -e trace=read,write ./programTrace I/O syscalls
lsof -p PIDCheck open file descriptors

Comments