Repository: dotnet/runtime
File: src/native/libs/System.Native/pal_io.c (C)

Code before:
    while ((result = fchmod(ToFileDescriptor(fd), (mode_t)mode)) < 0 && errno == EINTR);
    return result;
#else /* HAVE_FCHMOD */
    (void)fd; // unused
    (void)mode; // unused
    return EINTR;
#endif /* HAVE_FCHMOD */
}

int32_t SystemNative_FSync(intptr_t fd)
{
    int fileDescriptor = ToFileDescriptor(fd);

    int32_t result;
#if defined(TARGET_OSX) && HAVE_F_FULLFSYNC
    while ((result = fcntl(fileDescriptor, F_FULLFSYNC)) < 0 && errno == EINTR);
    if (result < 0)
    {
        // F_FULLFSYNC is not supported on all file systems and handle types (e.g., network
        // file systems, read-only handles). Fall back to fsync per Apple's recommendation:
        // https://developer.apple.com/documentation/xcode/reducing-disk-writes
        // For genuine I/O errors (e.g., EIO), fsync will also fail and propagate the error.
        while ((result = fsync(fileDescriptor)) < 0 && errno == EINTR);
    }
#else
    while ((result = fsync(fileDescriptor)) < 0 && errno == EINTR);
#endif
    return result;
}

int32_t SystemNative_FLock(intptr_t fd, int32_t operation)
{
    int32_t result;
#if !defined(TARGET_WASI)
    while ((result = flock(ToFileDescriptor(fd), operation)) < 0 && errno == EINTR);
#else /* TARGET_WASI */
    result = EINTR;
#endif /* TARGET_WASI */
    return result;
}

int32_t SystemNative_ChDir(const char* path)
{
    int32_t result;
    while ((result = chdir(path)) < 0 && errno == EINTR);
    return result;
}

int32_t SystemNative_Access(const char* path, int32_t mode)
{
    return access(path, mode);

Review comment (refactor):
@copilot can we avoid the duplication (L754 and L757 are now identical), either by moving it into a helper function or by changing the structure so that lines 747-749 and separately L755 are guarded by the ifdef?

Code after:
    while ((result = fchmod(ToFileDescriptor(fd), (mode_t)mode)) < 0 && errno == EINTR);
    return result;
#else /* HAVE_FCHMOD */
    (void)fd; // unused
    (void)mode; // unused
    return EINTR;
#endif /* HAVE_FCHMOD */
}

int32_t SystemNative_FSync(intptr_t fd)
{
    int fileDescriptor = ToFileDescriptor(fd);

    int32_t result;
#ifdef TARGET_OSX
    while ((result = fcntl(fileDescriptor, F_FULLFSYNC)) < 0 && errno == EINTR);
    if (result >= 0)
    {
        return result;
    }

    // F_FULLFSYNC is not supported on all file systems and handle types (e.g.,
    // network file systems, read-only handles). Fall back to fsync.
    // For genuine I/O errors (e.g., EIO), fsync will also fail and propagate the error.
#endif
    while ((result = fsync(fileDescriptor)) < 0 && errno == EINTR);
    return result;
}

int32_t SystemNative_FLock(intptr_t fd, int32_t operation)
{
    int32_t result;
#if !defined(TARGET_WASI)
    while ((result = flock(ToFileDescriptor(fd), operation)) < 0 && errno == EINTR);
#else /* TARGET_WASI */
    result = EINTR;
#endif /* TARGET_WASI */
    return result;
}

int32_t SystemNative_ChDir(const char* path)
{
    int32_t result;
    while ((result = chdir(path)) < 0 && errno == EINTR);
    return result;
}

int32_t SystemNative_Access(const char* path, int32_t mode)
{
    return access(path, mode);
}