Skip to content

Commit

Permalink
FEAT: improved file-related time values precision on POSIX platforms …
Browse files Browse the repository at this point in the history
…and resolved correct creation time on Linux (when possible)

resolves: Oldes/Rebol-issues#2626
related to: Oldes/Rebol-issues#2624
  • Loading branch information
Oldes committed Oct 1, 2024
1 parent 5a669cb commit 5aa41b0
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 4 deletions.
2 changes: 1 addition & 1 deletion src/core/p-file.c
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,7 @@ REBINT Mode_Syms[] = {
REBINT result, error;
REBOOL opened = FALSE; // had to be opened (shortcut case)

//Print("FILE ACTION: %r", Get_Action_Word(action));
//Debug_Fmt_("FILE ACTION: %r\n", Get_Action_Word(action));

port = Validate_Port_With_Request(port_value, RDI_FILE, &file);

Expand Down
77 changes: 75 additions & 2 deletions src/os/posix/dev-file.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <errno.h>
Expand All @@ -52,6 +51,51 @@
#include "reb-host.h"
#include "host-lib.h"

#ifdef TO_LINUX
#include <linux/stat.h>
//#include <linux/fcntl.h>
#include <fcntl.h>
#define statx foo
#define statx_timestamp foo_timestamp
struct statx;
struct statx_timestamp;
#include <sys/stat.h>
#undef statx
#undef statx_timestamp

#define AT_STATX_SYNC_TYPE 0x6000
#define AT_STATX_SYNC_AS_STAT 0x0000
#define AT_STATX_FORCE_SYNC 0x2000
#define AT_STATX_DONT_SYNC 0x4000

// Manually define SYS_statx if not present in the system headers
# ifndef SYS_statx
# if defined __aarch64__ || defined __arm__
# define SYS_statx 397
# elif defined __alpha__
# define SYS_statx 522
# elif defined __i386__ || defined __powerpc64__
# define SYS_statx 383
# elif defined __sparc__
# define SYS_statx 360
# elif defined __x86_64__
# define SYS_statx 332
# else
# warning "SYS_statx not defined for your architecture"
# endif
# endif

static __attribute__((unused))
ssize_t statx(int dfd, const char *filename, unsigned flags, unsigned int mask, struct statx *buffer)
{
return syscall(SYS_statx, dfd, filename, flags, mask, buffer);
}
#else
// stat on non Linux systems
#include <sys/stat.h>
#endif


#ifndef O_BINARY
#define O_BINARY 0
#endif
Expand All @@ -64,6 +108,7 @@
#define S_IWRITE S_IWUSR
#endif


// NOTE: the code below assumes a file id will never by zero. This should
// be safe. In posix, zero is stdin, which is handled by dev-stdio.c.

Expand Down Expand Up @@ -126,6 +171,34 @@ static REBOOL Seek_File_64(REBREQ *file)

static int Get_File_Info(REBREQ *file)
{
#ifdef SYS_statx
struct statx infox;
if (statx(AT_FDCWD | AT_STATX_FORCE_SYNC, file->file.path, 0, STATX_BASIC_STATS | STATX_BTIME, &infox) == -1) {
goto use_stat;
}

if (S_ISDIR(infox.stx_mode)) {
SET_FLAG(file->modes, RFM_DIR);
file->file.size = MIN_I64; // using MIN_I64 to notify, that size should be reported as NONE
}
else {
CLR_FLAG(file->modes, RFM_DIR);
file->file.size = infox.stx_size;
}
file->file.modified_time.l = (i32)(infox.stx_mtime.tv_sec);
file->file.accessed_time.l = (i32)(infox.stx_atime.tv_sec);
file->file.modified_time.h = (i32)(infox.stx_mtime.tv_nsec);
file->file.accessed_time.h = (i32)(infox.stx_atime.tv_nsec);

if (infox.stx_btime.tv_sec) {
file->file.created_time.l = (i32)(infox.stx_btime.tv_sec);
file->file.created_time.h = (i32)(infox.stx_btime.tv_nsec);
} else {
file->file.created_time = file->file.modified_time;
}
return DR_DONE;
#endif
use_stat:
struct stat info;

if (stat(file->file.path, &info)) {
Expand All @@ -143,7 +216,7 @@ static int Get_File_Info(REBREQ *file)
}
file->file.modified_time.l = (i32)(info.st_mtime);
file->file.accessed_time.l = (i32)(info.st_atime);
file->file.created_time.l = (i32)(info.st_ctime);
file->file.created_time.l = (i32)(info.st_ctime);

return DR_DONE;
}
Expand Down
5 changes: 4 additions & 1 deletion src/os/posix/host-lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -723,7 +723,10 @@ RL_LIB *RL; // Link back to reb-lib from embedded extensions (like for now: host
**
***********************************************************************/
{
Convert_Date((time_t *)&time->l, dat, 0);
time_t stime;
stime = time->l;
Convert_Date(&stime, dat, 0);
dat->nano = time->h;
}


Expand Down

0 comments on commit 5aa41b0

Please sign in to comment.