~ubuntu-branches/ubuntu/maverick/python3.1/maverick

« back to all changes in this revision

Viewing changes to Modules/fcntlmodule.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2009-03-23 00:01:27 UTC
  • Revision ID: james.westby@ubuntu.com-20090323000127-5fstfxju4ufrhthq
Tags: upstream-3.1~a1+20090322
ImportĀ upstreamĀ versionĀ 3.1~a1+20090322

Show diffs side-by-side

added added

removed removed

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