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

Delta Between Two Patch Sets: Modules/posixmodule.c

Issue 25994: File descriptor leaks in os.scandir()
Left Patch Set: Created 3 years, 7 months ago
Right Patch Set: Created 3 years, 7 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:
Left: Side by side diff | Download
Right: Side by side diff | Download
« Lib/test/test_os.py ('K') | « Misc/NEWS ('k') | no next file » | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 1
2 /* POSIX module implementation */ 2 /* POSIX module implementation */
3 3
4 /* This file is also used for Windows NT/MS-Win. In that case the 4 /* This file is also used for Windows NT/MS-Win. In that case the
5 module actually calls itself 'nt', not 'posix', and a few 5 module actually calls itself 'nt', 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. '_MSC_VER'. */ 9 test macro, e.g. '_MSC_VER'. */
10 10
(...skipping 11920 matching lines...) Expand 10 before | Expand all | Expand 10 after
11931 WIN32_FIND_DATAW file_data; 11931 WIN32_FIND_DATAW file_data;
11932 int first_time; 11932 int first_time;
11933 #else /* POSIX */ 11933 #else /* POSIX */
11934 DIR *dirp; 11934 DIR *dirp;
11935 #endif 11935 #endif
11936 } ScandirIterator; 11936 } ScandirIterator;
11937 11937
11938 #ifdef MS_WINDOWS 11938 #ifdef MS_WINDOWS
11939 11939
11940 static int 11940 static int
11941 ScandirIterator_isclosed(ScandirIterator *iterator) 11941 ScandirIterator_is_closed(ScandirIterator *iterator)
haypo 2016/02/09 16:50:33 i suggest to rename the function to ..._is_closed(
storchaka 2016/02/09 19:04:52 Done.
11942 { 11942 {
11943 return iterator->handle == INVALID_HANDLE_VALUE; 11943 return iterator->handle == INVALID_HANDLE_VALUE;
11944 } 11944 }
11945 11945
11946 static void 11946 static void
11947 ScandirIterator_closedir(ScandirIterator *iterator) 11947 ScandirIterator_closedir(ScandirIterator *iterator)
11948 { 11948 {
11949 if (iterator->handle == INVALID_HANDLE_VALUE) 11949 if (iterator->handle == INVALID_HANDLE_VALUE)
11950 return; 11950 return;
11951 11951
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
11993 } 11993 }
11994 11994
11995 /* Error or no more files */ 11995 /* Error or no more files */
11996 ScandirIterator_closedir(iterator); 11996 ScandirIterator_closedir(iterator);
11997 return NULL; 11997 return NULL;
11998 } 11998 }
11999 11999
12000 #else /* POSIX */ 12000 #else /* POSIX */
12001 12001
12002 static int 12002 static int
12003 ScandirIterator_isclosed(ScandirIterator *iterator) 12003 ScandirIterator_is_closed(ScandirIterator *iterator)
12004 { 12004 {
12005 return !iterator->dirp; 12005 return !iterator->dirp;
12006 } 12006 }
12007 12007
12008 static void 12008 static void
12009 ScandirIterator_closedir(ScandirIterator *iterator) 12009 ScandirIterator_closedir(ScandirIterator *iterator)
12010 { 12010 {
12011 if (!iterator->dirp) 12011 if (!iterator->dirp)
12012 return; 12012 return;
12013 12013
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
12086 static PyObject * 12086 static PyObject *
12087 ScandirIterator_exit(ScandirIterator *self, PyObject *args) 12087 ScandirIterator_exit(ScandirIterator *self, PyObject *args)
12088 { 12088 {
12089 ScandirIterator_closedir(self); 12089 ScandirIterator_closedir(self);
12090 Py_RETURN_NONE; 12090 Py_RETURN_NONE;
12091 } 12091 }
12092 12092
12093 static void 12093 static void
12094 ScandirIterator_dealloc(ScandirIterator *iterator) 12094 ScandirIterator_dealloc(ScandirIterator *iterator)
12095 { 12095 {
12096 if (!ScandirIterator_isclosed(iterator)) { 12096 if (!ScandirIterator_is_closed(iterator)) {
12097 PyObject *exc, *val, *tb; 12097 PyObject *exc, *val, *tb;
12098 Py_ssize_t old_refcount = Py_REFCNT(iterator); 12098 Py_ssize_t old_refcount = Py_REFCNT(iterator);
12099 /* Py_INCREF/Py_DECREF cannot be used, because the refcount is
12100 * likely zero, Py_DECREF would call again the destructor.
12101 */
12099 ++Py_REFCNT(iterator); 12102 ++Py_REFCNT(iterator);
haypo 2016/02/09 16:50:33 I suggest to add the following comment: /* Py_INC
storchaka 2016/02/09 19:04:52 Done.
12100 PyErr_Fetch(&exc, &val, &tb); 12103 PyErr_Fetch(&exc, &val, &tb);
12101 if (PyErr_WarnFormat(PyExc_ResourceWarning, 1, 12104 if (PyErr_WarnFormat(PyExc_ResourceWarning, 1,
12102 "unclosed scandir iterator %R", iterator)) { 12105 "unclosed scandir iterator %R", iterator)) {
12103 /* Spurious errors can appear at shutdown */ 12106 /* Spurious errors can appear at shutdown */
12104 if (PyErr_ExceptionMatches(PyExc_Warning)) 12107 if (PyErr_ExceptionMatches(PyExc_Warning))
12105 PyErr_WriteUnraisable((PyObject *) iterator); 12108 PyErr_WriteUnraisable((PyObject *) iterator);
12106 } 12109 }
12107 PyErr_Restore(exc, val, tb); 12110 PyErr_Restore(exc, val, tb);
12111 Py_REFCNT(iterator) = old_refcount;
12112
12108 ScandirIterator_closedir(iterator); 12113 ScandirIterator_closedir(iterator);
haypo 2016/02/09 16:50:33 You may call it after Py_REFCNT(iterator) = ... an
storchaka 2016/02/09 19:04:52 Done.
12109 Py_REFCNT(iterator) = old_refcount;
12110 } 12114 }
12111 Py_XDECREF(iterator->path.object); 12115 Py_XDECREF(iterator->path.object);
12112 path_cleanup(&iterator->path); 12116 path_cleanup(&iterator->path);
12113 Py_TYPE(iterator)->tp_free((PyObject *)iterator); 12117 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
12114 } 12118 }
12115 12119
12116 static PyMethodDef ScandirIterator_methods[] = { 12120 static PyMethodDef ScandirIterator_methods[] = {
12117 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS}, 12121 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
12118 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS}, 12122 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
12119 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS}, 12123 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
(...skipping 1078 matching lines...) Expand 10 before | Expand all | Expand 10 after
13198 PyModule_AddObject(m, "_have_functions", list); 13202 PyModule_AddObject(m, "_have_functions", list);
13199 13203
13200 initialized = 1; 13204 initialized = 1;
13201 13205
13202 return m; 13206 return m;
13203 } 13207 }
13204 13208
13205 #ifdef __cplusplus 13209 #ifdef __cplusplus
13206 } 13210 }
13207 #endif 13211 #endif
LEFTRIGHT
« Misc/NEWS ('k') | no next file » | Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Toggle Comments ('s')

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+