Modules/fcntlmodule.c
Source:
cpython 3.14 @ ab2d84fe1023/Modules/fcntlmodule.c
fcntl wraps the POSIX file control functions. It is available only on Unix-like systems.
Map
| Lines | Symbol | Role |
|---|---|---|
| 1-80 | fcntl_fcntl | fcntl(fd, cmd, arg=0) — get/set file descriptor flags |
| 81-180 | fcntl_ioctl | ioctl(fd, request, arg) — device-specific control |
| 181-280 | fcntl_flock | flock(fd, operation) — BSD-style advisory file locks |
| 281-400 | fcntl_lockf | lockf(fd, cmd, length, start, whence) — POSIX record locking |
Reading
fcntl()
// CPython: Modules/fcntlmodule.c:48 fcntl_fcntl
static PyObject *
fcntl_fcntl(PyObject *self, PyObject *args)
{
int fd, code;
/* Two call forms:
* fcntl(fd, cmd, int_arg=0) → fcntl(fd, cmd, int) returns int
* fcntl(fd, cmd, bytes_arg) → fcntl with struct arg, returns bytes
*/
if (PyArg_ParseTuple(args, "O&i|i:fcntl", conv_descriptor, &fd, &code, &arg)) {
Py_BEGIN_ALLOW_THREADS
ret = fcntl(fd, code, (int)arg);
Py_END_ALLOW_THREADS
return PyLong_FromLong((long)ret);
}
...
}
Common uses: fcntl.fcntl(fd, fcntl.F_SETFL, os.O_NONBLOCK) sets a socket to non-blocking mode.
ioctl()
// CPython: Modules/fcntlmodule.c:120 fcntl_ioctl
static PyObject *
fcntl_ioctl(PyObject *self, PyObject *args)
{
/* ioctl(fd, request, arg) — request is device-specific */
if (PyArg_ParseTuple(args, "O&k|iy*:ioctl", ...)) {
Py_BEGIN_ALLOW_THREADS
ret = ioctl(fd, code, &buf);
Py_END_ALLOW_THREADS
...
}
}
ioctl is used for terminal settings (TIOCGWINSZ for terminal size), network interfaces, and device-specific operations.
flock()
// CPython: Modules/fcntlmodule.c:215 fcntl_flock
static PyObject *
fcntl_flock(PyObject *self, PyObject *args)
{
int fd, code;
PyArg_ParseTuple(args, "O&i:flock", conv_descriptor, &fd, &code);
Py_BEGIN_ALLOW_THREADS
ret = flock(fd, code);
Py_END_ALLOW_THREADS
if (ret < 0) {
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}
Py_RETURN_NONE;
}
flock(fd, LOCK_EX) acquires an exclusive lock on the entire file. LOCK_SH is shared, LOCK_UN releases. Locks are per-open-file-description (not per-process).
lockf()
// CPython: Modules/fcntlmodule.c:305 fcntl_lockf
static PyObject *
fcntl_lockf(PyObject *self, PyObject *args)
{
int fd, code, whence = 0;
PyObject *lenobj = NULL, *startobj = NULL;
/* lockf(fd, cmd, length=0, start=0, whence=SEEK_SET) */
/* Wraps fcntl(fd, F_SETLKW/F_SETLK/F_GETLK) with struct flock */
...
}
lockf supports byte-range locking (lock part of a file). fcntl.LOCK_EX | fcntl.LOCK_NB is non-blocking.