}
}
break;
-#ifdef HAS_UTIME
+#if defined(HAS_UTIME) || defined(HAS_FUTIMES)
case OP_UTIME:
what = "utime";
APPLY_TAINT_PROPER();
if (sp - mark > 2) {
-#if defined(I_UTIME) || defined(VMS)
+#if defined(HAS_FUTIMES)
+ struct timeval utbuf[2];
+ void *utbufp = utbuf;
+#elif defined(I_UTIME) || defined(VMS)
struct utimbuf utbuf;
struct utimbuf *utbufp = &utbuf;
#else
utbufp = NULL;
else {
Zero(&utbuf, sizeof utbuf, char);
-#ifdef BIG_TIME
+#ifdef HAS_FUTIMES
+ utbuf[0].tv_sec = (long)SvIVx(accessed); /* time accessed */
+ utbuf[0].tv_usec = 0;
+ utbuf[1].tv_sec = (long)SvIVx(modified); /* time modified */
+ utbuf[1].tv_usec = 0;
+#elif defined(BIG_TIME)
utbuf.actime = (Time_t)SvNVx(accessed); /* time accessed */
utbuf.modtime = (Time_t)SvNVx(modified); /* time modified */
#else
APPLY_TAINT_PROPER();
tot = sp - mark;
while (++mark <= sp) {
- char *name = SvPV_nolen(*mark);
- APPLY_TAINT_PROPER();
- if (PerlLIO_utime(name, utbufp))
- tot--;
+ GV* gv;
+ if (SvTYPE(*mark) == SVt_PVGV) {
+ gv = (GV*)*mark;
+ do_futimes:
+ if (GvIO(gv) && IoIFP(GvIOp(gv))) {
+#ifdef HAS_FUTIMES
+ APPLY_TAINT_PROPER();
+ if (futimes(PerlIO_fileno(IoIFP(GvIOn(gv))), utbufp))
+ tot--;
+#else
+ Perl_die(aTHX_ PL_no_func, "futimes");
+#endif
+ }
+ else {
+ tot--;
+ }
+ }
+ else if (SvROK(*mark) && SvTYPE(SvRV(*mark)) == SVt_PVGV) {
+ gv = (GV*)SvRV(*mark);
+ goto do_futimes;
+ }
+ else {
+ const char *name = SvPV_nolen_const(*mark);
+ APPLY_TAINT_PROPER();
+#ifdef HAS_FUTIMES
+ if (utimes(name, utbufp))
+#else
+ if (PerlLIO_utime(name, utbufp))
+#endif
+ tot--;
+ }
+
}
}
else
my $skip_mode_checks =
$^O eq 'cygwin' && $ENV{CYGWIN} !~ /ntsec/;
-plan tests => 42;
+plan tests => 49;
if (($^O eq 'MSWin32') || ($^O eq 'NetWare')) {
$delta = $accurate_timestamps ? 1 : 2; # Granularity of time on the filesystem
chmod 0777, 'b';
-$foo = (utime 500000000,500000000 + $delta,'b');
+$foo = (utime 500000000,500000000 + $delta,'b');
is($foo, 1, "utime");
+check_utime_result();
+
+utime undef, undef, 'b';
+($atime,$mtime) = (stat 'b')[8,9];
+print "# utime undef, undef --> $atime, $mtime\n";
+isnt($atime, 500000000, 'atime');
+isnt($mtime, 500000000 + $delta, 'mtime');
+
+SKIP: {
+ skip "no futimes", 4 unless ($Config{d_futimes} || "") eq "define";
+ open(my $fh, "<", 'b');
+ $foo = (utime 500000000,500000000 + $delta, $fh);
+ is($foo, 1, "futime");
+ check_utime_result();
+}
+
+sub check_utime_result {
($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,
$blksize,$blocks) = stat('b');
}
}
}
+}
+
+SKIP: {
+ skip "has futimes", 1 if ($Config{d_futimes} || "") eq "define";
+ open(my $fh, "<", "b") || die;
+ eval { utime(undef, undef, $fh); };
+ like($@, qr/^The futimes function is unimplemented at/, "futimes is unimplemented");
+}
is(unlink('b'), 1, "unlink b");