fcntlmodule.c 19.5 KB
Newer Older
1 2 3

/* fcntl module */

Thomas Wouters's avatar
Thomas Wouters committed
4 5
#define PY_SSIZE_T_CLEAN

Roger E. Masse's avatar
Roger E. Masse committed
6
#include "Python.h"
7

Guido van Rossum's avatar
Guido van Rossum committed
8 9 10 11
#ifdef HAVE_SYS_FILE_H
#include <sys/file.h>
#endif

12
#include <sys/ioctl.h>
13
#include <fcntl.h>
14 15 16
#ifdef HAVE_STROPTS_H
#include <stropts.h>
#endif
17

18 19 20
/*[clinic input]
module fcntl
[clinic start generated code]*/
21
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=124b58387c158179]*/
22

23 24 25 26 27 28
static int
conv_descriptor(PyObject *object, int *target)
{
    int fd = PyObject_AsFileDescriptor(object);

    if (fd < 0)
29
        return 0;
30 31 32 33
    *target = fd;
    return 1;
}

34 35 36 37 38 39 40
/* Must come after conv_descriptor definition. */
#include "clinic/fcntlmodule.c.h"

/*[clinic input]
fcntl.fcntl

    fd: object(type='int', converter='conv_descriptor')
41 42
    cmd as code: int
    arg: object(c_default='NULL') = 0
43
    /
44

45
Perform the operation `cmd` on file descriptor fd.
46

47
The values used for `cmd` are operating system dependent, and are available
48 49 50 51 52 53 54 55 56
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]*/
57

Roger E. Masse's avatar
Roger E. Masse committed
58
static PyObject *
59 60
fcntl_fcntl_impl(PyObject *module, int fd, int code, PyObject *arg)
/*[clinic end generated code: output=888fc93b51c295bd input=8cefbe59b29efbe2]*/
61
{
62
    unsigned int int_arg = 0;
63 64 65 66
    int ret;
    char *str;
    Py_ssize_t len;
    char buf[1024];
67
    int async_err = 0;
68

69 70 71 72 73 74 75 76 77 78
    if (arg != NULL) {
        int parse_result;

        if (PyArg_Parse(arg, "s#", &str, &len)) {
            if ((size_t)len > sizeof buf) {
                PyErr_SetString(PyExc_ValueError,
                                "fcntl string arg too long");
                return NULL;
            }
            memcpy(buf, str, len);
79 80 81 82 83
            do {
                Py_BEGIN_ALLOW_THREADS
                ret = fcntl(fd, code, buf);
                Py_END_ALLOW_THREADS
            } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
84
            if (ret < 0) {
85
                return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL;
86 87
            }
            return PyBytes_FromStringAndSize(buf, len);
88
        }
89 90 91

        PyErr_Clear();
        parse_result = PyArg_Parse(arg,
92
            "I;fcntl requires a file or file descriptor,"
93 94 95 96
            " an integer and optionally a third integer or a string",
            &int_arg);
        if (!parse_result) {
          return NULL;
97 98 99
        }
    }

100 101 102 103 104
    do {
        Py_BEGIN_ALLOW_THREADS
        ret = fcntl(fd, code, (int)int_arg);
        Py_END_ALLOW_THREADS
    } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
105
    if (ret < 0) {
106
        return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL;
107 108
    }
    return PyLong_FromLong((long)ret);
109 110
}

111

112 113 114 115
/*[clinic input]
fcntl.ioctl

    fd: object(type='int', converter='conv_descriptor')
116 117
    request as code: unsigned_int(bitwise=True)
    arg as ob_arg: object(c_default='NULL') = 0
118 119
    mutate_flag as mutate_arg: bool = True
    /
120

121
Perform the operation `request` on file descriptor `fd`.
122

123 124
The values used for `request` are operating system dependent, and are available
as constants in the fcntl or termios library modules, using the same names as
125 126 127 128 129 130 131 132 133 134 135 136
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.

137 138
If the argument is a mutable buffer and the mutable_flag argument is false,
the behavior is as if a string had been passed.
139 140 141 142 143 144 145 146 147 148 149

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]*/
150

