Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(167)

Side by Side Diff: Modules/posixmodule.c

Issue 12720: Expose linux extended filesystem attributes
Patch Set: Created 1 year, 9 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Lib/test/test_os.py ('k') | configure » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 1
2 /* POSIX module implementation */ 2 /* POSIX module implementation */
3 3
4 /* This file is also used for Windows NT/MS-Win and OS/2. In that case the 4 /* This file is also used for Windows NT/MS-Win and OS/2. In that case the
5 module actually calls itself 'nt' or 'os2', not 'posix', and a few 5 module actually calls itself 'nt' or 'os2', not 'posix', and a few
6 functions are either unimplemented or implemented differently. The source 6 functions are either unimplemented or implemented differently. The source
7 assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent 7 assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent
8 of the compiler used. Different compilers define their own feature 8 of the compiler used. Different compilers define their own feature
9 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. For OS/2, the compiler 9 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. For OS/2, the compiler
10 independent macro PYOS_OS2 should be defined. On OS/2 the default 10 independent macro PYOS_OS2 should be defined. On OS/2 the default
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 #ifdef HAVE_LANGINFO_H 98 #ifdef HAVE_LANGINFO_H
99 #include <langinfo.h> 99 #include <langinfo.h>
100 #endif 100 #endif
101 101
102 #ifdef HAVE_SYS_SENDFILE_H 102 #ifdef HAVE_SYS_SENDFILE_H
103 #include <sys/sendfile.h> 103 #include <sys/sendfile.h>
104 #endif 104 #endif
105 105
106 #ifdef HAVE_SCHED_H 106 #ifdef HAVE_SCHED_H
107 #include <sched.h> 107 #include <sched.h>
108 #endif
109
110 #ifdef HAVE_ATTR_XATTR_H
111 #include <attr/xattr.h>
108 #endif 112 #endif
109 113
110 #if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__) 114 #if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
111 #ifdef HAVE_SYS_SOCKET_H 115 #ifdef HAVE_SYS_SOCKET_H
112 #include <sys/socket.h> 116 #include <sys/socket.h>
113 #endif 117 #endif
114 #endif 118 #endif
115 119
116 /* Various compilers have only certain posix functions */ 120 /* Various compilers have only certain posix functions */
117 /* XXX Gosh I wish these were all moved into pyconfig.h */ 121 /* XXX Gosh I wish these were all moved into pyconfig.h */
(...skipping 9824 matching lines...) Expand 10 before | Expand all | Expand 10 after
9942 filename = PyBytes_AS_STRING(opath); 9946 filename = PyBytes_AS_STRING(opath);
9943 Py_BEGIN_ALLOW_THREADS 9947 Py_BEGIN_ALLOW_THREADS
9944 res = mkfifoat(dirfd, filename, mode); 9948 res = mkfifoat(dirfd, filename, mode);
9945 Py_END_ALLOW_THREADS 9949 Py_END_ALLOW_THREADS
9946 Py_DECREF(opath); 9950 Py_DECREF(opath);
9947 if (res < 0) 9951 if (res < 0)
9948 return posix_error(); 9952 return posix_error();
9949 Py_RETURN_NONE; 9953 Py_RETURN_NONE;
9950 } 9954 }
9951 #endif 9955 #endif
9956
9957 #ifdef HAVE_ATTR_XATTR_H
9958
9959 #define XATTR_BUF_SIZE 128
9960
9961 static int
9962 try_getxattr(const char *path, const char *name,
9963 ssize_t (*get)(const char *, const char *, void *, size_t),
9964 Py_ssize_t buf_size, PyObject **res)
9965 {
9966 PyObject *value;
9967 Py_ssize_t len;
9968
9969 assert(buf_size <= XATTR_SIZE_MAX);
9970 value = PyBytes_FromStringAndSize(NULL, buf_size);
9971 if (!value)
9972 return 0;
9973 Py_BEGIN_ALLOW_THREADS;
9974 len = get(path, name, PyBytes_AS_STRING(value), buf_size);
9975 Py_END_ALLOW_THREADS;
9976 if (len < 0) {
9977 Py_DECREF(value);
9978 if (errno == ERANGE) {
9979 value = NULL;
9980 }
9981 else {
9982 posix_error();
9983 return 0;
9984 }
9985 }
9986 else if (len != buf_size) {
9987 /* Can only shrink. */
9988 _PyBytes_Resize(&value, len);
9989 }
9990 *res = value;
9991 return 1;
9992 }
9993
9994 static PyObject *
9995 getxattr_common(const char *path, PyObject *name_obj,
9996 ssize_t (*get)(const char *, const char *, void *, size_t))
9997 {
9998 PyObject *value;
9999 const char *name = PyBytes_AS_STRING(name_obj);
10000
10001 /* Try a small value first. */
10002 if (!try_getxattr(path, name, get, 128, &value))
10003 return NULL;
10004 if (value)
10005 return value;
10006 /* Now the maximum possible one. */
10007 if (!try_getxattr(path, name, get, XATTR_SIZE_MAX, &value))
10008 return NULL;
10009 assert(value);
10010 return value;
10011 }
10012
10013 PyDoc_STRVAR(posix_getxattr__doc__,
10014 "getxattr(path, attr) -> value\n\n\
10015 Return the value of extended attribute *name* on *path*.");
10016
10017 static PyObject *
10018 posix_getxattr(PyObject *self, PyObject *args)
10019 {
10020 PyObject *path, *res, *name;
10021
10022 if (!PyArg_ParseTuple(args, "O&O&:getxattr", PyUnicode_FSConverter, &path,
10023 PyUnicode_FSConverter, &name))
10024 return NULL;
10025 res = getxattr_common(PyBytes_AS_STRING(path), name, getxattr);
10026 Py_DECREF(path);
10027 Py_DECREF(name);
10028 return res;
10029 }
10030
10031 PyDoc_STRVAR(posix_lgetxattr__doc__,
10032 "lgetxattr(path, attr) -> value\n\n\
10033 Like getxattr but don't follow symlinks.");
10034
10035 static PyObject *
10036 posix_lgetxattr(PyObject *self, PyObject *args)
10037 {
10038 PyObject *path, *res, *name;
10039
10040 if (!PyArg_ParseTuple(args, "O&O&:lgetxattr", PyUnicode_FSConverter, &path,
10041 PyUnicode_FSConverter, &name))
10042 return NULL;
10043 res = getxattr_common(PyBytes_AS_STRING(path), name, lgetxattr);
10044 Py_DECREF(path);
10045 Py_DECREF(name);
10046 return res;
10047 }
10048
10049 static ssize_t
10050 wrap_fgetxattr(const char *path, const char *name, void *value, size_t size)
10051 {
10052 /* Hack to share code. */
10053 return fgetxattr((int)(Py_uintptr_t)path, name, value, size);
10054 }
10055
10056 PyDoc_STRVAR(posix_fgetxattr__doc__,
10057 "fgetxattr(fd, attr) -> value\n\n\
10058 Like getxattr but operate on a fd instead of a path.");
10059
10060 static PyObject *
10061 posix_fgetxattr(PyObject *self, PyObject *args)
10062 {
10063 PyObject *res, *name;
10064 int fd;
10065
10066 if (!PyArg_ParseTuple(args, "iO&:fgetxattr", &fd, PyUnicode_FSConverter, &na me))
10067 return NULL;
10068 res = getxattr_common((const char *)(Py_uintptr_t)fd, name, wrap_fgetxattr);
10069 Py_DECREF(name);
10070 return res;
10071 }
10072
10073 PyDoc_STRVAR(posix_setxattr__doc__,
10074 "setxattr(path, attr, value, flags=0)\n\n\
10075 Set extended attribute *attr* on *path* to *value*.");
10076
10077 static PyObject *
10078 posix_setxattr(PyObject *self, PyObject *args)
10079 {
10080 PyObject *path, *name;
10081 Py_buffer data;
10082 int flags = 0, err;
10083
10084 if (!PyArg_ParseTuple(args, "O&O&y*|i:setxattr", PyUnicode_FSConverter,
10085 &path, PyUnicode_FSConverter, &name, &data, &flags))
10086 return NULL;
10087 Py_BEGIN_ALLOW_THREADS;
10088 err = setxattr(PyBytes_AS_STRING(path), PyBytes_AS_STRING(name),
10089 data.buf, data.len, flags);
10090 Py_END_ALLOW_THREADS;
10091 Py_DECREF(path);
10092 Py_DECREF(name);
10093 PyBuffer_Release(&data);
10094 if (err)
10095 return posix_error();
10096 Py_RETURN_NONE;
10097 }
10098
10099 PyDoc_STRVAR(posix_lsetxattr__doc__,
10100 "lsetxattr(path, attr, value, flags=0)\n\n\
10101 Like setxattr but don't follow symlinks.");
10102
10103 static PyObject *
10104 posix_lsetxattr(PyObject *self, PyObject *args)
10105 {
10106 PyObject *path, *name;
10107 Py_buffer data;
10108 int flags = 0, err;
10109
10110 if (!PyArg_ParseTuple(args, "O&O&y*|i:lsetxattr", PyUnicode_FSConverter,
10111 &path, PyUnicode_FSConverter, &name, &data, &flags))
10112 return NULL;
10113 Py_BEGIN_ALLOW_THREADS;
10114 err = lsetxattr(PyBytes_AS_STRING(path), PyBytes_AS_STRING(name),
10115 data.buf, data.len, flags);
10116 Py_END_ALLOW_THREADS;
10117 Py_DECREF(path);
10118 Py_DECREF(name);
10119 PyBuffer_Release(&data);
10120 if (err)
10121 return posix_error();
10122 Py_RETURN_NONE;
10123 }
10124
10125 PyDoc_STRVAR(posix_fsetxattr__doc__,
10126 "fsetxattr(fd, attr, value, flags=0)\n\n\
10127 Like setxattr but operates on *fd* instead of a path.");
10128
10129 static PyObject *
10130 posix_fsetxattr(PyObject *self, PyObject *args)
10131 {
10132 Py_buffer data;
10133 const char *name;
10134 int fd, flags = 0, err;
10135
10136 if (!PyArg_ParseTuple(args, "iO&y*|i:fsetxattr", &fd, PyUnicode_FSConverter,
10137 &name, &data, &flags))
10138 return NULL;
10139 Py_BEGIN_ALLOW_THREADS;
10140 err = fsetxattr(fd, PyBytes_AS_STRING(name), data.buf, data.len, flags);
10141 Py_END_ALLOW_THREADS;
10142 Py_DECREF(name);
10143 PyBuffer_Release(&data);
10144 if (err)
10145 return posix_error();
10146 Py_RETURN_NONE;
10147 }
10148
10149 PyDoc_STRVAR(posix_removexattr__doc__,
10150 "removexattr(path, attr)\n\n\
10151 Remove extended attribute *attr* on *path*.");
10152
10153 static PyObject *
10154 posix_removexattr(PyObject *self, PyObject *args)
10155 {
10156 PyObject *path, *name;
10157 int err;
10158
10159 if (!PyArg_ParseTuple(args, "O&O&:removexattr", PyUnicode_FSConverter, &path ,
10160 PyUnicode_FSConverter, &name))
10161 return NULL;
10162 Py_BEGIN_ALLOW_THREADS;
10163 err = removexattr(PyBytes_AS_STRING(path), PyBytes_AS_STRING(name));
10164 Py_END_ALLOW_THREADS;
10165 Py_DECREF(path);
10166 Py_DECREF(name);
10167 if (err)
10168 return posix_error();
10169 Py_RETURN_NONE;
10170 }
10171
10172 PyDoc_STRVAR(posix_lremovexattr__doc__,
10173 "lremovexattr(path, attr)\n\n\
10174 Like removexattr but don't follow symlinks.");
10175
10176 static PyObject *
10177 posix_lremovexattr(PyObject *self, PyObject *args)
10178 {
10179 PyObject *path, *name;
10180 int err;
10181
10182 if (!PyArg_ParseTuple(args, "O&O&:lremovexattr", PyUnicode_FSConverter, &pat h,
10183 PyUnicode_FSConverter, &name))
10184 return NULL;
10185 Py_BEGIN_ALLOW_THREADS;
10186 err = lremovexattr(PyBytes_AS_STRING(path), PyBytes_AS_STRING(name));
10187 Py_END_ALLOW_THREADS;
10188 Py_DECREF(path);
10189 Py_DECREF(name);
10190 if (err)
10191 return posix_error();
10192 Py_RETURN_NONE;
10193 }
10194
10195 PyDoc_STRVAR(posix_fremovexattr__doc__,
10196 "fremovexattr(fd, attr)\n\n\
10197 Like removexattr but operates on a file descriptor.");
10198
10199 static PyObject *
10200 posix_fremovexattr(PyObject *self, PyObject *args)
10201 {
10202 PyObject *name;
10203 int fd, err;
10204
10205 if (!PyArg_ParseTuple(args, "iO&:fremovexattr", &fd,
10206 PyUnicode_FSConverter, &name))
10207 return NULL;
10208 Py_BEGIN_ALLOW_THREADS;
10209 err = fremovexattr(fd, PyBytes_AS_STRING(name));
10210 Py_END_ALLOW_THREADS;
10211 Py_DECREF(name);
10212 if (err)
10213 return posix_error();
10214 Py_RETURN_NONE;
10215 }
10216
10217 static Py_ssize_t
10218 try_listxattr(const char *path, ssize_t (*list)(const char *, char *, size_t),
10219 Py_ssize_t buf_size, char **buf)
10220 {
10221 Py_ssize_t len;
10222
10223 *buf = PyMem_MALLOC(buf_size);
10224 if (!*buf) {
10225 PyErr_NoMemory();
10226 return -1;
10227 }
10228 Py_BEGIN_ALLOW_THREADS;
10229 len = list(path, *buf, buf_size);
10230 Py_END_ALLOW_THREADS;
10231 if (len < 0) {
10232 PyMem_FREE(*buf);
10233 if (errno != ERANGE)
10234 posix_error();
10235 return -1;
10236 }
10237 return len;
10238 }
10239
10240 static PyObject *
10241 listxattr_common(const char *path, ssize_t (*list)(const char *, char *, size_t) )
10242 {
10243 PyObject *res, *attr;
10244 Py_ssize_t len, err, start, i;
10245 char *buf;
10246
10247 len = try_listxattr(path, list, 256, &buf);
10248 if (len < 0) {
10249 if (PyErr_Occurred())
10250 return NULL;
10251 len = try_listxattr(path, list, XATTR_LIST_MAX, &buf);
10252 if (len < 0)
10253 return NULL;
10254 }
10255 res = PyList_New(0);
10256 if (!res) {
10257 PyMem_FREE(buf);
10258 return NULL;
10259 }
10260 for (start = i = 0; i < len; i++) {
10261 if (!buf[i]) {
10262 attr = PyUnicode_DecodeFSDefaultAndSize(&buf[start], i - start);
10263 if (!attr) {
10264 Py_DECREF(res);
10265 PyMem_FREE(buf);
10266 return NULL;
10267 }
10268 err = PyList_Append(res, attr);
10269 Py_DECREF(attr);
10270 if (err) {
10271 Py_DECREF(res);
10272 PyMem_FREE(buf);
10273 return NULL;
10274 }
10275 start = i + 1;
10276 }
10277 }
10278 PyMem_FREE(buf);
10279 return res;
10280 }
10281
10282 PyDoc_STRVAR(posix_listxattr__doc__,
10283 "listxattr(path)\n\n\
10284 Return a list of extended attributes on *path*.");
10285
10286 static PyObject *
10287 posix_listxattr(PyObject *self, PyObject *args)
10288 {
10289 PyObject *path, *res;
10290
10291 if (!PyArg_ParseTuple(args, "O&:listxattr", PyUnicode_FSConverter, &path))
10292 return NULL;
10293 res = listxattr_common(PyBytes_AS_STRING(path), listxattr);
10294 Py_DECREF(path);
10295 return res;
10296 }
10297
10298 PyDoc_STRVAR(posix_llistxattr__doc__,
10299 "llistxattr(path)\n\n\
10300 Like listxattr but don't follow symlinks..");
10301
10302 static PyObject *
10303 posix_llistxattr(PyObject *self, PyObject *args)
10304 {
10305 PyObject *path, *res;
10306
10307 if (!PyArg_ParseTuple(args, "O&:llistxattr", PyUnicode_FSConverter, &path))
10308 return NULL;
10309 res = listxattr_common(PyBytes_AS_STRING(path), llistxattr);
10310 Py_DECREF(path);
10311 return res;
10312 }
10313
10314 static ssize_t
10315 wrap_flistxattr(const char *path, char *buf, size_t len)
10316 {
10317 /* Hack to share code. */
10318 return flistxattr((int)(Py_uintptr_t)path, buf, len);
10319 }
10320
10321 PyDoc_STRVAR(posix_flistxattr__doc__,
10322 "flistxattr(path)\n\n\
10323 Like flistxattr but operates on a file descriptor.");
10324
10325 static PyObject *
10326 posix_flistxattr(PyObject *self, PyObject *args)
10327 {
10328 long fd;
10329
10330 if (!PyArg_ParseTuple(args, "i:flistxattr", &fd))
10331 return NULL;
10332 return listxattr_common((const char *)(Py_uintptr_t)fd, wrap_flistxattr);
10333 }
10334
10335 #endif /* HAVE_ATTR_XATTR_H */
9952 10336
9953 static PyMethodDef posix_methods[] = { 10337 static PyMethodDef posix_methods[] = {
9954 {"access", posix_access, METH_VARARGS, posix_access__doc__}, 10338 {"access", posix_access, METH_VARARGS, posix_access__doc__},
9955 #ifdef HAVE_TTYNAME 10339 #ifdef HAVE_TTYNAME
9956 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__}, 10340 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
9957 #endif 10341 #endif
9958 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__}, 10342 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
9959 #ifdef HAVE_CHFLAGS 10343 #ifdef HAVE_CHFLAGS
9960 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__}, 10344 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
9961 #endif /* HAVE_CHFLAGS */ 10345 #endif /* HAVE_CHFLAGS */
(...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after
10391 {"symlinkat", posix_symlinkat, METH_VARARGS, posix_symlinkat__doc__}, 10775 {"symlinkat", posix_symlinkat, METH_VARARGS, posix_symlinkat__doc__},
10392 #endif /* HAVE_SYMLINKAT */ 10776 #endif /* HAVE_SYMLINKAT */
10393 #ifdef HAVE_UNLINKAT 10777 #ifdef HAVE_UNLINKAT
10394 {"unlinkat", posix_unlinkat, METH_VARARGS, posix_unlinkat__doc__}, 10778 {"unlinkat", posix_unlinkat, METH_VARARGS, posix_unlinkat__doc__},
10395 #endif 10779 #endif
10396 #ifdef HAVE_UTIMENSAT 10780 #ifdef HAVE_UTIMENSAT
10397 {"utimensat", posix_utimensat, METH_VARARGS, posix_utimensat__doc__}, 10781 {"utimensat", posix_utimensat, METH_VARARGS, posix_utimensat__doc__},
10398 #endif 10782 #endif
10399 #ifdef HAVE_MKFIFOAT 10783 #ifdef HAVE_MKFIFOAT
10400 {"mkfifoat", posix_mkfifoat, METH_VARARGS, posix_mkfifoat__doc__}, 10784 {"mkfifoat", posix_mkfifoat, METH_VARARGS, posix_mkfifoat__doc__},
10785 #endif
10786 #ifdef HAVE_ATTR_XATTR_H
10787 {"setxattr", posix_setxattr, METH_VARARGS, posix_setxattr__doc__},
10788 {"lsetxattr", posix_lsetxattr, METH_VARARGS, posix_lsetxattr__doc__},
10789 {"fsetxattr", posix_fsetxattr, METH_VARARGS, posix_fsetxattr__doc__},
10790 {"getxattr", posix_getxattr, METH_VARARGS, posix_getxattr__doc__},
10791 {"lgetxattr", posix_lgetxattr, METH_VARARGS, posix_lgetxattr__doc__},
10792 {"fgetxattr", posix_fgetxattr, METH_VARARGS, posix_fgetxattr__doc__},
10793 {"removexattr", posix_removexattr, METH_VARARGS, posix_removexattr__doc__},
10794 {"lremovexattr", posix_lremovexattr, METH_VARARGS, posix_lremovexattr__doc__ },
10795 {"fremovexattr", posix_fremovexattr, METH_VARARGS, posix_fremovexattr__doc__ },
10796 {"listxattr", posix_listxattr, METH_VARARGS, posix_listxattr__doc__},
10797 {"llistxattr", posix_llistxattr, METH_VARARGS, posix_llistxattr__doc__},
10798 {"flistxattr", posix_flistxattr, METH_VARARGS, posix_flistxattr__doc__},
10401 #endif 10799 #endif
10402 {NULL, NULL} /* Sentinel */ 10800 {NULL, NULL} /* Sentinel */
10403 }; 10801 };
10404 10802
10405 10803
10406 static int 10804 static int
10407 ins(PyObject *module, char *symbol, long value) 10805 ins(PyObject *module, char *symbol, long value)
10408 { 10806 {
10409 return PyModule_AddIntConstant(module, symbol, value); 10807 return PyModule_AddIntConstant(module, symbol, value);
10410 } 10808 }
(...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after
10839 if (ins(d, "SCHED_OTHER", (long)SCHED_OTHER)) return -1; 11237 if (ins(d, "SCHED_OTHER", (long)SCHED_OTHER)) return -1;
10840 #ifdef SCHED_BATCH 11238 #ifdef SCHED_BATCH
10841 if (ins(d, "SCHED_BATCH", (long)SCHED_BATCH)) return -1; 11239 if (ins(d, "SCHED_BATCH", (long)SCHED_BATCH)) return -1;
10842 #endif 11240 #endif
10843 #ifdef SCHED_IDLE 11241 #ifdef SCHED_IDLE
10844 if (ins(d, "SCHED_IDLE", (long)SCHED_IDLE)) return -1; 11242 if (ins(d, "SCHED_IDLE", (long)SCHED_IDLE)) return -1;
10845 #endif 11243 #endif
10846 #ifdef SCHED_RESET_ON_FORK 11244 #ifdef SCHED_RESET_ON_FORK
10847 if (ins(d, "SCHED_RESET_ON_FORK", (long)SCHED_RESET_ON_FORK)) return -1; 11245 if (ins(d, "SCHED_RESET_ON_FORK", (long)SCHED_RESET_ON_FORK)) return -1;
10848 #endif 11246 #endif
11247 #endif
11248
11249 #ifdef HAVE_ATTR_XATTR_H
11250 if (ins(d, "XATTR_CREATE", (long)XATTR_CREATE)) return -1;
11251 if (ins(d, "XATTR_REPLACE", (long)XATTR_REPLACE)) return -1;
11252 if (ins(d, "XATTR_SIZE_MAX", (long)XATTR_SIZE_MAX)) return -1;
10849 #endif 11253 #endif
10850 11254
10851 #if defined(PYOS_OS2) 11255 #if defined(PYOS_OS2)
10852 if (insertvalues(d)) return -1; 11256 if (insertvalues(d)) return -1;
10853 #endif 11257 #endif
10854 return 0; 11258 return 0;
10855 } 11259 }
10856 11260
10857 11261
10858 #if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !def ined(__QNX__) 11262 #if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !def ined(__QNX__)
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
11007 11411
11008 11412
11009 #endif /* __APPLE__ */ 11413 #endif /* __APPLE__ */
11010 return m; 11414 return m;
11011 11415
11012 } 11416 }
11013 11417
11014 #ifdef __cplusplus 11418 #ifdef __cplusplus
11015 } 11419 }
11016 #endif 11420 #endif
OLDNEW
« no previous file with comments | « Lib/test/test_os.py ('k') | configure » ('j') | no next file with comments »

RSS Feeds Recent Issues | This issue
This is Rietveld cbc36f91f3f7