1/*[clinic input]
2preserve
3[clinic start generated code]*/
4
5PyDoc_STRVAR(fcntl_fcntl__doc__,
6"fcntl($module, fd, cmd, arg=0, /)\n"
7"--\n"
8"\n"
9"Perform the operation `cmd` on file descriptor fd.\n"
10"\n"
11"The values used for `cmd` are operating system dependent, and are available\n"
12"as constants in the fcntl module, using the same names as used in\n"
13"the relevant C header files.  The argument arg is optional, and\n"
14"defaults to 0; it may be an int or a string.  If arg is given as a string,\n"
15"the return value of fcntl is a string of that length, containing the\n"
16"resulting value put in the arg buffer by the operating system.  The length\n"
17"of the arg string is not allowed to exceed 1024 bytes.  If the arg given\n"
18"is an integer or if none is specified, the result value is an integer\n"
19"corresponding to the return value of the fcntl call in the C code.");
20
21#define FCNTL_FCNTL_METHODDEF    \
22    {"fcntl", _PyCFunction_CAST(fcntl_fcntl), METH_FASTCALL, fcntl_fcntl__doc__},
23
24static PyObject *
25fcntl_fcntl_impl(PyObject *module, int fd, int code, PyObject *arg);
26
27static PyObject *
28fcntl_fcntl(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
29{
30    PyObject *return_value = NULL;
31    int fd;
32    int code;
33    PyObject *arg = NULL;
34
35    if (!_PyArg_CheckPositional("fcntl", nargs, 2, 3)) {
36        goto exit;
37    }
38    if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) {
39        goto exit;
40    }
41    code = _PyLong_AsInt(args[1]);
42    if (code == -1 && PyErr_Occurred()) {
43        goto exit;
44    }
45    if (nargs < 3) {
46        goto skip_optional;
47    }
48    arg = args[2];
49skip_optional:
50    return_value = fcntl_fcntl_impl(module, fd, code, arg);
51
52exit:
53    return return_value;
54}
55
56PyDoc_STRVAR(fcntl_ioctl__doc__,
57"ioctl($module, fd, request, arg=0, mutate_flag=True, /)\n"
58"--\n"
59"\n"
60"Perform the operation `request` on file descriptor `fd`.\n"
61"\n"
62"The values used for `request` are operating system dependent, and are available\n"
63"as constants in the fcntl or termios library modules, using the same names as\n"
64"used in the relevant C header files.\n"
65"\n"
66"The argument `arg` is optional, and defaults to 0; it may be an int or a\n"
67"buffer containing character data (most likely a string or an array).\n"
68"\n"
69"If the argument is a mutable buffer (such as an array) and if the\n"
70"mutate_flag argument (which is only allowed in this case) is true then the\n"
71"buffer is (in effect) passed to the operating system and changes made by\n"
72"the OS will be reflected in the contents of the buffer after the call has\n"
73"returned.  The return value is the integer returned by the ioctl system\n"
74"call.\n"
75"\n"
76"If the argument is a mutable buffer and the mutable_flag argument is false,\n"
77"the behavior is as if a string had been passed.\n"
78"\n"
79"If the argument is an immutable buffer (most likely a string) then a copy\n"
80"of the buffer is passed to the operating system and the return value is a\n"
81"string of the same length containing whatever the operating system put in\n"
82"the buffer.  The length of the arg buffer in this case is not allowed to\n"
83"exceed 1024 bytes.\n"
84"\n"
85"If the arg given is an integer or if none is specified, the result value is\n"
86"an integer corresponding to the return value of the ioctl call in the C\n"
87"code.");
88
89#define FCNTL_IOCTL_METHODDEF    \
90    {"ioctl", _PyCFunction_CAST(fcntl_ioctl), METH_FASTCALL, fcntl_ioctl__doc__},
91
92static PyObject *
93fcntl_ioctl_impl(PyObject *module, int fd, unsigned int code,
94                 PyObject *ob_arg, int mutate_arg);
95
96static PyObject *
97fcntl_ioctl(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
98{
99    PyObject *return_value = NULL;
100    int fd;
101    unsigned int code;
102    PyObject *ob_arg = NULL;
103    int mutate_arg = 1;
104
105    if (!_PyArg_CheckPositional("ioctl", nargs, 2, 4)) {
106        goto exit;
107    }
108    if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) {
109        goto exit;
110    }
111    code = (unsigned int)PyLong_AsUnsignedLongMask(args[1]);
112    if (code == (unsigned int)-1 && PyErr_Occurred()) {
113        goto exit;
114    }
115    if (nargs < 3) {
116        goto skip_optional;
117    }
118    ob_arg = args[2];
119    if (nargs < 4) {
120        goto skip_optional;
121    }
122    mutate_arg = PyObject_IsTrue(args[3]);
123    if (mutate_arg < 0) {
124        goto exit;
125    }
126skip_optional:
127    return_value = fcntl_ioctl_impl(module, fd, code, ob_arg, mutate_arg);
128
129exit:
130    return return_value;
131}
132
133PyDoc_STRVAR(fcntl_flock__doc__,
134"flock($module, fd, operation, /)\n"
135"--\n"
136"\n"
137"Perform the lock operation `operation` on file descriptor `fd`.\n"
138"\n"
139"See the Unix manual page for flock(2) for details (On some systems, this\n"
140"function is emulated using fcntl()).");
141
142#define FCNTL_FLOCK_METHODDEF    \
143    {"flock", _PyCFunction_CAST(fcntl_flock), METH_FASTCALL, fcntl_flock__doc__},
144
145static PyObject *
146fcntl_flock_impl(PyObject *module, int fd, int code);
147
148static PyObject *
149fcntl_flock(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
150{
151    PyObject *return_value = NULL;
152    int fd;
153    int code;
154
155    if (!_PyArg_CheckPositional("flock", nargs, 2, 2)) {
156        goto exit;
157    }
158    if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) {
159        goto exit;
160    }
161    code = _PyLong_AsInt(args[1]);
162    if (code == -1 && PyErr_Occurred()) {
163        goto exit;
164    }
165    return_value = fcntl_flock_impl(module, fd, code);
166
167exit:
168    return return_value;
169}
170
171PyDoc_STRVAR(fcntl_lockf__doc__,
172"lockf($module, fd, cmd, len=0, start=0, whence=0, /)\n"
173"--\n"
174"\n"
175"A wrapper around the fcntl() locking calls.\n"
176"\n"
177"`fd` is the file descriptor of the file to lock or unlock, and operation is one\n"
178"of the following values:\n"
179"\n"
180"    LOCK_UN - unlock\n"
181"    LOCK_SH - acquire a shared lock\n"
182"    LOCK_EX - acquire an exclusive lock\n"
183"\n"
184"When operation is LOCK_SH or LOCK_EX, it can also be bitwise ORed with\n"
185"LOCK_NB to avoid blocking on lock acquisition.  If LOCK_NB is used and the\n"
186"lock cannot be acquired, an OSError will be raised and the exception will\n"
187"have an errno attribute set to EACCES or EAGAIN (depending on the operating\n"
188"system -- for portability, check for either value).\n"
189"\n"
190"`len` is the number of bytes to lock, with the default meaning to lock to\n"
191"EOF.  `start` is the byte offset, relative to `whence`, to that the lock\n"
192"starts.  `whence` is as with fileobj.seek(), specifically:\n"
193"\n"
194"    0 - relative to the start of the file (SEEK_SET)\n"
195"    1 - relative to the current buffer position (SEEK_CUR)\n"
196"    2 - relative to the end of the file (SEEK_END)");
197
198#define FCNTL_LOCKF_METHODDEF    \
199    {"lockf", _PyCFunction_CAST(fcntl_lockf), METH_FASTCALL, fcntl_lockf__doc__},
200
201static PyObject *
202fcntl_lockf_impl(PyObject *module, int fd, int code, PyObject *lenobj,
203                 PyObject *startobj, int whence);
204
205static PyObject *
206fcntl_lockf(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
207{
208    PyObject *return_value = NULL;
209    int fd;
210    int code;
211    PyObject *lenobj = NULL;
212    PyObject *startobj = NULL;
213    int whence = 0;
214
215    if (!_PyArg_CheckPositional("lockf", nargs, 2, 5)) {
216        goto exit;
217    }
218    if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) {
219        goto exit;
220    }
221    code = _PyLong_AsInt(args[1]);
222    if (code == -1 && PyErr_Occurred()) {
223        goto exit;
224    }
225    if (nargs < 3) {
226        goto skip_optional;
227    }
228    lenobj = args[2];
229    if (nargs < 4) {
230        goto skip_optional;
231    }
232    startobj = args[3];
233    if (nargs < 5) {
234        goto skip_optional;
235    }
236    whence = _PyLong_AsInt(args[4]);
237    if (whence == -1 && PyErr_Occurred()) {
238        goto exit;
239    }
240skip_optional:
241    return_value = fcntl_lockf_impl(module, fd, code, lenobj, startobj, whence);
242
243exit:
244    return return_value;
245}
246/*[clinic end generated code: output=b8cb14ab35de4c6a input=a9049054013a1b77]*/
247