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