cpython: 6e6532d313a1 (original) (raw)
new file mode 100644
--- /dev/null
+++ b/Modules/clinic/fcntlmodule.c.h
@@ -0,0 +1,188 @@
+/[clinic input]
+preserve
+[clinic start generated code]/
+
+PyDoc_STRVAR(fcntl_fcntl__doc__,
+"fcntl($module, fd, code, arg=None, /)\n"
+"--\n"
+"\n"
+"Perform the operation code
on file descriptor fd.\n"
+"\n"
+"The values used for code
are operating system dependent, and are available\n"
+"as constants in the fcntl module, using the same names as used in\n"
+"the relevant C header files. The argument arg is optional, and\n"
+"defaults to 0; it may be an int or a string. If arg is given as a string,\n"
+"the return value of fcntl is a string of that length, containing the\n"
+"resulting value put in the arg buffer by the operating system. The length\n"
+"of the arg string is not allowed to exceed 1024 bytes. If the arg given\n"
+"is an integer or if none is specified, the result value is an integer\n"
+"corresponding to the return value of the fcntl call in the C code.");
+
+#define FCNTL_FCNTL_METHODDEF [](#l1.25)
+ +static PyObject * +fcntl_fcntl_impl(PyModuleDef *module, int fd, int code, PyObject *arg); + +static PyObject * +fcntl_fcntl(PyModuleDef *module, PyObject *args) +{
- if (!PyArg_ParseTuple(args,
"O&i|O:fcntl",[](#l1.40)
conv_descriptor, &fd, &code, &arg))[](#l1.41)
goto exit;[](#l1.42)
- return_value = fcntl_fcntl_impl(module, fd, code, arg);
+}
+
+PyDoc_STRVAR(fcntl_ioctl__doc__,
+"ioctl($module, fd, op, arg=None, mutate_flag=True, /)\n"
+"--\n"
+"\n"
+"Perform the operation op on file descriptor fd.\n"
+"\n"
+"The values used for op are operating system dependent, and are available as\n"
+"constants in the fcntl or termios library modules, using the same names as\n"
+"used in the relevant C header files.\n"
+"\n"
+"The argument arg
is optional, and defaults to 0; it may be an int or a\n"
+"buffer containing character data (most likely a string or an array).\n"
+"\n"
+"If the argument is a mutable buffer (such as an array) and if the\n"
+"mutate_flag argument (which is only allowed in this case) is true then the\n"
+"buffer is (in effect) passed to the operating system and changes made by\n"
+"the OS will be reflected in the contents of the buffer after the call has\n"
+"returned. The return value is the integer returned by the ioctl system\n"
+"call.\n"
+"\n"
+"If the argument is a mutable buffer and the mutable_flag argument is not\n"
+"passed or is false, the behavior is as if a string had been passed. This\n"
+"behavior will change in future releases of Python.\n"
+"\n"
+"If the argument is an immutable buffer (most likely a string) then a copy\n"
+"of the buffer is passed to the operating system and the return value is a\n"
+"string of the same length containing whatever the operating system put in\n"
+"the buffer. The length of the arg buffer in this case is not allowed to\n"
+"exceed 1024 bytes.\n"
+"\n"
+"If the arg given is an integer or if none is specified, the result value is\n"
+"an integer corresponding to the return value of the ioctl call in the C\n"
+"code.");
+
+#define FCNTL_IOCTL_METHODDEF [](#l1.83)
+ +static PyObject * +fcntl_ioctl_impl(PyModuleDef *module, int fd, unsigned int code, PyObject *ob_arg, int mutate_arg); + +static PyObject * +fcntl_ioctl(PyModuleDef *module, PyObject *args) +{
- PyObject *return_value = NULL;
- int fd;
- unsigned int code;
- PyObject *ob_arg = NULL;
- int mutate_arg = 1;
- if (!PyArg_ParseTuple(args,
"O&I|Op:ioctl",[](#l1.99)
conv_descriptor, &fd, &code, &ob_arg, &mutate_arg))[](#l1.100)
goto exit;[](#l1.101)
- return_value = fcntl_ioctl_impl(module, fd, code, ob_arg, mutate_arg);
+} + +PyDoc_STRVAR(fcntl_flock__doc__, +"flock($module, fd, code, /)\n" +"--\n" +"\n" +"Perform the lock operation op on file descriptor fd.\n" +"\n" +"See the Unix manual page for flock(2) for details (On some systems, this\n" +"function is emulated using fcntl())."); + +#define FCNTL_FLOCK_METHODDEF [](#l1.117)
+ +static PyObject * +fcntl_flock_impl(PyModuleDef *module, int fd, int code); + +static PyObject * +fcntl_flock(PyModuleDef *module, PyObject *args) +{
- if (!PyArg_ParseTuple(args,
"O&i:flock",[](#l1.131)
conv_descriptor, &fd, &code))[](#l1.132)
goto exit;[](#l1.133)
- return_value = fcntl_flock_impl(module, fd, code);
+} + +PyDoc_STRVAR(fcntl_lockf__doc__, +"lockf($module, fd, code, lenobj=None, startobj=None, whence=0, /)\n" +"--\n" +"\n" +"A wrapper around the fcntl() locking calls.\n" +"\n" +"fd is the file descriptor of the file to lock or unlock, and operation is one\n" +"of the following values:\n" +"\n" +" LOCK_UN - unlock\n" +" LOCK_SH - acquire a shared lock\n" +" LOCK_EX - acquire an exclusive lock\n" +"\n" +"When operation is LOCK_SH or LOCK_EX, it can also be bitwise ORed with\n" +"LOCK_NB to avoid blocking on lock acquisition. If LOCK_NB is used and the\n" +"lock cannot be acquired, an IOError will be raised and the exception will\n" +"have an errno attribute set to EACCES or EAGAIN (depending on the operating\n" +"system -- for portability, check for either value).\n" +"\n" +"length is the number of bytes to lock, with the default meaning to lock to\n" +"EOF. start is the byte offset, relative to whence, to that the lock\n" +"starts. whence is as with fileobj.seek(), specifically:\n" +"\n" +" 0 - relative to the start of the file (SEEK_SET)\n" +" 1 - relative to the current buffer position (SEEK_CUR)\n" +" 2 - relative to the end of the file (SEEK_END)"); + +#define FCNTL_LOCKF_METHODDEF [](#l1.167)
+ +static PyObject * +fcntl_lockf_impl(PyModuleDef *module, int fd, int code, PyObject *lenobj, PyObject *startobj, int whence); + +static PyObject * +fcntl_lockf(PyModuleDef *module, PyObject *args) +{
- PyObject *return_value = NULL;
- int fd;
- int code;
- PyObject *lenobj = NULL;
- PyObject *startobj = NULL;
- int whence = 0;
- if (!PyArg_ParseTuple(args,
"O&i|OOi:lockf",[](#l1.184)
conv_descriptor, &fd, &code, &lenobj, &startobj, &whence))[](#l1.185)
goto exit;[](#l1.186)
- return_value = fcntl_lockf_impl(module, fd, code, lenobj, startobj, whence);
+} +/[clinic end generated code: output=84bdde73a92f7c61 input=a9049054013a1b77]/
--- a/Modules/fcntlmodule.c +++ b/Modules/fcntlmodule.c @@ -15,6 +15,12 @@ #include <stropts.h> #endif +/[clinic input] +output preset file +module fcntl +[clinic start generated code]/ +/[clinic end generated code: output=da39a3ee5e6b4b0d input=c7356fdb126a904a]/ + static int conv_descriptor(PyObject *object, int *target) { @@ -26,48 +32,72 @@ conv_descriptor(PyObject *object, int t return 1; } +/ Must come after conv_descriptor definition. / +#include "clinic/fcntlmodule.c.h" -/ fcntl(fd, op, [arg]) / +/[clinic input] +fcntl.fcntl +
+
+Perform the operation code
on file descriptor fd.
+
+The values used for code
are operating system dependent, and are available
+as constants in the fcntl module, using the same names as used in
+the relevant C header files. The argument arg is optional, and
+defaults to 0; it may be an int or a string. If arg is given as a string,
+the return value of fcntl is a string of that length, containing the
+resulting value put in the arg buffer by the operating system. The length
+of the arg string is not allowed to exceed 1024 bytes. If the arg given
+is an integer or if none is specified, the result value is an integer
+corresponding to the return value of the fcntl call in the C code.
+[clinic start generated code]*/
static PyObject *
-fcntl_fcntl(PyObject *self, PyObject *args)
+fcntl_fcntl_impl(PyModuleDef module, int fd, int code, PyObject arg)
+/[clinic end generated code: output=afc5bfa74a03ef0d input=4850c13a41e86930]/
{
- if (PyArg_ParseTuple(args, "O&is#:fcntl",
conv_descriptor, &fd, &code, &str, &len)) {[](#l2.60)
if ((size_t)len > sizeof buf) {[](#l2.61)
PyErr_SetString(PyExc_ValueError,[](#l2.62)
"fcntl string arg too long");[](#l2.63)
return NULL;[](#l2.64)
if (PyArg_Parse(arg, "s#", &str, &len)) {[](#l2.68)
if ((size_t)len > sizeof buf) {[](#l2.69)
PyErr_SetString(PyExc_ValueError,[](#l2.70)
"fcntl string arg too long");[](#l2.71)
return NULL;[](#l2.72)
}[](#l2.73)
memcpy(buf, str, len);[](#l2.74)
Py_BEGIN_ALLOW_THREADS[](#l2.75)
ret = fcntl(fd, code, buf);[](#l2.76)
Py_END_ALLOW_THREADS[](#l2.77)
if (ret < 0) {[](#l2.78)
PyErr_SetFromErrno(PyExc_IOError);[](#l2.79)
return NULL;[](#l2.80)
}[](#l2.81)
return PyBytes_FromStringAndSize(buf, len);[](#l2.82) }[](#l2.83)
memcpy(buf, str, len);[](#l2.84)
Py_BEGIN_ALLOW_THREADS[](#l2.85)
ret = fcntl(fd, code, buf);[](#l2.86)
Py_END_ALLOW_THREADS[](#l2.87)
if (ret < 0) {[](#l2.88)
PyErr_SetFromErrno(PyExc_IOError);[](#l2.89)
return NULL;[](#l2.90)
PyErr_Clear();[](#l2.92)
parse_result = PyArg_Parse(arg,[](#l2.93)
"l;fcntl requires a file or file descriptor,"[](#l2.94)
" an integer and optionally a third integer or a string",[](#l2.95)
&int_arg);[](#l2.96)
if (!parse_result) {[](#l2.97)
return NULL;[](#l2.98) }[](#l2.99)
}return PyBytes_FromStringAndSize(buf, len);[](#l2.100)
- PyErr_Clear();
- arg = 0;
- if (!PyArg_ParseTuple(args,
"O&i|l;fcntl requires a file or file descriptor,"[](#l2.106)
" an integer and optionally a third integer or a string",[](#l2.107)
conv_descriptor, &fd, &code, &arg)) {[](#l2.108)
return NULL;[](#l2.109)
- } Py_BEGIN_ALLOW_THREADS
- ret = fcntl(fd, code, arg);
- ret = fcntl(fd, code, int_arg); Py_END_ALLOW_THREADS if (ret < 0) { PyErr_SetFromErrno(PyExc_IOError);
@@ -76,29 +106,53 @@ fcntl_fcntl(PyObject *self, PyObject ar return PyLong_FromLong((long)ret); } -PyDoc_STRVAR(fcntl_doc, -"fcntl(fd, op, [arg])\n[](#l2.122) -\n[](#l2.123) -Perform the operation op on file descriptor fd. The values used\n[](#l2.124) -for op are operating system dependent, and are available\n[](#l2.125) -as constants in the fcntl module, using the same names as used in\n[](#l2.126) -the relevant C header files. The argument arg is optional, and\n[](#l2.127) -defaults to 0; it may be an int or a string. If arg is given as a string,\n[](#l2.128) -the return value of fcntl is a string of that length, containing the\n[](#l2.129) -resulting value put in the arg buffer by the operating system. The length\n[](#l2.130) -of the arg string is not allowed to exceed 1024 bytes. If the arg given\n[](#l2.131) -is an integer or if none is specified, the result value is an integer\n[](#l2.132) -corresponding to the return value of the fcntl call in the C code."); + +/[clinic input] +fcntl.ioctl +
- fd: object(type='int', converter='conv_descriptor')
- op as code: unsigned_int(bitwise=True)
- arg as ob_arg: object = NULL
- mutate_flag as mutate_arg: bool = True
- /
+
+Perform the operation op on file descriptor fd.
+
+The values used for op are operating system dependent, and are available as
+constants in the fcntl or termios library modules, using the same names as
+used in the relevant C header files.
+
+The argument arg
is optional, and defaults to 0; it may be an int or a
+buffer containing character data (most likely a string or an array).
+If the argument is a mutable buffer (such as an array) and if the
+mutate_flag argument (which is only allowed in this case) is true then the
+buffer is (in effect) passed to the operating system and changes made by
+the OS will be reflected in the contents of the buffer after the call has
+returned. The return value is the integer returned by the ioctl system
+call.
-/* ioctl(fd, op, [arg]) /
+If the argument is a mutable buffer and the mutable_flag argument is not
+passed or is false, the behavior is as if a string had been passed. This
+behavior will change in future releases of Python.
+
+If the argument is an immutable buffer (most likely a string) then a copy
+of the buffer is passed to the operating system and the return value is a
+string of the same length containing whatever the operating system put in
+the buffer. The length of the arg buffer in this case is not allowed to
+exceed 1024 bytes.
+
+If the arg given is an integer or if none is specified, the result value is
+an integer corresponding to the return value of the ioctl call in the C
+code.
+[clinic start generated code]/
static PyObject *
-fcntl_ioctl(PyObject *self, PyObject *args)
+fcntl_ioctl_impl(PyModuleDef module, int fd, unsigned int code, PyObject ob_arg, int mutate_arg)
+/[clinic end generated code: output=ad47738c118622bf input=a55a6ee8e494c449]/
{
#define IOCTL_BUFSZ 1024
- /* We use the unsigned non-checked 'I' format for the 'code' parameter because Python turns 0x8000000 into either a large positive number (PyLong or PyInt on 64-bit platforms) or a negative number on others (32-bit PyInt) @@ -111,101 +165,98 @@ fcntl_ioctl(PyObject *self, PyObject *ar in their unsigned long ioctl codes this will break and need special casing based on the platform being built on. */
- int mutate_arg = 1; char buf[IOCTL_BUFSZ+1]; /* argument plus NUL byte */
- if (PyArg_ParseTuple(args, "O&Iw*|i:ioctl",
conv_descriptor, &fd, &code,[](#l2.203)
&pstr, &mutate_arg)) {[](#l2.204)
char *arg;[](#l2.205)
str = pstr.buf;[](#l2.206)
len = pstr.len;[](#l2.207)
- if (ob_arg != NULL) {
if (PyArg_Parse(ob_arg, "w*:ioctl", &pstr)) {[](#l2.209)
char *arg;[](#l2.210)
str = pstr.buf;[](#l2.211)
len = pstr.len;[](#l2.212)
if (mutate_arg) {[](#l2.214)
if (len <= IOCTL_BUFSZ) {[](#l2.215)
memcpy(buf, str, len);[](#l2.216)
buf[len] = '\0';[](#l2.217)
arg = buf;[](#l2.218)
if (mutate_arg) {[](#l2.219)
if (len <= IOCTL_BUFSZ) {[](#l2.220)
memcpy(buf, str, len);[](#l2.221)
buf[len] = '\0';[](#l2.222)
arg = buf;[](#l2.223)
}[](#l2.224)
else {[](#l2.225)
arg = str;[](#l2.226)
}[](#l2.227) }[](#l2.228) else {[](#l2.229)
arg = str;[](#l2.230)
if (len > IOCTL_BUFSZ) {[](#l2.231)
PyBuffer_Release(&pstr);[](#l2.232)
PyErr_SetString(PyExc_ValueError,[](#l2.233)
"ioctl string arg too long");[](#l2.234)
return NULL;[](#l2.235)
}[](#l2.236)
else {[](#l2.237)
memcpy(buf, str, len);[](#l2.238)
buf[len] = '\0';[](#l2.239)
arg = buf;[](#l2.240)
}[](#l2.241)
}[](#l2.242)
if (buf == arg) {[](#l2.243)
Py_BEGIN_ALLOW_THREADS /* think array.resize() */[](#l2.244)
ret = ioctl(fd, code, arg);[](#l2.245)
Py_END_ALLOW_THREADS[](#l2.246)
}[](#l2.247)
else {[](#l2.248)
ret = ioctl(fd, code, arg);[](#l2.249)
}[](#l2.250)
if (mutate_arg && (len <= IOCTL_BUFSZ)) {[](#l2.251)
memcpy(str, buf, len);[](#l2.252)
}[](#l2.253)
PyBuffer_Release(&pstr); /* No further access to str below this point */[](#l2.254)
if (ret < 0) {[](#l2.255)
PyErr_SetFromErrno(PyExc_IOError);[](#l2.256)
return NULL;[](#l2.257)
}[](#l2.258)
if (mutate_arg) {[](#l2.259)
return PyLong_FromLong(ret);[](#l2.260)
}[](#l2.261)
else {[](#l2.262)
return PyBytes_FromStringAndSize(buf, len);[](#l2.263) }[](#l2.264) }[](#l2.265)
else {[](#l2.266)
PyErr_Clear();[](#l2.268)
if (PyArg_Parse(ob_arg, "s*:ioctl", &pstr)) {[](#l2.269)
str = pstr.buf;[](#l2.270)
len = pstr.len;[](#l2.271) if (len > IOCTL_BUFSZ) {[](#l2.272) PyBuffer_Release(&pstr);[](#l2.273) PyErr_SetString(PyExc_ValueError,[](#l2.274)
"ioctl string arg too long");[](#l2.275)
"ioctl string arg too long");[](#l2.276) return NULL;[](#l2.277) }[](#l2.278)
else {[](#l2.279)
memcpy(buf, str, len);[](#l2.280)
buf[len] = '\0';[](#l2.281)
arg = buf;[](#l2.282)
}[](#l2.283)
}[](#l2.284)
if (buf == arg) {[](#l2.285)
Py_BEGIN_ALLOW_THREADS /* think array.resize() */[](#l2.286)
ret = ioctl(fd, code, arg);[](#l2.287)
memcpy(buf, str, len);[](#l2.288)
buf[len] = '\0';[](#l2.289)
Py_BEGIN_ALLOW_THREADS[](#l2.290)
ret = ioctl(fd, code, buf);[](#l2.291) Py_END_ALLOW_THREADS[](#l2.292)
}[](#l2.293)
else {[](#l2.294)
ret = ioctl(fd, code, arg);[](#l2.295)
}[](#l2.296)
if (mutate_arg && (len <= IOCTL_BUFSZ)) {[](#l2.297)
memcpy(str, buf, len);[](#l2.298)
}[](#l2.299)
PyBuffer_Release(&pstr); /* No further access to str below this point */[](#l2.300)
if (ret < 0) {[](#l2.301)
PyErr_SetFromErrno(PyExc_IOError);[](#l2.302)
return NULL;[](#l2.303)
}[](#l2.304)
if (mutate_arg) {[](#l2.305)
return PyLong_FromLong(ret);[](#l2.306)
}[](#l2.307)
else {[](#l2.308)
if (ret < 0) {[](#l2.309)
PyBuffer_Release(&pstr);[](#l2.310)
PyErr_SetFromErrno(PyExc_IOError);[](#l2.311)
return NULL;[](#l2.312)
}[](#l2.313)
PyBuffer_Release(&pstr);[](#l2.314) return PyBytes_FromStringAndSize(buf, len);[](#l2.315) }[](#l2.316)
- PyErr_Clear();
- if (PyArg_ParseTuple(args, "O&Is*:ioctl",
conv_descriptor, &fd, &code, &pstr)) {[](#l2.321)
str = pstr.buf;[](#l2.322)
len = pstr.len;[](#l2.323)
if (len > IOCTL_BUFSZ) {[](#l2.324)
PyBuffer_Release(&pstr);[](#l2.325)
PyErr_SetString(PyExc_ValueError,[](#l2.326)
"ioctl string arg too long");[](#l2.327)
return NULL;[](#l2.328)
PyErr_Clear();[](#l2.329)
if (!PyArg_Parse(ob_arg,[](#l2.330)
"i;ioctl requires a file or file descriptor,"[](#l2.331)
" an integer and optionally an integer or buffer argument",[](#l2.332)
&arg)) {[](#l2.333)
return NULL;[](#l2.334) }[](#l2.335)
memcpy(buf, str, len);[](#l2.336)
buf[len] = '\0';[](#l2.337)
Py_BEGIN_ALLOW_THREADS[](#l2.338)
ret = ioctl(fd, code, buf);[](#l2.339)
Py_END_ALLOW_THREADS[](#l2.340)
if (ret < 0) {[](#l2.341)
PyBuffer_Release(&pstr);[](#l2.342)
PyErr_SetFromErrno(PyExc_IOError);[](#l2.343)
return NULL;[](#l2.344)
}[](#l2.345)
PyBuffer_Release(&pstr);[](#l2.346)
return PyBytes_FromStringAndSize(buf, len);[](#l2.347)
- }
- PyErr_Clear();
- arg = 0;
- if (!PyArg_ParseTuple(args,
"O&I|i;ioctl requires a file or file descriptor,"[](#l2.353)
" an integer and optionally an integer or buffer argument",[](#l2.354)
conv_descriptor, &fd, &code, &arg)) {[](#l2.355)
return NULL;[](#l2.356)
} Py_BEGIN_ALLOW_THREADS ret = ioctl(fd, code, arg); @@ -218,52 +269,25 @@ fcntl_ioctl(PyObject *self, PyObject *ar// Fall-through to outside the 'if' statement.[](#l2.357)
#undef IOCTL_BUFSZ } -PyDoc_STRVAR(ioctl_doc, -"ioctl(fd, op[, arg[, mutate_flag]])\n[](#l2.366) -\n[](#l2.367) -Perform the operation op on file descriptor fd. The values used for op\n[](#l2.368) -are operating system dependent, and are available as constants in the\n[](#l2.369) -fcntl or termios library modules, using the same names as used in the\n[](#l2.370) -relevant C header files.\n[](#l2.371) -\n[](#l2.372) -The argument arg is optional, and defaults to 0; it may be an int or a\n[](#l2.373) -buffer containing character data (most likely a string or an array). \n[](#l2.374) -\n[](#l2.375) -If the argument is a mutable buffer (such as an array) and if the\n[](#l2.376) -mutate_flag argument (which is only allowed in this case) is true then the\n[](#l2.377) -buffer is (in effect) passed to the operating system and changes made by\n[](#l2.378) -the OS will be reflected in the contents of the buffer after the call has\n[](#l2.379) -returned. The return value is the integer returned by the ioctl system\n[](#l2.380) -call.\n[](#l2.381) -\n[](#l2.382) -If the argument is a mutable buffer and the mutable_flag argument is not\n[](#l2.383) -passed or is false, the behavior is as if a string had been passed. This\n[](#l2.384) -behavior will change in future releases of Python.\n[](#l2.385) -\n[](#l2.386) -If the argument is an immutable buffer (most likely a string) then a copy\n[](#l2.387) -of the buffer is passed to the operating system and the return value is a\n[](#l2.388) -string of the same length containing whatever the operating system put in\n[](#l2.389) -the buffer. The length of the arg buffer in this case is not allowed to\n[](#l2.390) -exceed 1024 bytes.\n[](#l2.391) -\n[](#l2.392) -If the arg given is an integer or if none is specified, the result value is\n[](#l2.393) -an integer corresponding to the return value of the ioctl call in the C\n[](#l2.394) -code."); +/*[clinic input] +fcntl.flock
-/* flock(fd, operation) / +Perform the lock operation op on file descriptor fd. + +See the Unix manual page for flock(2) for details (On some systems, this +function is emulated using fcntl()). +[clinic start generated code]/ static PyObject * -fcntl_flock(PyObject *self, PyObject args) +fcntl_flock_impl(PyModuleDef module, int fd, int code) +/[clinic end generated code: output=c9035133a7dbfc96 input=b762aa9448d05e43]/ {
- int fd;
- int code; int ret;
- if (!PyArg_ParseTuple(args, "O&i:flock",
conv_descriptor, &fd, &code))[](#l2.420)
return NULL;[](#l2.421)
- #ifdef HAVE_FLOCK Py_BEGIN_ALLOW_THREADS ret = flock(fd, code); @@ -299,29 +323,49 @@ fcntl_flock(PyObject *self, PyObject *ar PyErr_SetFromErrno(PyExc_IOError); return NULL; }
} -PyDoc_STRVAR(flock_doc, -"flock(fd, operation)\n[](#l2.436) -\n[](#l2.437) -Perform the lock operation op on file descriptor fd. See the Unix \n[](#l2.438) -manual page for flock(2) for details. (On some systems, this function is\n[](#l2.439) -emulated using fcntl().)"); - -/* lockf(fd, operation) / +/[clinic input] +fcntl.lockf +
- fd: object(type='int', converter='conv_descriptor')
- code: int
- lenobj: object = NULL
- startobj: object = NULL
- whence: int = 0
- /
+ +A wrapper around the fcntl() locking calls. + +fd is the file descriptor of the file to lock or unlock, and operation is one +of the following values: +
+ +When operation is LOCK_SH or LOCK_EX, it can also be bitwise ORed with +LOCK_NB to avoid blocking on lock acquisition. If LOCK_NB is used and the +lock cannot be acquired, an IOError will be raised and the exception will +have an errno attribute set to EACCES or EAGAIN (depending on the operating +system -- for portability, check for either value). + +length is the number of bytes to lock, with the default meaning to lock to +EOF. start is the byte offset, relative to whence, to that the lock +starts. whence is as with fileobj.seek(), specifically: +
- 0 - relative to the start of the file (SEEK_SET)
- 1 - relative to the current buffer position (SEEK_CUR)
- 2 - relative to the end of the file (SEEK_END)
+[clinic start generated code]*/ + static PyObject * -fcntl_lockf(PyObject *self, PyObject *args) +fcntl_lockf_impl(PyModuleDef *module, int fd, int code, PyObject lenobj, PyObject startobj, int whence) +/[clinic end generated code: output=5536df2892bf3ce9 input=44856fa06db36184]/ {
- if (!PyArg_ParseTuple(args, "O&i|OOi:lockf",
conv_descriptor, &fd, &code,[](#l2.487)
&lenobj, &startobj, &whence))[](#l2.488)
return NULL;[](#l2.489)
#ifndef LOCK_SH #define LOCK_SH 1 /* shared lock */ @@ -374,43 +418,17 @@ fcntl_lockf(PyObject *self, PyObject *ar PyErr_SetFromErrno(PyExc_IOError); return NULL; }
} -PyDoc_STRVAR(lockf_doc, -"lockf (fd, operation, length=0, start=0, whence=0)\n[](#l2.504) -\n[](#l2.505) -This is essentially a wrapper around the fcntl() locking calls. fd is the\n[](#l2.506) -file descriptor of the file to lock or unlock, and operation is one of the\n[](#l2.507) -following values:\n[](#l2.508) -\n[](#l2.509)
- LOCK_UN - unlock\n[](#l2.510)
- LOCK_SH - acquire a shared lock\n[](#l2.511)
- LOCK_EX - acquire an exclusive lock\n[](#l2.512)
-\n[](#l2.513) -When operation is LOCK_SH or LOCK_EX, it can also be bitwise ORed with\n[](#l2.514) -LOCK_NB to avoid blocking on lock acquisition. If LOCK_NB is used and the\n[](#l2.515) -lock cannot be acquired, an IOError will be raised and the exception will\n[](#l2.516) -have an errno attribute set to EACCES or EAGAIN (depending on the operating\n[](#l2.517) -system -- for portability, check for either value).\n[](#l2.518) -\n[](#l2.519) -length is the number of bytes to lock, with the default meaning to lock to\n[](#l2.520) -EOF. start is the byte offset, relative to whence, to that the lock\n[](#l2.521) -starts. whence is as with fileobj.seek(), specifically:\n[](#l2.522) -\n[](#l2.523)
- 0 - relative to the start of the file (SEEK_SET)\n[](#l2.524)
- 1 - relative to the current buffer position (SEEK_CUR)\n[](#l2.525)
- 2 - relative to the end of the file (SEEK_END)");
- /* List of functions */ static PyMethodDef fcntl_methods[] = {
- {"fcntl", fcntl_fcntl, METH_VARARGS, fcntl_doc},
- {"ioctl", fcntl_ioctl, METH_VARARGS, ioctl_doc},
- {"flock", fcntl_flock, METH_VARARGS, flock_doc},
- {"lockf", fcntl_lockf, METH_VARARGS, lockf_doc},
- {NULL, NULL} /* sentinel */