You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1618 lines
43 KiB

13 years ago
  1. #include "Python.h"
  2. #include "osdefs.h"
  3. #include <locale.h>
  4. #ifdef MS_WINDOWS
  5. # include <malloc.h>
  6. # include <windows.h>
  7. #endif
  8. #ifdef HAVE_LANGINFO_H
  9. #include <langinfo.h>
  10. #endif
  11. #ifdef HAVE_SYS_IOCTL_H
  12. #include <sys/ioctl.h>
  13. #endif
  14. #ifdef HAVE_FCNTL_H
  15. #include <fcntl.h>
  16. #endif /* HAVE_FCNTL_H */
  17. #ifdef __APPLE__
  18. extern wchar_t* _Py_DecodeUTF8_surrogateescape(const char *s, Py_ssize_t size);
  19. #endif
  20. #ifdef O_CLOEXEC
  21. /* Does open() support the O_CLOEXEC flag? Possible values:
  22. -1: unknown
  23. 0: open() ignores O_CLOEXEC flag, ex: Linux kernel older than 2.6.23
  24. 1: open() supports O_CLOEXEC flag, close-on-exec is set
  25. The flag is used by _Py_open(), _Py_open_noraise(), io.FileIO
  26. and os.open(). */
  27. int _Py_open_cloexec_works = -1;
  28. #endif
  29. PyObject *
  30. _Py_device_encoding(int fd)
  31. {
  32. #if defined(MS_WINDOWS)
  33. UINT cp;
  34. #endif
  35. if (!_PyVerify_fd(fd) || !isatty(fd)) {
  36. Py_RETURN_NONE;
  37. }
  38. #if defined(MS_WINDOWS)
  39. if (fd == 0)
  40. cp = GetConsoleCP();
  41. else if (fd == 1 || fd == 2)
  42. cp = GetConsoleOutputCP();
  43. else
  44. cp = 0;
  45. /* GetConsoleCP() and GetConsoleOutputCP() return 0 if the application
  46. has no console */
  47. if (cp != 0)
  48. return PyUnicode_FromFormat("cp%u", (unsigned int)cp);
  49. #elif defined(CODESET)
  50. {
  51. char *codeset = nl_langinfo(CODESET);
  52. if (codeset != NULL && codeset[0] != 0)
  53. return PyUnicode_FromString(codeset);
  54. }
  55. #endif
  56. Py_RETURN_NONE;
  57. }
  58. #if !defined(__APPLE__) && !defined(MS_WINDOWS)
  59. extern int _Py_normalize_encoding(const char *, char *, size_t);
  60. /* Workaround FreeBSD and OpenIndiana locale encoding issue with the C locale.
  61. On these operating systems, nl_langinfo(CODESET) announces an alias of the
  62. ASCII encoding, whereas mbstowcs() and wcstombs() functions use the
  63. ISO-8859-1 encoding. The problem is that os.fsencode() and os.fsdecode() use
  64. locale.getpreferredencoding() codec. For example, if command line arguments
  65. are decoded by mbstowcs() and encoded back by os.fsencode(), we get a
  66. UnicodeEncodeError instead of retrieving the original byte string.
  67. The workaround is enabled if setlocale(LC_CTYPE, NULL) returns "C",
  68. nl_langinfo(CODESET) announces "ascii" (or an alias to ASCII), and at least
  69. one byte in range 0x80-0xff can be decoded from the locale encoding. The
  70. workaround is also enabled on error, for example if getting the locale
  71. failed.
  72. Values of force_ascii:
  73. 1: the workaround is used: Py_EncodeLocale() uses
  74. encode_ascii_surrogateescape() and Py_DecodeLocale() uses
  75. decode_ascii_surrogateescape()
  76. 0: the workaround is not used: Py_EncodeLocale() uses wcstombs() and
  77. Py_DecodeLocale() uses mbstowcs()
  78. -1: unknown, need to call check_force_ascii() to get the value
  79. */
  80. static int force_ascii = -1;
  81. static int
  82. check_force_ascii(void)
  83. {
  84. char *loc;
  85. #if defined(HAVE_LANGINFO_H) && defined(CODESET)
  86. char *codeset, **alias;
  87. char encoding[100];
  88. int is_ascii;
  89. unsigned int i;
  90. char* ascii_aliases[] = {
  91. "ascii",
  92. "646",
  93. "ansi-x3.4-1968",
  94. "ansi-x3-4-1968",
  95. "ansi-x3.4-1986",
  96. "cp367",
  97. "csascii",
  98. "ibm367",
  99. "iso646-us",
  100. "iso-646.irv-1991",
  101. "iso-ir-6",
  102. "us",
  103. "us-ascii",
  104. NULL
  105. };
  106. #endif
  107. loc = setlocale(LC_CTYPE, NULL);
  108. if (loc == NULL)
  109. goto error;
  110. if (strcmp(loc, "C") != 0) {
  111. /* the LC_CTYPE locale is different than C */
  112. return 0;
  113. }
  114. #if defined(HAVE_LANGINFO_H) && defined(CODESET)
  115. codeset = nl_langinfo(CODESET);
  116. if (!codeset || codeset[0] == '\0') {
  117. /* CODESET is not set or empty */
  118. goto error;
  119. }
  120. if (!_Py_normalize_encoding(codeset, encoding, sizeof(encoding)))
  121. goto error;
  122. is_ascii = 0;
  123. for (alias=ascii_aliases; *alias != NULL; alias++) {
  124. if (strcmp(encoding, *alias) == 0) {
  125. is_ascii = 1;
  126. break;
  127. }
  128. }
  129. if (!is_ascii) {
  130. /* nl_langinfo(CODESET) is not "ascii" or an alias of ASCII */
  131. return 0;
  132. }
  133. for (i=0x80; i<0xff; i++) {
  134. unsigned char ch;
  135. wchar_t wch;
  136. size_t res;
  137. ch = (unsigned char)i;
  138. res = mbstowcs(&wch, (char*)&ch, 1);
  139. if (res != (size_t)-1) {
  140. /* decoding a non-ASCII character from the locale encoding succeed:
  141. the locale encoding is not ASCII, force ASCII */
  142. return 1;
  143. }
  144. }
  145. /* None of the bytes in the range 0x80-0xff can be decoded from the locale
  146. encoding: the locale encoding is really ASCII */
  147. return 0;
  148. #else
  149. /* nl_langinfo(CODESET) is not available: always force ASCII */
  150. return 1;
  151. #endif
  152. error:
  153. /* if an error occured, force the ASCII encoding */
  154. return 1;
  155. }
  156. static char*
  157. encode_ascii_surrogateescape(const wchar_t *text, size_t *error_pos)
  158. {
  159. char *result = NULL, *out;
  160. size_t len, i;
  161. wchar_t ch;
  162. if (error_pos != NULL)
  163. *error_pos = (size_t)-1;
  164. len = wcslen(text);
  165. result = PyMem_Malloc(len + 1); /* +1 for NUL byte */
  166. if (result == NULL)
  167. return NULL;
  168. out = result;
  169. for (i=0; i<len; i++) {
  170. ch = text[i];
  171. if (ch <= 0x7f) {
  172. /* ASCII character */
  173. *out++ = (char)ch;
  174. }
  175. else if (0xdc80 <= ch && ch <= 0xdcff) {
  176. /* UTF-8b surrogate */
  177. *out++ = (char)(ch - 0xdc00);
  178. }
  179. else {
  180. if (error_pos != NULL)
  181. *error_pos = i;
  182. PyMem_Free(result);
  183. return NULL;
  184. }
  185. }
  186. *out = '\0';
  187. return result;
  188. }
  189. #endif /* !defined(__APPLE__) && !defined(MS_WINDOWS) */
  190. #if !defined(__APPLE__) && (!defined(MS_WINDOWS) || !defined(HAVE_MBRTOWC))
  191. static wchar_t*
  192. decode_ascii_surrogateescape(const char *arg, size_t *size)
  193. {
  194. wchar_t *res;
  195. unsigned char *in;
  196. wchar_t *out;
  197. size_t argsize = strlen(arg) + 1;
  198. if (argsize > PY_SSIZE_T_MAX/sizeof(wchar_t))
  199. return NULL;
  200. res = PyMem_RawMalloc(argsize*sizeof(wchar_t));
  201. if (!res)
  202. return NULL;
  203. in = (unsigned char*)arg;
  204. out = res;
  205. while(*in)
  206. if(*in < 128)
  207. *out++ = *in++;
  208. else
  209. *out++ = 0xdc00 + *in++;
  210. *out = 0;
  211. if (size != NULL)
  212. *size = out - res;
  213. return res;
  214. }
  215. #endif
  216. /* Decode a byte string from the locale encoding with the
  217. surrogateescape error handler: undecodable bytes are decoded as characters
  218. in range U+DC80..U+DCFF. If a byte sequence can be decoded as a surrogate
  219. character, escape the bytes using the surrogateescape error handler instead
  220. of decoding them.
  221. Return a pointer to a newly allocated wide character string, use
  222. PyMem_RawFree() to free the memory. If size is not NULL, write the number of
  223. wide characters excluding the null character into *size
  224. Return NULL on decoding error or memory allocation error. If *size* is not
  225. NULL, *size is set to (size_t)-1 on memory error or set to (size_t)-2 on
  226. decoding error.
  227. Decoding errors should never happen, unless there is a bug in the C
  228. library.
  229. Use the Py_EncodeLocale() function to encode the character string back to a
  230. byte string. */
  231. wchar_t*
  232. Py_DecodeLocale(const char* arg, size_t *size)
  233. {
  234. #ifdef __APPLE__
  235. wchar_t *wstr;
  236. wstr = _Py_DecodeUTF8_surrogateescape(arg, strlen(arg));
  237. if (size != NULL) {
  238. if (wstr != NULL)
  239. *size = wcslen(wstr);
  240. else
  241. *size = (size_t)-1;
  242. }
  243. return wstr;
  244. #else
  245. wchar_t *res;
  246. size_t argsize;
  247. size_t count;
  248. #ifdef HAVE_MBRTOWC
  249. unsigned char *in;
  250. wchar_t *out;
  251. mbstate_t mbs;
  252. #endif
  253. #ifndef MS_WINDOWS
  254. if (force_ascii == -1)
  255. force_ascii = check_force_ascii();
  256. if (force_ascii) {
  257. /* force ASCII encoding to workaround mbstowcs() issue */
  258. res = decode_ascii_surrogateescape(arg, size);
  259. if (res == NULL)
  260. goto oom;
  261. return res;
  262. }
  263. #endif
  264. #ifdef HAVE_BROKEN_MBSTOWCS
  265. /* Some platforms have a broken implementation of
  266. * mbstowcs which does not count the characters that
  267. * would result from conversion. Use an upper bound.
  268. */
  269. argsize = strlen(arg);
  270. #else
  271. argsize = mbstowcs(NULL, arg, 0);
  272. #endif
  273. if (argsize != (size_t)-1) {
  274. if (argsize == PY_SSIZE_T_MAX)
  275. goto oom;
  276. argsize += 1;
  277. if (argsize > PY_SSIZE_T_MAX/sizeof(wchar_t))
  278. goto oom;
  279. res = (wchar_t *)PyMem_RawMalloc(argsize*sizeof(wchar_t));
  280. if (!res)
  281. goto oom;
  282. count = mbstowcs(res, arg, argsize);
  283. if (count != (size_t)-1) {
  284. wchar_t *tmp;
  285. /* Only use the result if it contains no
  286. surrogate characters. */
  287. for (tmp = res; *tmp != 0 &&
  288. !Py_UNICODE_IS_SURROGATE(*tmp); tmp++)
  289. ;
  290. if (*tmp == 0) {
  291. if (size != NULL)
  292. *size = count;
  293. return res;
  294. }
  295. }
  296. PyMem_RawFree(res);
  297. }
  298. /* Conversion failed. Fall back to escaping with surrogateescape. */
  299. #ifdef HAVE_MBRTOWC
  300. /* Try conversion with mbrtwoc (C99), and escape non-decodable bytes. */
  301. /* Overallocate; as multi-byte characters are in the argument, the
  302. actual output could use less memory. */
  303. argsize = strlen(arg) + 1;
  304. if (argsize > PY_SSIZE_T_MAX/sizeof(wchar_t))
  305. goto oom;
  306. res = (wchar_t*)PyMem_RawMalloc(argsize*sizeof(wchar_t));
  307. if (!res)
  308. goto oom;
  309. in = (unsigned char*)arg;
  310. out = res;
  311. memset(&mbs, 0, sizeof mbs);
  312. while (argsize) {
  313. size_t converted = mbrtowc(out, (char*)in, argsize, &mbs);
  314. if (converted == 0)
  315. /* Reached end of string; null char stored. */
  316. break;
  317. if (converted == (size_t)-2) {
  318. /* Incomplete character. This should never happen,
  319. since we provide everything that we have -
  320. unless there is a bug in the C library, or I
  321. misunderstood how mbrtowc works. */
  322. PyMem_RawFree(res);
  323. if (size != NULL)
  324. *size = (size_t)-2;
  325. return NULL;
  326. }
  327. if (converted == (size_t)-1) {
  328. /* Conversion error. Escape as UTF-8b, and start over
  329. in the initial shift state. */
  330. *out++ = 0xdc00 + *in++;
  331. argsize--;
  332. memset(&mbs, 0, sizeof mbs);
  333. continue;
  334. }
  335. if (Py_UNICODE_IS_SURROGATE(*out)) {
  336. /* Surrogate character. Escape the original
  337. byte sequence with surrogateescape. */
  338. argsize -= converted;
  339. while (converted--)
  340. *out++ = 0xdc00 + *in++;
  341. continue;
  342. }
  343. /* successfully converted some bytes */
  344. in += converted;
  345. argsize -= converted;
  346. out++;
  347. }
  348. if (size != NULL)
  349. *size = out - res;
  350. #else /* HAVE_MBRTOWC */
  351. /* Cannot use C locale for escaping; manually escape as if charset
  352. is ASCII (i.e. escape all bytes > 128. This will still roundtrip
  353. correctly in the locale's charset, which must be an ASCII superset. */
  354. res = decode_ascii_surrogateescape(arg, size);
  355. if (res == NULL)
  356. goto oom;
  357. #endif /* HAVE_MBRTOWC */
  358. return res;
  359. oom:
  360. if (size != NULL)
  361. *size = (size_t)-1;
  362. return NULL;
  363. #endif /* __APPLE__ */
  364. }
  365. /* Encode a wide character string to the locale encoding with the
  366. surrogateescape error handler: surrogate characters in the range
  367. U+DC80..U+DCFF are converted to bytes 0x80..0xFF.
  368. Return a pointer to a newly allocated byte string, use PyMem_Free() to free
  369. the memory. Return NULL on encoding or memory allocation error.
  370. If error_pos is not NULL, *error_pos is set to the index of the invalid
  371. character on encoding error, or set to (size_t)-1 otherwise.
  372. Use the Py_DecodeLocale() function to decode the bytes string back to a wide
  373. character string. */
  374. char*
  375. Py_EncodeLocale(const wchar_t *text, size_t *error_pos)
  376. {
  377. #ifdef __APPLE__
  378. Py_ssize_t len;
  379. PyObject *unicode, *bytes = NULL;
  380. char *cpath;
  381. unicode = PyUnicode_FromWideChar(text, wcslen(text));
  382. if (unicode == NULL)
  383. return NULL;
  384. bytes = _PyUnicode_AsUTF8String(unicode, "surrogateescape");
  385. Py_DECREF(unicode);
  386. if (bytes == NULL) {
  387. PyErr_Clear();
  388. if (error_pos != NULL)
  389. *error_pos = (size_t)-1;
  390. return NULL;
  391. }
  392. len = PyBytes_GET_SIZE(bytes);
  393. cpath = PyMem_Malloc(len+1);
  394. if (cpath == NULL) {
  395. PyErr_Clear();
  396. Py_DECREF(bytes);
  397. if (error_pos != NULL)
  398. *error_pos = (size_t)-1;
  399. return NULL;
  400. }
  401. memcpy(cpath, PyBytes_AsString(bytes), len + 1);
  402. Py_DECREF(bytes);
  403. return cpath;
  404. #else /* __APPLE__ */
  405. const size_t len = wcslen(text);
  406. char *result = NULL, *bytes = NULL;
  407. size_t i, size, converted;
  408. wchar_t c, buf[2];
  409. #ifndef MS_WINDOWS
  410. if (force_ascii == -1)
  411. force_ascii = check_force_ascii();
  412. if (force_ascii)
  413. return encode_ascii_surrogateescape(text, error_pos);
  414. #endif
  415. /* The function works in two steps:
  416. 1. compute the length of the output buffer in bytes (size)
  417. 2. outputs the bytes */
  418. size = 0;
  419. buf[1] = 0;
  420. while (1) {
  421. for (i=0; i < len; i++) {
  422. c = text[i];
  423. if (c >= 0xdc80 && c <= 0xdcff) {
  424. /* UTF-8b surrogate */
  425. if (bytes != NULL) {
  426. *bytes++ = c - 0xdc00;
  427. size--;
  428. }
  429. else
  430. size++;
  431. continue;
  432. }
  433. else {
  434. buf[0] = c;
  435. if (bytes != NULL)
  436. converted = wcstombs(bytes, buf, size);
  437. else
  438. converted = wcstombs(NULL, buf, 0);
  439. if (converted == (size_t)-1) {
  440. if (result != NULL)
  441. PyMem_Free(result);
  442. if (error_pos != NULL)
  443. *error_pos = i;
  444. return NULL;
  445. }
  446. if (bytes != NULL) {
  447. bytes += converted;
  448. size -= converted;
  449. }
  450. else
  451. size += converted;
  452. }
  453. }
  454. if (result != NULL) {
  455. *bytes = '\0';
  456. break;
  457. }
  458. size += 1; /* nul byte at the end */
  459. result = PyMem_Malloc(size);
  460. if (result == NULL) {
  461. if (error_pos != NULL)
  462. *error_pos = (size_t)-1;
  463. return NULL;
  464. }
  465. bytes = result;
  466. }
  467. return result;
  468. #endif /* __APPLE__ */
  469. }
  470. #ifdef MS_WINDOWS
  471. static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
  472. static void
  473. FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
  474. {
  475. /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
  476. /* Cannot simply cast and dereference in_ptr,
  477. since it might not be aligned properly */
  478. __int64 in;
  479. memcpy(&in, in_ptr, sizeof(in));
  480. *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
  481. *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
  482. }
  483. void
  484. _Py_time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
  485. {
  486. /* XXX endianness */
  487. __int64 out;
  488. out = time_in + secs_between_epochs;
  489. out = out * 10000000 + nsec_in / 100;
  490. memcpy(out_ptr, &out, sizeof(out));
  491. }
  492. /* Below, we *know* that ugo+r is 0444 */
  493. #if _S_IREAD != 0400
  494. #error Unsupported C library
  495. #endif
  496. static int
  497. attributes_to_mode(DWORD attr)
  498. {
  499. int m = 0;
  500. if (attr & FILE_ATTRIBUTE_DIRECTORY)
  501. m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
  502. else
  503. m |= _S_IFREG;
  504. if (attr & FILE_ATTRIBUTE_READONLY)
  505. m |= 0444;
  506. else
  507. m |= 0666;
  508. return m;
  509. }
  510. void
  511. _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag,
  512. struct _Py_stat_struct *result)
  513. {
  514. memset(result, 0, sizeof(*result));
  515. result->st_mode = attributes_to_mode(info->dwFileAttributes);
  516. result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
  517. result->st_dev = info->dwVolumeSerialNumber;
  518. result->st_rdev = result->st_dev;
  519. FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
  520. FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
  521. FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
  522. result->st_nlink = info->nNumberOfLinks;
  523. result->st_ino = (((__int64)info->nFileIndexHigh)<<32) + info->nFileIndexLow;
  524. if (reparse_tag == IO_REPARSE_TAG_SYMLINK) {
  525. /* first clear the S_IFMT bits */
  526. result->st_mode ^= (result->st_mode & S_IFMT);
  527. /* now set the bits that make this a symlink */
  528. result->st_mode |= S_IFLNK;
  529. }
  530. result->st_file_attributes = info->dwFileAttributes;
  531. }
  532. #endif
  533. /* Return information about a file.
  534. On POSIX, use fstat().
  535. On Windows, use GetFileType() and GetFileInformationByHandle() which support
  536. files larger than 2 GB. fstat() may fail with EOVERFLOW on files larger
  537. than 2 GB because the file size type is an signed 32-bit integer: see issue
  538. #23152.
  539. On Windows, set the last Windows error and return nonzero on error. On
  540. POSIX, set errno and return nonzero on error. Fill status and return 0 on
  541. success. */
  542. int
  543. _Py_fstat_noraise(int fd, struct _Py_stat_struct *status)
  544. {
  545. #ifdef MS_WINDOWS
  546. BY_HANDLE_FILE_INFORMATION info;
  547. HANDLE h;
  548. int type;
  549. if (!_PyVerify_fd(fd))
  550. h = INVALID_HANDLE_VALUE;
  551. else
  552. h = (HANDLE)_get_osfhandle(fd);
  553. /* Protocol violation: we explicitly clear errno, instead of
  554. setting it to a POSIX error. Callers should use GetLastError. */
  555. errno = 0;
  556. if (h == INVALID_HANDLE_VALUE) {
  557. /* This is really a C library error (invalid file handle).
  558. We set the Win32 error to the closes one matching. */
  559. SetLastError(ERROR_INVALID_HANDLE);
  560. return -1;
  561. }
  562. memset(status, 0, sizeof(*status));
  563. type = GetFileType(h);
  564. if (type == FILE_TYPE_UNKNOWN) {
  565. DWORD error = GetLastError();
  566. if (error != 0)
  567. return -1;
  568. /* else: valid but unknown file */
  569. }
  570. if (type != FILE_TYPE_DISK) {
  571. if (type == FILE_TYPE_CHAR)
  572. status->st_mode = _S_IFCHR;
  573. else if (type == FILE_TYPE_PIPE)
  574. status->st_mode = _S_IFIFO;
  575. return 0;
  576. }
  577. if (!GetFileInformationByHandle(h, &info)) {
  578. return -1;
  579. }
  580. _Py_attribute_data_to_stat(&info, 0, status);
  581. /* specific to fstat() */
  582. status->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
  583. return 0;
  584. #else
  585. return fstat(fd, status);
  586. #endif
  587. }
  588. /* Return information about a file.
  589. On POSIX, use fstat().
  590. On Windows, use GetFileType() and GetFileInformationByHandle() which support
  591. files larger than 2 GB. fstat() may fail with EOVERFLOW on files larger
  592. than 2 GB because the file size type is an signed 32-bit integer: see issue
  593. #23152.
  594. Raise an exception and return -1 on error. On Windows, set the last Windows
  595. error on error. On POSIX, set errno on error. Fill status and return 0 on
  596. success.
  597. The GIL must be held. */
  598. int
  599. _Py_fstat(int fd, struct _Py_stat_struct *status)
  600. {
  601. int res;
  602. Py_BEGIN_ALLOW_THREADS
  603. res = _Py_fstat_noraise(fd, status);
  604. Py_END_ALLOW_THREADS
  605. if (res != 0) {
  606. #ifdef MS_WINDOWS
  607. PyErr_SetFromWindowsErr(0);
  608. #else
  609. PyErr_SetFromErrno(PyExc_OSError);
  610. #endif
  611. return -1;
  612. }
  613. return 0;
  614. }
  615. /* Call _wstat() on Windows, or encode the path to the filesystem encoding and
  616. call stat() otherwise. Only fill st_mode attribute on Windows.
  617. Return 0 on success, -1 on _wstat() / stat() error, -2 if an exception was
  618. raised. */
  619. int
  620. _Py_stat(PyObject *path, struct stat *statbuf)
  621. {
  622. #ifdef MS_WINDOWS
  623. int err;
  624. struct _stat wstatbuf;
  625. wchar_t *wpath;
  626. wpath = PyUnicode_AsUnicode(path);
  627. if (wpath == NULL)
  628. return -2;
  629. err = _wstat(wpath, &wstatbuf);
  630. if (!err)
  631. statbuf->st_mode = wstatbuf.st_mode;
  632. return err;
  633. #else
  634. int ret;
  635. PyObject *bytes = PyUnicode_EncodeFSDefault(path);
  636. if (bytes == NULL)
  637. return -2;
  638. ret = stat(PyBytes_AS_STRING(bytes), statbuf);
  639. Py_DECREF(bytes);
  640. return ret;
  641. #endif
  642. }
  643. static int
  644. get_inheritable(int fd, int raise)
  645. {
  646. #ifdef MS_WINDOWS
  647. HANDLE handle;
  648. DWORD flags;
  649. if (!_PyVerify_fd(fd)) {
  650. if (raise)
  651. PyErr_SetFromErrno(PyExc_OSError);
  652. return -1;
  653. }
  654. handle = (HANDLE)_get_osfhandle(fd);
  655. if (handle == INVALID_HANDLE_VALUE) {
  656. if (raise)
  657. PyErr_SetFromErrno(PyExc_OSError);
  658. return -1;
  659. }
  660. if (!GetHandleInformation(handle, &flags)) {
  661. if (raise)
  662. PyErr_SetFromWindowsErr(0);
  663. return -1;
  664. }
  665. return (flags & HANDLE_FLAG_INHERIT);
  666. #else
  667. int flags;
  668. flags = fcntl(fd, F_GETFD, 0);
  669. if (flags == -1) {
  670. if (raise)
  671. PyErr_SetFromErrno(PyExc_OSError);
  672. return -1;
  673. }
  674. return !(flags & FD_CLOEXEC);
  675. #endif
  676. }
  677. /* Get the inheritable flag of the specified file descriptor.
  678. Return 1 if the file descriptor can be inherited, 0 if it cannot,
  679. raise an exception and return -1 on error. */
  680. int
  681. _Py_get_inheritable(int fd)
  682. {
  683. return get_inheritable(fd, 1);
  684. }
  685. static int
  686. set_inheritable(int fd, int inheritable, int raise, int *atomic_flag_works)
  687. {
  688. #ifdef MS_WINDOWS
  689. HANDLE handle;
  690. DWORD flags;
  691. #else
  692. #if defined(HAVE_SYS_IOCTL_H) && defined(FIOCLEX) && defined(FIONCLEX)
  693. static int ioctl_works = -1;
  694. int request;
  695. int err;
  696. #endif
  697. int flags;
  698. int res;
  699. #endif
  700. /* atomic_flag_works can only be used to make the file descriptor
  701. non-inheritable */
  702. assert(!(atomic_flag_works != NULL && inheritable));
  703. if (atomic_flag_works != NULL && !inheritable) {
  704. if (*atomic_flag_works == -1) {
  705. int isInheritable = get_inheritable(fd, raise);
  706. if (isInheritable == -1)
  707. return -1;
  708. *atomic_flag_works = !isInheritable;
  709. }
  710. if (*atomic_flag_works)
  711. return 0;
  712. }
  713. #ifdef MS_WINDOWS
  714. if (!_PyVerify_fd(fd)) {
  715. if (raise)
  716. PyErr_SetFromErrno(PyExc_OSError);
  717. return -1;
  718. }
  719. handle = (HANDLE)_get_osfhandle(fd);
  720. if (handle == INVALID_HANDLE_VALUE) {
  721. if (raise)
  722. PyErr_SetFromErrno(PyExc_OSError);
  723. return -1;
  724. }
  725. if (inheritable)
  726. flags = HANDLE_FLAG_INHERIT;
  727. else
  728. flags = 0;
  729. if (!SetHandleInformation(handle, HANDLE_FLAG_INHERIT, flags)) {
  730. if (raise)
  731. PyErr_SetFromWindowsErr(0);
  732. return -1;
  733. }
  734. return 0;
  735. #else
  736. #if defined(HAVE_SYS_IOCTL_H) && defined(FIOCLEX) && defined(FIONCLEX)
  737. if (ioctl_works != 0) {
  738. /* fast-path: ioctl() only requires one syscall */
  739. if (inheritable)
  740. request = FIONCLEX;
  741. else
  742. request = FIOCLEX;
  743. err = ioctl(fd, request, NULL);
  744. if (!err) {
  745. ioctl_works = 1;
  746. return 0;
  747. }
  748. if (errno != ENOTTY) {
  749. if (raise)
  750. PyErr_SetFromErrno(PyExc_OSError);
  751. return -1;
  752. }
  753. else {
  754. /* Issue #22258: Here, ENOTTY means "Inappropriate ioctl for
  755. device". The ioctl is declared but not supported by the kernel.
  756. Remember that ioctl() doesn't work. It is the case on
  757. Illumos-based OS for example. */
  758. ioctl_works = 0;
  759. }
  760. /* fallback to fcntl() if ioctl() does not work */
  761. }
  762. #endif
  763. /* slow-path: fcntl() requires two syscalls */
  764. flags = fcntl(fd, F_GETFD);
  765. if (flags < 0) {
  766. if (raise)
  767. PyErr_SetFromErrno(PyExc_OSError);
  768. return -1;
  769. }
  770. if (inheritable)
  771. flags &= ~FD_CLOEXEC;
  772. else
  773. flags |= FD_CLOEXEC;
  774. res = fcntl(fd, F_SETFD, flags);
  775. if (res < 0) {
  776. if (raise)
  777. PyErr_SetFromErrno(PyExc_OSError);
  778. return -1;
  779. }
  780. return 0;
  781. #endif
  782. }
  783. /* Make the file descriptor non-inheritable.
  784. Return 0 on success, set errno and return -1 on error. */
  785. static int
  786. make_non_inheritable(int fd)
  787. {
  788. return set_inheritable(fd, 0, 0, NULL);
  789. }
  790. /* Set the inheritable flag of the specified file descriptor.
  791. On success: return 0, on error: raise an exception if raise is nonzero
  792. and return -1.
  793. If atomic_flag_works is not NULL:
  794. * if *atomic_flag_works==-1, check if the inheritable is set on the file
  795. descriptor: if yes, set *atomic_flag_works to 1, otherwise set to 0 and
  796. set the inheritable flag
  797. * if *atomic_flag_works==1: do nothing
  798. * if *atomic_flag_works==0: set inheritable flag to False
  799. Set atomic_flag_works to NULL if no atomic flag was used to create the
  800. file descriptor.
  801. atomic_flag_works can only be used to make a file descriptor
  802. non-inheritable: atomic_flag_works must be NULL if inheritable=1. */
  803. int
  804. _Py_set_inheritable(int fd, int inheritable, int *atomic_flag_works)
  805. {
  806. return set_inheritable(fd, inheritable, 1, atomic_flag_works);
  807. }
  808. static int
  809. _Py_open_impl(const char *pathname, int flags, int gil_held)
  810. {
  811. int fd;
  812. int async_err = 0;
  813. #ifndef MS_WINDOWS
  814. int *atomic_flag_works;
  815. #endif
  816. #ifdef MS_WINDOWS
  817. flags |= O_NOINHERIT;
  818. #elif defined(O_CLOEXEC)
  819. atomic_flag_works = &_Py_open_cloexec_works;
  820. flags |= O_CLOEXEC;
  821. #else
  822. atomic_flag_works = NULL;
  823. #endif
  824. if (gil_held) {
  825. do {
  826. Py_BEGIN_ALLOW_THREADS
  827. fd = open(pathname, flags);
  828. Py_END_ALLOW_THREADS
  829. } while (fd < 0
  830. && errno == EINTR && !(async_err = PyErr_CheckSignals()));
  831. if (async_err)
  832. return -1;
  833. if (fd < 0) {
  834. PyErr_SetFromErrnoWithFilename(PyExc_OSError, pathname);
  835. return -1;
  836. }
  837. }
  838. else {
  839. fd = open(pathname, flags);
  840. if (fd < 0)
  841. return -1;
  842. }
  843. #ifndef MS_WINDOWS
  844. if (set_inheritable(fd, 0, gil_held, atomic_flag_works) < 0) {
  845. close(fd);
  846. return -1;
  847. }
  848. #endif
  849. return fd;
  850. }
  851. /* Open a file with the specified flags (wrapper to open() function).
  852. Return a file descriptor on success. Raise an exception and return -1 on
  853. error.
  854. The file descriptor is created non-inheritable.
  855. When interrupted by a signal (open() fails with EINTR), retry the syscall,
  856. except if the Python signal handler raises an exception.
  857. The GIL must be held. */
  858. int
  859. _Py_open(const char *pathname, int flags)
  860. {
  861. /* _Py_open() must be called with the GIL held. */
  862. assert(PyGILState_Check());
  863. return _Py_open_impl(pathname, flags, 1);
  864. }
  865. /* Open a file with the specified flags (wrapper to open() function).
  866. Return a file descriptor on success. Set errno and return -1 on error.
  867. The file descriptor is created non-inheritable.
  868. If interrupted by a signal, fail with EINTR. */
  869. int
  870. _Py_open_noraise(const char *pathname, int flags)
  871. {
  872. return _Py_open_impl(pathname, flags, 0);
  873. }
  874. /* Open a file. Use _wfopen() on Windows, encode the path to the locale
  875. encoding and use fopen() otherwise.
  876. The file descriptor is created non-inheritable.
  877. If interrupted by a signal, fail with EINTR. */
  878. FILE *
  879. _Py_wfopen(const wchar_t *path, const wchar_t *mode)
  880. {
  881. FILE *f;
  882. #ifndef MS_WINDOWS
  883. char *cpath;
  884. char cmode[10];
  885. size_t r;
  886. r = wcstombs(cmode, mode, 10);
  887. if (r == (size_t)-1 || r >= 10) {
  888. errno = EINVAL;
  889. return NULL;
  890. }
  891. cpath = Py_EncodeLocale(path, NULL);
  892. if (cpath == NULL)
  893. return NULL;
  894. f = fopen(cpath, cmode);
  895. PyMem_Free(cpath);
  896. #else
  897. f = _wfopen(path, mode);
  898. #endif
  899. if (f == NULL)
  900. return NULL;
  901. if (make_non_inheritable(fileno(f)) < 0) {
  902. fclose(f);
  903. return NULL;
  904. }
  905. return f;
  906. }
  907. /* Wrapper to fopen().
  908. The file descriptor is created non-inheritable.
  909. If interrupted by a signal, fail with EINTR. */
  910. FILE*
  911. _Py_fopen(const char *pathname, const char *mode)
  912. {
  913. FILE *f = fopen(pathname, mode);
  914. if (f == NULL)
  915. return NULL;
  916. if (make_non_inheritable(fileno(f)) < 0) {
  917. fclose(f);
  918. return NULL;
  919. }
  920. return f;
  921. }
  922. /* Open a file. Call _wfopen() on Windows, or encode the path to the filesystem
  923. encoding and call fopen() otherwise.
  924. Return the new file object on success. Raise an exception and return NULL
  925. on error.
  926. The file descriptor is created non-inheritable.
  927. When interrupted by a signal (open() fails with EINTR), retry the syscall,
  928. except if the Python signal handler raises an exception.
  929. The GIL must be held. */
  930. FILE*
  931. _Py_fopen_obj(PyObject *path, const char *mode)
  932. {
  933. FILE *f;
  934. int async_err = 0;
  935. #ifdef MS_WINDOWS
  936. wchar_t *wpath;
  937. wchar_t wmode[10];
  938. int usize;
  939. assert(PyGILState_Check());
  940. if (!PyUnicode_Check(path)) {
  941. PyErr_Format(PyExc_TypeError,
  942. "str file path expected under Windows, got %R",
  943. Py_TYPE(path));
  944. return NULL;
  945. }
  946. wpath = PyUnicode_AsUnicode(path);
  947. if (wpath == NULL)
  948. return NULL;
  949. usize = MultiByteToWideChar(CP_ACP, 0, mode, -1, wmode, sizeof(wmode));
  950. if (usize == 0) {
  951. PyErr_SetFromWindowsErr(0);
  952. return NULL;
  953. }
  954. do {
  955. Py_BEGIN_ALLOW_THREADS
  956. f = _wfopen(wpath, wmode);
  957. Py_END_ALLOW_THREADS
  958. } while (f == NULL
  959. && errno == EINTR && !(async_err = PyErr_CheckSignals()));
  960. #else
  961. PyObject *bytes;
  962. char *path_bytes;
  963. assert(PyGILState_Check());
  964. if (!PyUnicode_FSConverter(path, &bytes))
  965. return NULL;
  966. path_bytes = PyBytes_AS_STRING(bytes);
  967. do {
  968. Py_BEGIN_ALLOW_THREADS
  969. f = fopen(path_bytes, mode);
  970. Py_END_ALLOW_THREADS
  971. } while (f == NULL
  972. && errno == EINTR && !(async_err = PyErr_CheckSignals()));
  973. Py_DECREF(bytes);
  974. #endif
  975. if (async_err)
  976. return NULL;
  977. if (f == NULL) {
  978. PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path);
  979. return NULL;
  980. }
  981. if (set_inheritable(fileno(f), 0, 1, NULL) < 0) {
  982. fclose(f);
  983. return NULL;
  984. }
  985. return f;
  986. }
  987. /* Read count bytes from fd into buf.
  988. *
  989. * On success, return the number of read bytes, it can be lower than count.
  990. * If the current file offset is at or past the end of file, no bytes are read,
  991. * and read() returns zero.
  992. *
  993. * On error, raise an exception, set errno and return -1.
  994. *
  995. * When interrupted by a signal (read() fails with EINTR), retry the syscall.
  996. * If the Python signal handler raises an exception, the function returns -1
  997. * (the syscall is not retried).
  998. *
  999. * The GIL must be held. */
  1000. Py_ssize_t
  1001. _Py_read(int fd, void *buf, size_t count)
  1002. {
  1003. Py_ssize_t n;
  1004. int err;
  1005. int async_err = 0;
  1006. /* _Py_read() must not be called with an exception set, otherwise the
  1007. * caller may think that read() was interrupted by a signal and the signal
  1008. * handler raised an exception. */
  1009. assert(!PyErr_Occurred());
  1010. if (!_PyVerify_fd(fd)) {
  1011. /* save/restore errno because PyErr_SetFromErrno() can modify it */
  1012. err = errno;
  1013. PyErr_SetFromErrno(PyExc_OSError);
  1014. errno = err;
  1015. return -1;
  1016. }
  1017. #ifdef MS_WINDOWS
  1018. if (count > INT_MAX) {
  1019. /* On Windows, the count parameter of read() is an int */
  1020. count = INT_MAX;
  1021. }
  1022. #else
  1023. if (count > PY_SSIZE_T_MAX) {
  1024. /* if count is greater than PY_SSIZE_T_MAX,
  1025. * read() result is undefined */
  1026. count = PY_SSIZE_T_MAX;
  1027. }
  1028. #endif
  1029. do {
  1030. Py_BEGIN_ALLOW_THREADS
  1031. errno = 0;
  1032. #ifdef MS_WINDOWS
  1033. n = read(fd, buf, (int)count);
  1034. #else
  1035. n = read(fd, buf, count);
  1036. #endif
  1037. /* save/restore errno because PyErr_CheckSignals()
  1038. * and PyErr_SetFromErrno() can modify it */
  1039. err = errno;
  1040. Py_END_ALLOW_THREADS
  1041. } while (n < 0 && err == EINTR &&
  1042. !(async_err = PyErr_CheckSignals()));
  1043. if (async_err) {
  1044. /* read() was interrupted by a signal (failed with EINTR)
  1045. * and the Python signal handler raised an exception */
  1046. errno = err;
  1047. assert(errno == EINTR && PyErr_Occurred());
  1048. return -1;
  1049. }
  1050. if (n < 0) {
  1051. PyErr_SetFromErrno(PyExc_OSError);
  1052. errno = err;
  1053. return -1;
  1054. }
  1055. return n;
  1056. }
  1057. /* Write count bytes of buf into fd.
  1058. *
  1059. * -On success, return the number of written bytes, it can be lower than count
  1060. * including 0
  1061. * - On error, raise an exception, set errno and return -1.
  1062. *
  1063. * When interrupted by a signal (write() fails with EINTR), retry the syscall.
  1064. * If the Python signal handler raises an exception, the function returns -1
  1065. * (the syscall is not retried).
  1066. *
  1067. * The GIL must be held. */
  1068. Py_ssize_t
  1069. _Py_write(int fd, const void *buf, size_t count)
  1070. {
  1071. Py_ssize_t n;
  1072. int err;
  1073. int async_err = 0;
  1074. /* _Py_write() must not be called with an exception set, otherwise the
  1075. * caller may think that write() was interrupted by a signal and the signal
  1076. * handler raised an exception. */
  1077. assert(!PyErr_Occurred());
  1078. if (!_PyVerify_fd(fd)) {
  1079. /* save/restore errno because PyErr_SetFromErrno() can modify it */
  1080. err = errno;
  1081. PyErr_SetFromErrno(PyExc_OSError);
  1082. errno = err;
  1083. return -1;
  1084. }
  1085. #ifdef MS_WINDOWS
  1086. if (count > 32767 && isatty(fd)) {
  1087. /* Issue #11395: the Windows console returns an error (12: not
  1088. enough space error) on writing into stdout if stdout mode is
  1089. binary and the length is greater than 66,000 bytes (or less,
  1090. depending on heap usage). */
  1091. count = 32767;
  1092. }
  1093. else if (count > INT_MAX)
  1094. count = INT_MAX;
  1095. #else
  1096. if (count > PY_SSIZE_T_MAX) {
  1097. /* write() should truncate count to PY_SSIZE_T_MAX, but it's safer
  1098. * to do it ourself to have a portable behaviour. */
  1099. count = PY_SSIZE_T_MAX;
  1100. }
  1101. #endif
  1102. do {
  1103. Py_BEGIN_ALLOW_THREADS
  1104. errno = 0;
  1105. #ifdef MS_WINDOWS
  1106. n = write(fd, buf, (int)count);
  1107. #else
  1108. n = write(fd, buf, count);
  1109. #endif
  1110. /* save/restore errno because PyErr_CheckSignals()
  1111. * and PyErr_SetFromErrno() can modify it */
  1112. err = errno;
  1113. Py_END_ALLOW_THREADS
  1114. } while (n < 0 && errno == EINTR &&
  1115. !(async_err = PyErr_CheckSignals()));
  1116. if (async_err) {
  1117. /* write() was interrupted by a signal (failed with EINTR)
  1118. * and the Python signal handler raised an exception */
  1119. errno = err;
  1120. assert(errno == EINTR && PyErr_Occurred());
  1121. return -1;
  1122. }
  1123. if (n < 0) {
  1124. PyErr_SetFromErrno(PyExc_OSError);
  1125. errno = err;
  1126. return -1;
  1127. }
  1128. return n;
  1129. }
  1130. #ifdef HAVE_READLINK
  1131. /* Read value of symbolic link. Encode the path to the locale encoding, decode
  1132. the result from the locale encoding. Return -1 on error. */
  1133. int
  1134. _Py_wreadlink(const wchar_t *path, wchar_t *buf, size_t bufsiz)
  1135. {
  1136. char *cpath;
  1137. char cbuf[MAXPATHLEN];
  1138. wchar_t *wbuf;
  1139. int res;
  1140. size_t r1;
  1141. cpath = Py_EncodeLocale(path, NULL);
  1142. if (cpath == NULL) {
  1143. errno = EINVAL;
  1144. return -1;
  1145. }
  1146. res = (int)readlink(cpath, cbuf, Py_ARRAY_LENGTH(cbuf));
  1147. PyMem_Free(cpath);
  1148. if (res == -1)
  1149. return -1;
  1150. if (res == Py_ARRAY_LENGTH(cbuf)) {
  1151. errno = EINVAL;
  1152. return -1;
  1153. }
  1154. cbuf[res] = '\0'; /* buf will be null terminated */
  1155. wbuf = Py_DecodeLocale(cbuf, &r1);
  1156. if (wbuf == NULL) {
  1157. errno = EINVAL;
  1158. return -1;
  1159. }
  1160. if (bufsiz <= r1) {
  1161. PyMem_RawFree(wbuf);
  1162. errno = EINVAL;
  1163. return -1;
  1164. }
  1165. wcsncpy(buf, wbuf, bufsiz);
  1166. PyMem_RawFree(wbuf);
  1167. return (int)r1;
  1168. }
  1169. #endif
  1170. #ifdef HAVE_REALPATH
  1171. /* Return the canonicalized absolute pathname. Encode path to the locale
  1172. encoding, decode the result from the locale encoding.
  1173. Return NULL on error. */
  1174. wchar_t*
  1175. _Py_wrealpath(const wchar_t *path,
  1176. wchar_t *resolved_path, size_t resolved_path_size)
  1177. {
  1178. char *cpath;
  1179. char cresolved_path[MAXPATHLEN];
  1180. wchar_t *wresolved_path;
  1181. char *res;
  1182. size_t r;
  1183. cpath = Py_EncodeLocale(path, NULL);
  1184. if (cpath == NULL) {
  1185. errno = EINVAL;
  1186. return NULL;
  1187. }
  1188. res = realpath(cpath, cresolved_path);
  1189. PyMem_Free(cpath);
  1190. if (res == NULL)
  1191. return NULL;
  1192. wresolved_path = Py_DecodeLocale(cresolved_path, &r);
  1193. if (wresolved_path == NULL) {
  1194. errno = EINVAL;
  1195. return NULL;
  1196. }
  1197. if (resolved_path_size <= r) {
  1198. PyMem_RawFree(wresolved_path);
  1199. errno = EINVAL;
  1200. return NULL;
  1201. }
  1202. wcsncpy(resolved_path, wresolved_path, resolved_path_size);
  1203. PyMem_RawFree(wresolved_path);
  1204. return resolved_path;
  1205. }
  1206. #endif
  1207. /* Get the current directory. size is the buffer size in wide characters
  1208. including the null character. Decode the path from the locale encoding.
  1209. Return NULL on error. */
  1210. wchar_t*
  1211. _Py_wgetcwd(wchar_t *buf, size_t size)
  1212. {
  1213. #ifdef MS_WINDOWS
  1214. int isize = (int)Py_MIN(size, INT_MAX);
  1215. return _wgetcwd(buf, isize);
  1216. #else
  1217. char fname[MAXPATHLEN];
  1218. wchar_t *wname;
  1219. size_t len;
  1220. if (getcwd(fname, Py_ARRAY_LENGTH(fname)) == NULL)
  1221. return NULL;
  1222. wname = Py_DecodeLocale(fname, &len);
  1223. if (wname == NULL)
  1224. return NULL;
  1225. if (size <= len) {
  1226. PyMem_RawFree(wname);
  1227. return NULL;
  1228. }
  1229. wcsncpy(buf, wname, size);
  1230. PyMem_RawFree(wname);
  1231. return buf;
  1232. #endif
  1233. }
  1234. /* Duplicate a file descriptor. The new file descriptor is created as
  1235. non-inheritable. Return a new file descriptor on success, raise an OSError
  1236. exception and return -1 on error.
  1237. The GIL is released to call dup(). The caller must hold the GIL. */
  1238. int
  1239. _Py_dup(int fd)
  1240. {
  1241. #ifdef MS_WINDOWS
  1242. HANDLE handle;
  1243. DWORD ftype;
  1244. #endif
  1245. if (!_PyVerify_fd(fd)) {
  1246. PyErr_SetFromErrno(PyExc_OSError);
  1247. return -1;
  1248. }
  1249. #ifdef MS_WINDOWS
  1250. handle = (HANDLE)_get_osfhandle(fd);
  1251. if (handle == INVALID_HANDLE_VALUE) {
  1252. PyErr_SetFromErrno(PyExc_OSError);
  1253. return -1;
  1254. }
  1255. /* get the file type, ignore the error if it failed */
  1256. ftype = GetFileType(handle);
  1257. Py_BEGIN_ALLOW_THREADS
  1258. fd = dup(fd);
  1259. Py_END_ALLOW_THREADS
  1260. if (fd < 0) {
  1261. PyErr_SetFromErrno(PyExc_OSError);
  1262. return -1;
  1263. }
  1264. /* Character files like console cannot be make non-inheritable */
  1265. if (ftype != FILE_TYPE_CHAR) {
  1266. if (_Py_set_inheritable(fd, 0, NULL) < 0) {
  1267. close(fd);
  1268. return -1;
  1269. }
  1270. }
  1271. #elif defined(HAVE_FCNTL_H) && defined(F_DUPFD_CLOEXEC)
  1272. Py_BEGIN_ALLOW_THREADS
  1273. fd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
  1274. Py_END_ALLOW_THREADS
  1275. if (fd < 0) {
  1276. PyErr_SetFromErrno(PyExc_OSError);
  1277. return -1;
  1278. }
  1279. #else
  1280. Py_BEGIN_ALLOW_THREADS
  1281. fd = dup(fd);
  1282. Py_END_ALLOW_THREADS
  1283. if (fd < 0) {
  1284. PyErr_SetFromErrno(PyExc_OSError);
  1285. return -1;
  1286. }
  1287. if (_Py_set_inheritable(fd, 0, NULL) < 0) {
  1288. close(fd);
  1289. return -1;
  1290. }
  1291. #endif
  1292. return fd;
  1293. }
  1294. #ifndef MS_WINDOWS
  1295. /* Get the blocking mode of the file descriptor.
  1296. Return 0 if the O_NONBLOCK flag is set, 1 if the flag is cleared,
  1297. raise an exception and return -1 on error. */
  1298. int
  1299. _Py_get_blocking(int fd)
  1300. {
  1301. int flags = fcntl(fd, F_GETFL, 0);
  1302. if (flags < 0) {
  1303. PyErr_SetFromErrno(PyExc_OSError);
  1304. return -1;
  1305. }
  1306. return !(flags & O_NONBLOCK);
  1307. }
  1308. /* Set the blocking mode of the specified file descriptor.
  1309. Set the O_NONBLOCK flag if blocking is False, clear the O_NONBLOCK flag
  1310. otherwise.
  1311. Return 0 on success, raise an exception and return -1 on error. */
  1312. int
  1313. _Py_set_blocking(int fd, int blocking)
  1314. {
  1315. #if defined(HAVE_SYS_IOCTL_H) && defined(FIONBIO)
  1316. int arg = !blocking;
  1317. if (ioctl(fd, FIONBIO, &arg) < 0)
  1318. goto error;
  1319. #else
  1320. int flags, res;
  1321. flags = fcntl(fd, F_GETFL, 0);
  1322. if (flags < 0)
  1323. goto error;
  1324. if (blocking)
  1325. flags = flags & (~O_NONBLOCK);
  1326. else
  1327. flags = flags | O_NONBLOCK;
  1328. res = fcntl(fd, F_SETFL, flags);
  1329. if (res < 0)
  1330. goto error;
  1331. #endif
  1332. return 0;
  1333. error:
  1334. PyErr_SetFromErrno(PyExc_OSError);
  1335. return -1;
  1336. }
  1337. #endif
  1338. #ifdef _MSC_VER
  1339. #if _MSC_VER >= 1900
  1340. /* This function lets the Windows CRT validate the file handle without
  1341. terminating the process if it's invalid. */
  1342. int
  1343. _PyVerify_fd(int fd)
  1344. {
  1345. intptr_t osh;
  1346. /* Fast check for the only condition we know */
  1347. if (fd < 0) {
  1348. _set_errno(EBADF);
  1349. return 0;
  1350. }
  1351. osh = _get_osfhandle(fd);
  1352. return osh != (intptr_t)-1;
  1353. }
  1354. #elif _MSC_VER >= 1400
  1355. /* Legacy implementation of _PyVerify_fd while transitioning to
  1356. * MSVC 14.0. This should eventually be removed. (issue23524)
  1357. */
  1358. /* Microsoft CRT in VS2005 and higher will verify that a filehandle is
  1359. * valid and raise an assertion if it isn't.
  1360. * Normally, an invalid fd is likely to be a C program error and therefore
  1361. * an assertion can be useful, but it does contradict the POSIX standard
  1362. * which for write(2) states:
  1363. * "Otherwise, -1 shall be returned and errno set to indicate the error."
  1364. * "[EBADF] The fildes argument is not a valid file descriptor open for
  1365. * writing."
  1366. * Furthermore, python allows the user to enter any old integer
  1367. * as a fd and should merely raise a python exception on error.
  1368. * The Microsoft CRT doesn't provide an official way to check for the
  1369. * validity of a file descriptor, but we can emulate its internal behaviour
  1370. * by using the exported __pinfo data member and knowledge of the
  1371. * internal structures involved.
  1372. * The structures below must be updated for each version of visual studio
  1373. * according to the file internal.h in the CRT source, until MS comes
  1374. * up with a less hacky way to do this.
  1375. * (all of this is to avoid globally modifying the CRT behaviour using
  1376. * _set_invalid_parameter_handler() and _CrtSetReportMode())
  1377. */
  1378. /* The actual size of the structure is determined at runtime.
  1379. * Only the first items must be present.
  1380. */
  1381. typedef struct {
  1382. intptr_t osfhnd;
  1383. char osfile;
  1384. } my_ioinfo;
  1385. extern __declspec(dllimport) char * __pioinfo[];
  1386. #define IOINFO_L2E 5
  1387. #define IOINFO_ARRAYS 64
  1388. #define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
  1389. #define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
  1390. #define FOPEN 0x01
  1391. #define _NO_CONSOLE_FILENO (intptr_t)-2
  1392. /* This function emulates what the windows CRT does to validate file handles */
  1393. int
  1394. _PyVerify_fd(int fd)
  1395. {
  1396. const int i1 = fd >> IOINFO_L2E;
  1397. const int i2 = fd & ((1 << IOINFO_L2E) - 1);
  1398. static size_t sizeof_ioinfo = 0;
  1399. /* Determine the actual size of the ioinfo structure,
  1400. * as used by the CRT loaded in memory
  1401. */
  1402. if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
  1403. sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
  1404. }
  1405. if (sizeof_ioinfo == 0) {
  1406. /* This should not happen... */
  1407. goto fail;
  1408. }
  1409. /* See that it isn't a special CLEAR fileno */
  1410. if (fd != _NO_CONSOLE_FILENO) {
  1411. /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
  1412. * we check pointer validity and other info
  1413. */
  1414. if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
  1415. /* finally, check that the file is open */
  1416. my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
  1417. if (info->osfile & FOPEN) {
  1418. return 1;
  1419. }
  1420. }
  1421. }
  1422. fail:
  1423. errno = EBADF;
  1424. return 0;
  1425. }
  1426. #endif /* _MSC_VER >= 1900 || _MSC_VER >= 1400 */
  1427. #endif /* defined _MSC_VER */