src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c

Print this page
rev 10532 : 8055421: (fs) bad error handling in java.base/unix/native/libnio/fs/UnixNativeDispatcher.c


 316     /* strerror() is not thread-safe on AIX so we have to use strerror_r() */
 317     char buffer[256];
 318     msg = (strerror_r((int)error, buffer, 256) == 0) ? buffer : "Error while calling strerror_r";
 319 #else
 320     msg = strerror((int)error);
 321 #endif
 322     len = strlen(msg);
 323     bytes = (*env)->NewByteArray(env, len);
 324     if (bytes != NULL) {
 325         (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)msg);
 326     }
 327     return bytes;
 328 }
 329 
 330 JNIEXPORT jint
 331 Java_sun_nio_fs_UnixNativeDispatcher_dup(JNIEnv* env, jclass this, jint fd) {
 332 
 333     int res = -1;
 334 
 335     RESTARTABLE(dup((int)fd), res);
 336     if (fd == -1) {
 337         throwUnixException(env, errno);
 338     }
 339     return (jint)res;
 340 }
 341 
 342 JNIEXPORT jlong JNICALL
 343 Java_sun_nio_fs_UnixNativeDispatcher_fopen0(JNIEnv* env, jclass this,
 344     jlong pathAddress, jlong modeAddress)
 345 {
 346     FILE* fp = NULL;
 347     const char* path = (const char*)jlong_to_ptr(pathAddress);
 348     const char* mode = (const char*)jlong_to_ptr(modeAddress);
 349 
 350     do {
 351         fp = fopen(path, mode);
 352     } while (fp == NULL && errno == EINTR);
 353 
 354     if (fp == NULL) {
 355         throwUnixException(env, errno);
 356     }
 357 
 358     return ptr_to_jlong(fp);
 359 }
 360 
 361 JNIEXPORT void JNICALL
 362 Java_sun_nio_fs_UnixNativeDispatcher_fclose(JNIEnv* env, jclass this, jlong stream)
 363 {
 364     int res;
 365     FILE* fp = jlong_to_ptr(stream);
 366 
 367     do {
 368         res = fclose(fp);
 369     } while (res == EOF && errno == EINTR);
 370     if (res == EOF) {


 371         throwUnixException(env, errno);
 372     }
 373 }
 374 
 375 JNIEXPORT jint JNICALL
 376 Java_sun_nio_fs_UnixNativeDispatcher_open0(JNIEnv* env, jclass this,
 377     jlong pathAddress, jint oflags, jint mode)
 378 {
 379     jint fd;
 380     const char* path = (const char*)jlong_to_ptr(pathAddress);
 381 
 382     RESTARTABLE(open64(path, (int)oflags, (mode_t)mode), fd);
 383     if (fd == -1) {
 384         throwUnixException(env, errno);
 385     }
 386     return fd;
 387 }
 388 
 389 JNIEXPORT jint JNICALL
 390 Java_sun_nio_fs_UnixNativeDispatcher_openat0(JNIEnv* env, jclass this, jint dfd,


 658 
 659 JNIEXPORT jlong JNICALL
 660 Java_sun_nio_fs_UnixNativeDispatcher_fdopendir(JNIEnv* env, jclass this, int dfd) {
 661     DIR* dir;
 662 
 663     if (my_fdopendir_func == NULL) {
 664         JNU_ThrowInternalError(env, "should not reach here");
 665         return (jlong)-1;
 666     }
 667 
 668     /* EINTR not listed as a possible error */
 669     dir = (*my_fdopendir_func)((int)dfd);
 670     if (dir == NULL) {
 671         throwUnixException(env, errno);
 672     }
 673     return ptr_to_jlong(dir);
 674 }
 675 
 676 JNIEXPORT void JNICALL
 677 Java_sun_nio_fs_UnixNativeDispatcher_closedir(JNIEnv* env, jclass this, jlong dir) {
 678     int err;
 679     DIR* dirp = jlong_to_ptr(dir);
 680 
 681     RESTARTABLE(closedir(dirp), err);
 682     if (errno == -1) {
 683         throwUnixException(env, errno);
 684     }
 685 }
 686 
 687 JNIEXPORT jbyteArray JNICALL
 688 Java_sun_nio_fs_UnixNativeDispatcher_readdir(JNIEnv* env, jclass this, jlong value) {
 689     struct dirent64* result;
 690     struct {
 691         struct dirent64 buf;
 692         char name_extra[PATH_MAX + 1 - sizeof result->d_name];
 693     } entry;
 694     struct dirent64* ptr = &entry.buf;
 695     int res;
 696     DIR* dirp = jlong_to_ptr(value);
 697 
 698     /* EINTR not listed as a possible error */
 699     /* TDB: reentrant version probably not required here */
 700     res = readdir64_r(dirp, ptr, &result);
 701 
 702 #ifdef _AIX




 316     /* strerror() is not thread-safe on AIX so we have to use strerror_r() */
 317     char buffer[256];
 318     msg = (strerror_r((int)error, buffer, 256) == 0) ? buffer : "Error while calling strerror_r";
 319 #else
 320     msg = strerror((int)error);
 321 #endif
 322     len = strlen(msg);
 323     bytes = (*env)->NewByteArray(env, len);
 324     if (bytes != NULL) {
 325         (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)msg);
 326     }
 327     return bytes;
 328 }
 329 
 330 JNIEXPORT jint
 331 Java_sun_nio_fs_UnixNativeDispatcher_dup(JNIEnv* env, jclass this, jint fd) {
 332 
 333     int res = -1;
 334 
 335     RESTARTABLE(dup((int)fd), res);
 336     if (res == -1) {
 337         throwUnixException(env, errno);
 338     }
 339     return (jint)res;
 340 }
 341 
 342 JNIEXPORT jlong JNICALL
 343 Java_sun_nio_fs_UnixNativeDispatcher_fopen0(JNIEnv* env, jclass this,
 344     jlong pathAddress, jlong modeAddress)
 345 {
 346     FILE* fp = NULL;
 347     const char* path = (const char*)jlong_to_ptr(pathAddress);
 348     const char* mode = (const char*)jlong_to_ptr(modeAddress);
 349 
 350     do {
 351         fp = fopen(path, mode);
 352     } while (fp == NULL && errno == EINTR);
 353 
 354     if (fp == NULL) {
 355         throwUnixException(env, errno);
 356     }
 357 
 358     return ptr_to_jlong(fp);
 359 }
 360 
 361 JNIEXPORT void JNICALL
 362 Java_sun_nio_fs_UnixNativeDispatcher_fclose(JNIEnv* env, jclass this, jlong stream)
 363 {

 364     FILE* fp = jlong_to_ptr(stream);
 365 
 366     /* NOTE: fclose() wrapper is only used with read-only streams.
 367      * If it ever is used with write streams, it might be better to add
 368      * RESTARTABLE(fflush(fp)) before closing, to make sure the stream
 369      * is completely written even if fclose() failed.
 370      */
 371     if (fclose(fp) == EOF && errno != EINTR) {
 372         throwUnixException(env, errno);
 373     }
 374 }
 375 
 376 JNIEXPORT jint JNICALL
 377 Java_sun_nio_fs_UnixNativeDispatcher_open0(JNIEnv* env, jclass this,
 378     jlong pathAddress, jint oflags, jint mode)
 379 {
 380     jint fd;
 381     const char* path = (const char*)jlong_to_ptr(pathAddress);
 382 
 383     RESTARTABLE(open64(path, (int)oflags, (mode_t)mode), fd);
 384     if (fd == -1) {
 385         throwUnixException(env, errno);
 386     }
 387     return fd;
 388 }
 389 
 390 JNIEXPORT jint JNICALL
 391 Java_sun_nio_fs_UnixNativeDispatcher_openat0(JNIEnv* env, jclass this, jint dfd,


 659 
 660 JNIEXPORT jlong JNICALL
 661 Java_sun_nio_fs_UnixNativeDispatcher_fdopendir(JNIEnv* env, jclass this, int dfd) {
 662     DIR* dir;
 663 
 664     if (my_fdopendir_func == NULL) {
 665         JNU_ThrowInternalError(env, "should not reach here");
 666         return (jlong)-1;
 667     }
 668 
 669     /* EINTR not listed as a possible error */
 670     dir = (*my_fdopendir_func)((int)dfd);
 671     if (dir == NULL) {
 672         throwUnixException(env, errno);
 673     }
 674     return ptr_to_jlong(dir);
 675 }
 676 
 677 JNIEXPORT void JNICALL
 678 Java_sun_nio_fs_UnixNativeDispatcher_closedir(JNIEnv* env, jclass this, jlong dir) {

 679     DIR* dirp = jlong_to_ptr(dir);
 680 
 681     if (closedir(dirp) == -1 && errno != EINTR) {

 682         throwUnixException(env, errno);
 683     }
 684 }
 685 
 686 JNIEXPORT jbyteArray JNICALL
 687 Java_sun_nio_fs_UnixNativeDispatcher_readdir(JNIEnv* env, jclass this, jlong value) {
 688     struct dirent64* result;
 689     struct {
 690         struct dirent64 buf;
 691         char name_extra[PATH_MAX + 1 - sizeof result->d_name];
 692     } entry;
 693     struct dirent64* ptr = &entry.buf;
 694     int res;
 695     DIR* dirp = jlong_to_ptr(value);
 696 
 697     /* EINTR not listed as a possible error */
 698     /* TDB: reentrant version probably not required here */
 699     res = readdir64_r(dirp, ptr, &result);
 700 
 701 #ifdef _AIX