Skip Menu |

This queue is for tickets about the Time-HiRes CPAN distribution.

Report information
The Basics
Id: 132753
Status: new
Priority: 0/
Queue: Time-HiRes

People
Owner: Nobody in particular
Requestors: ppisar [...] redhat.com
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: 1.9760
Fixed in: (no value)



Subject: Bad check for futimens() and utimensat()
Makefile.PL checks for presence of futimens() with this program: #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include <sys/stat.h> int main(int argc, char** argv) { int ret1, ret2; struct timespec ts1[2], ts2[2]; ret1 = futimens(0, ts1); char buf[1]; read(0, buf, 0); /* Assuming reading nothing updates atime (the [0]) */ ret2 = futimens(0, ts2); ret1 == 0 && ret2 == 0 && (ts1[0].tv_nsec != 0 || ts2[0].tv_nsec != 0) ? exit(0) : exit(errno ? errno : -1); } Clang compiler warns that ts1[0].tv_nsec is unitialized. And that's true because futimens() does not write into the timespec structure. After reading the code I think that an author of the test mistaken stat() and futimens() calls. futimens() is used to copy a timespec argument value into a file system. While stat() is used for retrieving the time stamp from the file system.
Dne Po 01.čen.2020 08:33:40, ppisar napsal(a): Show quoted text
> Clang compiler warns that ts1[0].tv_nsec is unitialized. And that's > true because futimens() does not write into the timespec structure. > > After reading the code I think that an author of the test mistaken > stat() and futimens() calls. futimens() is used to copy a timespec > argument value into a file system. While stat() is used for retrieving > the time stamp from the file system.
There other issues with the test. E.g. futimens() requires that the user is an owner of the file. But /dev/stdin is a symlink to /dev/pts/... file owned by a superuser on my system. Here is completely reworked test that works for me: #define _POSIX_C_SOURCE 200809L #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <errno.h> int main(int argc, char** argv) { int fd, saved_errno; struct stat sb1, sb2; struct timespec ts[2]; ts[0].tv_nsec = ts[1].tv_nsec = 42; /* Not to hit UTIME_OMIT and UTIME_NOW */ if (argc < 1) exit(-1); fd = open(argv[0], O_RDONLY); /* futimens() requires a file owned by the process user */ if (fd == -1) exit(-1); if (-1 == fstat(fd, &sb1)) { close(fd); exit(-1); } if (-1 == futimens(fd, ts)) { saved_errno = errno; close(fd); exit(saved_errno ? saved_errno : -1); } if (-1 == fstat(fd, &sb2)) { close(fd); exit(-1); } close(fd); exit((sb1.st_mtim.tv_sec == sb2.st_mtim.tv_sec && sb1.st_mtim.tv_nsec == sb2.st_mtim.tv_nsec) ? -1 : 0); }