Roger E. Masse's avatar
Roger E. Masse committed
151
static PyObject *
152
fcntl_ioctl_impl(PyObject *module, int fd, unsigned int code,
153
                 PyObject *ob_arg, int mutate_arg)
154
/*[clinic end generated code: output=7f7f5840c65991be input=ede70c433cccbbb2]*/
155
{
156
#define IOCTL_BUFSZ 1024
157 158
    /* We use the unsigned non-checked 'I' format for the 'code' parameter
       because the system expects it to be a 32bit bit field value
159 160
       regardless of it being passed as an int or unsigned long on
       various platforms.  See the termios.TIOCSWINSZ constant across
161
       platforms for an example of this.
162 163 164 165 166

       If any of the 64bit platforms ever decide to use more than 32bits
       in their unsigned long ioctl codes this will break and need
       special casing based on the platform being built on.
     */
167
    int arg = 0;
168 169 170 171 172 173
    int ret;
    Py_buffer pstr;
    char *str;
    Py_ssize_t len;
    char buf[IOCTL_BUFSZ+1];  /* argument plus NUL byte */

174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215
    if (ob_arg != NULL) {
        if (PyArg_Parse(ob_arg, "w*:ioctl", &pstr)) {
            char *arg;
            str = pstr.buf;
            len = pstr.len;

            if (mutate_arg) {
                if (len <= IOCTL_BUFSZ) {
                    memcpy(buf, str, len);
                    buf[len] = '\0';
                    arg = buf;
                }
                else {
                    arg = str;
                }
            }
            else {
                if (len > IOCTL_BUFSZ) {
                    PyBuffer_Release(&pstr);
                    PyErr_SetString(PyExc_ValueError,
                        "ioctl string arg too long");
                    return NULL;
                }
                else {
                    memcpy(buf, str, len);
                    buf[len] = '\0';
                    arg = buf;
                }
            }
            if (buf == arg) {
                Py_BEGIN_ALLOW_THREADS /* think array.resize() */
                ret = ioctl(fd, code, arg);
                Py_END_ALLOW_THREADS
            }
            else {
                ret = ioctl(fd, code, arg);
            }
            if (mutate_arg && (len <= IOCTL_BUFSZ)) {
                memcpy(str, buf, len);
            }
            PyBuffer_Release(&pstr); /* No further access to str below this point */
            if (ret < 0) {
216
                PyErr_SetFromErrno(PyExc_OSError);
217 218 219 220
                return NULL;
            }
            if (mutate_arg) {
                return PyLong_FromLong(ret);
221 222
            }
            else {
223
                return PyBytes_FromStringAndSize(buf, len);
224 225
            }
        }
226 227 228 229 230

        PyErr_Clear();
        if (PyArg_Parse(ob_arg, "s*:ioctl", &pstr)) {
            str = pstr.buf;
            len = pstr.len;
231 232 233
            if (len > IOCTL_BUFSZ) {
                PyBuffer_Release(&pstr);
                PyErr_SetString(PyExc_ValueError,
234
                                "ioctl string arg too long");
235 236
                return NULL;
            }
237 238 239 240
            memcpy(buf, str, len);
            buf[len] = '\0';
            Py_BEGIN_ALLOW_THREADS
            ret = ioctl(fd, code, buf);
241
            Py_END_ALLOW_THREADS
242 243
            if (ret < 0) {
                PyBuffer_Release(&pstr);
244
                PyErr_SetFromErrno(PyExc_OSError);
245 246 247
                return NULL;
            }
            PyBuffer_Release(&pstr);
248 249 250
            return PyBytes_FromStringAndSize(buf, len);
        }

251 252 253 254 255 256
        PyErr_Clear();
        if (!PyArg_Parse(ob_arg,
             "i;ioctl requires a file or file descriptor,"
             " an integer and optionally an integer or buffer argument",
             &arg)) {
          return NULL;
257
        }
258
        // Fall-through to outside the 'if' statement.
259 260 261 262 263
    }
    Py_BEGIN_ALLOW_THREADS
    ret = ioctl(fd, code, arg);
    Py_END_ALLOW_THREADS
    if (ret < 0) {
264
        PyErr_SetFromErrno(PyExc_OSError);
265 266 267
        return NULL;
    }
    return PyLong_FromLong((long)ret);
268
#undef IOCTL_BUFSZ
269 270
}

