egallesio / STklos

STklos Scheme
http://stklos.net
GNU General Public License v2.0
69 stars 17 forks source link

implicit declaration of function 'utimensat' #518

Closed ryandesign closed 1 year ago

ryandesign commented 1 year ago

stklos 1.70 and git master fail to build on older versions of macOS:

170.c:493:17: error: use of undeclared identifier 'UTIME_NOW'
        nsec1 = UTIME_NOW;
                ^
170.c:494:17: error: use of undeclared identifier 'UTIME_NOW'
        nsec2 = UTIME_NOW;
                ^
170.c:500:79: error: use of undeclared identifier 'UTIME_NOW'
            if      (STk_eqv(time1, symb_time_now) == STk_true)       nsec1 = UTIME_NOW;
                                                                              ^
170.c:501:79: error: use of undeclared identifier 'UTIME_OMIT'
            else if (STk_eqv(time1, symb_time_unchanged) == STk_true) nsec1 = UTIME_OMIT;
                                                                              ^
170.c:514:79: error: use of undeclared identifier 'UTIME_NOW'
            if      (STk_eqv(time2, symb_time_now) == STk_true)       nsec2 = UTIME_NOW;
                                                                              ^
170.c:515:79: error: use of undeclared identifier 'UTIME_OMIT'
            else if (STk_eqv(time2, symb_time_unchanged) == STk_true) nsec2 = UTIME_OMIT;
                                                                              ^
170.c:534:13: warning: implicit declaration of function 'utimensat' is invalid in C99 [-Wimplicit-function-declaration]
    int e = utimensat(AT_FDCWD,cname, t, 0);
            ^
1 warning and 6 errors generated.
make[3]: *** [170.so] Error 1

Here is a full build log from macOS 10.12: https://build.macports.org/builders/ports-10.12_x86_64-builder/builds/222826/steps/install-port/logs/stdio

Can 170.c survive without utimensat? If so, you probably want a configure test to check if it exists before you use it in 170.c.

jpellegrini commented 1 year ago

utimensat is POSIX since 2001 (same thing as in #519 ), and declared in fcntl.h. Why is it not available? I think it's easy to not include SRFI 170 based on configure flags (but not system.c).

ryandesign commented 1 year ago

macOS 10.13 (2017) is the earliest version of macOS that includes utimensat.

ryandesign commented 1 year ago

utimensat is POSIX.1-2008. macOS (since version 10.5 (2007)) is a certified UNIX 03 (a.k.a. POSIX.1-2001) operating system.

lassik commented 1 year ago

It's probably OK to substitute utimes(). Not all file systems guarantee nanosecond precision anyway.

jpellegrini commented 1 year ago

It's probably OK to substitute utimes(). Not all file systems guarantee nanosecond precision anyway.

I suppose this could work fine if it's done selectively (if utimensat is not supported, use utimes)...

ryandesign commented 1 year ago

Not all file systems guarantee nanosecond precision

Right. macOS used to use HFS+, a.k.a the Mac OS Extended file system. It was introduced in Mac OS 8.1 in 1998 and it has second precision. macOS 10.12.4 introduced APFS, the new Apple File System. It has nanosecond precision. macOS 10.13 is the first version to support booting from APFS volumes. I guess there was no need to have a utimensat function prior to then.

lassik commented 1 year ago

I suppose this could work fine if it's done selectively (if utimensat is not supported, use utimes)...

Could autoconf check for it and define HAVE_UTIMENSAT?

jpellegrini commented 1 year ago

Could autoconf check for it and define HAVE_UTIMENSAT?

Isn't this easier with an #if defined(something)? There could be some symbol that, when defined, means we use (or not use) utimensat

egallesio commented 1 year ago

I have added a test in autoconf for utimensat, and wrote some code (with a resolution of 1s) for systems without this primitive. I hope it works (simulated the absence of utimensat). So, I close this issue. Feel free to reopen it if something is incorrect