@@ -30,7 +30,8 @@ extern wchar_t* _Py_DecodeUTF8_surrogateescape(const char *s, Py_ssize_t size);
3030 0: open() ignores O_CLOEXEC flag, ex: Linux kernel older than 2.6.23
3131 1: open() supports O_CLOEXEC flag, close-on-exec is set
3232
33- The flag is used by _Py_open(), io.FileIO and os.open() */
33+ The flag is used by _Py_open(), _Py_open_noraise(), io.FileIO
34+ and os.open(). */
3435int _Py_open_cloexec_works = -1 ;
3536#endif
3637
@@ -907,37 +908,74 @@ _Py_set_inheritable(int fd, int inheritable, int *atomic_flag_works)
907908 return set_inheritable (fd , inheritable , 1 , atomic_flag_works );
908909}
909910
910- /* Open a file with the specified flags (wrapper to open() function).
911- The file descriptor is created non-inheritable. */
912- int
913- _Py_open (const char * pathname , int flags )
911+ static int
912+ _Py_open_impl (const char * pathname , int flags , int gil_held )
914913{
915914 int fd ;
916- #ifdef MS_WINDOWS
917- fd = open (pathname , flags | O_NOINHERIT );
918- if (fd < 0 )
919- return fd ;
920- #else
921-
915+ #ifndef MS_WINDOWS
922916 int * atomic_flag_works ;
923- #ifdef O_CLOEXEC
917+ #endif
918+
919+ #ifdef MS_WINDOWS
920+ flags |= O_NOINHERIT ;
921+ #elif defined(O_CLOEXEC )
924922 atomic_flag_works = & _Py_open_cloexec_works ;
925923 flags |= O_CLOEXEC ;
926924#else
927925 atomic_flag_works = NULL ;
928926#endif
929- fd = open (pathname , flags );
930- if (fd < 0 )
931- return fd ;
932927
933- if (set_inheritable (fd , 0 , 0 , atomic_flag_works ) < 0 ) {
928+ if (gil_held ) {
929+ Py_BEGIN_ALLOW_THREADS
930+ fd = open (pathname , flags );
931+ Py_END_ALLOW_THREADS
932+
933+ if (fd < 0 ) {
934+ PyErr_SetFromErrnoWithFilename (PyExc_OSError , pathname );
935+ return -1 ;
936+ }
937+ }
938+ else {
939+ fd = open (pathname , flags );
940+ if (fd < 0 )
941+ return -1 ;
942+ }
943+
944+ #ifndef MS_WINDOWS
945+ if (set_inheritable (fd , 0 , gil_held , atomic_flag_works ) < 0 ) {
934946 close (fd );
935947 return -1 ;
936948 }
937- #endif /* !MS_WINDOWS */
949+ #endif
950+
938951 return fd ;
939952}
940953
954+ /* Open a file with the specified flags (wrapper to open() function).
955+ Return a file descriptor on success. Raise an exception and return -1 on
956+ error.
957+
958+ The file descriptor is created non-inheritable.
959+
960+ The GIL must be held. Use _Py_open_noraise() if the GIL cannot be held. */
961+ int
962+ _Py_open (const char * pathname , int flags )
963+ {
964+ /* _Py_open() must be called with the GIL held. */
965+ assert (PyGILState_Check ());
966+ return _Py_open_impl (pathname , flags , 1 );
967+ }
968+
969+ /* Open a file with the specified flags (wrapper to open() function).
970+ Return a file descriptor on success. Set errno and return -1 on error.
971+
972+ The file descriptor is created non-inheritable. */
973+ int
974+ _Py_open_noraise (const char * pathname , int flags )
975+ {
976+ return _Py_open_impl (pathname , flags , 0 );
977+ }
978+
941979/* Open a file. Use _wfopen() on Windows, encode the path to the locale
942980 encoding and use fopen() otherwise. The file descriptor is created
943981 non-inheritable. */
0 commit comments