Print this page
Split |
Close |
Expand all |
Collapse all |
--- old/src/solaris/native/sun/nio/fs/UnixNativeDispatcher.c
+++ new/src/solaris/native/sun/nio/fs/UnixNativeDispatcher.c
1 1 /*
2 2 * Copyright (c) 2008, 2011, Oracle and/or its affiliates. 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
6 6 * under the terms of the GNU General Public License version 2 only, as
7 7 * published by the Free Software Foundation. Oracle designates this
8 8 * particular file as subject to the "Classpath" exception as provided
9 9 * by Oracle in the LICENSE file that accompanied this code.
10 10 *
11 11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 14 * version 2 for more details (a copy is included in the LICENSE file that
15 15 * accompanied this code).
16 16 *
17 17 * You should have received a copy of the GNU General Public License version
18 18 * 2 along with this work; if not, write to the Free Software Foundation,
19 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 20 *
21 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 22 * or visit www.oracle.com if you need additional information or have any
23 23 * questions.
24 24 */
25 25
26 26 #include <stdio.h>
27 27 #include <stdlib.h>
28 28 #include <limits.h>
29 29 #include <fcntl.h>
30 30 #include <dirent.h>
31 31 #include <unistd.h>
32 32 #include <pwd.h>
33 33 #include <grp.h>
34 34 #include <errno.h>
35 35 #include <dlfcn.h>
36 36 #include <sys/types.h>
37 37 #include <sys/stat.h>
38 38 #include <sys/statvfs.h>
39 39 #include <sys/time.h>
40 40
41 41 #ifdef __solaris__
42 42 #include <strings.h>
43 43 #include <sys/mnttab.h>
44 44 #include <sys/mkdev.h>
45 45 #endif
46 46
47 47 #ifdef __linux__
48 48 #include <string.h>
49 49 #include <mntent.h>
50 50 #endif
51 51
52 52 #include "jni.h"
53 53 #include "jni_util.h"
54 54 #include "jlong.h"
55 55
56 56 #include "sun_nio_fs_UnixNativeDispatcher.h"
57 57
58 58 /**
59 59 * Size of password or group entry when not available via sysconf
60 60 */
61 61 #define ENT_BUF_SIZE 1024
62 62
63 63 #define RESTARTABLE(_cmd, _result) do { \
64 64 do { \
65 65 _result = _cmd; \
66 66 } while((_result == -1) && (errno == EINTR)); \
67 67 } while(0)
68 68
69 69 #define RESTARTABLE_RETURN_PTR(_cmd, _result) do { \
70 70 do { \
71 71 _result = _cmd; \
72 72 } while((_result == NULL) && (errno == EINTR)); \
73 73 } while(0)
74 74
75 75 static jfieldID attrs_st_mode;
76 76 static jfieldID attrs_st_ino;
77 77 static jfieldID attrs_st_dev;
78 78 static jfieldID attrs_st_rdev;
79 79 static jfieldID attrs_st_nlink;
80 80 static jfieldID attrs_st_uid;
81 81 static jfieldID attrs_st_gid;
82 82 static jfieldID attrs_st_size;
83 83 static jfieldID attrs_st_atime;
84 84 static jfieldID attrs_st_mtime;
85 85 static jfieldID attrs_st_ctime;
86 86
87 87 static jfieldID attrs_f_frsize;
88 88 static jfieldID attrs_f_blocks;
89 89 static jfieldID attrs_f_bfree;
90 90 static jfieldID attrs_f_bavail;
91 91
92 92 static jfieldID entry_name;
93 93 static jfieldID entry_dir;
94 94 static jfieldID entry_fstype;
95 95 static jfieldID entry_options;
96 96 static jfieldID entry_dev;
97 97
98 98 /**
99 99 * System calls that may not be available at run time.
100 100 */
101 101 typedef int openat64_func(int, const char *, int, ...);
102 102 typedef int fstatat64_func(int, const char *, struct stat64 *, int);
103 103 typedef int unlinkat_func(int, const char*, int);
104 104 typedef int renameat_func(int, const char*, int, const char*);
105 105 typedef int futimesat_func(int, const char *, const struct timeval *);
106 106 typedef DIR* fdopendir_func(int);
107 107
108 108 static openat64_func* my_openat64_func = NULL;
109 109 static fstatat64_func* my_fstatat64_func = NULL;
110 110 static unlinkat_func* my_unlinkat_func = NULL;
111 111 static renameat_func* my_renameat_func = NULL;
112 112 static futimesat_func* my_futimesat_func = NULL;
113 113 static fdopendir_func* my_fdopendir_func = NULL;
114 114
115 115 /**
116 116 * fstatat missing from glibc on Linux. Temporary workaround
117 117 * for x86/x64.
118 118 */
119 119 #if defined(__linux__) && defined(__i386)
120 120 #define FSTATAT64_SYSCALL_AVAILABLE
121 121 static int fstatat64_wrapper(int dfd, const char *path,
122 122 struct stat64 *statbuf, int flag)
123 123 {
124 124 #ifndef __NR_fstatat64
125 125 #define __NR_fstatat64 300
126 126 #endif
127 127 return syscall(__NR_fstatat64, dfd, path, statbuf, flag);
128 128 }
129 129 #endif
130 130
131 131 #if defined(__linux__) && defined(__x86_64__)
132 132 #define FSTATAT64_SYSCALL_AVAILABLE
133 133 static int fstatat64_wrapper(int dfd, const char *path,
134 134 struct stat64 *statbuf, int flag)
135 135 {
136 136 #ifndef __NR_newfstatat
137 137 #define __NR_newfstatat 262
138 138 #endif
139 139 return syscall(__NR_newfstatat, dfd, path, statbuf, flag);
140 140 }
141 141 #endif
142 142
143 143 /**
144 144 * Call this to throw an internal UnixException when a system/library
145 145 * call fails
146 146 */
147 147 static void throwUnixException(JNIEnv* env, int errnum) {
148 148 jobject x = JNU_NewObjectByName(env, "sun/nio/fs/UnixException",
149 149 "(I)V", errnum);
150 150 if (x != NULL) {
151 151 (*env)->Throw(env, x);
152 152 }
153 153 }
154 154
155 155 /**
156 156 * Initialization
157 157 */
158 158 JNIEXPORT jint JNICALL
159 159 Java_sun_nio_fs_UnixNativeDispatcher_init(JNIEnv* env, jclass this)
160 160 {
161 161 jint flags = 0;
162 162 jclass clazz;
163 163
164 164 clazz = (*env)->FindClass(env, "sun/nio/fs/UnixFileAttributes");
165 165 if (clazz == NULL) {
166 166 return 0;
167 167 }
168 168 attrs_st_mode = (*env)->GetFieldID(env, clazz, "st_mode", "I");
169 169 attrs_st_ino = (*env)->GetFieldID(env, clazz, "st_ino", "J");
170 170 attrs_st_dev = (*env)->GetFieldID(env, clazz, "st_dev", "J");
171 171 attrs_st_rdev = (*env)->GetFieldID(env, clazz, "st_rdev", "J");
172 172 attrs_st_nlink = (*env)->GetFieldID(env, clazz, "st_nlink", "I");
173 173 attrs_st_uid = (*env)->GetFieldID(env, clazz, "st_uid", "I");
174 174 attrs_st_gid = (*env)->GetFieldID(env, clazz, "st_gid", "I");
175 175 attrs_st_size = (*env)->GetFieldID(env, clazz, "st_size", "J");
176 176 attrs_st_atime = (*env)->GetFieldID(env, clazz, "st_atime", "J");
177 177 attrs_st_mtime = (*env)->GetFieldID(env, clazz, "st_mtime", "J");
178 178 attrs_st_ctime = (*env)->GetFieldID(env, clazz, "st_ctime", "J");
179 179
180 180 clazz = (*env)->FindClass(env, "sun/nio/fs/UnixFileStoreAttributes");
181 181 if (clazz == NULL) {
182 182 return 0;
183 183 }
184 184 attrs_f_frsize = (*env)->GetFieldID(env, clazz, "f_frsize", "J");
185 185 attrs_f_blocks = (*env)->GetFieldID(env, clazz, "f_blocks", "J");
186 186 attrs_f_bfree = (*env)->GetFieldID(env, clazz, "f_bfree", "J");
187 187 attrs_f_bavail = (*env)->GetFieldID(env, clazz, "f_bavail", "J");
188 188
189 189 clazz = (*env)->FindClass(env, "sun/nio/fs/UnixMountEntry");
190 190 if (clazz == NULL) {
191 191 return 0;
192 192 }
193 193 entry_name = (*env)->GetFieldID(env, clazz, "name", "[B");
194 194 entry_dir = (*env)->GetFieldID(env, clazz, "dir", "[B");
195 195 entry_fstype = (*env)->GetFieldID(env, clazz, "fstype", "[B");
196 196 entry_options = (*env)->GetFieldID(env, clazz, "opts", "[B");
197 197 entry_dev = (*env)->GetFieldID(env, clazz, "dev", "J");
198 198
199 199 /* system calls that might not be available at run time */
200 200
201 201 #if defined(__solaris__) && defined(_LP64)
202 202 /* Solaris 64-bit does not have openat64/fstatat64 */
203 203 my_openat64_func = (openat64_func*)dlsym(RTLD_DEFAULT, "openat");
204 204 my_fstatat64_func = (fstatat64_func*)dlsym(RTLD_DEFAULT, "fstatat");
205 205 #else
206 206 my_openat64_func = (openat64_func*) dlsym(RTLD_DEFAULT, "openat64");
207 207 my_fstatat64_func = (fstatat64_func*) dlsym(RTLD_DEFAULT, "fstatat64");
208 208 #endif
209 209 my_unlinkat_func = (unlinkat_func*) dlsym(RTLD_DEFAULT, "unlinkat");
210 210 my_renameat_func = (renameat_func*) dlsym(RTLD_DEFAULT, "renameat");
211 211 my_futimesat_func = (futimesat_func*) dlsym(RTLD_DEFAULT, "futimesat");
212 212 my_fdopendir_func = (fdopendir_func*) dlsym(RTLD_DEFAULT, "fdopendir");
213 213
214 214 #if defined(FSTATAT64_SYSCALL_AVAILABLE)
215 215 /* fstatat64 missing from glibc */
216 216 if (my_fstatat64_func == NULL)
217 217 my_fstatat64_func = (fstatat64_func*)&fstatat64_wrapper;
218 218 #endif
219 219
220 220 if (my_openat64_func != NULL && my_fstatat64_func != NULL &&
221 221 my_unlinkat_func != NULL && my_renameat_func != NULL &&
222 222 my_futimesat_func != NULL && my_fdopendir_func != NULL)
223 223 {
224 224 flags |= sun_nio_fs_UnixNativeDispatcher_HAS_AT_SYSCALLS;
225 225 }
226 226
227 227 return flags;
228 228 }
229 229
230 230 JNIEXPORT jbyteArray JNICALL
231 231 Java_sun_nio_fs_UnixNativeDispatcher_getcwd(JNIEnv* env, jclass this) {
232 232 jbyteArray result = NULL;
233 233 char buf[PATH_MAX+1];
234 234
235 235 /* EINTR not listed as a possible error */
236 236 char* cwd = getcwd(buf, sizeof(buf));
237 237 if (cwd == NULL) {
238 238 throwUnixException(env, errno);
239 239 } else {
240 240 jsize len = (jsize)strlen(buf);
241 241 result = (*env)->NewByteArray(env, len);
242 242 if (result != NULL) {
243 243 (*env)->SetByteArrayRegion(env, result, 0, len, (jbyte*)buf);
244 244 }
245 245 }
246 246 return result;
247 247 }
248 248
249 249 JNIEXPORT jbyteArray
250 250 Java_sun_nio_fs_UnixNativeDispatcher_strerror(JNIEnv* env, jclass this, jint error)
251 251 {
252 252 char* msg;
253 253 jsize len;
254 254 jbyteArray bytes;
255 255
256 256 msg = strerror((int)error);
257 257 len = strlen(msg);
258 258 bytes = (*env)->NewByteArray(env, len);
259 259 if (bytes != NULL) {
260 260 (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)msg);
261 261 }
262 262 return bytes;
263 263 }
264 264
265 265 JNIEXPORT jint
266 266 Java_sun_nio_fs_UnixNativeDispatcher_dup(JNIEnv* env, jclass this, jint fd) {
267 267
268 268 int res = -1;
269 269
270 270 RESTARTABLE(dup((int)fd), res);
271 271 if (fd == -1) {
272 272 throwUnixException(env, errno);
273 273 }
274 274 return (jint)res;
275 275 }
276 276
277 277 JNIEXPORT jlong JNICALL
278 278 Java_sun_nio_fs_UnixNativeDispatcher_fopen0(JNIEnv* env, jclass this,
279 279 jlong pathAddress, jlong modeAddress)
280 280 {
281 281 FILE* fp = NULL;
282 282 const char* path = (const char*)jlong_to_ptr(pathAddress);
283 283 const char* mode = (const char*)jlong_to_ptr(modeAddress);
284 284
285 285 do {
286 286 fp = fopen(path, mode);
287 287 } while (fp == NULL && errno == EINTR);
288 288
289 289 if (fp == NULL) {
290 290 throwUnixException(env, errno);
291 291 }
292 292
293 293 return ptr_to_jlong(fp);
294 294 }
295 295
296 296 JNIEXPORT void JNICALL
297 297 Java_sun_nio_fs_UnixNativeDispatcher_fclose(JNIEnv* env, jclass this, jlong stream)
298 298 {
299 299 int res;
300 300 FILE* fp = jlong_to_ptr(stream);
301 301
302 302 do {
303 303 res = fclose(fp);
304 304 } while (res == EOF && errno == EINTR);
305 305 if (res == EOF) {
306 306 throwUnixException(env, errno);
307 307 }
308 308 }
309 309
310 310 JNIEXPORT jint JNICALL
311 311 Java_sun_nio_fs_UnixNativeDispatcher_open0(JNIEnv* env, jclass this,
312 312 jlong pathAddress, jint oflags, jint mode)
313 313 {
314 314 jint fd;
315 315 const char* path = (const char*)jlong_to_ptr(pathAddress);
316 316
317 317 RESTARTABLE(open64(path, (int)oflags, (mode_t)mode), fd);
318 318 if (fd == -1) {
319 319 throwUnixException(env, errno);
320 320 }
321 321 return fd;
322 322 }
323 323
324 324 JNIEXPORT jint JNICALL
325 325 Java_sun_nio_fs_UnixNativeDispatcher_openat0(JNIEnv* env, jclass this, jint dfd,
326 326 jlong pathAddress, jint oflags, jint mode)
327 327 {
328 328 jint fd;
329 329 const char* path = (const char*)jlong_to_ptr(pathAddress);
330 330
331 331 if (my_openat64_func == NULL) {
332 332 JNU_ThrowInternalError(env, "should not reach here");
333 333 return -1;
334 334 }
335 335
336 336 RESTARTABLE((*my_openat64_func)(dfd, path, (int)oflags, (mode_t)mode), fd);
337 337 if (fd == -1) {
338 338 throwUnixException(env, errno);
339 339 }
340 340 return fd;
341 341 }
342 342
343 343 JNIEXPORT void JNICALL
344 344 Java_sun_nio_fs_UnixNativeDispatcher_close(JNIEnv* env, jclass this, jint fd) {
345 345 int err;
346 346 /* TDB - need to decide if EIO and other errors should cause exception */
347 347 RESTARTABLE(close((int)fd), err);
348 348 }
349 349
350 350 JNIEXPORT jint JNICALL
351 351 Java_sun_nio_fs_UnixNativeDispatcher_read(JNIEnv* env, jclass this, jint fd,
352 352 jlong address, jint nbytes)
353 353 {
354 354 ssize_t n;
355 355 void* bufp = jlong_to_ptr(address);
356 356 RESTARTABLE(read((int)fd, bufp, (size_t)nbytes), n);
357 357 if (n == -1) {
358 358 throwUnixException(env, errno);
359 359 }
360 360 return (jint)n;
361 361 }
362 362
363 363 JNIEXPORT jint JNICALL
364 364 Java_sun_nio_fs_UnixNativeDispatcher_write(JNIEnv* env, jclass this, jint fd,
365 365 jlong address, jint nbytes)
366 366 {
367 367 ssize_t n;
368 368 void* bufp = jlong_to_ptr(address);
369 369 RESTARTABLE(write((int)fd, bufp, (size_t)nbytes), n);
370 370 if (n == -1) {
371 371 throwUnixException(env, errno);
372 372 }
373 373 return (jint)n;
374 374 }
375 375
376 376 /**
377 377 * Copy stat64 members into sun.nio.fs.UnixFileAttributes
378 378 */
379 379 static void prepAttributes(JNIEnv* env, struct stat64* buf, jobject attrs) {
380 380 (*env)->SetIntField(env, attrs, attrs_st_mode, (jint)buf->st_mode);
381 381 (*env)->SetLongField(env, attrs, attrs_st_ino, (jlong)buf->st_ino);
382 382 (*env)->SetLongField(env, attrs, attrs_st_dev, (jlong)buf->st_dev);
383 383 (*env)->SetLongField(env, attrs, attrs_st_rdev, (jlong)buf->st_rdev);
384 384 (*env)->SetIntField(env, attrs, attrs_st_nlink, (jint)buf->st_nlink);
385 385 (*env)->SetIntField(env, attrs, attrs_st_uid, (jint)buf->st_uid);
386 386 (*env)->SetIntField(env, attrs, attrs_st_gid, (jint)buf->st_gid);
387 387 (*env)->SetLongField(env, attrs, attrs_st_size, (jlong)buf->st_size);
388 388 (*env)->SetLongField(env, attrs, attrs_st_atime, (jlong)buf->st_atime);
389 389 (*env)->SetLongField(env, attrs, attrs_st_mtime, (jlong)buf->st_mtime);
390 390 (*env)->SetLongField(env, attrs, attrs_st_ctime, (jlong)buf->st_ctime);
391 391 }
392 392
393 393 JNIEXPORT void JNICALL
394 394 Java_sun_nio_fs_UnixNativeDispatcher_stat0(JNIEnv* env, jclass this,
395 395 jlong pathAddress, jobject attrs)
396 396 {
397 397 int err;
398 398 struct stat64 buf;
399 399 const char* path = (const char*)jlong_to_ptr(pathAddress);
400 400
401 401 RESTARTABLE(stat64(path, &buf), err);
402 402 if (err == -1) {
403 403 throwUnixException(env, errno);
404 404 } else {
405 405 prepAttributes(env, &buf, attrs);
406 406 }
407 407 }
408 408
409 409 JNIEXPORT void JNICALL
410 410 Java_sun_nio_fs_UnixNativeDispatcher_lstat0(JNIEnv* env, jclass this,
411 411 jlong pathAddress, jobject attrs)
412 412 {
413 413 int err;
414 414 struct stat64 buf;
415 415 const char* path = (const char*)jlong_to_ptr(pathAddress);
416 416
417 417 RESTARTABLE(lstat64(path, &buf), err);
418 418 if (err == -1) {
419 419 throwUnixException(env, errno);
420 420 } else {
421 421 prepAttributes(env, &buf, attrs);
422 422 }
423 423 }
424 424
425 425 JNIEXPORT void JNICALL
426 426 Java_sun_nio_fs_UnixNativeDispatcher_fstat(JNIEnv* env, jclass this, jint fd,
427 427 jobject attrs)
428 428 {
429 429 int err;
430 430 struct stat64 buf;
431 431
432 432 RESTARTABLE(fstat64((int)fd, &buf), err);
433 433 if (err == -1) {
434 434 throwUnixException(env, errno);
435 435 } else {
436 436 prepAttributes(env, &buf, attrs);
437 437 }
438 438 }
439 439
440 440 JNIEXPORT void JNICALL
441 441 Java_sun_nio_fs_UnixNativeDispatcher_fstatat0(JNIEnv* env, jclass this, jint dfd,
442 442 jlong pathAddress, jint flag, jobject attrs)
443 443 {
444 444 int err;
445 445 struct stat64 buf;
446 446 const char* path = (const char*)jlong_to_ptr(pathAddress);
447 447
448 448 if (my_fstatat64_func == NULL) {
449 449 JNU_ThrowInternalError(env, "should not reach here");
450 450 return;
451 451 }
452 452 RESTARTABLE((*my_fstatat64_func)((int)dfd, path, &buf, (int)flag), err);
453 453 if (err == -1) {
454 454 throwUnixException(env, errno);
455 455 } else {
456 456 prepAttributes(env, &buf, attrs);
457 457 }
458 458 }
459 459
460 460 JNIEXPORT void JNICALL
461 461 Java_sun_nio_fs_UnixNativeDispatcher_chmod0(JNIEnv* env, jclass this,
462 462 jlong pathAddress, jint mode)
463 463 {
464 464 int err;
465 465 const char* path = (const char*)jlong_to_ptr(pathAddress);
466 466
467 467 RESTARTABLE(chmod(path, (mode_t)mode), err);
468 468 if (err == -1) {
469 469 throwUnixException(env, errno);
470 470 }
471 471 }
472 472
473 473 JNIEXPORT void JNICALL
474 474 Java_sun_nio_fs_UnixNativeDispatcher_fchmod(JNIEnv* env, jclass this, jint filedes,
475 475 jint mode)
476 476 {
477 477 int err;
478 478
479 479 RESTARTABLE(fchmod((int)filedes, (mode_t)mode), err);
480 480 if (err == -1) {
481 481 throwUnixException(env, errno);
482 482 }
483 483 }
484 484
485 485
486 486 JNIEXPORT void JNICALL
487 487 Java_sun_nio_fs_UnixNativeDispatcher_chown0(JNIEnv* env, jclass this,
488 488 jlong pathAddress, jint uid, jint gid)
489 489 {
490 490 int err;
491 491 const char* path = (const char*)jlong_to_ptr(pathAddress);
492 492
493 493 RESTARTABLE(chown(path, (uid_t)uid, (gid_t)gid), err);
494 494 if (err == -1) {
495 495 throwUnixException(env, errno);
496 496 }
497 497 }
498 498
499 499 JNIEXPORT void JNICALL
500 500 Java_sun_nio_fs_UnixNativeDispatcher_lchown0(JNIEnv* env, jclass this, jlong pathAddress, jint uid, jint gid)
501 501 {
502 502 int err;
503 503 const char* path = (const char*)jlong_to_ptr(pathAddress);
504 504
505 505 RESTARTABLE(lchown(path, (uid_t)uid, (gid_t)gid), err);
506 506 if (err == -1) {
507 507 throwUnixException(env, errno);
508 508 }
509 509 }
510 510
511 511 JNIEXPORT void JNICALL
512 512 Java_sun_nio_fs_UnixNativeDispatcher_fchown(JNIEnv* env, jclass this, jint filedes, jint uid, jint gid)
513 513 {
514 514 int err;
515 515
516 516 RESTARTABLE(fchown(filedes, (uid_t)uid, (gid_t)gid), err);
517 517 if (err == -1) {
518 518 throwUnixException(env, errno);
519 519 }
520 520 }
521 521
522 522 JNIEXPORT void JNICALL
523 523 Java_sun_nio_fs_UnixNativeDispatcher_utimes0(JNIEnv* env, jclass this,
524 524 jlong pathAddress, jlong accessTime, jlong modificationTime)
525 525 {
526 526 int err;
527 527 struct timeval times[2];
528 528 const char* path = (const char*)jlong_to_ptr(pathAddress);
529 529
530 530 times[0].tv_sec = accessTime / 1000000;
531 531 times[0].tv_usec = accessTime % 1000000;
532 532
533 533 times[1].tv_sec = modificationTime / 1000000;
534 534 times[1].tv_usec = modificationTime % 1000000;
535 535
536 536 RESTARTABLE(utimes(path, ×[0]), err);
537 537 if (err == -1) {
538 538 throwUnixException(env, errno);
539 539 }
540 540 }
541 541
542 542 JNIEXPORT void JNICALL
543 543 Java_sun_nio_fs_UnixNativeDispatcher_futimes(JNIEnv* env, jclass this, jint filedes,
544 544 jlong accessTime, jlong modificationTime)
545 545 {
546 546 struct timeval times[2];
547 547 int err = 0;
548 548
549 549 times[0].tv_sec = accessTime / 1000000;
550 550 times[0].tv_usec = accessTime % 1000000;
551 551
552 552 times[1].tv_sec = modificationTime / 1000000;
553 553 times[1].tv_usec = modificationTime % 1000000;
554 554
555 555 if (my_futimesat_func != NULL) {
556 556 RESTARTABLE((*my_futimesat_func)(filedes, NULL, ×[0]), err);
557 557 if (err == -1) {
558 558 throwUnixException(env, errno);
559 559 }
560 560 }
561 561 }
562 562
563 563 JNIEXPORT jlong JNICALL
564 564 Java_sun_nio_fs_UnixNativeDispatcher_opendir0(JNIEnv* env, jclass this,
565 565 jlong pathAddress)
566 566 {
567 567 DIR* dir;
568 568 const char* path = (const char*)jlong_to_ptr(pathAddress);
569 569
570 570 /* EINTR not listed as a possible error */
571 571 dir = opendir(path);
572 572 if (dir == NULL) {
573 573 throwUnixException(env, errno);
574 574 }
575 575 return ptr_to_jlong(dir);
576 576 }
577 577
578 578 JNIEXPORT jlong JNICALL
579 579 Java_sun_nio_fs_UnixNativeDispatcher_fdopendir(JNIEnv* env, jclass this, int dfd) {
580 580 DIR* dir;
581 581
582 582 if (my_fdopendir_func == NULL) {
583 583 JNU_ThrowInternalError(env, "should not reach here");
584 584 return (jlong)-1;
585 585 }
586 586
587 587 /* EINTR not listed as a possible error */
588 588 dir = (*my_fdopendir_func)((int)dfd);
589 589 if (dir == NULL) {
590 590 throwUnixException(env, errno);
591 591 }
592 592 return ptr_to_jlong(dir);
593 593 }
594 594
595 595 JNIEXPORT void JNICALL
596 596 Java_sun_nio_fs_UnixNativeDispatcher_closedir(JNIEnv* env, jclass this, jlong dir) {
597 597 int err;
↓ open down ↓ |
597 lines elided |
↑ open up ↑ |
598 598 DIR* dirp = jlong_to_ptr(dir);
599 599
600 600 RESTARTABLE(closedir(dirp), err);
601 601 if (errno == -1) {
602 602 throwUnixException(env, errno);
603 603 }
604 604 }
605 605
606 606 JNIEXPORT jbyteArray JNICALL
607 607 Java_sun_nio_fs_UnixNativeDispatcher_readdir(JNIEnv* env, jclass this, jlong value) {
608 - char entry[sizeof(struct dirent64) + PATH_MAX + 1];
609 - struct dirent64* ptr = (struct dirent64*)&entry;
610 608 struct dirent64* result;
609 + struct {
610 + struct dirent64 buf;
611 + char name_extra[PATH_MAX + 1 - sizeof result->d_name];
612 + } entry;
613 + struct dirent64* ptr = &entry.buf;
611 614 int res;
612 615 DIR* dirp = jlong_to_ptr(value);
613 616
614 617 /* EINTR not listed as a possible error */
615 618 /* TDB: reentrant version probably not required here */
616 619 res = readdir64_r(dirp, ptr, &result);
617 620 if (res != 0) {
618 621 throwUnixException(env, res);
619 622 return NULL;
620 623 } else {
621 624 if (result == NULL) {
622 625 return NULL;
623 626 } else {
624 627 jsize len = strlen(ptr->d_name);
625 628 jbyteArray bytes = (*env)->NewByteArray(env, len);
626 629 if (bytes != NULL) {
627 630 (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)(ptr->d_name));
628 631 }
629 632 return bytes;
630 633 }
631 634 }
632 635 }
633 636
634 637 JNIEXPORT void JNICALL
635 638 Java_sun_nio_fs_UnixNativeDispatcher_mkdir0(JNIEnv* env, jclass this,
636 639 jlong pathAddress, jint mode)
637 640 {
638 641 const char* path = (const char*)jlong_to_ptr(pathAddress);
639 642
640 643 /* EINTR not listed as a possible error */
641 644 if (mkdir(path, (mode_t)mode) == -1) {
642 645 throwUnixException(env, errno);
643 646 }
644 647 }
645 648
646 649 JNIEXPORT void JNICALL
647 650 Java_sun_nio_fs_UnixNativeDispatcher_rmdir0(JNIEnv* env, jclass this,
648 651 jlong pathAddress)
649 652 {
650 653 const char* path = (const char*)jlong_to_ptr(pathAddress);
651 654
652 655 /* EINTR not listed as a possible error */
653 656 if (rmdir(path) == -1) {
654 657 throwUnixException(env, errno);
655 658 }
656 659 }
657 660
658 661 JNIEXPORT void JNICALL
659 662 Java_sun_nio_fs_UnixNativeDispatcher_link0(JNIEnv* env, jclass this,
660 663 jlong existingAddress, jlong newAddress)
661 664 {
662 665 int err;
663 666 const char* existing = (const char*)jlong_to_ptr(existingAddress);
664 667 const char* newname = (const char*)jlong_to_ptr(newAddress);
665 668
666 669 RESTARTABLE(link(existing, newname), err);
667 670 if (err == -1) {
668 671 throwUnixException(env, errno);
669 672 }
670 673 }
671 674
672 675
673 676 JNIEXPORT void JNICALL
674 677 Java_sun_nio_fs_UnixNativeDispatcher_unlink0(JNIEnv* env, jclass this,
675 678 jlong pathAddress)
676 679 {
677 680 const char* path = (const char*)jlong_to_ptr(pathAddress);
678 681
679 682 /* EINTR not listed as a possible error */
680 683 if (unlink(path) == -1) {
681 684 throwUnixException(env, errno);
682 685 }
683 686 }
684 687
685 688 JNIEXPORT void JNICALL
686 689 Java_sun_nio_fs_UnixNativeDispatcher_unlinkat0(JNIEnv* env, jclass this, jint dfd,
687 690 jlong pathAddress, jint flags)
688 691 {
689 692 const char* path = (const char*)jlong_to_ptr(pathAddress);
690 693
691 694 if (my_unlinkat_func == NULL) {
692 695 JNU_ThrowInternalError(env, "should not reach here");
693 696 return;
694 697 }
695 698
696 699 /* EINTR not listed as a possible error */
697 700 if ((*my_unlinkat_func)((int)dfd, path, (int)flags) == -1) {
698 701 throwUnixException(env, errno);
699 702 }
700 703 }
701 704
702 705 JNIEXPORT void JNICALL
703 706 Java_sun_nio_fs_UnixNativeDispatcher_rename0(JNIEnv* env, jclass this,
704 707 jlong fromAddress, jlong toAddress)
705 708 {
706 709 const char* from = (const char*)jlong_to_ptr(fromAddress);
707 710 const char* to = (const char*)jlong_to_ptr(toAddress);
708 711
709 712 /* EINTR not listed as a possible error */
710 713 if (rename(from, to) == -1) {
711 714 throwUnixException(env, errno);
712 715 }
713 716 }
714 717
715 718 JNIEXPORT void JNICALL
716 719 Java_sun_nio_fs_UnixNativeDispatcher_renameat0(JNIEnv* env, jclass this,
717 720 jint fromfd, jlong fromAddress, jint tofd, jlong toAddress)
718 721 {
719 722 const char* from = (const char*)jlong_to_ptr(fromAddress);
720 723 const char* to = (const char*)jlong_to_ptr(toAddress);
721 724
722 725 if (my_renameat_func == NULL) {
723 726 JNU_ThrowInternalError(env, "should not reach here");
724 727 return;
725 728 }
726 729
727 730 /* EINTR not listed as a possible error */
728 731 if ((*my_renameat_func)((int)fromfd, from, (int)tofd, to) == -1) {
729 732 throwUnixException(env, errno);
730 733 }
731 734 }
732 735
733 736 JNIEXPORT void JNICALL
734 737 Java_sun_nio_fs_UnixNativeDispatcher_symlink0(JNIEnv* env, jclass this,
735 738 jlong targetAddress, jlong linkAddress)
736 739 {
737 740 const char* target = (const char*)jlong_to_ptr(targetAddress);
738 741 const char* link = (const char*)jlong_to_ptr(linkAddress);
739 742
740 743 /* EINTR not listed as a possible error */
741 744 if (symlink(target, link) == -1) {
742 745 throwUnixException(env, errno);
743 746 }
744 747 }
745 748
746 749 JNIEXPORT jbyteArray JNICALL
747 750 Java_sun_nio_fs_UnixNativeDispatcher_readlink0(JNIEnv* env, jclass this,
748 751 jlong pathAddress)
749 752 {
750 753 jbyteArray result = NULL;
751 754 char target[PATH_MAX+1];
752 755 const char* path = (const char*)jlong_to_ptr(pathAddress);
753 756
754 757 /* EINTR not listed as a possible error */
755 758 int n = readlink(path, target, sizeof(target));
756 759 if (n == -1) {
757 760 throwUnixException(env, errno);
758 761 } else {
759 762 jsize len;
760 763 if (n == sizeof(target)) {
761 764 n--;
762 765 }
763 766 target[n] = '\0';
764 767 len = (jsize)strlen(target);
765 768 result = (*env)->NewByteArray(env, len);
766 769 if (result != NULL) {
767 770 (*env)->SetByteArrayRegion(env, result, 0, len, (jbyte*)target);
768 771 }
769 772 }
770 773 return result;
771 774 }
772 775
773 776 JNIEXPORT jbyteArray JNICALL
774 777 Java_sun_nio_fs_UnixNativeDispatcher_realpath0(JNIEnv* env, jclass this,
775 778 jlong pathAddress)
776 779 {
777 780 jbyteArray result = NULL;
778 781 char resolved[PATH_MAX+1];
779 782 const char* path = (const char*)jlong_to_ptr(pathAddress);
780 783
781 784 /* EINTR not listed as a possible error */
782 785 if (realpath(path, resolved) == NULL) {
783 786 throwUnixException(env, errno);
784 787 } else {
785 788 jsize len = (jsize)strlen(resolved);
786 789 result = (*env)->NewByteArray(env, len);
787 790 if (result != NULL) {
788 791 (*env)->SetByteArrayRegion(env, result, 0, len, (jbyte*)resolved);
789 792 }
790 793 }
791 794 return result;
792 795 }
793 796
794 797 JNIEXPORT void JNICALL
795 798 Java_sun_nio_fs_UnixNativeDispatcher_access0(JNIEnv* env, jclass this,
796 799 jlong pathAddress, jint amode)
797 800 {
798 801 int err;
799 802 const char* path = (const char*)jlong_to_ptr(pathAddress);
800 803
801 804 RESTARTABLE(access(path, (int)amode), err);
802 805 if (err == -1) {
803 806 throwUnixException(env, errno);
804 807 }
805 808 }
806 809
807 810 JNIEXPORT void JNICALL
808 811 Java_sun_nio_fs_UnixNativeDispatcher_statvfs0(JNIEnv* env, jclass this,
809 812 jlong pathAddress, jobject attrs)
810 813 {
811 814 int err;
812 815 struct statvfs64 buf;
813 816 const char* path = (const char*)jlong_to_ptr(pathAddress);
814 817
815 818
816 819 RESTARTABLE(statvfs64(path, &buf), err);
817 820 if (err == -1) {
818 821 throwUnixException(env, errno);
819 822 } else {
820 823 (*env)->SetLongField(env, attrs, attrs_f_frsize, long_to_jlong(buf.f_frsize));
821 824 (*env)->SetLongField(env, attrs, attrs_f_blocks, long_to_jlong(buf.f_blocks));
822 825 (*env)->SetLongField(env, attrs, attrs_f_bfree, long_to_jlong(buf.f_bfree));
823 826 (*env)->SetLongField(env, attrs, attrs_f_bavail, long_to_jlong(buf.f_bavail));
824 827 }
825 828 }
826 829
827 830 JNIEXPORT jlong JNICALL
828 831 Java_sun_nio_fs_UnixNativeDispatcher_pathconf0(JNIEnv* env, jclass this,
829 832 jlong pathAddress, jint name)
830 833 {
831 834 long err;
832 835 const char* path = (const char*)jlong_to_ptr(pathAddress);
833 836
834 837 err = pathconf(path, (int)name);
835 838 if (err == -1) {
836 839 throwUnixException(env, errno);
837 840 }
838 841 return (jlong)err;
839 842 }
840 843
841 844 JNIEXPORT jlong JNICALL
842 845 Java_sun_nio_fs_UnixNativeDispatcher_fpathconf(JNIEnv* env, jclass this,
843 846 jint fd, jint name)
844 847 {
845 848 long err;
846 849
847 850 err = fpathconf((int)fd, (int)name);
848 851 if (err == -1) {
849 852 throwUnixException(env, errno);
850 853 }
851 854 return (jlong)err;
852 855 }
853 856
854 857 JNIEXPORT void JNICALL
855 858 Java_sun_nio_fs_UnixNativeDispatcher_mknod0(JNIEnv* env, jclass this,
856 859 jlong pathAddress, jint mode, jlong dev)
857 860 {
858 861 int err;
859 862 const char* path = (const char*)jlong_to_ptr(pathAddress);
860 863
861 864 RESTARTABLE(mknod(path, (mode_t)mode, (dev_t)dev), err);
862 865 if (err == -1) {
863 866 throwUnixException(env, errno);
864 867 }
865 868 }
866 869
867 870 JNIEXPORT jbyteArray JNICALL
868 871 Java_sun_nio_fs_UnixNativeDispatcher_getpwuid(JNIEnv* env, jclass this, jint uid)
869 872 {
870 873 jbyteArray result = NULL;
871 874 int buflen;
872 875 char* pwbuf;
873 876
874 877 /* allocate buffer for password record */
875 878 buflen = (int)sysconf(_SC_GETPW_R_SIZE_MAX);
876 879 if (buflen == -1)
877 880 buflen = ENT_BUF_SIZE;
878 881 pwbuf = (char*)malloc(buflen);
879 882 if (pwbuf == NULL) {
880 883 JNU_ThrowOutOfMemoryError(env, "native heap");
881 884 } else {
882 885 struct passwd pwent;
883 886 struct passwd* p = NULL;
884 887 int res = 0;
885 888
886 889 errno = 0;
887 890 #ifdef __solaris__
888 891 RESTARTABLE_RETURN_PTR(getpwuid_r((uid_t)uid, &pwent, pwbuf, (size_t)buflen), p);
889 892 #else
890 893 RESTARTABLE(getpwuid_r((uid_t)uid, &pwent, pwbuf, (size_t)buflen, &p), res);
891 894 #endif
892 895
893 896 if (res != 0 || p == NULL || p->pw_name == NULL || *(p->pw_name) == '\0') {
894 897 /* not found or error */
895 898 if (errno == 0)
896 899 errno = ENOENT;
897 900 throwUnixException(env, errno);
898 901 } else {
899 902 jsize len = strlen(p->pw_name);
900 903 result = (*env)->NewByteArray(env, len);
901 904 if (result != NULL) {
902 905 (*env)->SetByteArrayRegion(env, result, 0, len, (jbyte*)(p->pw_name));
903 906 }
904 907 }
905 908 free(pwbuf);
906 909 }
907 910
908 911 return result;
909 912 }
910 913
911 914
912 915 JNIEXPORT jbyteArray JNICALL
913 916 Java_sun_nio_fs_UnixNativeDispatcher_getgrgid(JNIEnv* env, jclass this, jint gid)
914 917 {
915 918 jbyteArray result = NULL;
916 919 int buflen;
917 920 int retry;
918 921
919 922 /* initial size of buffer for group record */
920 923 buflen = (int)sysconf(_SC_GETGR_R_SIZE_MAX);
921 924 if (buflen == -1)
922 925 buflen = ENT_BUF_SIZE;
923 926
924 927 do {
925 928 struct group grent;
926 929 struct group* g = NULL;
927 930 int res = 0;
928 931
929 932 char* grbuf = (char*)malloc(buflen);
930 933 if (grbuf == NULL) {
931 934 JNU_ThrowOutOfMemoryError(env, "native heap");
932 935 return NULL;
933 936 }
934 937
935 938 errno = 0;
936 939 #ifdef __solaris__
937 940 RESTARTABLE_RETURN_PTR(getgrgid_r((gid_t)gid, &grent, grbuf, (size_t)buflen), g);
938 941 #else
939 942 RESTARTABLE(getgrgid_r((gid_t)gid, &grent, grbuf, (size_t)buflen, &g), res);
940 943 #endif
941 944
942 945 retry = 0;
943 946 if (res != 0 || g == NULL || g->gr_name == NULL || *(g->gr_name) == '\0') {
944 947 /* not found or error */
945 948 if (errno == ERANGE) {
946 949 /* insufficient buffer size so need larger buffer */
947 950 buflen += ENT_BUF_SIZE;
948 951 retry = 1;
949 952 } else {
950 953 if (errno == 0)
951 954 errno = ENOENT;
952 955 throwUnixException(env, errno);
953 956 }
954 957 } else {
955 958 jsize len = strlen(g->gr_name);
956 959 result = (*env)->NewByteArray(env, len);
957 960 if (result != NULL) {
958 961 (*env)->SetByteArrayRegion(env, result, 0, len, (jbyte*)(g->gr_name));
959 962 }
960 963 }
961 964
962 965 free(grbuf);
963 966
964 967 } while (retry);
965 968
966 969 return result;
967 970 }
968 971
969 972 JNIEXPORT jint JNICALL
970 973 Java_sun_nio_fs_UnixNativeDispatcher_getpwnam0(JNIEnv* env, jclass this,
971 974 jlong nameAddress)
972 975 {
973 976 jint uid = -1;
974 977 int buflen;
975 978 char* pwbuf;
976 979
977 980 /* allocate buffer for password record */
978 981 buflen = (int)sysconf(_SC_GETPW_R_SIZE_MAX);
979 982 if (buflen == -1)
980 983 buflen = ENT_BUF_SIZE;
981 984 pwbuf = (char*)malloc(buflen);
982 985 if (pwbuf == NULL) {
983 986 JNU_ThrowOutOfMemoryError(env, "native heap");
984 987 } else {
985 988 struct passwd pwent;
986 989 struct passwd* p = NULL;
987 990 int res = 0;
988 991 const char* name = (const char*)jlong_to_ptr(nameAddress);
989 992
990 993 errno = 0;
991 994 #ifdef __solaris__
992 995 RESTARTABLE_RETURN_PTR(getpwnam_r(name, &pwent, pwbuf, (size_t)buflen), p);
993 996 #else
994 997 RESTARTABLE(getpwnam_r(name, &pwent, pwbuf, (size_t)buflen, &p), res);
995 998 #endif
996 999
997 1000 if (res != 0 || p == NULL || p->pw_name == NULL || *(p->pw_name) == '\0') {
998 1001 /* not found or error */
999 1002 if (errno != 0 && errno != ENOENT && errno != ESRCH)
1000 1003 throwUnixException(env, errno);
1001 1004 } else {
1002 1005 uid = p->pw_uid;
1003 1006 }
1004 1007 free(pwbuf);
1005 1008 }
1006 1009
1007 1010 return uid;
1008 1011 }
1009 1012
1010 1013 JNIEXPORT jint JNICALL
1011 1014 Java_sun_nio_fs_UnixNativeDispatcher_getgrnam0(JNIEnv* env, jclass this,
1012 1015 jlong nameAddress)
1013 1016 {
1014 1017 jint gid = -1;
1015 1018 int buflen, retry;
1016 1019
1017 1020 /* initial size of buffer for group record */
1018 1021 buflen = (int)sysconf(_SC_GETGR_R_SIZE_MAX);
1019 1022 if (buflen == -1)
1020 1023 buflen = ENT_BUF_SIZE;
1021 1024
1022 1025 do {
1023 1026 struct group grent;
1024 1027 struct group* g = NULL;
1025 1028 int res = 0;
1026 1029 char *grbuf;
1027 1030 const char* name = (const char*)jlong_to_ptr(nameAddress);
1028 1031
1029 1032 grbuf = (char*)malloc(buflen);
1030 1033 if (grbuf == NULL) {
1031 1034 JNU_ThrowOutOfMemoryError(env, "native heap");
1032 1035 return -1;
1033 1036 }
1034 1037
1035 1038 errno = 0;
1036 1039 #ifdef __solaris__
1037 1040 RESTARTABLE_RETURN_PTR(getgrnam_r(name, &grent, grbuf, (size_t)buflen), g);
1038 1041 #else
1039 1042 RESTARTABLE(getgrnam_r(name, &grent, grbuf, (size_t)buflen, &g), res);
1040 1043 #endif
1041 1044
1042 1045 retry = 0;
1043 1046 if (res != 0 || g == NULL || g->gr_name == NULL || *(g->gr_name) == '\0') {
1044 1047 /* not found or error */
1045 1048 if (errno != 0 && errno != ENOENT && errno != ESRCH) {
1046 1049 if (errno == ERANGE) {
1047 1050 /* insufficient buffer size so need larger buffer */
1048 1051 buflen += ENT_BUF_SIZE;
1049 1052 retry = 1;
1050 1053 } else {
1051 1054 throwUnixException(env, errno);
1052 1055 }
1053 1056 }
1054 1057 } else {
1055 1058 gid = g->gr_gid;
1056 1059 }
1057 1060
1058 1061 free(grbuf);
1059 1062
1060 1063 } while (retry);
1061 1064
1062 1065 return gid;
1063 1066 }
1064 1067
1065 1068 JNIEXPORT jint JNICALL
1066 1069 Java_sun_nio_fs_UnixNativeDispatcher_getextmntent(JNIEnv* env, jclass this,
1067 1070 jlong value, jobject entry)
1068 1071 {
1069 1072 #ifdef __solaris__
1070 1073 struct extmnttab ent;
1071 1074 #else
1072 1075 struct mntent ent;
1073 1076 char buf[1024];
1074 1077 int buflen = sizeof(buf);
1075 1078 struct mntent* m;
1076 1079 #endif
1077 1080 FILE* fp = jlong_to_ptr(value);
1078 1081 jsize len;
1079 1082 jbyteArray bytes;
1080 1083 char* name;
1081 1084 char* dir;
1082 1085 char* fstype;
1083 1086 char* options;
1084 1087 dev_t dev;
1085 1088
1086 1089 #ifdef __solaris__
1087 1090 if (getextmntent(fp, &ent, 0))
1088 1091 return -1;
1089 1092 name = ent.mnt_special;
1090 1093 dir = ent.mnt_mountp;
1091 1094 fstype = ent.mnt_fstype;
1092 1095 options = ent.mnt_mntopts;
1093 1096 dev = makedev(ent.mnt_major, ent.mnt_minor);
1094 1097 if (dev == NODEV) {
1095 1098 /* possible bug on Solaris 8 and 9 */
1096 1099 throwUnixException(env, errno);
1097 1100 return -1;
1098 1101 }
1099 1102 #else
1100 1103 m = getmntent_r(fp, &ent, (char*)&buf, buflen);
1101 1104 if (m == NULL)
1102 1105 return -1;
1103 1106 name = m->mnt_fsname;
1104 1107 dir = m->mnt_dir;
1105 1108 fstype = m->mnt_type;
1106 1109 options = m->mnt_opts;
1107 1110 dev = 0;
1108 1111 #endif
1109 1112
1110 1113 len = strlen(name);
1111 1114 bytes = (*env)->NewByteArray(env, len);
1112 1115 if (bytes == NULL)
1113 1116 return -1;
1114 1117 (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)name);
1115 1118 (*env)->SetObjectField(env, entry, entry_name, bytes);
1116 1119
1117 1120 len = strlen(dir);
1118 1121 bytes = (*env)->NewByteArray(env, len);
1119 1122 if (bytes == NULL)
1120 1123 return -1;
1121 1124 (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)dir);
1122 1125 (*env)->SetObjectField(env, entry, entry_dir, bytes);
1123 1126
1124 1127 len = strlen(fstype);
1125 1128 bytes = (*env)->NewByteArray(env, len);
1126 1129 if (bytes == NULL)
1127 1130 return -1;
1128 1131 (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)fstype);
1129 1132 (*env)->SetObjectField(env, entry, entry_fstype, bytes);
1130 1133
1131 1134 len = strlen(options);
1132 1135 bytes = (*env)->NewByteArray(env, len);
1133 1136 if (bytes == NULL)
1134 1137 return -1;
1135 1138 (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)options);
1136 1139 (*env)->SetObjectField(env, entry, entry_options, bytes);
1137 1140
1138 1141 if (dev != 0)
1139 1142 (*env)->SetLongField(env, entry, entry_dev, (jlong)dev);
1140 1143
1141 1144 return 0;
1142 1145 }
↓ open down ↓ |
522 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX