diff options
Diffstat (limited to 'Python/fileutils.c')
| -rw-r--r-- | Python/fileutils.c | 120 | 
1 files changed, 88 insertions, 32 deletions
| diff --git a/Python/fileutils.c b/Python/fileutils.c index a55064f..227e92a 100644 --- a/Python/fileutils.c +++ b/Python/fileutils.c @@ -82,11 +82,11 @@ extern int _Py_normalize_encoding(const char *, char *, size_t);     Values of force_ascii: -       1: the workaround is used: _Py_wchar2char() uses -          encode_ascii_surrogateescape() and _Py_char2wchar() uses +       1: the workaround is used: Py_EncodeLocale() uses +          encode_ascii_surrogateescape() and Py_DecodeLocale() uses            decode_ascii_surrogateescape() -       0: the workaround is not used: _Py_wchar2char() uses wcstombs() and -          _Py_char2wchar() uses mbstowcs() +       0: the workaround is not used: Py_EncodeLocale() uses wcstombs() and +          Py_DecodeLocale() uses mbstowcs()        -1: unknown, need to call check_force_ascii() to get the value  */  static int force_ascii = -1; @@ -241,24 +241,26 @@ decode_ascii_surrogateescape(const char *arg, size_t *size)  /* Decode a byte string from the locale encoding with the -   surrogateescape error handler (undecodable bytes are decoded as characters -   in range U+DC80..U+DCFF). If a byte sequence can be decoded as a surrogate +   surrogateescape error handler: undecodable bytes are decoded as characters +   in range U+DC80..U+DCFF. If a byte sequence can be decoded as a surrogate     character, escape the bytes using the surrogateescape error handler instead     of decoding them. -   Use _Py_wchar2char() to encode the character string back to a byte string. +   Return a pointer to a newly allocated wide character string, use +   PyMem_RawFree() to free the memory. If size is not NULL, write the number of +   wide characters excluding the null character into *size -   Return a pointer to a newly allocated wide character string (use -   PyMem_RawFree() to free the memory) and write the number of written wide -   characters excluding the null character into *size if size is not NULL, or -   NULL on error (decoding or memory allocation error). If size is not NULL, -   *size is set to (size_t)-1 on memory error and (size_t)-2 on decoding -   error. +   Return NULL on decoding error or memory allocation error. If *size* is not +   NULL, *size is set to (size_t)-1 on memory error or set to (size_t)-2 on +   decoding error. -   Conversion errors should never happen, unless there is a bug in the C -   library. */ +   Decoding errors should never happen, unless there is a bug in the C +   library. + +   Use the Py_EncodeLocale() function to encode the character string back to a +   byte string. */  wchar_t* -_Py_char2wchar(const char* arg, size_t *size) +Py_DecodeLocale(const char* arg, size_t *size)  {  #ifdef __APPLE__      wchar_t *wstr; @@ -389,19 +391,20 @@ oom:  #endif   /* __APPLE__ */  } -/* Encode a (wide) character string to the locale encoding with the -   surrogateescape error handler (characters in range U+DC80..U+DCFF are -   converted to bytes 0x80..0xFF). +/* Encode a wide character string to the locale encoding with the +   surrogateescape error handler: surrogate characters in the range +   U+DC80..U+DCFF are converted to bytes 0x80..0xFF. -   This function is the reverse of _Py_char2wchar(). +   Return a pointer to a newly allocated byte string, use PyMem_Free() to free +   the memory. Return NULL on encoding or memory allocation error. -   Return a pointer to a newly allocated byte string (use PyMem_Free() to free -   the memory), or NULL on encoding or memory allocation error. +   If error_pos is not NULL, *error_pos is set to the index of the invalid +   character on encoding error, or set to (size_t)-1 otherwise. -   If error_pos is not NULL: *error_pos is the index of the invalid character -   on encoding error, or (size_t)-1 otherwise. */ +   Use the Py_DecodeLocale() function to decode the bytes string back to a wide +   character string. */  char* -_Py_wchar2char(const wchar_t *text, size_t *error_pos) +Py_EncodeLocale(const wchar_t *text, size_t *error_pos)  {  #ifdef __APPLE__      Py_ssize_t len; @@ -520,7 +523,7 @@ _Py_wstat(const wchar_t* path, struct stat *buf)  {      int err;      char *fname; -    fname = _Py_wchar2char(path, NULL); +    fname = Py_EncodeLocale(path, NULL);      if (fname == NULL) {          errno = EINVAL;          return -1; @@ -784,7 +787,7 @@ _Py_wfopen(const wchar_t *path, const wchar_t *mode)          errno = EINVAL;          return NULL;      } -    cpath = _Py_wchar2char(path, NULL); +    cpath = Py_EncodeLocale(path, NULL);      if (cpath == NULL)          return NULL;      f = fopen(cpath, cmode); @@ -875,7 +878,7 @@ _Py_wreadlink(const wchar_t *path, wchar_t *buf, size_t bufsiz)      int res;      size_t r1; -    cpath = _Py_wchar2char(path, NULL); +    cpath = Py_EncodeLocale(path, NULL);      if (cpath == NULL) {          errno = EINVAL;          return -1; @@ -889,7 +892,7 @@ _Py_wreadlink(const wchar_t *path, wchar_t *buf, size_t bufsiz)          return -1;      }      cbuf[res] = '\0'; /* buf will be null terminated */ -    wbuf = _Py_char2wchar(cbuf, &r1); +    wbuf = Py_DecodeLocale(cbuf, &r1);      if (wbuf == NULL) {          errno = EINVAL;          return -1; @@ -920,7 +923,7 @@ _Py_wrealpath(const wchar_t *path,      wchar_t *wresolved_path;      char *res;      size_t r; -    cpath = _Py_wchar2char(path, NULL); +    cpath = Py_EncodeLocale(path, NULL);      if (cpath == NULL) {          errno = EINVAL;          return NULL; @@ -930,7 +933,7 @@ _Py_wrealpath(const wchar_t *path,      if (res == NULL)          return NULL; -    wresolved_path = _Py_char2wchar(cresolved_path, &r); +    wresolved_path = Py_DecodeLocale(cresolved_path, &r);      if (wresolved_path == NULL) {          errno = EINVAL;          return NULL; @@ -963,7 +966,7 @@ _Py_wgetcwd(wchar_t *buf, size_t size)      if (getcwd(fname, Py_ARRAY_LENGTH(fname)) == NULL)          return NULL; -    wname = _Py_char2wchar(fname, &len); +    wname = Py_DecodeLocale(fname, &len);      if (wname == NULL)          return NULL;      if (size <= len) { @@ -1045,3 +1048,56 @@ _Py_dup(int fd)      return fd;  } +#ifndef MS_WINDOWS +/* Get the blocking mode of the file descriptor. +   Return 0 if the O_NONBLOCK flag is set, 1 if the flag is cleared, +   raise an exception and return -1 on error. */ +int +_Py_get_blocking(int fd) +{ +    int flags = fcntl(fd, F_GETFL, 0); +    if (flags < 0) { +        PyErr_SetFromErrno(PyExc_OSError); +        return -1; +    } + +    return !(flags & O_NONBLOCK); +} + +/* Set the blocking mode of the specified file descriptor. + +   Set the O_NONBLOCK flag if blocking is False, clear the O_NONBLOCK flag +   otherwise. + +   Return 0 on success, raise an exception and return -1 on error. */ +int +_Py_set_blocking(int fd, int blocking) +{ +#if defined(HAVE_SYS_IOCTL_H) && defined(FIONBIO) +    int arg = !blocking; +    if (ioctl(fd, FIONBIO, &arg) < 0) +        goto error; +#else +    int flags, res; + +    flags = fcntl(fd, F_GETFL, 0); +    if (flags < 0) +        goto error; + +    if (blocking) +        flags = flags & (~O_NONBLOCK); +    else +        flags = flags | O_NONBLOCK; + +    res = fcntl(fd, F_SETFL, flags); +    if (res < 0) +        goto error; +#endif +    return 0; + +error: +    PyErr_SetFromErrno(PyExc_OSError); +    return -1; +} +#endif + | 
