|
1 | 1 | /*
|
2 |
| - * Copyright (c) 2023, Red Hat, Inc. |
| 2 | + * Copyright (c) 2024 Alibaba Group Holding Limited. All Rights Reserved. |
3 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
4 | 4 | *
|
5 | 5 | * This code is free software; you can redistribute it and/or modify it
|
|
21 | 21 | * questions.
|
22 | 22 | */
|
23 | 23 | #include "jni.h"
|
24 |
| -#if defined(__linux__) |
| 24 | +#include <linux/fcntl.h> |
| 25 | +#include <stdio.h> |
| 26 | +#include <string.h> |
| 27 | +#include <sys/stat.h> |
| 28 | +#include <bits/types.h> |
25 | 29 | #include <dlfcn.h>
|
| 30 | +#ifndef STATX_BASIC_STATS |
| 31 | +#define STATX_BASIC_STATS 0x000007ffU |
| 32 | +#endif |
| 33 | +#ifndef STATX_BTIME |
| 34 | +#define STATX_BTIME 0x00000800U |
| 35 | +#endif |
| 36 | +#ifndef _GNU_SOURCE |
| 37 | +#define _GNU_SOURCE |
| 38 | +#endif |
| 39 | +#ifndef RTLD_DEFAULT |
| 40 | +#define RTLD_DEFAULT RTLD_LOCAL |
| 41 | +#endif |
| 42 | + |
| 43 | +/* |
| 44 | + * Timestamp structure for the timestamps in struct statx. |
| 45 | + */ |
| 46 | +struct my_statx_timestamp { |
| 47 | + __int64_t tv_sec; |
| 48 | + __uint32_t tv_nsec; |
| 49 | + __int32_t __reserved; |
| 50 | +}; |
| 51 | + |
| 52 | +/* |
| 53 | + * struct statx used by statx system call on >= glibc 2.28 |
| 54 | + * systems |
| 55 | + */ |
| 56 | +struct my_statx |
| 57 | +{ |
| 58 | + __uint32_t stx_mask; |
| 59 | + __uint32_t stx_blksize; |
| 60 | + __uint64_t stx_attributes; |
| 61 | + __uint32_t stx_nlink; |
| 62 | + __uint32_t stx_uid; |
| 63 | + __uint32_t stx_gid; |
| 64 | + __uint16_t stx_mode; |
| 65 | + __uint16_t __statx_pad1[1]; |
| 66 | + __uint64_t stx_ino; |
| 67 | + __uint64_t stx_size; |
| 68 | + __uint64_t stx_blocks; |
| 69 | + __uint64_t stx_attributes_mask; |
| 70 | + struct my_statx_timestamp stx_atime; |
| 71 | + struct my_statx_timestamp stx_btime; |
| 72 | + struct my_statx_timestamp stx_ctime; |
| 73 | + struct my_statx_timestamp stx_mtime; |
| 74 | + __uint32_t stx_rdev_major; |
| 75 | + __uint32_t stx_rdev_minor; |
| 76 | + __uint32_t stx_dev_major; |
| 77 | + __uint32_t stx_dev_minor; |
| 78 | + __uint64_t __statx_pad2[14]; |
| 79 | +}; |
| 80 | + |
| 81 | +#if defined(__linux__) |
| 82 | +typedef int statx_func(int dirfd, const char *restrict pathname, int flags, |
| 83 | + unsigned int mask, struct my_statx *restrict statxbuf); |
| 84 | +#endif |
| 85 | +#if defined(__linux__) |
| 86 | +static statx_func* my_statx_func = NULL; |
26 | 87 | #endif
|
27 | 88 |
|
28 | 89 | // static native boolean linuxIsCreationTimeSupported()
|
29 | 90 | JNIEXPORT jboolean JNICALL
|
30 |
| -Java_CreationTimeHelper_linuxIsCreationTimeSupported(JNIEnv *env, jclass cls) |
31 |
| -{ |
| 91 | +Java_CreationTimeHelper_linuxIsCreationTimeSupported(JNIEnv *env, jclass cls, jstring file) { |
32 | 92 | #if defined(__linux__)
|
33 |
| - void* statx_func = dlsym(RTLD_DEFAULT, "statx"); |
34 |
| - return statx_func != NULL ? JNI_TRUE : JNI_FALSE; |
| 93 | + struct my_statx stx; |
| 94 | + int ret, atflag = AT_SYMLINK_NOFOLLOW; |
| 95 | + memset(&stx, 0xbf, sizeof(stx)); |
| 96 | + unsigned int mask = STATX_BASIC_STATS | STATX_BTIME; |
| 97 | + |
| 98 | + my_statx_func = (statx_func*) dlsym(RTLD_DEFAULT, "statx"); |
| 99 | + if (my_statx_func == NULL) { |
| 100 | + return JNI_FALSE; |
| 101 | + } |
| 102 | + |
| 103 | + if (file == NULL) { |
| 104 | + printf("input file error!\n"); |
| 105 | + return JNI_FALSE; |
| 106 | + } |
| 107 | + const char *utfChars = (*env)->GetStringUTFChars(env, file, NULL); |
| 108 | + if (utfChars == NULL) { |
| 109 | + printf("jstring convert to char array error!\n"); |
| 110 | + return JNI_FALSE; |
| 111 | + } |
| 112 | + |
| 113 | + ret = my_statx_func(AT_FDCWD, utfChars, atflag, mask, &stx); |
| 114 | + |
| 115 | + if (file != NULL && utfChars != NULL) { |
| 116 | + (*env)->ReleaseStringUTFChars(env, file, utfChars); |
| 117 | + } |
| 118 | + |
| 119 | + #ifdef DEBUG |
| 120 | + printf("birth time = %ld\n", stx.stx_btime.tv_sec); |
| 121 | + #endif |
| 122 | + if (ret != 0) { |
| 123 | + return JNI_FALSE; |
| 124 | + } |
| 125 | + if (stx.stx_mask & STATX_BTIME) |
| 126 | + return JNI_TRUE; |
| 127 | + return JNI_FALSE; |
35 | 128 | #else
|
36 | 129 | return JNI_FALSE;
|
37 | 130 | #endif
|
|
0 commit comments