271 272 273 274
/*[clinic input]
fcntl.flock

    fd: object(type='int', converter='conv_descriptor')
275
    operation as code: int
276 277
    /

278
Perform the lock operation `operation` on file descriptor `fd`.
279 280 281 282

See the Unix manual page for flock(2) for details (On some systems, this
function is emulated using fcntl()).
[clinic start generated code]*/
Guido van Rossum's avatar
Guido van Rossum committed
283

Roger E. Masse's avatar
Roger E. Masse committed
284
static PyObject *
285 286
fcntl_flock_impl(PyObject *module, int fd, int code)
/*[clinic end generated code: output=84059e2b37d2fc64 input=b70a0a41ca22a8a0]*/
Guido van Rossum's avatar
Guido van Rossum committed
287
{
288
    int ret;
289
    int async_err = 0;
Guido van Rossum's avatar
Guido van Rossum committed
290

291
#ifdef HAVE_FLOCK
292 293 294 295 296
    do {
        Py_BEGIN_ALLOW_THREADS
        ret = flock(fd, code);
        Py_END_ALLOW_THREADS
    } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
297 298 299
#else

#ifndef LOCK_SH
300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318
#define LOCK_SH         1       /* shared lock */
#define LOCK_EX         2       /* exclusive lock */
#define LOCK_NB         4       /* don't block when locking */
#define LOCK_UN         8       /* unlock */
#endif
    {
        struct flock l;
        if (code == LOCK_UN)
            l.l_type = F_UNLCK;
        else if (code & LOCK_SH)
            l.l_type = F_RDLCK;
        else if (code & LOCK_EX)
            l.l_type = F_WRLCK;
        else {
            PyErr_SetString(PyExc_ValueError,
                            "unrecognized flock argument");
            return NULL;
        }
        l.l_whence = l.l_start = l.l_len = 0;
319 320 321 322 323
        do {
            Py_BEGIN_ALLOW_THREADS
            ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
            Py_END_ALLOW_THREADS
        } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
324
    }
325
#endif /* HAVE_FLOCK */
326
    if (ret < 0) {
327
        return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL;
328
    }
329
    Py_RETURN_NONE;
Guido van Rossum's avatar
Guido van Rossum committed
330 331
}

332

333 334 335 336
/*[clinic input]
fcntl.lockf

    fd: object(type='int', converter='conv_descriptor')
337 338 339
    cmd as code: int
    len as lenobj: object(c_default='NULL') = 0
    start as startobj: object(c_default='NULL') = 0
340 341 342 343 344
    whence: int = 0
    /

A wrapper around the fcntl() locking calls.

345
`fd` is the file descriptor of the file to lock or unlock, and operation is one
346 347 348 349 350 351 352 353
of the following values:

    LOCK_UN - unlock
    LOCK_SH - acquire a shared lock
    LOCK_EX - acquire an exclusive lock

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
354
lock cannot be acquired, an OSError will be raised and the exception will
355 356 357
have an errno attribute set to EACCES or EAGAIN (depending on the operating
system -- for portability, check for either value).

358 359 360
`len` 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:
361 362 363 364 365

    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]*/
366

Roger E. Masse's avatar
Roger E. Masse committed
367
static PyObject *
368
fcntl_lockf_impl(PyObject *module, int fd, int code, PyObject *lenobj,
369
                 PyObject *startobj, int whence)
