Patch #1180695: Implement nanosecond stat resolution on FreeBSD,

add st_gen, st_birthtime.
This commit is contained in:
Martin v. Löwis 2005-08-09 15:00:59 +00:00
parent 147fbe5a55
commit ebd9d5ba1a
6 changed files with 373 additions and 1 deletions

View File

@ -996,6 +996,12 @@ also be available:
\member{st_rdev} (type of device if an inode device). \member{st_rdev} (type of device if an inode device).
\member{st_flags} (user defined flags for file). \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: On Mac OS systems, the following attributes may also be available:
\member{st_rsize}, \member{st_rsize},
\member{st_creator}, \member{st_creator},
@ -1037,6 +1043,7 @@ Availability: Macintosh, \UNIX, Windows.
\versionchanged \versionchanged
[Added access to values as attributes of the returned object]{2.2} [Added access to values as attributes of the returned object]{2.2}
\versionchanged[Added st_gen, st_birthtime]{2.5}
\end{funcdesc} \end{funcdesc}
\begin{funcdesc}{stat_float_times}{\optional{newvalue}} \begin{funcdesc}{stat_float_times}{\optional{newvalue}}

View File

@ -121,6 +121,9 @@ Core and builtins
Extension Modules 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 - Patch #1231069: The fcntl.ioctl function now uses the 'I' code for
the request code argument, which results in more C-like behaviour the request code argument, which results in more C-like behaviour
for large or negative values. for large or negative values.

View File

@ -705,6 +705,12 @@ static PyStructSequence_Field stat_result_fields[] = {
#endif #endif
#ifdef HAVE_STRUCT_STAT_ST_FLAGS #ifdef HAVE_STRUCT_STAT_ST_FLAGS
{"st_flags", "user defined flags for file"}, {"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 #endif
{0} {0}
}; };
@ -733,6 +739,18 @@ static PyStructSequence_Field stat_result_fields[] = {
#define ST_FLAGS_IDX ST_RDEV_IDX #define ST_FLAGS_IDX ST_RDEV_IDX
#endif #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 = { static PyStructSequence_Desc stat_result_desc = {
"stat_result", /* name */ "stat_result", /* name */
stat_result__doc__, /* doc */ stat_result__doc__, /* doc */
@ -877,8 +895,14 @@ _pystat_fromstructstat(STRUCT_STAT st)
ansec = st.st_atim.tv_nsec; ansec = st.st_atim.tv_nsec;
mnsec = st.st_mtim.tv_nsec; mnsec = st.st_mtim.tv_nsec;
cnsec = st.st_ctim.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 #else
ansec = mnsec = cnsec = 0; ansec = mnsec = cnsec = 0;
#endif
#endif #endif
fill_time(v, 7, st.st_atime, ansec); fill_time(v, 7, st.st_atime, ansec);
fill_time(v, 8, st.st_mtime, mnsec); fill_time(v, 8, st.st_mtime, mnsec);
@ -896,6 +920,29 @@ _pystat_fromstructstat(STRUCT_STAT st)
PyStructSequence_SET_ITEM(v, ST_RDEV_IDX, PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
PyInt_FromLong((long)st.st_rdev)); PyInt_FromLong((long)st.st_rdev));
#endif #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 #ifdef HAVE_STRUCT_STAT_ST_FLAGS
PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX, PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
PyInt_FromLong((long)st.st_flags)); PyInt_FromLong((long)st.st_flags));

289
configure vendored
View File

@ -1,5 +1,5 @@
#! /bin/sh #! /bin/sh
# From configure.in Revision: 1.485 . # From configure.in Revision: 1.486 .
# Guess values for system-dependent variables and create Makefiles. # Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.59 for python 2.5. # Generated by GNU Autoconf 2.59 for python 2.5.
# #
@ -16524,6 +16524,226 @@ cat >>confdefs.h <<_ACEOF
_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 fi
echo "$as_me:$LINENO: checking for struct stat.st_blocks" >&5 echo "$as_me:$LINENO: checking for struct stat.st_blocks" >&5
@ -20266,6 +20486,73 @@ _ACEOF
fi 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 # 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 "$as_me:$LINENO: checking whether mvwdelch is an expression" >&5
echo $ECHO_N "checking whether mvwdelch is an expression... $ECHO_C" >&6 echo $ECHO_N "checking whether mvwdelch is an expression... $ECHO_C" >&6

View File

@ -2424,6 +2424,8 @@ AC_STRUCT_TIMEZONE
AC_CHECK_MEMBERS([struct stat.st_rdev]) AC_CHECK_MEMBERS([struct stat.st_rdev])
AC_CHECK_MEMBERS([struct stat.st_blksize]) AC_CHECK_MEMBERS([struct stat.st_blksize])
AC_CHECK_MEMBERS([struct stat.st_flags]) 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_STRUCT_ST_BLOCKS
AC_MSG_CHECKING(for time.h that defines altzone) AC_MSG_CHECKING(for time.h that defines altzone)
@ -3042,6 +3044,23 @@ then
[Define if you have struct stat.st_mtim.tv_nsec]) [Define if you have struct stat.st_mtim.tv_nsec])
fi 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 # On HP/UX 11.0, mvwdelch is a block with a return statement
AC_MSG_CHECKING(whether mvwdelch is an expression) AC_MSG_CHECKING(whether mvwdelch is an expression)
AC_CACHE_VAL(ac_cv_mvwdelch_is_expression, AC_CACHE_VAL(ac_cv_mvwdelch_is_expression,

View File

@ -455,6 +455,9 @@
/* Define if you have struct stat.st_mtim.tv_nsec */ /* Define if you have struct stat.st_mtim.tv_nsec */
#undef HAVE_STAT_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. /* Define if your compiler supports variable length function prototypes (e.g.
void fprintf(FILE *, char *, ...);) *and* <stdarg.h> */ void fprintf(FILE *, char *, ...);) *and* <stdarg.h> */
#undef HAVE_STDARG_PROTOTYPES #undef HAVE_STDARG_PROTOTYPES
@ -483,6 +486,9 @@
/* Define to 1 if you have the <stropts.h> header file. */ /* Define to 1 if you have the <stropts.h> header file. */
#undef HAVE_STROPTS_H #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'. */ /* Define to 1 if `st_blksize' is member of `struct stat'. */
#undef HAVE_STRUCT_STAT_ST_BLKSIZE #undef HAVE_STRUCT_STAT_ST_BLKSIZE
@ -492,6 +498,9 @@
/* Define to 1 if `st_flags' is member of `struct stat'. */ /* Define to 1 if `st_flags' is member of `struct stat'. */
#undef HAVE_STRUCT_STAT_ST_FLAGS #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'. */ /* Define to 1 if `st_rdev' is member of `struct stat'. */
#undef HAVE_STRUCT_STAT_ST_RDEV #undef HAVE_STRUCT_STAT_ST_RDEV