# 8.12 `fcntl` -- The `fcntl()` and `ioctl()` system calls

Availability: Unix.

This module performs file control and I/O control on file descriptors. It is an interface to the `fcntl()` and `ioctl()` Unix routines. File descriptors can be obtained with the `fileno()` method of a file or socket object.

The module defines the following functions:

`fcntl` (fd, op[, arg])
  Perform the requested operation on file descriptor fd. The operation is defined by op and is operating system dependent. Typically these codes can be retrieved from the library module `FCNTL`. The argument arg is optional, and defaults to the integer value `0`. When present, it can either be an integer value, or a string. With the argument missing or an integer value, the return value of this function is the integer return value of the C `fcntl()` call. When the argument is a string it represents a binary structure, e.g. created by `struct.pack()`. The binary data is copied to a buffer whose address is passed to the C `fcntl()` call. The return value after a successful call is the contents of the buffer, converted to a string object. In case the `fcntl()` fails, an `IOError` is raised.

`ioctl` (fd, op, arg)
  This function is identical to the `fcntl()` function, except that the operations are typically defined in the library module `IOCTL`.

`flock` (fd, op)
  Perform the lock operation op on file descriptor fd. See the Unix manual flock(3) for details. (On some systems, this function is emulated using `fcntl()`.)

`lockf` (fd, code, [len, [start, [whence]]])
  This is a wrapper around the `FCNTL.F_SETLK` and `FCNTL.F_SETLKW` `fcntl()` calls. See the Unix manual for details.

If the library modules `FCNTL` or `IOCTL` are missing, you can find the opcodes in the C include files `<sys/fcntl.h>` and `<sys/ioctl.h>`. You can create the modules yourself with the h2py script, found in the `Tools/scripts/` directory.

Examples (all on a SVR4 compliant system):

      import struct, fcntl, FCNTL

      file = open(...)
      rv = fcntl(file.fileno(), FCNTL.O_NDELAY, 1)

      lockdata = struct.pack('hhllhh', FCNTL.F_WRLCK, 0, 0, 0, 0, 0)
      rv = fcntl.fcntl(file.fileno(), FCNTL.F_SETLKW, lockdata)

Note that in the first example the return value variable `rv` will hold an integer value; in the second example it will hold a string value. The structure lay-out for the lockdata variable is system dependent -- therefore using the `flock()` call may be better.