370
/*[clinic end generated code: output=4985e7a172e7461a input=3a5dc01b04371f1a]*/
Guido van Rossum's avatar
Guido van Rossum committed
371
{
372
    int ret;
373
    int async_err = 0;
Guido van Rossum's avatar
Guido van Rossum committed
374 375

#ifndef LOCK_SH
376 377 378 379
#define LOCK_SH         1       /* shared lock */
#define LOCK_EX         2       /* exclusive lock */
#define LOCK_NB         4       /* don't block when locking */
#define LOCK_UN         8       /* unlock */
380
#endif  /* LOCK_SH */
381 382 383 384 385 386 387 388 389 390 391 392 393 394 395
    {
        struct flock l;
        if (code == LOCK_UN)
            l.l_type = F_UNLCK;
        else if (code & LOCK_SH)
            l.l_type = F_RDLCK;
        else if (code & LOCK_EX)
            l.l_type = F_WRLCK;
        else {
            PyErr_SetString(PyExc_ValueError,
                            "unrecognized lockf argument");
            return NULL;
        }
        l.l_start = l.l_len = 0;
        if (startobj != NULL) {
396
#if !defined(HAVE_LARGEFILE_SUPPORT)
397
            l.l_start = PyLong_AsLong(startobj);
398
#else
399 400 401 402 403 404 405 406
            l.l_start = PyLong_Check(startobj) ?
                            PyLong_AsLongLong(startobj) :
                    PyLong_AsLong(startobj);
#endif
            if (PyErr_Occurred())
                return NULL;
        }
        if (lenobj != NULL) {
407
#if !defined(HAVE_LARGEFILE_SUPPORT)
408
            l.l_len = PyLong_AsLong(lenobj);
409
#else
410 411 412 413 414 415 416 417
            l.l_len = PyLong_Check(lenobj) ?
                            PyLong_AsLongLong(lenobj) :
                    PyLong_AsLong(lenobj);
#endif
            if (PyErr_Occurred())
                return NULL;
        }
        l.l_whence = whence;
418 419 420 421 422
        do {
            Py_BEGIN_ALLOW_THREADS
            ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
            Py_END_ALLOW_THREADS
        } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
423 424
    }
    if (ret < 0) {
425
        return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL;
426
    }
427
    Py_RETURN_NONE;
Guido van Rossum's avatar
Guido van Rossum committed
428
}
Guido van Rossum's avatar
Guido van Rossum committed
429

430 431
/* List of functions */

Roger E. Masse's avatar
Roger E. Masse committed
432
static PyMethodDef fcntl_methods[] = {
433 434 435 436 437
    FCNTL_FCNTL_METHODDEF
    FCNTL_IOCTL_METHODDEF
    FCNTL_FLOCK_METHODDEF
    FCNTL_LOCKF_METHODDEF
    {NULL, NULL}  /* sentinel */
438 439 440
};


