Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 699f352

Browse files
committed
Trent Mick <[email protected]>:
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.
1 parent dfb4ebd commit 699f352

1 file changed

Lines changed: 102 additions & 67 deletions

File tree

Modules/posixmodule.c

Lines changed: 102 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,18 @@ extern int lstat Py_PROTO((const char *, struct stat *));
284284
#define USE_TMPNAM_R
285285
#endif
286286

287+
/* choose the appropriate stat and fstat functions and return structs */
288+
#ifdef MS_WIN64
289+
# define STAT _stati64
290+
# define FSTAT _fstati64
291+
# define STRUCT_STAT struct _stati64
292+
#else
293+
# define STAT stat
294+
# define FSTAT fstat
295+
# define STRUCT_STAT struct stat
296+
#endif
297+
298+
287299
/* Return a dictionary corresponding to the POSIX environment table */
288300

289301
#if !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
@@ -539,14 +551,64 @@ posix_strintint(args, format, func)
539551
return Py_None;
540552
}
541553

554+
555+
556+
/* pack a system stat C structure into the Python stat tuple
557+
(used by posix_stat() and posix_fstat()) */
558+
static PyObject*
559+
_pystat_fromstructstat(st)
560+
STRUCT_STAT st;
561+
{
562+
PyObject *v = PyTuple_New(10);
563+
if (v == NULL)
564+
return NULL;
565+
566+
PyTuple_SetItem(v, 0, PyInt_FromLong((long)st.st_mode));
567+
#ifdef HAVE_LARGEFILE_SUPPORT
568+
PyTuple_SetItem(v, 1, PyLong_FromLongLong((LONG_LONG)st.st_ino));
569+
#else
570+
PyTuple_SetItem(v, 1, PyInt_FromLong((long)st.st_ino));
571+
#endif
572+
#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
573+
PyTuple_SetItem(v, 2, PyLong_FromLongLong((LONG_LONG)st.st_dev));
574+
#else
575+
PyTuple_SetItem(v, 2, PyInt_FromLong((long)st.st_dev));
576+
#endif
577+
PyTuple_SetItem(v, 3, PyInt_FromLong((long)st.st_nlink));
578+
PyTuple_SetItem(v, 4, PyInt_FromLong((long)st.st_uid));
579+
PyTuple_SetItem(v, 5, PyInt_FromLong((long)st.st_gid));
580+
#ifdef HAVE_LARGEFILE_SUPPORT
581+
PyTuple_SetItem(v, 6, PyLong_FromLongLong((LONG_LONG)st.st_size));
582+
#else
583+
PyTuple_SetItem(v, 6, PyInt_FromLong(st.st_size));
584+
#endif
585+
#if SIZEOF_TIME_T > SIZEOF_LONG
586+
PyTuple_SetItem(v, 7, PyLong_FromLongLong((LONG_LONG)st.st_atime));
587+
PyTuple_SetItem(v, 8, PyLong_FromLongLong((LONG_LONG)st.st_mtime));
588+
PyTuple_SetItem(v, 9, PyLong_FromLongLong((LONG_LONG)st.st_ctime));
589+
#else
590+
PyTuple_SetItem(v, 7, PyInt_FromLong((long)st.st_atime));
591+
PyTuple_SetItem(v, 8, PyInt_FromLong((long)st.st_mtime));
592+
PyTuple_SetItem(v, 9, PyInt_FromLong((long)st.st_ctime));
593+
#endif
594+
595+
if (PyErr_Occurred()) {
596+
Py_DECREF(v);
597+
return NULL;
598+
}
599+
600+
return v;
601+
}
602+
603+
542604
static PyObject *
543605
posix_do_stat(self, args, format, statfunc)
544606
PyObject *self;
545607
PyObject *args;
546608
char *format;
547-
int (*statfunc) Py_FPROTO((const char *, struct stat *));
609+
int (*statfunc) Py_FPROTO((const char *, STRUCT_STAT *));
548610
{
549-
struct stat st;
611+
STRUCT_STAT st;
550612
char *path;
551613
int res;
552614

@@ -585,31 +647,8 @@ posix_do_stat(self, args, format, statfunc)
585647
Py_END_ALLOW_THREADS
586648
if (res != 0)
587649
return posix_error_with_filename(path);
588-
#if !defined(HAVE_LARGEFILE_SUPPORT)
589-
return Py_BuildValue("(llllllllll)",
590-
(long)st.st_mode,
591-
(long)st.st_ino,
592-
(long)st.st_dev,
593-
(long)st.st_nlink,
594-
(long)st.st_uid,
595-
(long)st.st_gid,
596-
(long)st.st_size,
597-
(long)st.st_atime,
598-
(long)st.st_mtime,
599-
(long)st.st_ctime);
600-
#else
601-
return Py_BuildValue("(lLllllLlll)",
602-
(long)st.st_mode,
603-
(LONG_LONG)st.st_ino,
604-
(long)st.st_dev,
605-
(long)st.st_nlink,
606-
(long)st.st_uid,
607-
(long)st.st_gid,
608-
(LONG_LONG)st.st_size,
609-
(long)st.st_atime,
610-
(long)st.st_mtime,
611-
(long)st.st_ctime);
612-
#endif
650+
651+
return _pystat_fromstructstat(st);
613652
}
614653

