ยปCore Development>Code coverage>Python/fileutils.c

Python code coverage for Python/fileutils.c

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