|
From: | Dr . Jürgen Sauermann |
Subject: | Re: SVN 1752: error in Command.cc doesn't compile on macOS |
Date: | Wed, 14 Feb 2024 18:45:32 +0100 |
User-agent: | Mozilla Thunderbird |
To get the file modification time, you query the st_mtimespec.tv_sec field of the struct stat returned by stat(). Both platforms are returning the file modification/access/status as a struct timestat to support both second and millisecond resolution. For some reason known only to Apple those fields returned in the struct stat are named differently.
The changed line in my earlier response has the necessary change.
- Paul
Sent from my iPhone
On Feb 14, 2024, at 3:43 AM, Dr. Jürgen Sauermann <mail@jürgen-sauermann.de> wrote:
Hi Paul,
thanks. Could you please have a look at your /usr/include/.../stat.h
file and let me know how to get the modification time (or a macro
that tells if it is present or absent)?
Thanks,
Jürgen
On 2/13/24 19:56, Paul Rockwell wrote:
When compiling SVN 1752 on macOS, an error is thrown by src/Command.cc:
g++ -DHAVE_CONFIG_H -I. -I.. -Wall -I sql -I /Volumes/MyPassport/paulrockwell/Documents/apl/trunk -I/opt/local/include -std=c++11 -I /Volumes/MyPassport/paulrockwell/Documents/apl/trunk -MT apl-Command.o -MD -MP -MF .deps/apl-Command.Tpo -c -o apl-Command.o `test -f 'Command.cc' || echo './'`Command.cc
Command.cc:2033:49: error: no member named 'st_mtim' in 'stat'
if (sort == SORT_TIME) return st.st_mtim.tv_sec;
~~ ^
Evidently on macOS the system-defined definition of struct stat is defined differently than on Linux (from "man 1 stat" on macOS):
The buf argument is a pointer to a stat structure as defined by ⟨sys/stat.h⟩ and into which information is
placed concerning the file. When the macro _DARWIN_FEATURE_64_BIT_INODE is not defined (see below for more
information about this macro), the stat structure is defined as:
struct stat { /* when _DARWIN_FEATURE_64_BIT_INODE is NOT defined */
dev_t st_dev; /* device inode resides on */
ino_t st_ino; /* inode's number */
mode_t st_mode; /* inode protection mode */
nlink_t st_nlink; /* number of hard links to the file */
uid_t st_uid; /* user-id of owner */
gid_t st_gid; /* group-id of owner */
dev_t st_rdev; /* device type, for special file inode */
struct timespec st_atimespec; /* time of last access */
struct timespec st_mtimespec; /* time of last data modification */
struct timespec st_ctimespec; /* time of last file status change */
off_t st_size; /* file size, in bytes */
quad_t st_blocks; /* blocks allocated for file */
u_long st_blksize;/* optimal file sys I/O ops blocksize */
u_long st_flags; /* user defined flags for file */
u_long st_gen; /* file generation number */
};
However, when the macro _DARWIN_FEATURE_64_BIT_INODE is defined, the stat structure will now be defined as:
struct stat { /* when _DARWIN_FEATURE_64_BIT_INODE is defined */
dev_t st_dev; /* ID of device containing file */
mode_t st_mode; /* Mode of file (see below) */
nlink_t st_nlink; /* Number of hard links */
ino_t st_ino; /* File serial number */
uid_t st_uid; /* User ID of the file */
gid_t st_gid; /* Group ID of the file */
dev_t st_rdev; /* Device ID */
struct timespec st_atimespec; /* time of last access */
struct timespec st_mtimespec; /* time of last data modification */
struct timespec st_ctimespec; /* time of last status change */
struct timespec st_birthtimespec; /* time of file creation(birth) */
off_t st_size; /* file size, in bytes */
blkcnt_t st_blocks; /* blocks allocated for file */
blksize_t st_blksize; /* optimal blocksize for I/O */
uint32_t st_flags; /* user defined flags for file */
uint32_t st_gen; /* file generation number */
int32_t st_lspare; /* RESERVED: DO NOT USE! */
int64_t st_qspare[2]; /* RESERVED: DO NOT USE! */
};
On Linux, the struct is defined as:
struct stat {
dev_t st_dev; /* ID of device containing file */
ino_t st_ino; /* Inode number */
mode_t st_mode; /* File type and mode */
nlink_t st_nlink; /* Number of hard links */
uid_t st_uid; /* User ID of owner */
gid_t st_gid; /* Group ID of owner */
dev_t st_rdev; /* Device ID (if special file) */
off_t st_size; /* Total size, in bytes */
blksize_t st_blksize; /* Block size for filesystem I/O */
blkcnt_t st_blocks; /* Number of 512 B blocks allocated */
/* Since POSIX.1-2008, this structure supports nanosecond
precision for the following timestamp fields.
For the details before POSIX.1-2008, see VERSIONS. */
struct timespec st_atim; /* Time of last access */
struct timespec st_mtim; /* Time of last modification */
struct timespec st_ctim; /* Time of last status change */
#define st_atime st_atim.tv_sec /* Backward compatibility */
#define st_mtime st_mtim.tv_sec
#define st_ctime st_ctim.tv_sec
};
struct timespec seems to be defined the same on both platforms.
struct stat seems to contain the same information as available on Linux, but the fields for st_atime, st_mtime, and st_ctime are named differently on the Mac. It appears that the Mac definitions may pre-date POSIX.1-2008. Maybe that's why the differences - perhaps Apple anticipated the updated standard but never went back to update the definitions once approved?
I've modified the source of Command.cc to change line 2033 from
if (sort == SORT_TIME) return st.st_mtim.tv_sec;
toif (sort == SORT_TIME) return st.st_mtimespec.tv_sec;
and the module compiles successfully. I can conditionalize this with #ifdef __APPLE__ like I did with my changes toBacktrace.cc, but thought I'd defer to you to determine how you want to handle this.
- Paul Rockwell
.
[Prev in Thread] | Current Thread | [Next in Thread] |