615654

@@ -1158,7 +1197,7 @@ posix_stat(self, args)
11581197
PyObject *self;
11591198
PyObject *args;
11601199
{
1161-
return posix_do_stat(self, args, "s:stat", stat);
1200+
return posix_do_stat(self, args, "s:stat", STAT);
11621201
}
11631202

11641203

@@ -1546,6 +1585,7 @@ posix_spawnv(self, args)
15461585
PyObject *argv;
15471586
char **argvlist;
15481587
int mode, i, argc;
1588+
intptr_t spawnval;
15491589
PyObject *(*getitem) Py_PROTO((PyObject *, int));
15501590

15511591
/* spawnv has three arguments: (mode, path, argv), where
@@ -1581,14 +1621,18 @@ posix_spawnv(self, args)
15811621

15821622
if (mode == _OLD_P_OVERLAY)
15831623
mode = _P_OVERLAY;
1584-
i = _spawnv(mode, path, argvlist);
1624+
spawnval = _spawnv(mode, path, argvlist);
15851625

15861626
PyMem_DEL(argvlist);
15871627

1588-
if (i == -1)
1628+
if (spawnval == -1)
15891629
return posix_error();
15901630
else
1591-
return Py_BuildValue("i", i);
1631+
#if SIZEOF_LONG == SIZE_VOID_P
1632+
return Py_BuildValue("l", spawnval);
1633+
#else
1634+
return Py_BuildValue("L", spawnval);
1635+
#endif
15921636
}
15931637

15941638

@@ -1612,6 +1656,7 @@ posix_spawnve(self, args)
16121656
char **envlist;
16131657
PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
16141658
int mode, i, pos, argc, envc;
1659+
intptr_t spawnval;
16151660
PyObject *(*getitem) Py_PROTO((PyObject *, int));
16161661

16171662
/* spawnve has four arguments: (mode, path, argv, env), where
@@ -1689,11 +1734,15 @@ posix_spawnve(self, args)
16891734

16901735
if (mode == _OLD_P_OVERLAY)
16911736
mode = _P_OVERLAY;
1692-
i = _spawnve(mode, path, argvlist, envlist);
1693-
if (i == -1)
1737+
spawnval = _spawnve(mode, path, argvlist, envlist);
1738+
if (spawnval == -1)
16941739
(void) posix_error();
16951740
else
1696-
res = Py_BuildValue("i", i);
1741+
#if SIZEOF_LONG == SIZE_VOID_P
1742+
res = Py_BuildValue("l", spawnval);
1743+
#else
1744+
res = Py_BuildValue("L", spawnval);
1745+
#endif
16971746

16981747
fail_2:
16991748
while (--envc >= 0)
@@ -2328,7 +2377,7 @@ posix_lstat(self, args)
23282377
#ifdef HAVE_LSTAT
23292378
return posix_do_stat(self, args, "s:lstat", lstat);
23302379
#else /* !HAVE_LSTAT */
2331-
return posix_do_stat(self, args, "s:lstat", stat);
2380+
return posix_do_stat(self, args, "s:lstat", STAT);
23322381
#endif /* !HAVE_LSTAT */
23332382
}
23342383