441
PyDoc_STRVAR(module_doc,
442
"This module performs file control and I/O control on file\n\
443 444
descriptors.  It is an interface to the fcntl() and ioctl() Unix\n\
routines.  File descriptors can be obtained with the fileno() method of\n\
445
a file or socket object.");
446

447 448
/* Module initialisation */

449

450
static int
451
all_ins(PyObject* m)
452
{
453 454 455 456
    if (PyModule_AddIntMacro(m, LOCK_SH)) return -1;
    if (PyModule_AddIntMacro(m, LOCK_EX)) return -1;
    if (PyModule_AddIntMacro(m, LOCK_NB)) return -1;
    if (PyModule_AddIntMacro(m, LOCK_UN)) return -1;
457 458
/* GNU extensions, as of glibc 2.2.4 */
#ifdef LOCK_MAND
459
    if (PyModule_AddIntMacro(m, LOCK_MAND)) return -1;
460 461
#endif
#ifdef LOCK_READ
462
    if (PyModule_AddIntMacro(m, LOCK_READ)) return -1;
463 464
#endif
#ifdef LOCK_WRITE
465
    if (PyModule_AddIntMacro(m, LOCK_WRITE)) return -1;
466 467
#endif
#ifdef LOCK_RW
468
    if (PyModule_AddIntMacro(m, LOCK_RW)) return -1;
469 470
#endif

471
#ifdef F_DUPFD
472
    if (PyModule_AddIntMacro(m, F_DUPFD)) return -1;
473
#endif
474
#ifdef F_DUPFD_CLOEXEC
475
    if (PyModule_AddIntMacro(m, F_DUPFD_CLOEXEC)) return -1;
476
#endif
477
#ifdef F_GETFD
478
    if (PyModule_AddIntMacro(m, F_GETFD)) return -1;
479 480
#endif
#ifdef F_SETFD
481
    if (PyModule_AddIntMacro(m, F_SETFD)) return -1;
482 483
#endif
#ifdef F_GETFL
484
    if (PyModule_AddIntMacro(m, F_GETFL)) return -1;
485 486
#endif
#ifdef F_SETFL
487
    if (PyModule_AddIntMacro(m, F_SETFL)) return -1;
488 489
#endif
#ifdef F_GETLK
490
    if (PyModule_AddIntMacro(m, F_GETLK)) return -1;
491 492
#endif
#ifdef F_SETLK
493
    if (PyModule_AddIntMacro(m, F_SETLK)) return -1;
494 495
#endif
#ifdef F_SETLKW
496
    if (PyModule_AddIntMacro(m, F_SETLKW)) return -1;
497 498
#endif
#ifdef F_GETOWN
499
    if (PyModule_AddIntMacro(m, F_GETOWN)) return -1;
500 501
#endif
#ifdef F_SETOWN
502
    if (PyModule_AddIntMacro(m, F_SETOWN)) return -1;
503 504
#endif
#ifdef F_GETSIG
505
    if (PyModule_AddIntMacro(m, F_GETSIG)) return -1;
506 507
#endif
#ifdef F_SETSIG
508
    if (PyModule_AddIntMacro(m, F_SETSIG)) return -1;
509 510
#endif
#ifdef F_RDLCK
511
    if (PyModule_AddIntMacro(m, F_RDLCK)) return -1;
512 513
#endif
#ifdef F_WRLCK
514
    if (PyModule_AddIntMacro(m, F_WRLCK)) return -1;
515 516
#endif
#ifdef F_UNLCK
517
    if (PyModule_AddIntMacro(m, F_UNLCK)) return -1;
518
#endif
519 520
/* LFS constants */
#ifdef F_GETLK64
521
    if (PyModule_AddIntMacro(m, F_GETLK64)) return -1;
522 523
#endif
#ifdef F_SETLK64
524
    if (PyModule_AddIntMacro(m, F_SETLK64)) return -1;
525 526
#endif
#ifdef F_SETLKW64
527
    if (PyModule_AddIntMacro(m, F_SETLKW64)) return -1;
528 529
#endif
/* GNU extensions, as of glibc 2.2.4. */
530
#ifdef FASYNC
531
    if (PyModule_AddIntMacro(m, FASYNC)) return -1;
532
#endif
533
#ifdef F_SETLEASE
534
    if (PyModule_AddIntMacro(m, F_SETLEASE)) return -1;
535 536
#endif
#ifdef F_GETLEASE
537
    if (PyModule_AddIntMacro(m, F_GETLEASE)) return -1;
538 539
#endif
#ifdef F_NOTIFY
540
    if (PyModule_AddIntMacro(m, F_NOTIFY)) return -1;
541 542 543
#endif
/* Old BSD flock(). */
#ifdef F_EXLCK
544
    if (PyModule_AddIntMacro(m, F_EXLCK)) return -1;
545 546
#endif
#ifdef F_SHLCK
547
    if (PyModule_AddIntMacro(m, F_SHLCK)) return -1;
548 549
#endif

550
/* OS X specifics */
Georg Brandl's avatar
Georg Brandl committed
551
#ifdef F_FULLFSYNC
552
    if (PyModule_AddIntMacro(m, F_FULLFSYNC)) return -1;
Georg Brandl's avatar
Georg Brandl committed
553
#endif
554
#ifdef F_NOCACHE
555
    if (PyModule_AddIntMacro(m, F_NOCACHE)) return -1;
556
#endif
Georg Brandl's avatar
Georg Brandl committed
557

558 559
/* For F_{GET|SET}FL */
#ifdef FD_CLOEXEC
560
    if (PyModule_AddIntMacro(m, FD_CLOEXEC)) return -1;
561 562 563 564
#endif

/* For F_NOTIFY */
#ifdef DN_ACCESS
565
    if (PyModule_AddIntMacro(m, DN_ACCESS)) return -1;
566 567
#endif
#ifdef DN_MODIFY
568
    if (PyModule_AddIntMacro(m, DN_MODIFY)) return -1;
569 570
#endif
#ifdef DN_CREATE
571
    if (PyModule_AddIntMacro(m, DN_CREATE)) return -1;
572 573
#endif
#ifdef DN_DELETE
574
    if (PyModule_AddIntMacro(m, DN_DELETE)) return -1;
575 576
#endif
#ifdef DN_RENAME
577
    if (PyModule_AddIntMacro(m, DN_RENAME)) return -1;
578 579
#endif
#ifdef DN_ATTRIB
580
    if (PyModule_AddIntMacro(m, DN_ATTRIB)) return -1;
581 582
#endif
#ifdef DN_MULTISHOT
583
    if (PyModule_AddIntMacro(m, DN_MULTISHOT)) return -1;
584 585
#endif

586
#ifdef HAVE_STROPTS_H
587
    /* Unix 98 guarantees that these are in stropts.h. */
588 589 590 591 592 593 594 595 596 597 598 599 600 601 602
    if (PyModule_AddIntMacro(m, I_PUSH)) return -1;
    if (PyModule_AddIntMacro(m, I_POP)) return -1;
    if (PyModule_AddIntMacro(m, I_LOOK)) return -1;
    if (PyModule_AddIntMacro(m, I_FLUSH)) return -1;
    if (PyModule_AddIntMacro(m, I_FLUSHBAND)) return -1;
    if (PyModule_AddIntMacro(m, I_SETSIG)) return -1;
    if (PyModule_AddIntMacro(m, I_GETSIG)) return -1;
    if (PyModule_AddIntMacro(m, I_FIND)) return -1;
    if (PyModule_AddIntMacro(m, I_PEEK)) return -1;
    if (PyModule_AddIntMacro(m, I_SRDOPT)) return -1;
    if (PyModule_AddIntMacro(m, I_GRDOPT)) return -1;
    if (PyModule_AddIntMacro(m, I_NREAD)) return -1;
    if (PyModule_AddIntMacro(m, I_FDINSERT)) return -1;
    if (PyModule_AddIntMacro(m, I_STR)) return -1;
    if (PyModule_AddIntMacro(m, I_SWROPT)) return -1;
Michael W. Hudson's avatar
Michael W. Hudson committed
603
#ifdef I_GWROPT
604
    /* despite the comment above, old-ish glibcs miss a couple... */
605 606 607 608 609 610 611 612 613 614
    if (PyModule_AddIntMacro(m, I_GWROPT)) return -1;
#endif
    if (PyModule_AddIntMacro(m, I_SENDFD)) return -1;
    if (PyModule_AddIntMacro(m, I_RECVFD)) return -1;
    if (PyModule_AddIntMacro(m, I_LIST)) return -1;
    if (PyModule_AddIntMacro(m, I_ATMARK)) return -1;
    if (PyModule_AddIntMacro(m, I_CKBAND)) return -1;
    if (PyModule_AddIntMacro(m, I_GETBAND)) return -1;
    if (PyModule_AddIntMacro(m, I_CANPUT)) return -1;
    if (PyModule_AddIntMacro(m, I_SETCLTIME)) return -1;
Michael W. Hudson's avatar
Michael W. Hudson committed
615
#ifdef I_GETCLTIME
616
    if (PyModule_AddIntMacro(m, I_GETCLTIME)) return -1;
Michael W. Hudson's avatar
Michael W. Hudson committed
617
#endif
618 619 620 621
    if (PyModule_AddIntMacro(m, I_LINK)) return -1;
    if (PyModule_AddIntMacro(m, I_UNLINK)) return -1;
    if (PyModule_AddIntMacro(m, I_PLINK)) return -1;
    if (PyModule_AddIntMacro(m, I_PUNLINK)) return -1;
622
#endif
623 624

    return 0;
625 626
}

627 628

static struct PyModuleDef fcntlmodule = {
629 630 631 632 633 634 635 636 637
    PyModuleDef_HEAD_INIT,
    "fcntl",
    module_doc,
    -1,
    fcntl_methods,
    NULL,
    NULL,
    NULL,
    NULL
638 639
};

640
PyMODINIT_FUNC
641
PyInit_fcntl(void)
642
{
643
    PyObject *m;
644

645 646 647 648
    /* Create the module and add the functions and documentation */
    m = PyModule_Create(&fcntlmodule);
    if (m == NULL)
        return NULL;
649

650
    /* Add some symbolic constants to the module */
651 652 653
    if (all_ins(m) < 0)
        return NULL;

654
    return m;
655
}