cpython: 128f92ae8bae (original) (raw)
Mercurial > cpython
changeset 95285:128f92ae8bae
Issue #23752: _Py_fstat() is now responsible to raise the Python exception Add _Py_fstat_noraise() function when a Python exception is not welcome. [#23752]
Victor Stinner victor.stinner@gmail.com | |
---|---|
date | Mon, 30 Mar 2015 10:09:31 +0200 |
parents | 2fcd99929dba |
children | e00b581a65ec |
files | Include/fileutils.h Modules/_io/fileio.c Modules/main.c Modules/mmapmodule.c Modules/posixmodule.c Modules/signalmodule.c Programs/_freeze_importlib.c Python/dynload_shlib.c Python/fileutils.c Python/marshal.c Python/random.c Python/sysmodule.c |
diffstat | 12 files changed, 89 insertions(+), 57 deletions(-)[+] [-] Include/fileutils.h 8 Modules/_io/fileio.c 10 Modules/main.c 6 Modules/mmapmodule.c 25 Modules/posixmodule.c 2 Modules/signalmodule.c 10 Programs/_freeze_importlib.c 6 Python/dynload_shlib.c 14 Python/fileutils.c 58 Python/marshal.c 2 Python/random.c 3 Python/sysmodule.c 2 |
line wrap: on
line diff
--- a/Include/fileutils.h +++ b/Include/fileutils.h @@ -41,12 +41,16 @@ struct _Py_stat_struct { PyAPI_FUNC(int) _Py_fstat( int fd,
+ +PyAPI_FUNC(int) _Py_fstat_noraise(
#endif /* Py_LIMITED_API */ PyAPI_FUNC(int) _Py_stat( PyObject *path,
#ifndef Py_LIMITED_API PyAPI_FUNC(int) _Py_open(
--- a/Modules/_io/fileio.c +++ b/Modules/_io/fileio.c @@ -399,10 +399,8 @@ fileio_init(PyObject *oself, PyObject *a } self->blksize = DEFAULT_BUFFER_SIZE;
#if defined(S_ISDIR) && defined(EISDIR) /* On Unix, open will succeed for directories. In Python, there should be no file objects referring to @@ -589,7 +587,7 @@ new_buffersize(fileio *self, size_t curr static PyObject * fileio_readall(fileio *self) {
- struct _Py_stat_struct status; Py_off_t pos, end; PyObject *result; Py_ssize_t bytes_read = 0; @@ -606,8 +604,8 @@ fileio_readall(fileio *self)
#else pos = lseek(self->fd, 0L, SEEK_CUR); #endif
- if (_Py_fstat_noraise(self->fd, &status) == 0)
else end = (Py_off_t)-1;end = status.st_size;[](#l2.31)
--- a/Modules/main.c +++ b/Modules/main.c @@ -753,9 +753,11 @@ Py_Main(int argc, wchar_t **argv) } { struct _Py_stat_struct sb;
if (_Py_fstat(fileno(fp), &sb) == 0 &&[](#l3.7)
if (_Py_fstat_noraise(fileno(fp), &sb) == 0 &&[](#l3.8) S_ISDIR(sb.st_mode)) {[](#l3.9)
fprintf(stderr, "%ls: '%ls' is a directory, cannot continue\n", argv[0], filename);[](#l3.10)
fprintf(stderr,[](#l3.11)
"%ls: '%ls' is a directory, cannot continue\n",[](#l3.12)
argv[0], filename);[](#l3.13) fclose(fp);[](#l3.14) return 1;[](#l3.15) }[](#l3.16)
--- a/Modules/mmapmodule.c +++ b/Modules/mmapmodule.c @@ -465,15 +465,13 @@ mmap_size_method(mmap_object *self, #ifdef UNIX {
struct _Py_stat_struct buf;[](#l4.7)
if (-1 == _Py_fstat(self->fd, &buf)) {[](#l4.8)
PyErr_SetFromErrno(PyExc_OSError);[](#l4.9)
struct _Py_stat_struct status;[](#l4.10)
if (_Py_fstat(self->fd, &status) == -1)[](#l4.11) return NULL;[](#l4.12)
}[](#l4.13)
return PyLong_FromLongLong(buf.st_size);[](#l4.15)
return PyLong_FromLongLong(status.st_size);[](#l4.16)
return PyLong_FromLong(buf.st_size);[](#l4.18)
return PyLong_FromLong(status.st_size);[](#l4.19)
#endif } #endif /* UNIX */ @@ -1112,7 +1110,7 @@ static Py_ssize_t static PyObject * new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict) {
- struct _Py_stat_struct status; mmap_object *m_obj; PyObject *map_size_obj = NULL; Py_ssize_t map_size; @@ -1177,25 +1175,26 @@ new_mmap_object(PyTypeObject *type, PyOb if (fd != -1) (void)fcntl(fd, F_FULLFSYNC);
- if (fd != -1 && _Py_fstat_noraise(fd, &status) == 0
&& S_ISREG(status.st_mode)) {[](#l4.38) if (map_size == 0) {[](#l4.39)
if (st.st_size == 0) {[](#l4.40)
if (status.st_size == 0) {[](#l4.41) PyErr_SetString(PyExc_ValueError,[](#l4.42) "cannot mmap an empty file");[](#l4.43) return NULL;[](#l4.44) }[](#l4.45)
if (offset >= st.st_size) {[](#l4.46)
if (offset >= status.st_size) {[](#l4.47) PyErr_SetString(PyExc_ValueError,[](#l4.48) "mmap offset is greater than file size");[](#l4.49) return NULL;[](#l4.50) }[](#l4.51)
if (st.st_size - offset > PY_SSIZE_T_MAX) {[](#l4.52)
if (status.st_size - offset > PY_SSIZE_T_MAX) {[](#l4.53) PyErr_SetString(PyExc_ValueError,[](#l4.54) "mmap length is too large");[](#l4.55) return NULL;[](#l4.56) }[](#l4.57)
map_size = (Py_ssize_t) (st.st_size - offset);[](#l4.58)
} else if (offset + map_size > st.st_size) {[](#l4.59)
map_size = (Py_ssize_t) (status.st_size - offset);[](#l4.60)
} else if (offset + map_size > status.st_size) {[](#l4.61) PyErr_SetString(PyExc_ValueError,[](#l4.62) "mmap length is greater than file size");[](#l4.63) return NULL;[](#l4.64)
--- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -351,7 +351,7 @@ static int win32_can_symlink = 0; #ifdef MS_WINDOWS
define STAT win32_stat
define LSTAT win32_lstat
-# define FSTAT _Py_fstat +# define FSTAT _Py_fstat_noraise
define STRUCT_STAT struct _Py_stat_struct
define STAT stat
--- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -503,7 +503,7 @@ signal_siginterrupt(PyObject *self, PyOb static PyObject * signal_set_wakeup_fd(PyObject *self, PyObject *args) {
#ifdef MS_WINDOWS PyObject *fdobj; SOCKET_T sockfd, old_sockfd; @@ -559,10 +559,8 @@ signal_set_wakeup_fd(PyObject *self, PyO return NULL; }
if (_Py_fstat(fd, &st) != 0) {[](#l6.16)
PyErr_SetExcFromWindowsErr(PyExc_OSError, GetLastError());[](#l6.17)
if (_Py_fstat(fd, &status) != 0)[](#l6.18) return NULL;[](#l6.19)
}[](#l6.20)
/* on Windows, a file cannot be set to non-blocking mode */ } @@ -591,10 +589,8 @@ signal_set_wakeup_fd(PyObject *self, PyO return NULL; }
if (_Py_fstat(fd, &st) != 0) {[](#l6.28)
PyErr_SetFromErrno(PyExc_OSError);[](#l6.29)
if (_Py_fstat(fd, &status) != 0)[](#l6.30) return NULL;[](#l6.31)
}[](#l6.32)
blocking = _Py_get_blocking(fd); if (blocking < 0)
--- a/Programs/_freeze_importlib.c +++ b/Programs/_freeze_importlib.c @@ -35,7 +35,7 @@ main(int argc, char *argv[]) { char *inpath, *outpath; FILE *infile = NULL, *outfile = NULL;
- struct _Py_stat_struct status; size_t text_size, data_size, n; char *text = NULL; unsigned char *data; @@ -54,11 +54,11 @@ main(int argc, char *argv[]) fprintf(stderr, "cannot open '%s' for reading\n", inpath); goto error; }
- if (_Py_fstat_noraise(fileno(infile), &status)) { fprintf(stderr, "cannot fstat '%s'\n", inpath); goto error; }
- text_size = status.st_size; text = (char *) malloc(text_size + 1); if (text == NULL) { fprintf(stderr, "could not allocate %ld bytes\n", (long) text_size);
--- a/Python/dynload_shlib.c +++ b/Python/dynload_shlib.c @@ -71,22 +71,20 @@ dl_funcptr _PyImport_GetDynLoadFunc(cons if (fp != NULL) { int i;
struct _Py_stat_struct statb;[](#l8.7)
if (_Py_fstat(fileno(fp), &statb) == -1) {[](#l8.8)
PyErr_SetFromErrno(PyExc_IOError);[](#l8.9)
struct _Py_stat_struct status;[](#l8.10)
if (_Py_fstat(fileno(fp), &status) == -1)[](#l8.11) return NULL;[](#l8.12)
}[](#l8.13) for (i = 0; i < nhandles; i++) {[](#l8.14)
if (statb.st_dev == handles[i].dev &&[](#l8.15)
statb.st_ino == handles[i].ino) {[](#l8.16)
if (status.st_dev == handles[i].dev &&[](#l8.17)
status.st_ino == handles[i].ino) {[](#l8.18) p = (dl_funcptr) dlsym(handles[i].handle,[](#l8.19) funcname);[](#l8.20) return p;[](#l8.21) }[](#l8.22) }[](#l8.23) if (nhandles < 128) {[](#l8.24)
handles[nhandles].dev = statb.st_dev;[](#l8.25)
handles[nhandles].ino = statb.st_ino;[](#l8.26)
handles[nhandles].dev = status.st_dev;[](#l8.27)
}handles[nhandles].ino = status.st_ino;[](#l8.28) }[](#l8.29)
--- a/Python/fileutils.c +++ b/Python/fileutils.c @@ -565,7 +565,8 @@ attributes_to_mode(DWORD attr) } void -_Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, struct _Py_stat_struct *result) +_Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag,
struct _Py_stat_struct *result)[](#l9.9)
{ memset(result, 0, sizeof(*result)); result->st_mode = attributes_to_mode(info->dwFileAttributes); @@ -595,9 +596,12 @@ void files larger than 2 GB. fstat() may fail with EOVERFLOW on files larger than 2 GB because the file size type is an signed 32-bit integer: see issue #23152.
- On Windows, set the last Windows error and return nonzero on error. On
- POSIX, set errno and return nonzero on error. Fill status and return 0 on
- success. */ int -_Py_fstat(int fd, struct _Py_stat_struct *result) +_Py_fstat_noraise(int fd, struct _Py_stat_struct *status) {
#ifdef MS_WINDOWS BY_HANDLE_FILE_INFORMATION info; @@ -619,22 +623,21 @@ int SetLastError(ERROR_INVALID_HANDLE); return -1; }
type = GetFileType(h); if (type == FILE_TYPE_UNKNOWN) { DWORD error = GetLastError();
if (error != 0) {[](#l9.38)
if (error != 0)[](#l9.39) return -1;[](#l9.40)
} if (type != FILE_TYPE_DISK) { if (type == FILE_TYPE_CHAR)}[](#l9.41) /* else: valid but unknown file */[](#l9.42)
result->st_mode = _S_IFCHR;[](#l9.47)
status->st_mode = _S_IFCHR;[](#l9.48) else if (type == FILE_TYPE_PIPE)[](#l9.49)
result->st_mode = _S_IFIFO;[](#l9.50)
#endif } +/* Return information about a file. +
- On POSIX, use fstat(). +
- On Windows, use GetFileType() and GetFileInformationByHandle() which support
- files larger than 2 GB. fstat() may fail with EOVERFLOW on files larger
- than 2 GB because the file size type is an signed 32-bit integer: see issue
- #23152.
- Raise an exception and return -1 on error. On Windows, set the last Windows
- error on error. On POSIX, set errno on error. Fill status and return 0 on
- success. +
- The GIL must be held. */ +int +_Py_fstat(int fd, struct _Py_stat_struct *status) +{
- int res;
PyErr_SetFromWindowsErr(0);[](#l9.96)
PyErr_SetFromErrno(PyExc_OSError);[](#l9.98)
+} /* Call _wstat() on Windows, or encode the path to the filesystem encoding and call stat() otherwise. Only fill st_mode attribute on Windows.
--- a/Python/marshal.c +++ b/Python/marshal.c @@ -1486,7 +1486,7 @@ static off_t getfilesize(FILE *fp) { struct _Py_stat_struct st;
#if SIZEOF_OFF_T == 4 else if (st.st_size >= INT_MAX)
--- a/Python/random.c +++ b/Python/random.c @@ -221,7 +221,7 @@ dev_urandom_python(char buffer, Py_ssiz if (urandom_cache.fd >= 0) { / Does the fd point to the same thing as before? (issue #21207) */
if (_Py_fstat(urandom_cache.fd, &st)[](#l11.7)
if (_Py_fstat_noraise(urandom_cache.fd, &st)[](#l11.8) || st.st_dev != urandom_cache.st_dev[](#l11.9) || st.st_ino != urandom_cache.st_ino) {[](#l11.10) /* Something changed: forget the cached fd (but don't close it,[](#l11.11)
@@ -250,7 +250,6 @@ dev_urandom_python(char *buffer, Py_ssiz } else { if (_Py_fstat(fd, &st)) {
PyErr_SetFromErrno(PyExc_OSError);[](#l11.16) close(fd);[](#l11.17) return -1;[](#l11.18) }[](#l11.19)
--- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -1690,7 +1690,7 @@ PyObject * #if !defined(MS_WINDOWS) { struct _Py_stat_struct sb;
if (_Py_fstat(fileno(stdin), &sb) == 0 &&[](#l12.7)
if (_Py_fstat_noraise(fileno(stdin), &sb) == 0 &&[](#l12.8) S_ISDIR(sb.st_mode)) {[](#l12.9) /* There's nothing more we can do. */[](#l12.10) /* Py_FatalError() will core dump, so just exit. */[](#l12.11)