Doing Non-Blocking I/O (Perl Cookbook, 2nd Edition)

## 7.20. Doing Non-Blocking I/O

### 7.20.1. Problem

You want to read from or write to a filehandle without the system blocking your process until the program, file, socket, or device at the other end is ready. This is desired less often of regular files than of special files.

### 7.20.2. Solution

Open the file with `sysopen`, specifying the `O_NONBLOCK` option:

>     use Fcntl;
>     sysopen(MODEM, "/dev/cua0", O_NONBLOCK|O_RDWR)
>         or die "Can't open modem: $!\n";

If you already have an open filehandle, invoke the `blocking` method from IO::Handle with an argument of 0:

>     use IO::Handle;
>     MODEM->blocking(0);  # assume MODEM already opened

Or use the low-level `fcntl` function:

>     use Fcntl;

>     $flags = "";
>     fcntl(HANDLE, F_GETFL, $flags)
>         or die "Couldn't get flags for HANDLE : $!\n";
>     $flags |= O_NONBLOCK;
>     fcntl(HANDLE, F_SETFL, $flags)
>         or die "Couldn't set flags for HANDLE: $!\n";

### 7.20.3. Discussion

On a disk file, when no more data can be read because you're at the end of the file, the input operation returns immediately. But suppose the filehandle in question were the user's keyboard or a network connection. In those cases, simply because there's no data there right now doesn't mean there never will be, so the input function normally doesn't return until it gets data. Sometimes, though, you don't want to wait; you want to grab whatever's there and carry on with whatever you were doing.

Once a filehandle has been set for non-blocking I/O, the `sysread` or `syswrite` calls that would otherwise block will instead return `undef` and set `$!` to `EAGAIN`:

>     use Errno;

>     $rv = syswrite(HANDLE, $buffer, length $buffer);
>     if (!defined($rv) && $!{EAGAIN}) {
>         # would block
>     } elsif ($rv != length $buffer) {
>         # incomplete write
>     } else {
>         # successfully wrote
>     }

>     $rv = sysread(HANDLE, $buffer, $BUFSIZ);
>     if (!defined($rv) && $!{EAGAIN}) {
>         # would block
>     } else {
>         # successfully read $rv bytes from HANDLE
>     }

The `O_NONBLOCK` constant is part of the POSIX standard, so most machines should support it. We use the Errno module to test for the error `EAGAIN`. Testing `$!{EAGAIN}` is the same as testing whether `$! = = EAGAIN`.

### 7.20.4. See Also

The `sysopen` and `fcntl` functions in perlfunc(1) and in Chapter 29 of Programming Perl; the documentation for the standard Errno and IO::Handle modules (also in Chapter 32 of Programming Perl); your system's open(2) and fcntl(2) manpages; Recipe 7.22; Recipe 7.21

Copyright © 2003 O'Reilly & Associates. All rights reserved.