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.

741 lines
20 KiB

  1. #include "Python.h"
  2. #include "osdefs.h"
  3. #include <locale.h>
  4. #ifdef MS_WINDOWS
  5. # include <windows.h>
  6. #endif
  7. #ifdef HAVE_LANGINFO_H
  8. #include <langinfo.h>
  9. #endif
  10. #ifdef __APPLE__
  11. extern wchar_t* _Py_DecodeUTF8_surrogateescape(const char *s, Py_ssize_t size);
  12. #endif
  13. PyObject *
  14. _Py_device_encoding(int fd)
  15. {
  16. #if defined(MS_WINDOWS) || defined(MS_WIN64)
  17. UINT cp;
  18. #endif
  19. if (!_PyVerify_fd(fd) || !isatty(fd)) {
  20. Py_RETURN_NONE;
  21. }
  22. #if defined(MS_WINDOWS) || defined(MS_WIN64)
  23. if (fd == 0)
  24. cp = GetConsoleCP();
  25. else if (fd == 1 || fd == 2)
  26. cp = GetConsoleOutputCP();
  27. else
  28. cp = 0;
  29. /* GetConsoleCP() and GetConsoleOutputCP() return 0 if the application
  30. has no console */
  31. if (cp != 0)
  32. return PyUnicode_FromFormat("cp%u", (unsigned int)cp);
  33. #elif defined(CODESET)
  34. {
  35. char *codeset = nl_langinfo(CODESET);
  36. if (codeset != NULL && codeset[0] != 0)
  37. return PyUnicode_FromString(codeset);
  38. }
  39. #endif
  40. Py_RETURN_NONE;
  41. }
  42. #if !defined(__APPLE__) && !defined(MS_WINDOWS)
  43. extern int _Py_normalize_encoding(const char *, char *, size_t);
  44. /* Workaround FreeBSD and OpenIndiana locale encoding issue with the C locale.
  45. On these operating systems, nl_langinfo(CODESET) announces an alias of the
  46. ASCII encoding, whereas mbstowcs() and wcstombs() functions use the
  47. ISO-8859-1 encoding. The problem is that os.fsencode() and os.fsdecode() use
  48. locale.getpreferredencoding() codec. For example, if command line arguments
  49. are decoded by mbstowcs() and encoded back by os.fsencode(), we get a
  50. UnicodeEncodeError instead of retrieving the original byte string.
  51. The workaround is enabled if setlocale(LC_CTYPE, NULL) returns "C",
  52. nl_langinfo(CODESET) announces "ascii" (or an alias to ASCII), and at least
  53. one byte in range 0x80-0xff can be decoded from the locale encoding. The
  54. workaround is also enabled on error, for example if getting the locale
  55. failed.
  56. Values of locale_is_ascii:
  57. 1: the workaround is used: _Py_wchar2char() uses
  58. encode_ascii_surrogateescape() and _Py_char2wchar() uses
  59. decode_ascii_surrogateescape()
  60. 0: the workaround is not used: _Py_wchar2char() uses wcstombs() and
  61. _Py_char2wchar() uses mbstowcs()
  62. -1: unknown, need to call check_force_ascii() to get the value
  63. */
  64. static int force_ascii = -1;
  65. static int
  66. check_force_ascii(void)
  67. {
  68. char *loc;
  69. #if defined(HAVE_LANGINFO_H) && defined(CODESET)
  70. char *codeset, **alias;
  71. char encoding[100];
  72. int is_ascii;
  73. unsigned int i;
  74. char* ascii_aliases[] = {
  75. "ascii",
  76. "646",
  77. "ansi-x3.4-1968",
  78. "ansi-x3-4-1968",
  79. "ansi-x3.4-1986",
  80. "cp367",
  81. "csascii",
  82. "ibm367",
  83. "iso646-us",
  84. "iso-646.irv-1991",
  85. "iso-ir-6",
  86. "us",
  87. "us-ascii",
  88. NULL
  89. };
  90. #endif
  91. loc = setlocale(LC_CTYPE, NULL);
  92. if (loc == NULL)
  93. goto error;
  94. if (strcmp(loc, "C") != 0) {
  95. /* the LC_CTYPE locale is different than C */
  96. return 0;
  97. }
  98. #if defined(HAVE_LANGINFO_H) && defined(CODESET)
  99. codeset = nl_langinfo(CODESET);
  100. if (!codeset || codeset[0] == '\0') {
  101. /* CODESET is not set or empty */
  102. goto error;
  103. }
  104. if (!_Py_normalize_encoding(codeset, encoding, sizeof(encoding)))
  105. goto error;
  106. is_ascii = 0;
  107. for (alias=ascii_aliases; *alias != NULL; alias++) {
  108. if (strcmp(encoding, *alias) == 0) {
  109. is_ascii = 1;
  110. break;
  111. }
  112. }
  113. if (!is_ascii) {
  114. /* nl_langinfo(CODESET) is not "ascii" or an alias of ASCII */
  115. return 0;
  116. }
  117. for (i=0x80; i<0xff; i++) {
  118. unsigned char ch;
  119. wchar_t wch;
  120. size_t res;
  121. ch = (unsigned char)i;
  122. res = mbstowcs(&wch, (char*)&ch, 1);
  123. if (res != (size_t)-1) {
  124. /* decoding a non-ASCII character from the locale encoding succeed:
  125. the locale encoding is not ASCII, force ASCII */
  126. return 1;
  127. }
  128. }
  129. /* None of the bytes in the range 0x80-0xff can be decoded from the locale
  130. encoding: the locale encoding is really ASCII */
  131. return 0;
  132. #else
  133. /* nl_langinfo(CODESET) is not available: always force ASCII */
  134. return 1;
  135. #endif
  136. error:
  137. /* if an error occured, force the ASCII encoding */
  138. return 1;
  139. }
  140. static char*
  141. encode_ascii_surrogateescape(const wchar_t *text, size_t *error_pos)
  142. {
  143. char *result = NULL, *out;
  144. size_t len, i;
  145. wchar_t ch;
  146. if (error_pos != NULL)
  147. *error_pos = (size_t)-1;
  148. len = wcslen(text);
  149. result = PyMem_Malloc(len + 1); /* +1 for NUL byte */
  150. if (result == NULL)
  151. return NULL;
  152. out = result;
  153. for (i=0; i<len; i++) {
  154. ch = text[i];
  155. if (ch <= 0x7f) {
  156. /* ASCII character */
  157. *out++ = (char)ch;
  158. }
  159. else if (0xdc80 <= ch && ch <= 0xdcff) {
  160. /* UTF-8b surrogate */
  161. *out++ = (char)(ch - 0xdc00);
  162. }
  163. else {
  164. if (error_pos != NULL)
  165. *error_pos = i;
  166. PyMem_Free(result);
  167. return NULL;
  168. }
  169. }
  170. *out = '\0';
  171. return result;
  172. }
  173. #endif /* !defined(__APPLE__) && !defined(MS_WINDOWS) */
  174. #if !defined(__APPLE__) && (!defined(MS_WINDOWS) || !defined(HAVE_MBRTOWC))
  175. static wchar_t*
  176. decode_ascii_surrogateescape(const char *arg, size_t *size)
  177. {
  178. wchar_t *res;
  179. unsigned char *in;
  180. wchar_t *out;
  181. size_t argsize = strlen(arg) + 1;
  182. if (argsize > PY_SSIZE_T_MAX/sizeof(wchar_t))
  183. return NULL;
  184. res = PyMem_Malloc(argsize*sizeof(wchar_t));
  185. if (!res)
  186. return NULL;
  187. in = (unsigned char*)arg;
  188. out = res;
  189. while(*in)
  190. if(*in < 128)
  191. *out++ = *in++;
  192. else
  193. *out++ = 0xdc00 + *in++;
  194. *out = 0;
  195. if (size != NULL)
  196. *size = out - res;
  197. return res;
  198. }
  199. #endif
  200. /* Decode a byte string from the locale encoding with the
  201. surrogateescape error handler (undecodable bytes are decoded as characters
  202. in range U+DC80..U+DCFF). If a byte sequence can be decoded as a surrogate
  203. character, escape the bytes using the surrogateescape error handler instead
  204. of decoding them.
  205. Use _Py_wchar2char() to encode the character string back to a byte string.
  206. Return a pointer to a newly allocated wide character string (use
  207. PyMem_Free() to free the memory) and write the number of written wide
  208. characters excluding the null character into *size if size is not NULL, or
  209. NULL on error (decoding or memory allocation error). If size is not NULL,
  210. *size is set to (size_t)-1 on memory error and (size_t)-2 on decoding
  211. error.
  212. Conversion errors should never happen, unless there is a bug in the C
  213. library. */
  214. wchar_t*
  215. _Py_char2wchar(const char* arg, size_t *size)
  216. {
  217. #ifdef __APPLE__
  218. wchar_t *wstr;
  219. wstr = _Py_DecodeUTF8_surrogateescape(arg, strlen(arg));
  220. if (size != NULL) {
  221. if (wstr != NULL)
  222. *size = wcslen(wstr);
  223. else
  224. *size = (size_t)-1;
  225. }
  226. return wstr;
  227. #else
  228. wchar_t *res;
  229. size_t argsize;
  230. size_t count;
  231. unsigned char *in;
  232. wchar_t *out;
  233. #ifdef HAVE_MBRTOWC
  234. mbstate_t mbs;
  235. #endif
  236. #ifndef MS_WINDOWS
  237. if (force_ascii == -1)
  238. force_ascii = check_force_ascii();
  239. if (force_ascii) {
  240. /* force ASCII encoding to workaround mbstowcs() issue */
  241. res = decode_ascii_surrogateescape(arg, size);
  242. if (res == NULL)
  243. goto oom;
  244. return res;
  245. }
  246. #endif
  247. #ifdef HAVE_BROKEN_MBSTOWCS
  248. /* Some platforms have a broken implementation of
  249. * mbstowcs which does not count the characters that
  250. * would result from conversion. Use an upper bound.
  251. */
  252. argsize = strlen(arg);
  253. #else
  254. argsize = mbstowcs(NULL, arg, 0);
  255. #endif
  256. if (argsize != (size_t)-1) {
  257. if (argsize == PY_SSIZE_T_MAX)
  258. goto oom;
  259. argsize += 1;
  260. if (argsize > PY_SSIZE_T_MAX/sizeof(wchar_t))
  261. goto oom;
  262. res = (wchar_t *)PyMem_Malloc(argsize*sizeof(wchar_t));
  263. if (!res)
  264. goto oom;
  265. count = mbstowcs(res, arg, argsize);
  266. if (count != (size_t)-1) {
  267. wchar_t *tmp;
  268. /* Only use the result if it contains no
  269. surrogate characters. */
  270. for (tmp = res; *tmp != 0 &&
  271. (*tmp < 0xd800 || *tmp > 0xdfff); tmp++)
  272. ;
  273. if (*tmp == 0) {
  274. if (size != NULL)
  275. *size = count;
  276. return res;
  277. }
  278. }
  279. PyMem_Free(res);
  280. }
  281. /* Conversion failed. Fall back to escaping with surrogateescape. */
  282. #ifdef HAVE_MBRTOWC
  283. /* Try conversion with mbrtwoc (C99), and escape non-decodable bytes. */
  284. /* Overallocate; as multi-byte characters are in the argument, the
  285. actual output could use less memory. */
  286. argsize = strlen(arg) + 1;
  287. if (argsize > PY_SSIZE_T_MAX/sizeof(wchar_t))
  288. goto oom;
  289. res = (wchar_t*)PyMem_Malloc(argsize*sizeof(wchar_t));
  290. if (!res)
  291. goto oom;
  292. in = (unsigned char*)arg;
  293. out = res;
  294. memset(&mbs, 0, sizeof mbs);
  295. while (argsize) {
  296. size_t converted = mbrtowc(out, (char*)in, argsize, &mbs);
  297. if (converted == 0)
  298. /* Reached end of string; null char stored. */
  299. break;
  300. if (converted == (size_t)-2) {
  301. /* Incomplete character. This should never happen,
  302. since we provide everything that we have -
  303. unless there is a bug in the C library, or I
  304. misunderstood how mbrtowc works. */
  305. PyMem_Free(res);
  306. if (size != NULL)
  307. *size = (size_t)-2;
  308. return NULL;
  309. }
  310. if (converted == (size_t)-1) {
  311. /* Conversion error. Escape as UTF-8b, and start over
  312. in the initial shift state. */
  313. *out++ = 0xdc00 + *in++;
  314. argsize--;
  315. memset(&mbs, 0, sizeof mbs);
  316. continue;
  317. }
  318. if (*out >= 0xd800 && *out <= 0xdfff) {
  319. /* Surrogate character. Escape the original
  320. byte sequence with surrogateescape. */
  321. argsize -= converted;
  322. while (converted--)
  323. *out++ = 0xdc00 + *in++;
  324. continue;
  325. }
  326. /* successfully converted some bytes */
  327. in += converted;
  328. argsize -= converted;
  329. out++;
  330. }
  331. if (size != NULL)
  332. *size = out - res;
  333. #else /* HAVE_MBRTOWC */
  334. /* Cannot use C locale for escaping; manually escape as if charset
  335. is ASCII (i.e. escape all bytes > 128. This will still roundtrip
  336. correctly in the locale's charset, which must be an ASCII superset. */
  337. res = decode_ascii_surrogateescape(arg, size);
  338. if (res == NULL)
  339. goto oom;
  340. #endif /* HAVE_MBRTOWC */
  341. return res;
  342. oom:
  343. if (size != NULL)
  344. *size = (size_t)-1;
  345. return NULL;
  346. #endif /* __APPLE__ */
  347. }
  348. /* Encode a (wide) character string to the locale encoding with the
  349. surrogateescape error handler (characters in range U+DC80..U+DCFF are
  350. converted to bytes 0x80..0xFF).
  351. This function is the reverse of _Py_char2wchar().
  352. Return a pointer to a newly allocated byte string (use PyMem_Free() to free
  353. the memory), or NULL on encoding or memory allocation error.
  354. If error_pos is not NULL: *error_pos is the index of the invalid character
  355. on encoding error, or (size_t)-1 otherwise. */
  356. char*
  357. _Py_wchar2char(const wchar_t *text, size_t *error_pos)
  358. {
  359. #ifdef __APPLE__
  360. Py_ssize_t len;
  361. PyObject *unicode, *bytes = NULL;
  362. char *cpath;
  363. unicode = PyUnicode_FromWideChar(text, wcslen(text));
  364. if (unicode == NULL)
  365. return NULL;
  366. bytes = _PyUnicode_AsUTF8String(unicode, "surrogateescape");
  367. Py_DECREF(unicode);
  368. if (bytes == NULL) {
  369. PyErr_Clear();
  370. if (error_pos != NULL)
  371. *error_pos = (size_t)-1;
  372. return NULL;
  373. }
  374. len = PyBytes_GET_SIZE(bytes);
  375. cpath = PyMem_Malloc(len+1);
  376. if (cpath == NULL) {
  377. PyErr_Clear();
  378. Py_DECREF(bytes);
  379. if (error_pos != NULL)
  380. *error_pos = (size_t)-1;
  381. return NULL;
  382. }
  383. memcpy(cpath, PyBytes_AsString(bytes), len + 1);
  384. Py_DECREF(bytes);
  385. return cpath;
  386. #else /* __APPLE__ */
  387. const size_t len = wcslen(text);
  388. char *result = NULL, *bytes = NULL;
  389. size_t i, size, converted;
  390. wchar_t c, buf[2];
  391. #ifndef MS_WINDOWS
  392. if (force_ascii == -1)
  393. force_ascii = check_force_ascii();
  394. if (force_ascii)
  395. return encode_ascii_surrogateescape(text, error_pos);
  396. #endif
  397. /* The function works in two steps:
  398. 1. compute the length of the output buffer in bytes (size)
  399. 2. outputs the bytes */
  400. size = 0;
  401. buf[1] = 0;
  402. while (1) {
  403. for (i=0; i < len; i++) {
  404. c = text[i];
  405. if (c >= 0xdc80 && c <= 0xdcff) {
  406. /* UTF-8b surrogate */
  407. if (bytes != NULL) {
  408. *bytes++ = c - 0xdc00;
  409. size--;
  410. }
  411. else
  412. size++;
  413. continue;
  414. }
  415. else {
  416. buf[0] = c;
  417. if (bytes != NULL)
  418. converted = wcstombs(bytes, buf, size);
  419. else
  420. converted = wcstombs(NULL, buf, 0);
  421. if (converted == (size_t)-1) {
  422. if (result != NULL)
  423. PyMem_Free(result);
  424. if (error_pos != NULL)
  425. *error_pos = i;
  426. return NULL;
  427. }
  428. if (bytes != NULL) {
  429. bytes += converted;
  430. size -= converted;
  431. }
  432. else
  433. size += converted;
  434. }
  435. }
  436. if (result != NULL) {
  437. *bytes = '\0';
  438. break;
  439. }
  440. size += 1; /* nul byte at the end */
  441. result = PyMem_Malloc(size);
  442. if (result == NULL) {
  443. if (error_pos != NULL)
  444. *error_pos = (size_t)-1;
  445. return NULL;
  446. }
  447. bytes = result;
  448. }
  449. return result;
  450. #endif /* __APPLE__ */
  451. }
  452. /* In principle, this should use HAVE__WSTAT, and _wstat
  453. should be detected by autoconf. However, no current
  454. POSIX system provides that function, so testing for
  455. it is pointless.
  456. Not sure whether the MS_WINDOWS guards are necessary:
  457. perhaps for cygwin/mingw builds?
  458. */
  459. #if defined(HAVE_STAT) && !defined(MS_WINDOWS)
  460. /* Get file status. Encode the path to the locale encoding. */
  461. int
  462. _Py_wstat(const wchar_t* path, struct stat *buf)
  463. {
  464. int err;
  465. char *fname;
  466. fname = _Py_wchar2char(path, NULL);
  467. if (fname == NULL) {
  468. errno = EINVAL;
  469. return -1;
  470. }
  471. err = stat(fname, buf);
  472. PyMem_Free(fname);
  473. return err;
  474. }
  475. #endif
  476. #ifdef HAVE_STAT
  477. /* Call _wstat() on Windows, or encode the path to the filesystem encoding and
  478. call stat() otherwise. Only fill st_mode attribute on Windows.
  479. Return 0 on success, -1 on _wstat() / stat() error, -2 if an exception was
  480. raised. */
  481. int
  482. _Py_stat(PyObject *path, struct stat *statbuf)
  483. {
  484. #ifdef MS_WINDOWS
  485. int err;
  486. struct _stat wstatbuf;
  487. wchar_t *wpath;
  488. wpath = PyUnicode_AsUnicode(path);
  489. if (wpath == NULL)
  490. return -2;
  491. err = _wstat(wpath, &wstatbuf);
  492. if (!err)
  493. statbuf->st_mode = wstatbuf.st_mode;
  494. return err;
  495. #else
  496. int ret;
  497. PyObject *bytes = PyUnicode_EncodeFSDefault(path);
  498. if (bytes == NULL)
  499. return -2;
  500. ret = stat(PyBytes_AS_STRING(bytes), statbuf);
  501. Py_DECREF(bytes);
  502. return ret;
  503. #endif
  504. }
  505. #endif
  506. /* Open a file. Use _wfopen() on Windows, encode the path to the locale
  507. encoding and use fopen() otherwise. */
  508. FILE *
  509. _Py_wfopen(const wchar_t *path, const wchar_t *mode)
  510. {
  511. #ifndef MS_WINDOWS
  512. FILE *f;
  513. char *cpath;
  514. char cmode[10];
  515. size_t r;
  516. r = wcstombs(cmode, mode, 10);
  517. if (r == (size_t)-1 || r >= 10) {
  518. errno = EINVAL;
  519. return NULL;
  520. }
  521. cpath = _Py_wchar2char(path, NULL);
  522. if (cpath == NULL)
  523. return NULL;
  524. f = fopen(cpath, cmode);
  525. PyMem_Free(cpath);
  526. return f;
  527. #else
  528. return _wfopen(path, mode);
  529. #endif
  530. }
  531. /* Call _wfopen() on Windows, or encode the path to the filesystem encoding and
  532. call fopen() otherwise.
  533. Return the new file object on success, or NULL if the file cannot be open or
  534. (if PyErr_Occurred()) on unicode error */
  535. FILE*
  536. _Py_fopen(PyObject *path, const char *mode)
  537. {
  538. #ifdef MS_WINDOWS
  539. wchar_t *wpath;
  540. wchar_t wmode[10];
  541. int usize;
  542. if (!PyUnicode_Check(path)) {
  543. PyErr_Format(PyExc_TypeError,
  544. "str file path expected under Windows, got %R",
  545. Py_TYPE(path));
  546. return NULL;
  547. }
  548. wpath = PyUnicode_AsUnicode(path);
  549. if (wpath == NULL)
  550. return NULL;
  551. usize = MultiByteToWideChar(CP_ACP, 0, mode, -1, wmode, sizeof(wmode));
  552. if (usize == 0)
  553. return NULL;
  554. return _wfopen(wpath, wmode);
  555. #else
  556. FILE *f;
  557. PyObject *bytes;
  558. if (!PyUnicode_FSConverter(path, &bytes))
  559. return NULL;
  560. f = fopen(PyBytes_AS_STRING(bytes), mode);
  561. Py_DECREF(bytes);
  562. return f;
  563. #endif
  564. }
  565. #ifdef HAVE_READLINK
  566. /* Read value of symbolic link. Encode the path to the locale encoding, decode
  567. the result from the locale encoding. Return -1 on error. */
  568. int
  569. _Py_wreadlink(const wchar_t *path, wchar_t *buf, size_t bufsiz)
  570. {
  571. char *cpath;
  572. char cbuf[MAXPATHLEN];
  573. wchar_t *wbuf;
  574. int res;
  575. size_t r1;
  576. cpath = _Py_wchar2char(path, NULL);
  577. if (cpath == NULL) {
  578. errno = EINVAL;
  579. return -1;
  580. }
  581. res = (int)readlink(cpath, cbuf, Py_ARRAY_LENGTH(cbuf));
  582. PyMem_Free(cpath);
  583. if (res == -1)
  584. return -1;
  585. if (res == Py_ARRAY_LENGTH(cbuf)) {
  586. errno = EINVAL;
  587. return -1;
  588. }
  589. cbuf[res] = '\0'; /* buf will be null terminated */
  590. wbuf = _Py_char2wchar(cbuf, &r1);
  591. if (wbuf == NULL) {
  592. errno = EINVAL;
  593. return -1;
  594. }
  595. if (bufsiz <= r1) {
  596. PyMem_Free(wbuf);
  597. errno = EINVAL;
  598. return -1;
  599. }
  600. wcsncpy(buf, wbuf, bufsiz);
  601. PyMem_Free(wbuf);
  602. return (int)r1;
  603. }
  604. #endif
  605. #ifdef HAVE_REALPATH
  606. /* Return the canonicalized absolute pathname. Encode path to the locale
  607. encoding, decode the result from the locale encoding.
  608. Return NULL on error. */
  609. wchar_t*
  610. _Py_wrealpath(const wchar_t *path,
  611. wchar_t *resolved_path, size_t resolved_path_size)
  612. {
  613. char *cpath;
  614. char cresolved_path[MAXPATHLEN];
  615. wchar_t *wresolved_path;
  616. char *res;
  617. size_t r;
  618. cpath = _Py_wchar2char(path, NULL);
  619. if (cpath == NULL) {
  620. errno = EINVAL;
  621. return NULL;
  622. }
  623. res = realpath(cpath, cresolved_path);
  624. PyMem_Free(cpath);
  625. if (res == NULL)
  626. return NULL;
  627. wresolved_path = _Py_char2wchar(cresolved_path, &r);
  628. if (wresolved_path == NULL) {
  629. errno = EINVAL;
  630. return NULL;
  631. }
  632. if (resolved_path_size <= r) {
  633. PyMem_Free(wresolved_path);
  634. errno = EINVAL;
  635. return NULL;
  636. }
  637. wcsncpy(resolved_path, wresolved_path, resolved_path_size);
  638. PyMem_Free(wresolved_path);
  639. return resolved_path;
  640. }
  641. #endif
  642. /* Get the current directory. size is the buffer size in wide characters
  643. including the null character. Decode the path from the locale encoding.
  644. Return NULL on error. */
  645. wchar_t*
  646. _Py_wgetcwd(wchar_t *buf, size_t size)
  647. {
  648. #ifdef MS_WINDOWS
  649. return _wgetcwd(buf, size);
  650. #else
  651. char fname[MAXPATHLEN];
  652. wchar_t *wname;
  653. size_t len;
  654. if (getcwd(fname, Py_ARRAY_LENGTH(fname)) == NULL)
  655. return NULL;
  656. wname = _Py_char2wchar(fname, &len);
  657. if (wname == NULL)
  658. return NULL;
  659. if (size <= len) {
  660. PyMem_Free(wname);
  661. return NULL;
  662. }
  663. wcsncpy(buf, wname, size);
  664. PyMem_Free(wname);
  665. return buf;
  666. #endif
  667. }