# define STAT_NSEC(st, st_xtim) ((st)->st_xtim##espec.tv_nsec)
#endif
+/* Implement a macro to handle multiple formats (integer, float, and array
+ * containing seconds and nanoseconds). */
+#define PULL_TIME(st, st_xtim, svp) \
+{ \
+ SV *sv = svp; \
+ if (SvROK(sv)) { \
+ AV *av = (AV *)SvRV(sv); \
+ if (SvTYPE((SV *)av) != SVt_PVAV) { \
+ Perl_croak_nocontext("Reference was not array ref"); \
+ } \
+ if (av_len(av) != 1) { \
+ Perl_croak_nocontext("Array of incorrect dimension"); \
+ } \
+ (st)->st_xtim##e = SvIV(*(av_fetch(av, 0, FALSE))); \
+ STAT_NSEC(st, st_xtim) = SvIV(*(av_fetch(av, 1, FALSE))); \
+ } \
+ else if (SvNOK(sv) || SvIOK(sv)) { \
+ double tm = SvNV(sv); \
+ (st)->st_xtim##e = (int)tm; \
+ STAT_NSEC(st, st_xtim) = (tm - (int)tm) * 1000000000; \
+ } \
+ else { \
+ Perl_croak_nocontext("Invalid data type passed"); \
+ } \
+}
+
/* Determine if threads support should be included */
#ifdef USE_ITHREADS
# ifdef I_PTHREAD
else
rv = -ENOENT;
} else {
- double tm;
result->st_blocks = POPi;
result->st_blksize = POPi;
- /* Do a little gymnastics to transform the fractional part into nsec */
- tm = POPn;
- result->st_ctime = (int)tm;
- STAT_NSEC(result, st_ctim) = (tm - (int)tm) * 1000000000;
- tm = POPn;
- result->st_mtime = (int)tm;
- STAT_NSEC(result, st_mtim) = (tm - (int)tm) * 1000000000;
- tm = POPn;
- result->st_atime = (int)tm;
- STAT_NSEC(result, st_atim) = (tm - (int)tm) * 1000000000;
+ PULL_TIME(result, st_ctim, POPs);
+ PULL_TIME(result, st_mtim, POPs);
+ PULL_TIME(result, st_atim, POPs);
result->st_size = POPn; // we pop double here to support files larger than 4Gb (long limit)
result->st_rdev = POPi;
result->st_gid = POPi;
if (SvROK(*svp) &&
SvTYPE(av2 = (AV *)SvRV(*svp)) == SVt_PVAV &&
av_len(av2) == 12) {
- double tm;
st.st_dev = SvIV(*(av_fetch(av2, 0, FALSE)));
st.st_ino = SvIV(*(av_fetch(av2, 1, FALSE)));
st.st_mode = SvIV(*(av_fetch(av2, 2, FALSE)));
st.st_gid = SvIV(*(av_fetch(av2, 5, FALSE)));
st.st_rdev = SvIV(*(av_fetch(av2, 6, FALSE)));
st.st_size = SvNV(*(av_fetch(av2, 7, FALSE)));
- tm = SvNV(*(av_fetch(av2, 8, FALSE)));
- st.st_atime = (int)tm;
- STAT_NSEC(&st, st_atim) = (tm - (int)tm) * 1000000000;
- tm = SvNV(*(av_fetch(av2, 9, FALSE)));
- st.st_mtime = (int)tm;
- STAT_NSEC(&st, st_mtim) = (tm - (int)tm) * 1000000000;
- tm = SvNV(*(av_fetch(av2, 10, FALSE)));
- st.st_ctime = (int)tm;
- STAT_NSEC(&st, st_ctim) = (tm - (int)tm) * 1000000000;
+ PULL_TIME(&st, st_atim, *(av_fetch(av2, 8, FALSE)));
+ PULL_TIME(&st, st_mtim, *(av_fetch(av2, 9, FALSE)));
+ PULL_TIME(&st, st_ctim, *(av_fetch(av2, 10, FALSE)));
st.st_blksize = SvIV(*(av_fetch(av2, 11, FALSE)));
st.st_blocks = SvIV(*(av_fetch(av2, 12, FALSE)));
st_filled = 1;
else
rv = -ENOENT;
} else {
- double tm;
result->st_blocks = POPi;
result->st_blksize = POPi;
- /* Do a little gymnastics to transform the fractional part into nsec */
- tm = POPn;
- result->st_ctime = (int)tm;
- STAT_NSEC(result, st_ctim) = (tm - (int)tm) * 1000000000;
- tm = POPn;
- result->st_mtime = (int)tm;
- STAT_NSEC(result, st_mtim) = (tm - (int)tm) * 1000000000;
- tm = POPn;
- result->st_atime = (int)tm;
- STAT_NSEC(result, st_atim) = (tm - (int)tm) * 1000000000;
+ PULL_TIME(result, st_ctim, POPs);
+ PULL_TIME(result, st_mtim, POPs);
+ PULL_TIME(result, st_atim, POPs);
result->st_size = POPn; // we pop double here to support files larger than 4Gb (long limit)
result->st_rdev = POPi;
result->st_gid = POPi;