@@ -2652,7 +2701,11 @@ posix_lseek(self, args)
26522701
PyObject *args;
26532702
{
26542703
int fd, how;
2704+
#ifdef MS_WIN64
2705+
LONG_LONG pos, res;
2706+
#else
26552707
off_t pos, res;
2708+
#endif
26562709
PyObject *posobj;
26572710
if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
26582711
return NULL;
@@ -2675,7 +2728,11 @@ posix_lseek(self, args)
26752728
return NULL;
26762729

26772730
Py_BEGIN_ALLOW_THREADS
2731+
#ifdef MS_WIN64
2732+
res = _lseeki64(fd, pos, how);
2733+
#else
26782734
res = lseek(fd, pos, how);
2735+
#endif
26792736
Py_END_ALLOW_THREADS
26802737
if (res < 0)
26812738
return posix_error();
@@ -2749,40 +2806,17 @@ posix_fstat(self, args)
27492806
PyObject *args;
27502807
{
27512808
int fd;
2752-
struct stat st;
2809+
STRUCT_STAT st;
27532810
int res;
27542811
if (!PyArg_ParseTuple(args, "i:fstat", &fd))
27552812
return NULL;
27562813
Py_BEGIN_ALLOW_THREADS
2757-
res = fstat(fd, &st);
2814+
res = FSTAT(fd, &st);
27582815
Py_END_ALLOW_THREADS
27592816
if (res != 0)
27602817
return posix_error();
2761-
#if !defined(HAVE_LARGEFILE_SUPPORT)
2762-
return Py_BuildValue("(llllllllll)",
2763-
(long)st.st_mode,
2764-
(long)st.st_ino,
2765-
(long)st.st_dev,
2766-
(long)st.st_nlink,
2767-
(long)st.st_uid,
2768-
(long)st.st_gid,
2769-
(long)st.st_size,
2770-
(long)st.st_atime,
2771-
(long)st.st_mtime,
2772-
(long)st.st_ctime);
2773-
#else
2774-
return Py_BuildValue("(lLllllLlll)",
2775-
(long)st.st_mode,
2776-
(LONG_LONG)st.st_ino,
2777-
(long)st.st_dev,
2778-
(long)st.st_nlink,
2779-
(long)st.st_uid,
2780-
(long)st.st_gid,
2781-
(LONG_LONG)st.st_size,
2782-
(long)st.st_atime,
2783-
(long)st.st_mtime,
2784-
(long)st.st_ctime);
2785-
#endif
2818+
2819+
return _pystat_fromstructstat(st);
27862820
}
27872821

27882822

@@ -2863,8 +2897,8 @@ posix_pipe(self, args)
28632897
Py_END_ALLOW_THREADS
28642898
if (!ok)
28652899
return posix_error();
2866-
read_fd = _open_osfhandle((long)read, 0);
2867-
write_fd = _open_osfhandle((long)write, 1);
2900+
read_fd = _open_osfhandle((intptr_t)read, 0);
2901+
write_fd = _open_osfhandle((intptr_t)write, 1);
28682902
return Py_BuildValue("(ii)", read_fd, write_fd);
28692903
#endif /* MS_WIN32 */
28702904
#endif
@@ -3526,9 +3560,10 @@ conv_confname(arg, valuep, table, tablesize)
35263560
}
35273561
if (PyString_Check(arg)) {
35283562
/* look up the value in the table using a binary search */
3529-
int lo = 0;
3530-
int hi = tablesize;
3531-
int cmp, mid;
3563+
size_t lo = 0;
3564+
size_t mid;
3565+
size_t hi = tablesize;
3566+
int cmp;
35323567
char *confname = PyString_AS_STRING(arg);
35333568
while (lo < hi) {
35343569
mid = (lo + hi) / 2;

0 commit comments

Comments
 (0)