1 2/* fcntl module */ 3 4#define PY_SSIZE_T_CLEAN 5 6#include "Python.h" 7 8#ifdef HAVE_SYS_FILE_H 9#include <sys/file.h> 10#endif 11 12#include <sys/ioctl.h> 13#include <fcntl.h> 14#ifdef HAVE_STROPTS_H 15#include <stropts.h> 16#endif 17 18/*[clinic input] 19module fcntl 20[clinic start generated code]*/ 21/*[clinic end generated code: output=da39a3ee5e6b4b0d input=124b58387c158179]*/ 22 23#include "clinic/fcntlmodule.c.h" 24 25/*[clinic input] 26fcntl.fcntl 27 28 fd: fildes 29 cmd as code: int 30 arg: object(c_default='NULL') = 0 31 / 32 33Perform the operation `cmd` on file descriptor fd. 34 35The values used for `cmd` are operating system dependent, and are available 36as constants in the fcntl module, using the same names as used in 37the relevant C header files. The argument arg is optional, and 38defaults to 0; it may be an int or a string. If arg is given as a string, 39the return value of fcntl is a string of that length, containing the 40resulting value put in the arg buffer by the operating system. The length 41of the arg string is not allowed to exceed 1024 bytes. If the arg given 42is an integer or if none is specified, the result value is an integer 43corresponding to the return value of the fcntl call in the C code. 44[clinic start generated code]*/ 45 46static PyObject * 47fcntl_fcntl_impl(PyObject *module, int fd, int code, PyObject *arg) 48/*[clinic end generated code: output=888fc93b51c295bd input=7955340198e5f334]*/ 49{ 50 unsigned int int_arg = 0; 51 int ret; 52 char *str; 53 Py_ssize_t len; 54 char buf[1024]; 55 int async_err = 0; 56 57 if (PySys_Audit("fcntl.fcntl", "iiO", fd, code, arg ? arg : Py_None) < 0) { 58 return NULL; 59 } 60 61 if (arg != NULL) { 62 int parse_result; 63 64 if (PyArg_Parse(arg, "s#", &str, &len)) { 65 if ((size_t)len > sizeof buf) { 66 PyErr_SetString(PyExc_ValueError, 67 "fcntl string arg too long"); 68 return NULL; 69 } 70 memcpy(buf, str, len); 71 do { 72 Py_BEGIN_ALLOW_THREADS 73 ret = fcntl(fd, code, buf); 74 Py_END_ALLOW_THREADS 75 } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals())); 76 if (ret < 0) { 77 return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL; 78 } 79 return PyBytes_FromStringAndSize(buf, len); 80 } 81 82 PyErr_Clear(); 83 parse_result = PyArg_Parse(arg, 84 "I;fcntl requires a file or file descriptor," 85 " an integer and optionally a third integer or a string", 86 &int_arg); 87 if (!parse_result) { 88 return NULL; 89 } 90 } 91 92 do { 93 Py_BEGIN_ALLOW_THREADS 94 ret = fcntl(fd, code, (int)int_arg); 95 Py_END_ALLOW_THREADS 96 } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals())); 97 if (ret < 0) { 98 return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL; 99 } 100 return PyLong_FromLong((long)ret); 101} 102 103 104/*[clinic input] 105fcntl.ioctl 106 107 fd: fildes 108 request as code: unsigned_int(bitwise=True) 109 arg as ob_arg: object(c_default='NULL') = 0 110 mutate_flag as mutate_arg: bool = True 111 / 112 113Perform the operation `request` on file descriptor `fd`. 114 115The values used for `request` are operating system dependent, and are available 116as constants in the fcntl or termios library modules, using the same names as 117used in the relevant C header files. 118 119The argument `arg` is optional, and defaults to 0; it may be an int or a 120buffer containing character data (most likely a string or an array). 121 122If the argument is a mutable buffer (such as an array) and if the 123mutate_flag argument (which is only allowed in this case) is true then the 124buffer is (in effect) passed to the operating system and changes made by 125the OS will be reflected in the contents of the buffer after the call has 126returned. The return value is the integer returned by the ioctl system 127call. 128 129If the argument is a mutable buffer and the mutable_flag argument is false, 130the behavior is as if a string had been passed. 131 132If the argument is an immutable buffer (most likely a string) then a copy 133of the buffer is passed to the operating system and the return value is a 134string of the same length containing whatever the operating system put in 135the buffer. The length of the arg buffer in this case is not allowed to 136exceed 1024 bytes. 137 138If the arg given is an integer or if none is specified, the result value is 139an integer corresponding to the return value of the ioctl call in the C 140code. 141[clinic start generated code]*/ 142 143static PyObject * 144fcntl_ioctl_impl(PyObject *module, int fd, unsigned int code, 145 PyObject *ob_arg, int mutate_arg) 146/*[clinic end generated code: output=7f7f5840c65991be input=967b4a4cbeceb0a8]*/ 147{ 148#define IOCTL_BUFSZ 1024 149 /* We use the unsigned non-checked 'I' format for the 'code' parameter 150 because the system expects it to be a 32bit bit field value 151 regardless of it being passed as an int or unsigned long on 152 various platforms. See the termios.TIOCSWINSZ constant across 153 platforms for an example of this. 154 155 If any of the 64bit platforms ever decide to use more than 32bits 156 in their unsigned long ioctl codes this will break and need 157 special casing based on the platform being built on. 158 */ 159 int arg = 0; 160 int ret; 161 Py_buffer pstr; 162 char *str; 163 Py_ssize_t len; 164 char buf[IOCTL_BUFSZ+1]; /* argument plus NUL byte */ 165 166 if (PySys_Audit("fcntl.ioctl", "iIO", fd, code, 167 ob_arg ? ob_arg : Py_None) < 0) { 168 return NULL; 169 } 170 171 if (ob_arg != NULL) { 172 if (PyArg_Parse(ob_arg, "w*:ioctl", &pstr)) { 173 char *arg; 174 str = pstr.buf; 175 len = pstr.len; 176 177 if (mutate_arg) { 178 if (len <= IOCTL_BUFSZ) { 179 memcpy(buf, str, len); 180 buf[len] = '\0'; 181 arg = buf; 182 } 183 else { 184 arg = str; 185 } 186 } 187 else { 188 if (len > IOCTL_BUFSZ) { 189 PyBuffer_Release(&pstr); 190 PyErr_SetString(PyExc_ValueError, 191 "ioctl string arg too long"); 192 return NULL; 193 } 194 else { 195 memcpy(buf, str, len); 196 buf[len] = '\0'; 197 arg = buf; 198 } 199 } 200 if (buf == arg) { 201 Py_BEGIN_ALLOW_THREADS /* think array.resize() */ 202 ret = ioctl(fd, code, arg); 203 Py_END_ALLOW_THREADS 204 } 205 else { 206 ret = ioctl(fd, code, arg); 207 } 208 if (mutate_arg && (len <= IOCTL_BUFSZ)) { 209 memcpy(str, buf, len); 210 } 211 PyBuffer_Release(&pstr); /* No further access to str below this point */ 212 if (ret < 0) { 213 PyErr_SetFromErrno(PyExc_OSError); 214 return NULL; 215 } 216 if (mutate_arg) { 217 return PyLong_FromLong(ret); 218 } 219 else { 220 return PyBytes_FromStringAndSize(buf, len); 221 } 222 } 223 224 PyErr_Clear(); 225 if (PyArg_Parse(ob_arg, "s*:ioctl", &pstr)) { 226 str = pstr.buf; 227 len = pstr.len; 228 if (len > IOCTL_BUFSZ) { 229 PyBuffer_Release(&pstr); 230 PyErr_SetString(PyExc_ValueError, 231 "ioctl string arg too long"); 232 return NULL; 233 } 234 memcpy(buf, str, len); 235 buf[len] = '\0'; 236 Py_BEGIN_ALLOW_THREADS 237 ret = ioctl(fd, code, buf); 238 Py_END_ALLOW_THREADS 239 if (ret < 0) { 240 PyBuffer_Release(&pstr); 241 PyErr_SetFromErrno(PyExc_OSError); 242 return NULL; 243 } 244 PyBuffer_Release(&pstr); 245 return PyBytes_FromStringAndSize(buf, len); 246 } 247 248 PyErr_Clear(); 249 if (!PyArg_Parse(ob_arg, 250 "i;ioctl requires a file or file descriptor," 251 " an integer and optionally an integer or buffer argument", 252 &arg)) { 253 return NULL; 254 } 255 // Fall-through to outside the 'if' statement. 256 } 257 Py_BEGIN_ALLOW_THREADS 258 ret = ioctl(fd, code, arg); 259 Py_END_ALLOW_THREADS 260 if (ret < 0) { 261 PyErr_SetFromErrno(PyExc_OSError); 262 return NULL; 263 } 264 return PyLong_FromLong((long)ret); 265#undef IOCTL_BUFSZ 266} 267 268/*[clinic input] 269fcntl.flock 270 271 fd: fildes 272 operation as code: int 273 / 274 275Perform the lock operation `operation` on file descriptor `fd`. 276 277See the Unix manual page for flock(2) for details (On some systems, this 278function is emulated using fcntl()). 279[clinic start generated code]*/ 280 281static PyObject * 282fcntl_flock_impl(PyObject *module, int fd, int code) 283/*[clinic end generated code: output=84059e2b37d2fc64 input=0bfc00f795953452]*/ 284{ 285 int ret; 286 int async_err = 0; 287 288 if (PySys_Audit("fcntl.flock", "ii", fd, code) < 0) { 289 return NULL; 290 } 291 292#ifdef HAVE_FLOCK 293 do { 294 Py_BEGIN_ALLOW_THREADS 295 ret = flock(fd, code); 296 Py_END_ALLOW_THREADS 297 } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals())); 298#else 299 300#ifndef LOCK_SH 301#define LOCK_SH 1 /* shared lock */ 302#define LOCK_EX 2 /* exclusive lock */ 303#define LOCK_NB 4 /* don't block when locking */ 304#define LOCK_UN 8 /* unlock */ 305#endif 306 { 307 struct flock l; 308 if (code == LOCK_UN) 309 l.l_type = F_UNLCK; 310 else if (code & LOCK_SH) 311 l.l_type = F_RDLCK; 312 else if (code & LOCK_EX) 313 l.l_type = F_WRLCK; 314 else { 315 PyErr_SetString(PyExc_ValueError, 316 "unrecognized flock argument"); 317 return NULL; 318 } 319 l.l_whence = l.l_start = l.l_len = 0; 320 do { 321 Py_BEGIN_ALLOW_THREADS 322 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l); 323 Py_END_ALLOW_THREADS 324 } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals())); 325 } 326#endif /* HAVE_FLOCK */ 327 if (ret < 0) { 328 return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL; 329 } 330 Py_RETURN_NONE; 331} 332 333 334/*[clinic input] 335fcntl.lockf 336 337 fd: fildes 338 cmd as code: int 339 len as lenobj: object(c_default='NULL') = 0 340 start as startobj: object(c_default='NULL') = 0 341 whence: int = 0 342 / 343 344A wrapper around the fcntl() locking calls. 345 346`fd` is the file descriptor of the file to lock or unlock, and operation is one 347of the following values: 348 349 LOCK_UN - unlock 350 LOCK_SH - acquire a shared lock 351 LOCK_EX - acquire an exclusive lock 352 353When operation is LOCK_SH or LOCK_EX, it can also be bitwise ORed with 354LOCK_NB to avoid blocking on lock acquisition. If LOCK_NB is used and the 355lock cannot be acquired, an OSError will be raised and the exception will 356have an errno attribute set to EACCES or EAGAIN (depending on the operating 357system -- for portability, check for either value). 358 359`len` is the number of bytes to lock, with the default meaning to lock to 360EOF. `start` is the byte offset, relative to `whence`, to that the lock 361starts. `whence` is as with fileobj.seek(), specifically: 362 363 0 - relative to the start of the file (SEEK_SET) 364 1 - relative to the current buffer position (SEEK_CUR) 365 2 - relative to the end of the file (SEEK_END) 366[clinic start generated code]*/ 367 368static PyObject * 369fcntl_lockf_impl(PyObject *module, int fd, int code, PyObject *lenobj, 370 PyObject *startobj, int whence) 371/*[clinic end generated code: output=4985e7a172e7461a input=5480479fc63a04b8]*/ 372{ 373 int ret; 374 int async_err = 0; 375 376 if (PySys_Audit("fcntl.lockf", "iiOOi", fd, code, lenobj ? lenobj : Py_None, 377 startobj ? startobj : Py_None, whence) < 0) { 378 return NULL; 379 } 380 381#ifndef LOCK_SH 382#define LOCK_SH 1 /* shared lock */ 383#define LOCK_EX 2 /* exclusive lock */ 384#define LOCK_NB 4 /* don't block when locking */ 385#define LOCK_UN 8 /* unlock */ 386#endif /* LOCK_SH */ 387 { 388 struct flock l; 389 if (code == LOCK_UN) 390 l.l_type = F_UNLCK; 391 else if (code & LOCK_SH) 392 l.l_type = F_RDLCK; 393 else if (code & LOCK_EX) 394 l.l_type = F_WRLCK; 395 else { 396 PyErr_SetString(PyExc_ValueError, 397 "unrecognized lockf argument"); 398 return NULL; 399 } 400 l.l_start = l.l_len = 0; 401 if (startobj != NULL) { 402#if !defined(HAVE_LARGEFILE_SUPPORT) 403 l.l_start = PyLong_AsLong(startobj); 404#else 405 l.l_start = PyLong_Check(startobj) ? 406 PyLong_AsLongLong(startobj) : 407 PyLong_AsLong(startobj); 408#endif 409 if (PyErr_Occurred()) 410 return NULL; 411 } 412 if (lenobj != NULL) { 413#if !defined(HAVE_LARGEFILE_SUPPORT) 414 l.l_len = PyLong_AsLong(lenobj); 415#else 416 l.l_len = PyLong_Check(lenobj) ? 417 PyLong_AsLongLong(lenobj) : 418 PyLong_AsLong(lenobj); 419#endif 420 if (PyErr_Occurred()) 421 return NULL; 422 } 423 l.l_whence = whence; 424 do { 425 Py_BEGIN_ALLOW_THREADS 426 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l); 427 Py_END_ALLOW_THREADS 428 } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals())); 429 } 430 if (ret < 0) { 431 return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL; 432 } 433 Py_RETURN_NONE; 434} 435 436/* List of functions */ 437 438static PyMethodDef fcntl_methods[] = { 439 FCNTL_FCNTL_METHODDEF 440 FCNTL_IOCTL_METHODDEF 441 FCNTL_FLOCK_METHODDEF 442 FCNTL_LOCKF_METHODDEF 443 {NULL, NULL} /* sentinel */ 444}; 445 446 447PyDoc_STRVAR(module_doc, 448"This module performs file control and I/O control on file\n\ 449descriptors. It is an interface to the fcntl() and ioctl() Unix\n\ 450routines. File descriptors can be obtained with the fileno() method of\n\ 451a file or socket object."); 452 453/* Module initialisation */ 454 455 456static int 457all_ins(PyObject* m) 458{ 459 if (PyModule_AddIntMacro(m, LOCK_SH)) return -1; 460 if (PyModule_AddIntMacro(m, LOCK_EX)) return -1; 461 if (PyModule_AddIntMacro(m, LOCK_NB)) return -1; 462 if (PyModule_AddIntMacro(m, LOCK_UN)) return -1; 463/* GNU extensions, as of glibc 2.2.4 */ 464#ifdef LOCK_MAND 465 if (PyModule_AddIntMacro(m, LOCK_MAND)) return -1; 466#endif 467#ifdef LOCK_READ 468 if (PyModule_AddIntMacro(m, LOCK_READ)) return -1; 469#endif 470#ifdef LOCK_WRITE 471 if (PyModule_AddIntMacro(m, LOCK_WRITE)) return -1; 472#endif 473#ifdef LOCK_RW 474 if (PyModule_AddIntMacro(m, LOCK_RW)) return -1; 475#endif 476 477#ifdef F_DUPFD 478 if (PyModule_AddIntMacro(m, F_DUPFD)) return -1; 479#endif 480#ifdef F_DUPFD_CLOEXEC 481 if (PyModule_AddIntMacro(m, F_DUPFD_CLOEXEC)) return -1; 482#endif 483#ifdef F_GETFD 484 if (PyModule_AddIntMacro(m, F_GETFD)) return -1; 485#endif 486#ifdef F_SETFD 487 if (PyModule_AddIntMacro(m, F_SETFD)) return -1; 488#endif 489#ifdef F_GETFL 490 if (PyModule_AddIntMacro(m, F_GETFL)) return -1; 491#endif 492#ifdef F_SETFL 493 if (PyModule_AddIntMacro(m, F_SETFL)) return -1; 494#endif 495#ifdef F_GETLK 496 if (PyModule_AddIntMacro(m, F_GETLK)) return -1; 497#endif 498#ifdef F_SETLK 499 if (PyModule_AddIntMacro(m, F_SETLK)) return -1; 500#endif 501#ifdef F_SETLKW 502 if (PyModule_AddIntMacro(m, F_SETLKW)) return -1; 503#endif 504#ifdef F_OFD_GETLK 505 if (PyModule_AddIntMacro(m, F_OFD_GETLK)) return -1; 506#endif 507#ifdef F_OFD_SETLK 508 if (PyModule_AddIntMacro(m, F_OFD_SETLK)) return -1; 509#endif 510#ifdef F_OFD_SETLKW 511 if (PyModule_AddIntMacro(m, F_OFD_SETLKW)) return -1; 512#endif 513#ifdef F_GETOWN 514 if (PyModule_AddIntMacro(m, F_GETOWN)) return -1; 515#endif 516#ifdef F_SETOWN 517 if (PyModule_AddIntMacro(m, F_SETOWN)) return -1; 518#endif 519#ifdef F_GETPATH 520 if (PyModule_AddIntMacro(m, F_GETPATH)) return -1; 521#endif 522#ifdef F_GETSIG 523 if (PyModule_AddIntMacro(m, F_GETSIG)) return -1; 524#endif 525#ifdef F_SETSIG 526 if (PyModule_AddIntMacro(m, F_SETSIG)) return -1; 527#endif 528#ifdef F_RDLCK 529 if (PyModule_AddIntMacro(m, F_RDLCK)) return -1; 530#endif 531#ifdef F_WRLCK 532 if (PyModule_AddIntMacro(m, F_WRLCK)) return -1; 533#endif 534#ifdef F_UNLCK 535 if (PyModule_AddIntMacro(m, F_UNLCK)) return -1; 536#endif 537/* LFS constants */ 538#ifdef F_GETLK64 539 if (PyModule_AddIntMacro(m, F_GETLK64)) return -1; 540#endif 541#ifdef F_SETLK64 542 if (PyModule_AddIntMacro(m, F_SETLK64)) return -1; 543#endif 544#ifdef F_SETLKW64 545 if (PyModule_AddIntMacro(m, F_SETLKW64)) return -1; 546#endif 547/* GNU extensions, as of glibc 2.2.4. */ 548#ifdef FASYNC 549 if (PyModule_AddIntMacro(m, FASYNC)) return -1; 550#endif 551#ifdef F_SETLEASE 552 if (PyModule_AddIntMacro(m, F_SETLEASE)) return -1; 553#endif 554#ifdef F_GETLEASE 555 if (PyModule_AddIntMacro(m, F_GETLEASE)) return -1; 556#endif 557#ifdef F_NOTIFY 558 if (PyModule_AddIntMacro(m, F_NOTIFY)) return -1; 559#endif 560/* Old BSD flock(). */ 561#ifdef F_EXLCK 562 if (PyModule_AddIntMacro(m, F_EXLCK)) return -1; 563#endif 564#ifdef F_SHLCK 565 if (PyModule_AddIntMacro(m, F_SHLCK)) return -1; 566#endif 567 568/* Linux specifics */ 569#ifdef F_SETPIPE_SZ 570 if (PyModule_AddIntMacro(m, F_SETPIPE_SZ)) return -1; 571#endif 572#ifdef F_GETPIPE_SZ 573 if (PyModule_AddIntMacro(m, F_GETPIPE_SZ)) return -1; 574#endif 575 576/* OS X specifics */ 577#ifdef F_FULLFSYNC 578 if (PyModule_AddIntMacro(m, F_FULLFSYNC)) return -1; 579#endif 580#ifdef F_NOCACHE 581 if (PyModule_AddIntMacro(m, F_NOCACHE)) return -1; 582#endif 583 584/* FreeBSD specifics */ 585#ifdef F_DUP2FD 586 if (PyModule_AddIntMacro(m, F_DUP2FD)) return -1; 587#endif 588#ifdef F_DUP2FD_CLOEXEC 589 if (PyModule_AddIntMacro(m, F_DUP2FD_CLOEXEC)) return -1; 590#endif 591 592/* For F_{GET|SET}FL */ 593#ifdef FD_CLOEXEC 594 if (PyModule_AddIntMacro(m, FD_CLOEXEC)) return -1; 595#endif 596 597/* For F_NOTIFY */ 598#ifdef DN_ACCESS 599 if (PyModule_AddIntMacro(m, DN_ACCESS)) return -1; 600#endif 601#ifdef DN_MODIFY 602 if (PyModule_AddIntMacro(m, DN_MODIFY)) return -1; 603#endif 604#ifdef DN_CREATE 605 if (PyModule_AddIntMacro(m, DN_CREATE)) return -1; 606#endif 607#ifdef DN_DELETE 608 if (PyModule_AddIntMacro(m, DN_DELETE)) return -1; 609#endif 610#ifdef DN_RENAME 611 if (PyModule_AddIntMacro(m, DN_RENAME)) return -1; 612#endif 613#ifdef DN_ATTRIB 614 if (PyModule_AddIntMacro(m, DN_ATTRIB)) return -1; 615#endif 616#ifdef DN_MULTISHOT 617 if (PyModule_AddIntMacro(m, DN_MULTISHOT)) return -1; 618#endif 619 620#ifdef HAVE_STROPTS_H 621 /* Unix 98 guarantees that these are in stropts.h. */ 622 if (PyModule_AddIntMacro(m, I_PUSH)) return -1; 623 if (PyModule_AddIntMacro(m, I_POP)) return -1; 624 if (PyModule_AddIntMacro(m, I_LOOK)) return -1; 625 if (PyModule_AddIntMacro(m, I_FLUSH)) return -1; 626 if (PyModule_AddIntMacro(m, I_FLUSHBAND)) return -1; 627 if (PyModule_AddIntMacro(m, I_SETSIG)) return -1; 628 if (PyModule_AddIntMacro(m, I_GETSIG)) return -1; 629 if (PyModule_AddIntMacro(m, I_FIND)) return -1; 630 if (PyModule_AddIntMacro(m, I_PEEK)) return -1; 631 if (PyModule_AddIntMacro(m, I_SRDOPT)) return -1; 632 if (PyModule_AddIntMacro(m, I_GRDOPT)) return -1; 633 if (PyModule_AddIntMacro(m, I_NREAD)) return -1; 634 if (PyModule_AddIntMacro(m, I_FDINSERT)) return -1; 635 if (PyModule_AddIntMacro(m, I_STR)) return -1; 636 if (PyModule_AddIntMacro(m, I_SWROPT)) return -1; 637#ifdef I_GWROPT 638 /* despite the comment above, old-ish glibcs miss a couple... */ 639 if (PyModule_AddIntMacro(m, I_GWROPT)) return -1; 640#endif 641 if (PyModule_AddIntMacro(m, I_SENDFD)) return -1; 642 if (PyModule_AddIntMacro(m, I_RECVFD)) return -1; 643 if (PyModule_AddIntMacro(m, I_LIST)) return -1; 644 if (PyModule_AddIntMacro(m, I_ATMARK)) return -1; 645 if (PyModule_AddIntMacro(m, I_CKBAND)) return -1; 646 if (PyModule_AddIntMacro(m, I_GETBAND)) return -1; 647 if (PyModule_AddIntMacro(m, I_CANPUT)) return -1; 648 if (PyModule_AddIntMacro(m, I_SETCLTIME)) return -1; 649#ifdef I_GETCLTIME 650 if (PyModule_AddIntMacro(m, I_GETCLTIME)) return -1; 651#endif 652 if (PyModule_AddIntMacro(m, I_LINK)) return -1; 653 if (PyModule_AddIntMacro(m, I_UNLINK)) return -1; 654 if (PyModule_AddIntMacro(m, I_PLINK)) return -1; 655 if (PyModule_AddIntMacro(m, I_PUNLINK)) return -1; 656#endif 657#ifdef F_ADD_SEALS 658 /* Linux: file sealing for memfd_create() */ 659 if (PyModule_AddIntMacro(m, F_ADD_SEALS)) return -1; 660 if (PyModule_AddIntMacro(m, F_GET_SEALS)) return -1; 661 if (PyModule_AddIntMacro(m, F_SEAL_SEAL)) return -1; 662 if (PyModule_AddIntMacro(m, F_SEAL_SHRINK)) return -1; 663 if (PyModule_AddIntMacro(m, F_SEAL_GROW)) return -1; 664 if (PyModule_AddIntMacro(m, F_SEAL_WRITE)) return -1; 665#endif 666 return 0; 667} 668 669static int 670fcntl_exec(PyObject *module) 671{ 672 if (all_ins(module) < 0) { 673 return -1; 674 } 675 return 0; 676} 677 678static PyModuleDef_Slot fcntl_slots[] = { 679 {Py_mod_exec, fcntl_exec}, 680 {0, NULL} 681}; 682 683static struct PyModuleDef fcntlmodule = { 684 PyModuleDef_HEAD_INIT, 685 .m_name = "fcntl", 686 .m_doc = module_doc, 687 .m_size = 0, 688 .m_methods = fcntl_methods, 689 .m_slots = fcntl_slots, 690}; 691 692PyMODINIT_FUNC 693PyInit_fcntl(void) 694{ 695 return PyModuleDef_Init(&fcntlmodule); 696} 697