Patch #1180695: Implement nanosecond stat resolution on FreeBSD,
add st_gen, st_birthtime.
This commit is contained in:
parent
147fbe5a55
commit
ebd9d5ba1a
|
@ -996,6 +996,12 @@ also be available:
|
|||
\member{st_rdev} (type of device if an inode device).
|
||||
\member{st_flags} (user defined flags for file).
|
||||
|
||||
On other Unix systems (such as FreeBSD), the following attributes
|
||||
may be available (but may be only filled out of root tries to
|
||||
use them:
|
||||
\member{st_gen} (file generation number),
|
||||
\member{st_birthtime} (time of file creation).
|
||||
|
||||
On Mac OS systems, the following attributes may also be available:
|
||||
\member{st_rsize},
|
||||
\member{st_creator},
|
||||
|
@ -1037,6 +1043,7 @@ Availability: Macintosh, \UNIX, Windows.
|
|||
|
||||
\versionchanged
|
||||
[Added access to values as attributes of the returned object]{2.2}
|
||||
\versionchanged[Added st_gen, st_birthtime]{2.5}
|
||||
\end{funcdesc}
|
||||
|
||||
\begin{funcdesc}{stat_float_times}{\optional{newvalue}}
|
||||
|
|
|
@ -121,6 +121,9 @@ Core and builtins
|
|||
Extension Modules
|
||||
-----------------
|
||||
|
||||
- Patch #1180695: Add nanosecond stat resolution, and st_gen,
|
||||
st_birthtime for FreeBSD.
|
||||
|
||||
- Patch #1231069: The fcntl.ioctl function now uses the 'I' code for
|
||||
the request code argument, which results in more C-like behaviour
|
||||
for large or negative values.
|
||||
|
|
|
@ -705,6 +705,12 @@ static PyStructSequence_Field stat_result_fields[] = {
|
|||
#endif
|
||||
#ifdef HAVE_STRUCT_STAT_ST_FLAGS
|
||||
{"st_flags", "user defined flags for file"},
|
||||
#endif
|
||||
#ifdef HAVE_STRUCT_STAT_ST_GEN
|
||||
{"st_gen", "generation number"},
|
||||
#endif
|
||||
#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
|
||||
{"st_birthtime", "time of creation"},
|
||||
#endif
|
||||
{0}
|
||||
};
|
||||
|
@ -733,6 +739,18 @@ static PyStructSequence_Field stat_result_fields[] = {
|
|||
#define ST_FLAGS_IDX ST_RDEV_IDX
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STRUCT_STAT_ST_GEN
|
||||
#define ST_GEN_IDX (ST_RDEV_IDX+1)
|
||||
#else
|
||||
#define ST_GEN_IDX ST_RDEV_IDX
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
|
||||
#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
|
||||
#else
|
||||
#define ST_BIRTHTIME_IDX ST_GEN_IDX
|
||||
#endif
|
||||
|
||||
static PyStructSequence_Desc stat_result_desc = {
|
||||
"stat_result", /* name */
|
||||
stat_result__doc__, /* doc */
|
||||
|
@ -877,8 +895,14 @@ _pystat_fromstructstat(STRUCT_STAT st)
|
|||
ansec = st.st_atim.tv_nsec;
|
||||
mnsec = st.st_mtim.tv_nsec;
|
||||
cnsec = st.st_ctim.tv_nsec;
|
||||
#else
|
||||
#ifdef HAVE_STAT_TV_NSEC2
|
||||
ansec = st.st_atimespec.tv_nsec;
|
||||
mnsec = st.st_mtimespec.tv_nsec;
|
||||
cnsec = st.st_ctimespec.tv_nsec;
|
||||
#else
|
||||
ansec = mnsec = cnsec = 0;
|
||||
#endif
|
||||
#endif
|
||||
fill_time(v, 7, st.st_atime, ansec);
|
||||
fill_time(v, 8, st.st_mtime, mnsec);
|
||||
|
@ -896,6 +920,29 @@ _pystat_fromstructstat(STRUCT_STAT st)
|
|||
PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
|
||||
PyInt_FromLong((long)st.st_rdev));
|
||||
#endif
|
||||
#ifdef HAVE_STRUCT_STAT_ST_GEN
|
||||
PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
|
||||
PyInt_FromLong((long)st.st_gen));
|
||||
#endif
|
||||
#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
|
||||
{
|
||||
PyObject *val;
|
||||
unsigned long bsec,bnsec;
|
||||
bsec = (long)st.st_birthtime;
|
||||
#ifdef HAVE_STAT_TV_NSEC2
|
||||
bnsec = st.st_birthtimespec.tv_nsec;
|
||||
#else
|
||||
bnsec = 0;
|
||||
#endif
|
||||
if (_stat_float_times) {
|
||||
val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
|
||||
} else {
|
||||
val = PyInt_FromLong((long)bsec);
|
||||
}
|
||||
PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
|
||||
val);
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_STRUCT_STAT_ST_FLAGS
|
||||
PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
|
||||
PyInt_FromLong((long)st.st_flags));
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#! /bin/sh
|
||||
# From configure.in Revision: 1.485 .
|
||||
# From configure.in Revision: 1.486 .
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.59 for python 2.5.
|
||||
#
|
||||
|
@ -16524,6 +16524,226 @@ cat >>confdefs.h <<_ACEOF
|
|||
_ACEOF
|
||||
|
||||
|
||||
fi
|
||||
|
||||
echo "$as_me:$LINENO: checking for struct stat.st_gen" >&5
|
||||
echo $ECHO_N "checking for struct stat.st_gen... $ECHO_C" >&6
|
||||
if test "${ac_cv_member_struct_stat_st_gen+set}" = set; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
else
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
/* confdefs.h. */
|
||||
_ACEOF
|
||||
cat confdefs.h >>conftest.$ac_ext
|
||||
cat >>conftest.$ac_ext <<_ACEOF
|
||||
/* end confdefs.h. */
|
||||
$ac_includes_default
|
||||
int
|
||||
main ()
|
||||
{
|
||||
static struct stat ac_aggr;
|
||||
if (ac_aggr.st_gen)
|
||||
return 0;
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
rm -f conftest.$ac_objext
|
||||
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
|
||||
(eval $ac_compile) 2>conftest.er1
|
||||
ac_status=$?
|
||||
grep -v '^ *+' conftest.er1 >conftest.err
|
||||
rm -f conftest.er1
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } &&
|
||||
{ ac_try='test -z "$ac_c_werror_flag"
|
||||
|| test ! -s conftest.err'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); }; } &&
|
||||
{ ac_try='test -s conftest.$ac_objext'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); }; }; then
|
||||
ac_cv_member_struct_stat_st_gen=yes
|
||||
else
|
||||
echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
/* confdefs.h. */
|
||||
_ACEOF
|
||||
cat confdefs.h >>conftest.$ac_ext
|
||||
cat >>conftest.$ac_ext <<_ACEOF
|
||||
/* end confdefs.h. */
|
||||
$ac_includes_default
|
||||
int
|
||||
main ()
|
||||
{
|
||||
static struct stat ac_aggr;
|
||||
if (sizeof ac_aggr.st_gen)
|
||||
return 0;
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
rm -f conftest.$ac_objext
|
||||
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
|
||||
(eval $ac_compile) 2>conftest.er1
|
||||
ac_status=$?
|
||||
grep -v '^ *+' conftest.er1 >conftest.err
|
||||
rm -f conftest.er1
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } &&
|
||||
{ ac_try='test -z "$ac_c_werror_flag"
|
||||
|| test ! -s conftest.err'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); }; } &&
|
||||
{ ac_try='test -s conftest.$ac_objext'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); }; }; then
|
||||
ac_cv_member_struct_stat_st_gen=yes
|
||||
else
|
||||
echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
ac_cv_member_struct_stat_st_gen=no
|
||||
fi
|
||||
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
fi
|
||||
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
fi
|
||||
echo "$as_me:$LINENO: result: $ac_cv_member_struct_stat_st_gen" >&5
|
||||
echo "${ECHO_T}$ac_cv_member_struct_stat_st_gen" >&6
|
||||
if test $ac_cv_member_struct_stat_st_gen = yes; then
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_STRUCT_STAT_ST_GEN 1
|
||||
_ACEOF
|
||||
|
||||
|
||||
fi
|
||||
|
||||
echo "$as_me:$LINENO: checking for struct stat.st_birthtime" >&5
|
||||
echo $ECHO_N "checking for struct stat.st_birthtime... $ECHO_C" >&6
|
||||
if test "${ac_cv_member_struct_stat_st_birthtime+set}" = set; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
else
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
/* confdefs.h. */
|
||||
_ACEOF
|
||||
cat confdefs.h >>conftest.$ac_ext
|
||||
cat >>conftest.$ac_ext <<_ACEOF
|
||||
/* end confdefs.h. */
|
||||
$ac_includes_default
|
||||
int
|
||||
main ()
|
||||
{
|
||||
static struct stat ac_aggr;
|
||||
if (ac_aggr.st_birthtime)
|
||||
return 0;
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
rm -f conftest.$ac_objext
|
||||
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
|
||||
(eval $ac_compile) 2>conftest.er1
|
||||
ac_status=$?
|
||||
grep -v '^ *+' conftest.er1 >conftest.err
|
||||
rm -f conftest.er1
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } &&
|
||||
{ ac_try='test -z "$ac_c_werror_flag"
|
||||
|| test ! -s conftest.err'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); }; } &&
|
||||
{ ac_try='test -s conftest.$ac_objext'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); }; }; then
|
||||
ac_cv_member_struct_stat_st_birthtime=yes
|
||||
else
|
||||
echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
/* confdefs.h. */
|
||||
_ACEOF
|
||||
cat confdefs.h >>conftest.$ac_ext
|
||||
cat >>conftest.$ac_ext <<_ACEOF
|
||||
/* end confdefs.h. */
|
||||
$ac_includes_default
|
||||
int
|
||||
main ()
|
||||
{
|
||||
static struct stat ac_aggr;
|
||||
if (sizeof ac_aggr.st_birthtime)
|
||||
return 0;
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
rm -f conftest.$ac_objext
|
||||
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
|
||||
(eval $ac_compile) 2>conftest.er1
|
||||
ac_status=$?
|
||||
grep -v '^ *+' conftest.er1 >conftest.err
|
||||
rm -f conftest.er1
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } &&
|
||||
{ ac_try='test -z "$ac_c_werror_flag"
|
||||
|| test ! -s conftest.err'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); }; } &&
|
||||
{ ac_try='test -s conftest.$ac_objext'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); }; }; then
|
||||
ac_cv_member_struct_stat_st_birthtime=yes
|
||||
else
|
||||
echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
ac_cv_member_struct_stat_st_birthtime=no
|
||||
fi
|
||||
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
fi
|
||||
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
fi
|
||||
echo "$as_me:$LINENO: result: $ac_cv_member_struct_stat_st_birthtime" >&5
|
||||
echo "${ECHO_T}$ac_cv_member_struct_stat_st_birthtime" >&6
|
||||
if test $ac_cv_member_struct_stat_st_birthtime = yes; then
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_STRUCT_STAT_ST_BIRTHTIME 1
|
||||
_ACEOF
|
||||
|
||||
|
||||
fi
|
||||
|
||||
echo "$as_me:$LINENO: checking for struct stat.st_blocks" >&5
|
||||
|
@ -20266,6 +20486,73 @@ _ACEOF
|
|||
|
||||
fi
|
||||
|
||||
# Look for BSD style subsecond timestamps in struct stat
|
||||
echo "$as_me:$LINENO: checking for tv_nsec2 in struct stat" >&5
|
||||
echo $ECHO_N "checking for tv_nsec2 in struct stat... $ECHO_C" >&6
|
||||
if test "${ac_cv_stat_tv_nsec2+set}" = set; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
else
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
/* confdefs.h. */
|
||||
_ACEOF
|
||||
cat confdefs.h >>conftest.$ac_ext
|
||||
cat >>conftest.$ac_ext <<_ACEOF
|
||||
/* end confdefs.h. */
|
||||
#include <sys/stat.h>
|
||||
int
|
||||
main ()
|
||||
{
|
||||
|
||||
struct stat st;
|
||||
st.st_mtimespec.tv_nsec = 1;
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
rm -f conftest.$ac_objext
|
||||
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
|
||||
(eval $ac_compile) 2>conftest.er1
|
||||
ac_status=$?
|
||||
grep -v '^ *+' conftest.er1 >conftest.err
|
||||
rm -f conftest.er1
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } &&
|
||||
{ ac_try='test -z "$ac_c_werror_flag"
|
||||
|| test ! -s conftest.err'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); }; } &&
|
||||
{ ac_try='test -s conftest.$ac_objext'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); }; }; then
|
||||
ac_cv_stat_tv_nsec2=yes
|
||||
else
|
||||
echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
ac_cv_stat_tv_nsec2=no
|
||||
fi
|
||||
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
fi
|
||||
|
||||
echo "$as_me:$LINENO: result: $ac_cv_stat_tv_nsec2" >&5
|
||||
echo "${ECHO_T}$ac_cv_stat_tv_nsec2" >&6
|
||||
if test "$ac_cv_stat_tv_nsec2" = yes
|
||||
then
|
||||
|
||||
cat >>confdefs.h <<\_ACEOF
|
||||
#define HAVE_STAT_TV_NSEC2 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
|
||||
# On HP/UX 11.0, mvwdelch is a block with a return statement
|
||||
echo "$as_me:$LINENO: checking whether mvwdelch is an expression" >&5
|
||||
echo $ECHO_N "checking whether mvwdelch is an expression... $ECHO_C" >&6
|
||||
|
|
19
configure.in
19
configure.in
|
@ -2424,6 +2424,8 @@ AC_STRUCT_TIMEZONE
|
|||
AC_CHECK_MEMBERS([struct stat.st_rdev])
|
||||
AC_CHECK_MEMBERS([struct stat.st_blksize])
|
||||
AC_CHECK_MEMBERS([struct stat.st_flags])
|
||||
AC_CHECK_MEMBERS([struct stat.st_gen])
|
||||
AC_CHECK_MEMBERS([struct stat.st_birthtime])
|
||||
AC_STRUCT_ST_BLOCKS
|
||||
|
||||
AC_MSG_CHECKING(for time.h that defines altzone)
|
||||
|
@ -3042,6 +3044,23 @@ then
|
|||
[Define if you have struct stat.st_mtim.tv_nsec])
|
||||
fi
|
||||
|
||||
# Look for BSD style subsecond timestamps in struct stat
|
||||
AC_MSG_CHECKING(for tv_nsec2 in struct stat)
|
||||
AC_CACHE_VAL(ac_cv_stat_tv_nsec2,
|
||||
AC_TRY_COMPILE([#include <sys/stat.h>], [
|
||||
struct stat st;
|
||||
st.st_mtimespec.tv_nsec = 1;
|
||||
],
|
||||
ac_cv_stat_tv_nsec2=yes,
|
||||
ac_cv_stat_tv_nsec2=no,
|
||||
ac_cv_stat_tv_nsec2=no))
|
||||
AC_MSG_RESULT($ac_cv_stat_tv_nsec2)
|
||||
if test "$ac_cv_stat_tv_nsec2" = yes
|
||||
then
|
||||
AC_DEFINE(HAVE_STAT_TV_NSEC2, 1,
|
||||
[Define if you have struct stat.st_mtimensec])
|
||||
fi
|
||||
|
||||
# On HP/UX 11.0, mvwdelch is a block with a return statement
|
||||
AC_MSG_CHECKING(whether mvwdelch is an expression)
|
||||
AC_CACHE_VAL(ac_cv_mvwdelch_is_expression,
|
||||
|
|
|
@ -455,6 +455,9 @@
|
|||
/* Define if you have struct stat.st_mtim.tv_nsec */
|
||||
#undef HAVE_STAT_TV_NSEC
|
||||
|
||||
/* Define if you have struct stat.st_mtimensec */
|
||||
#undef HAVE_STAT_TV_NSEC2
|
||||
|
||||
/* Define if your compiler supports variable length function prototypes (e.g.
|
||||
void fprintf(FILE *, char *, ...);) *and* <stdarg.h> */
|
||||
#undef HAVE_STDARG_PROTOTYPES
|
||||
|
@ -483,6 +486,9 @@
|
|||
/* Define to 1 if you have the <stropts.h> header file. */
|
||||
#undef HAVE_STROPTS_H
|
||||
|
||||
/* Define to 1 if `st_birthtime' is member of `struct stat'. */
|
||||
#undef HAVE_STRUCT_STAT_ST_BIRTHTIME
|
||||
|
||||
/* Define to 1 if `st_blksize' is member of `struct stat'. */
|
||||
#undef HAVE_STRUCT_STAT_ST_BLKSIZE
|
||||
|
||||
|
@ -492,6 +498,9 @@
|
|||
/* Define to 1 if `st_flags' is member of `struct stat'. */
|
||||
#undef HAVE_STRUCT_STAT_ST_FLAGS
|
||||
|
||||
/* Define to 1 if `st_gen' is member of `struct stat'. */
|
||||
#undef HAVE_STRUCT_STAT_ST_GEN
|
||||
|
||||
/* Define to 1 if `st_rdev' is member of `struct stat'. */
|
||||
#undef HAVE_STRUCT_STAT_ST_RDEV
|
||||
|
||||
|
|
Loading…
Reference in New Issue