File: libCreationTimeHelper.c

package info (click to toggle)
openjdk-21 21.0.8%2B9-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 823,976 kB
  • sloc: java: 5,613,338; xml: 1,643,607; cpp: 1,296,296; ansic: 420,291; asm: 404,850; objc: 20,994; sh: 15,271; javascript: 11,245; python: 6,895; makefile: 2,362; perl: 357; awk: 351; sed: 172; jsp: 24; csh: 3
file content (142 lines) | stat: -rw-r--r-- 4,237 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/*
 * Copyright (c) 2023, Red Hat, Inc.
 * Copyright (c) 2024 Alibaba Group Holding Limited. All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */
#include "jni.h"
#include <stdbool.h>
#if defined(__linux__)
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dlfcn.h>
#ifndef STATX_BASIC_STATS
#define STATX_BASIC_STATS 0x000007ffU
#endif
#ifndef STATX_BTIME
#define STATX_BTIME 0x00000800U
#endif
#ifndef RTLD_DEFAULT
#define RTLD_DEFAULT RTLD_LOCAL
#endif
#ifndef AT_SYMLINK_NOFOLLOW
#define AT_SYMLINK_NOFOLLOW 0x100
#endif
#ifndef AT_FDCWD
#define AT_FDCWD -100
#endif

#ifndef __GLIBC__
// Alpine doesn't know these types, define them
typedef unsigned int       __uint32_t;
typedef unsigned short     __uint16_t;
typedef unsigned long int  __uint64_t;
#endif

/*
 * Timestamp structure for the timestamps in struct statx.
 */
struct my_statx_timestamp {
        int64_t   tv_sec;
        __uint32_t  tv_nsec;
        int32_t   __reserved;
};

/*
 * struct statx used by statx system call on >= glibc 2.28
 * systems
 */
struct my_statx
{
  __uint32_t stx_mask;
  __uint32_t stx_blksize;
  __uint64_t stx_attributes;
  __uint32_t stx_nlink;
  __uint32_t stx_uid;
  __uint32_t stx_gid;
  __uint16_t stx_mode;
  __uint16_t __statx_pad1[1];
  __uint64_t stx_ino;
  __uint64_t stx_size;
  __uint64_t stx_blocks;
  __uint64_t stx_attributes_mask;
  struct my_statx_timestamp stx_atime;
  struct my_statx_timestamp stx_btime;
  struct my_statx_timestamp stx_ctime;
  struct my_statx_timestamp stx_mtime;
  __uint32_t stx_rdev_major;
  __uint32_t stx_rdev_minor;
  __uint32_t stx_dev_major;
  __uint32_t stx_dev_minor;
  __uint64_t __statx_pad2[14];
};

typedef int statx_func(int dirfd, const char *restrict pathname, int flags,
                       unsigned int mask, struct my_statx *restrict statxbuf);

static statx_func* my_statx_func = NULL;
#endif  //#defined(__linux__)

// static native boolean linuxIsCreationTimeSupported()
JNIEXPORT jboolean JNICALL
Java_CreationTimeHelper_linuxIsCreationTimeSupported(JNIEnv *env, jclass cls, jstring file) {
#if defined(__linux__)
    struct my_statx stx = {0};
    int ret, atflag = AT_SYMLINK_NOFOLLOW;
    unsigned int mask = STATX_BASIC_STATS | STATX_BTIME;

    my_statx_func = (statx_func*) dlsym(RTLD_DEFAULT, "statx");
    if (my_statx_func == NULL) {
        return false;
    }

    if (file == NULL) {
        printf("input file error!\n");
        return JNI_FALSE;
    }
    const char *utfChars = (*env)->GetStringUTFChars(env, file, NULL);
    if (utfChars == NULL) {
        printf("jstring convert to char array error!\n");
        return JNI_FALSE;
    }

    ret = my_statx_func(AT_FDCWD, utfChars, atflag, mask, &stx);

    if (file != NULL && utfChars != NULL) {
        (*env)->ReleaseStringUTFChars(env, file, utfChars);
    }

    if (ret != 0) {
        return JNI_FALSE;
    }

    // On some systems where statx is available but birth time might still not
    // be supported as it's file system specific. The only reliable way to
    // check for supported or not is looking at the filled in STATX_BTIME bit
    // in the returned statx buffer mask.
    if ((stx.stx_mask & STATX_BTIME) != 0)
        return JNI_TRUE;
    return JNI_FALSE;
#else
    return JNI_FALSE;
#endif
}