Trent Mick <trentm@activestate.com>:
This patch fixes the posix module for large file support mainly on Win64, although some general cleanup is done as well. The changes are: - abstract stat->STAT, fstat->FSTAT, and struct stat->STRUCT_STAT This is because stat() etc. are not the correct functions to use on Win64 (nor maybe on other platforms?, if not then it is now trivial to select the appropriate one). On Win64 the appropriate system functions are _stati64(), etc. - add _pystat_fromstructstat(), it builds the return tuple for the fstat system call. This functionality was being duplicated. As well the construction of the tuple was modified to ensure no overflow of the time_t elements (sizeof(time_t) > sizeof(long) on Win64). - add overflow protection for the return values of posix_spawnv and posix_spawnve - use the proper 64-bit capable lseek() on Win64 - use intptr_t instead of long where appropriate from Win32/64 blocks (sizeof(void*) > sizeof(long) on Win64) This closes SourceForge patch #100513.
This commit is contained in:
parent
dfb4ebda24
commit
699f352fb2
|
@ -284,6 +284,18 @@ extern int lstat Py_PROTO((const char *, struct stat *));
|
||||||
#define USE_TMPNAM_R
|
#define USE_TMPNAM_R
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* choose the appropriate stat and fstat functions and return structs */
|
||||||
|
#ifdef MS_WIN64
|
||||||
|
# define STAT _stati64
|
||||||
|
# define FSTAT _fstati64
|
||||||
|
# define STRUCT_STAT struct _stati64
|
||||||
|
#else
|
||||||
|
# define STAT stat
|
||||||
|
# define FSTAT fstat
|
||||||
|
# define STRUCT_STAT struct stat
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Return a dictionary corresponding to the POSIX environment table */
|
/* Return a dictionary corresponding to the POSIX environment table */
|
||||||
|
|
||||||
#if !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
|
#if !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
|
||||||
|
@ -539,14 +551,64 @@ posix_strintint(args, format, func)
|
||||||
return Py_None;
|
return Py_None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* pack a system stat C structure into the Python stat tuple
|
||||||
|
(used by posix_stat() and posix_fstat()) */
|
||||||
|
static PyObject*
|
||||||
|
_pystat_fromstructstat(st)
|
||||||
|
STRUCT_STAT st;
|
||||||
|
{
|
||||||
|
PyObject *v = PyTuple_New(10);
|
||||||
|
if (v == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
PyTuple_SetItem(v, 0, PyInt_FromLong((long)st.st_mode));
|
||||||
|
#ifdef HAVE_LARGEFILE_SUPPORT
|
||||||
|
PyTuple_SetItem(v, 1, PyLong_FromLongLong((LONG_LONG)st.st_ino));
|
||||||
|
#else
|
||||||
|
PyTuple_SetItem(v, 1, PyInt_FromLong((long)st.st_ino));
|
||||||
|
#endif
|
||||||
|
#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
|
||||||
|
PyTuple_SetItem(v, 2, PyLong_FromLongLong((LONG_LONG)st.st_dev));
|
||||||
|
#else
|
||||||
|
PyTuple_SetItem(v, 2, PyInt_FromLong((long)st.st_dev));
|
||||||
|
#endif
|
||||||
|
PyTuple_SetItem(v, 3, PyInt_FromLong((long)st.st_nlink));
|
||||||
|
PyTuple_SetItem(v, 4, PyInt_FromLong((long)st.st_uid));
|
||||||
|
PyTuple_SetItem(v, 5, PyInt_FromLong((long)st.st_gid));
|
||||||
|
#ifdef HAVE_LARGEFILE_SUPPORT
|
||||||
|
PyTuple_SetItem(v, 6, PyLong_FromLongLong((LONG_LONG)st.st_size));
|
||||||
|
#else
|
||||||
|
PyTuple_SetItem(v, 6, PyInt_FromLong(st.st_size));
|
||||||
|
#endif
|
||||||
|
#if SIZEOF_TIME_T > SIZEOF_LONG
|
||||||
|
PyTuple_SetItem(v, 7, PyLong_FromLongLong((LONG_LONG)st.st_atime));
|
||||||
|
PyTuple_SetItem(v, 8, PyLong_FromLongLong((LONG_LONG)st.st_mtime));
|
||||||
|
PyTuple_SetItem(v, 9, PyLong_FromLongLong((LONG_LONG)st.st_ctime));
|
||||||
|
#else
|
||||||
|
PyTuple_SetItem(v, 7, PyInt_FromLong((long)st.st_atime));
|
||||||
|
PyTuple_SetItem(v, 8, PyInt_FromLong((long)st.st_mtime));
|
||||||
|
PyTuple_SetItem(v, 9, PyInt_FromLong((long)st.st_ctime));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (PyErr_Occurred()) {
|
||||||
|
Py_DECREF(v);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
posix_do_stat(self, args, format, statfunc)
|
posix_do_stat(self, args, format, statfunc)
|
||||||
PyObject *self;
|
PyObject *self;
|
||||||
PyObject *args;
|
PyObject *args;
|
||||||
char *format;
|
char *format;
|
||||||
int (*statfunc) Py_FPROTO((const char *, struct stat *));
|
int (*statfunc) Py_FPROTO((const char *, STRUCT_STAT *));
|
||||||
{
|
{
|
||||||
struct stat st;
|
STRUCT_STAT st;
|
||||||
char *path;
|
char *path;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
|
@ -585,31 +647,8 @@ posix_do_stat(self, args, format, statfunc)
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
if (res != 0)
|
if (res != 0)
|
||||||
return posix_error_with_filename(path);
|
return posix_error_with_filename(path);
|
||||||
#if !defined(HAVE_LARGEFILE_SUPPORT)
|
|
||||||
return Py_BuildValue("(llllllllll)",
|
return _pystat_fromstructstat(st);
|
||||||
(long)st.st_mode,
|
|
||||||
(long)st.st_ino,
|
|
||||||
(long)st.st_dev,
|
|
||||||
(long)st.st_nlink,
|
|
||||||
(long)st.st_uid,
|
|
||||||
(long)st.st_gid,
|
|
||||||
(long)st.st_size,
|
|
||||||
(long)st.st_atime,
|
|
||||||
(long)st.st_mtime,
|
|
||||||
(long)st.st_ctime);
|
|
||||||
#else
|
|
||||||
return Py_BuildValue("(lLllllLlll)",
|
|
||||||
(long)st.st_mode,
|
|
||||||
(LONG_LONG)st.st_ino,
|
|
||||||
(long)st.st_dev,
|
|
||||||
(long)st.st_nlink,
|
|
||||||
(long)st.st_uid,
|
|
||||||
(long)st.st_gid,
|
|
||||||
(LONG_LONG)st.st_size,
|
|
||||||
(long)st.st_atime,
|
|
||||||
(long)st.st_mtime,
|
|
||||||
(long)st.st_ctime);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1158,7 +1197,7 @@ posix_stat(self, args)
|
||||||
PyObject *self;
|
PyObject *self;
|
||||||
PyObject *args;
|
PyObject *args;
|
||||||
{
|
{
|
||||||
return posix_do_stat(self, args, "s:stat", stat);
|
return posix_do_stat(self, args, "s:stat", STAT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1546,6 +1585,7 @@ posix_spawnv(self, args)
|
||||||
PyObject *argv;
|
PyObject *argv;
|
||||||
char **argvlist;
|
char **argvlist;
|
||||||
int mode, i, argc;
|
int mode, i, argc;
|
||||||
|
intptr_t spawnval;
|
||||||
PyObject *(*getitem) Py_PROTO((PyObject *, int));
|
PyObject *(*getitem) Py_PROTO((PyObject *, int));
|
||||||
|
|
||||||
/* spawnv has three arguments: (mode, path, argv), where
|
/* spawnv has three arguments: (mode, path, argv), where
|
||||||
|
@ -1581,14 +1621,18 @@ posix_spawnv(self, args)
|
||||||
|
|
||||||
if (mode == _OLD_P_OVERLAY)
|
if (mode == _OLD_P_OVERLAY)
|
||||||
mode = _P_OVERLAY;
|
mode = _P_OVERLAY;
|
||||||
i = _spawnv(mode, path, argvlist);
|
spawnval = _spawnv(mode, path, argvlist);
|
||||||
|
|
||||||
PyMem_DEL(argvlist);
|
PyMem_DEL(argvlist);
|
||||||
|
|
||||||
if (i == -1)
|
if (spawnval == -1)
|
||||||
return posix_error();
|
return posix_error();
|
||||||
else
|
else
|
||||||
return Py_BuildValue("i", i);
|
#if SIZEOF_LONG == SIZE_VOID_P
|
||||||
|
return Py_BuildValue("l", spawnval);
|
||||||
|
#else
|
||||||
|
return Py_BuildValue("L", spawnval);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1612,6 +1656,7 @@ posix_spawnve(self, args)
|
||||||
char **envlist;
|
char **envlist;
|
||||||
PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
|
PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
|
||||||
int mode, i, pos, argc, envc;
|
int mode, i, pos, argc, envc;
|
||||||
|
intptr_t spawnval;
|
||||||
PyObject *(*getitem) Py_PROTO((PyObject *, int));
|
PyObject *(*getitem) Py_PROTO((PyObject *, int));
|
||||||
|
|
||||||
/* spawnve has four arguments: (mode, path, argv, env), where
|
/* spawnve has four arguments: (mode, path, argv, env), where
|
||||||
|
@ -1689,11 +1734,15 @@ posix_spawnve(self, args)
|
||||||
|
|
||||||
if (mode == _OLD_P_OVERLAY)
|
if (mode == _OLD_P_OVERLAY)
|
||||||
mode = _P_OVERLAY;
|
mode = _P_OVERLAY;
|
||||||
i = _spawnve(mode, path, argvlist, envlist);
|
spawnval = _spawnve(mode, path, argvlist, envlist);
|
||||||
if (i == -1)
|
if (spawnval == -1)
|
||||||
(void) posix_error();
|
(void) posix_error();
|
||||||
else
|
else
|
||||||
res = Py_BuildValue("i", i);
|
#if SIZEOF_LONG == SIZE_VOID_P
|
||||||
|
res = Py_BuildValue("l", spawnval);
|
||||||
|
#else
|
||||||
|
res = Py_BuildValue("L", spawnval);
|
||||||
|
#endif
|
||||||
|
|
||||||
fail_2:
|
fail_2:
|
||||||
while (--envc >= 0)
|
while (--envc >= 0)
|
||||||
|
@ -2328,7 +2377,7 @@ posix_lstat(self, args)
|
||||||
#ifdef HAVE_LSTAT
|
#ifdef HAVE_LSTAT
|
||||||
return posix_do_stat(self, args, "s:lstat", lstat);
|
return posix_do_stat(self, args, "s:lstat", lstat);
|
||||||
#else /* !HAVE_LSTAT */
|
#else /* !HAVE_LSTAT */
|
||||||
return posix_do_stat(self, args, "s:lstat", stat);
|
return posix_do_stat(self, args, "s:lstat", STAT);
|
||||||
#endif /* !HAVE_LSTAT */
|
#endif /* !HAVE_LSTAT */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2652,7 +2701,11 @@ posix_lseek(self, args)
|
||||||
PyObject *args;
|
PyObject *args;
|
||||||
{
|
{
|
||||||
int fd, how;
|
int fd, how;
|
||||||
|
#ifdef MS_WIN64
|
||||||
|
LONG_LONG pos, res;
|
||||||
|
#else
|
||||||
off_t pos, res;
|
off_t pos, res;
|
||||||
|
#endif
|
||||||
PyObject *posobj;
|
PyObject *posobj;
|
||||||
if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
|
if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -2675,7 +2728,11 @@ posix_lseek(self, args)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
|
#ifdef MS_WIN64
|
||||||
|
res = _lseeki64(fd, pos, how);
|
||||||
|
#else
|
||||||
res = lseek(fd, pos, how);
|
res = lseek(fd, pos, how);
|
||||||
|
#endif
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
return posix_error();
|
return posix_error();
|
||||||
|
@ -2749,40 +2806,17 @@ posix_fstat(self, args)
|
||||||
PyObject *args;
|
PyObject *args;
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
struct stat st;
|
STRUCT_STAT st;
|
||||||
int res;
|
int res;
|
||||||
if (!PyArg_ParseTuple(args, "i:fstat", &fd))
|
if (!PyArg_ParseTuple(args, "i:fstat", &fd))
|
||||||
return NULL;
|
return NULL;
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
res = fstat(fd, &st);
|
res = FSTAT(fd, &st);
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
if (res != 0)
|
if (res != 0)
|
||||||
return posix_error();
|
return posix_error();
|
||||||
#if !defined(HAVE_LARGEFILE_SUPPORT)
|
|
||||||
return Py_BuildValue("(llllllllll)",
|
return _pystat_fromstructstat(st);
|
||||||
(long)st.st_mode,
|
|
||||||
(long)st.st_ino,
|
|
||||||
(long)st.st_dev,
|
|
||||||
(long)st.st_nlink,
|
|
||||||
(long)st.st_uid,
|
|
||||||
(long)st.st_gid,
|
|
||||||
(long)st.st_size,
|
|
||||||
(long)st.st_atime,
|
|
||||||
(long)st.st_mtime,
|
|
||||||
(long)st.st_ctime);
|
|
||||||
#else
|
|
||||||
return Py_BuildValue("(lLllllLlll)",
|
|
||||||
(long)st.st_mode,
|
|
||||||
(LONG_LONG)st.st_ino,
|
|
||||||
(long)st.st_dev,
|
|
||||||
(long)st.st_nlink,
|
|
||||||
(long)st.st_uid,
|
|
||||||
(long)st.st_gid,
|
|
||||||
(LONG_LONG)st.st_size,
|
|
||||||
(long)st.st_atime,
|
|
||||||
(long)st.st_mtime,
|
|
||||||
(long)st.st_ctime);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2863,8 +2897,8 @@ posix_pipe(self, args)
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
if (!ok)
|
if (!ok)
|
||||||
return posix_error();
|
return posix_error();
|
||||||
read_fd = _open_osfhandle((long)read, 0);
|
read_fd = _open_osfhandle((intptr_t)read, 0);
|
||||||
write_fd = _open_osfhandle((long)write, 1);
|
write_fd = _open_osfhandle((intptr_t)write, 1);
|
||||||
return Py_BuildValue("(ii)", read_fd, write_fd);
|
return Py_BuildValue("(ii)", read_fd, write_fd);
|
||||||
#endif /* MS_WIN32 */
|
#endif /* MS_WIN32 */
|
||||||
#endif
|
#endif
|
||||||
|
@ -3526,9 +3560,10 @@ conv_confname(arg, valuep, table, tablesize)
|
||||||
}
|
}
|
||||||
if (PyString_Check(arg)) {
|
if (PyString_Check(arg)) {
|
||||||
/* look up the value in the table using a binary search */
|
/* look up the value in the table using a binary search */
|
||||||
int lo = 0;
|
size_t lo = 0;
|
||||||
int hi = tablesize;
|
size_t mid;
|
||||||
int cmp, mid;
|
size_t hi = tablesize;
|
||||||
|
int cmp;
|
||||||
char *confname = PyString_AS_STRING(arg);
|
char *confname = PyString_AS_STRING(arg);
|
||||||
while (lo < hi) {
|
while (lo < hi) {
|
||||||
mid = (lo + hi) / 2;
|
mid = (lo + hi) / 2;
|
||||||
|
|
Loading…
Reference in New Issue