--- a/jdk/src/solaris/native/sun/nio/fs/UnixNativeDispatcher.c Thu Feb 03 12:57:04 2011 +0000
+++ b/jdk/src/solaris/native/sun/nio/fs/UnixNativeDispatcher.c Thu Feb 03 13:37:42 2011 +0000
@@ -55,12 +55,23 @@
#include "sun_nio_fs_UnixNativeDispatcher.h"
+/**
+ * Size of password or group entry when not available via sysconf
+ */
+#define ENT_BUF_SIZE 1024
+
#define RESTARTABLE(_cmd, _result) do { \
do { \
_result = _cmd; \
} while((_result == -1) && (errno == EINTR)); \
} while(0)
+#define RESTARTABLE_RETURN_PTR(_cmd, _result) do { \
+ do { \
+ _result = _cmd; \
+ } while((_result == NULL) && (errno == EINTR)); \
+} while(0)
+
static jfieldID attrs_st_mode;
static jfieldID attrs_st_ino;
static jfieldID attrs_st_dev;
@@ -858,37 +869,41 @@
{
jbyteArray result = NULL;
int buflen;
+ char* pwbuf;
+ /* allocate buffer for password record */
buflen = (int)sysconf(_SC_GETPW_R_SIZE_MAX);
- if (buflen == -1) {
- throwUnixException(env, errno);
+ if (buflen == -1)
+ buflen = ENT_BUF_SIZE;
+ pwbuf = (char*)malloc(buflen);
+ if (pwbuf == NULL) {
+ JNU_ThrowOutOfMemoryError(env, "native heap");
} else {
- char* pwbuf = (char*)malloc(buflen);
- if (pwbuf == NULL) {
- JNU_ThrowOutOfMemoryError(env, "native heap");
- } else {
- struct passwd pwent;
- struct passwd* p;
- int res = 0;
+ struct passwd pwent;
+ struct passwd* p = NULL;
+ int res = 0;
-#ifdef __solaris__
- p = getpwuid_r((uid_t)uid, &pwent, pwbuf, (size_t)buflen);
-#else
- res = getpwuid_r((uid_t)uid, &pwent, pwbuf, (size_t)buflen, &p);
-#endif
+ errno = 0;
+ #ifdef __solaris__
+ RESTARTABLE_RETURN_PTR(getpwuid_r((uid_t)uid, &pwent, pwbuf, (size_t)buflen), p);
+ #else
+ RESTARTABLE(getpwuid_r((uid_t)uid, &pwent, pwbuf, (size_t)buflen, &p), res);
+ #endif
- if (res != 0 || p == NULL || p->pw_name == NULL || *(p->pw_name) == '\0') {
+ if (res != 0 || p == NULL || p->pw_name == NULL || *(p->pw_name) == '\0') {
+ /* not found or error */
+ if (errno != 0 && errno != ENOENT)
throwUnixException(env, errno);
- } else {
- jsize len = strlen(p->pw_name);
- result = (*env)->NewByteArray(env, len);
- if (result != NULL) {
- (*env)->SetByteArrayRegion(env, result, 0, len, (jbyte*)(p->pw_name));
- }
+ } else {
+ jsize len = strlen(p->pw_name);
+ result = (*env)->NewByteArray(env, len);
+ if (result != NULL) {
+ (*env)->SetByteArrayRegion(env, result, 0, len, (jbyte*)(p->pw_name));
}
- free(pwbuf);
}
+ free(pwbuf);
}
+
return result;
}
@@ -898,36 +913,55 @@
{
jbyteArray result = NULL;
int buflen;
+ int retry;
+ /* initial size of buffer for group record */
buflen = (int)sysconf(_SC_GETGR_R_SIZE_MAX);
- if (buflen == -1) {
- throwUnixException(env, errno);
- } else {
+ if (buflen == -1)
+ buflen = ENT_BUF_SIZE;
+
+ do {
+ struct group grent;
+ struct group* g = NULL;
+ int res = 0;
+
char* grbuf = (char*)malloc(buflen);
if (grbuf == NULL) {
JNU_ThrowOutOfMemoryError(env, "native heap");
- } else {
- struct group grent;
- struct group* g;
- int res = 0;
+ return NULL;
+ }
+
+ errno = 0;
+ #ifdef __solaris__
+ RESTARTABLE_RETURN_PTR(getgrgid_r((gid_t)gid, &grent, grbuf, (size_t)buflen), g);
+ #else
+ RESTARTABLE(getgrgid_r((gid_t)gid, &grent, grbuf, (size_t)buflen, &g), res);
+ #endif
-#ifdef __solaris__
- g = getgrgid_r((gid_t)gid, &grent, grbuf, (size_t)buflen);
-#else
- res = getgrgid_r((gid_t)gid, &grent, grbuf, (size_t)buflen, &g);
-#endif
- if (res != 0 || g == NULL || g->gr_name == NULL || *(g->gr_name) == '\0') {
- throwUnixException(env, errno);
- } else {
- jsize len = strlen(g->gr_name);
- result = (*env)->NewByteArray(env, len);
- if (result != NULL) {
- (*env)->SetByteArrayRegion(env, result, 0, len, (jbyte*)(g->gr_name));
+ retry = 0;
+ if (res != 0 || g == NULL || g->gr_name == NULL || *(g->gr_name) == '\0') {
+ /* not found or error */
+ if (errno != 0 && errno != ENOENT) {
+ if (errno == ERANGE) {
+ /* insufficient buffer size so need larger buffer */
+ buflen += ENT_BUF_SIZE;
+ retry = 1;
+ } else {
+ throwUnixException(env, errno);
}
}
- free(grbuf);
+ } else {
+ jsize len = strlen(g->gr_name);
+ result = (*env)->NewByteArray(env, len);
+ if (result != NULL) {
+ (*env)->SetByteArrayRegion(env, result, 0, len, (jbyte*)(g->gr_name));
+ }
}
- }
+
+ free(grbuf);
+
+ } while (retry);
+
return result;
}
@@ -938,36 +972,37 @@
jint uid = -1;
int buflen;
char* pwbuf;
- struct passwd pwent;
- struct passwd* p;
- int res = 0;
- const char* name = (const char*)jlong_to_ptr(nameAddress);
+ /* allocate buffer for password record */
buflen = (int)sysconf(_SC_GETPW_R_SIZE_MAX);
- if (buflen == -1) {
- throwUnixException(env, errno);
- return -1;
- }
+ if (buflen == -1)
+ buflen = ENT_BUF_SIZE;
pwbuf = (char*)malloc(buflen);
if (pwbuf == NULL) {
JNU_ThrowOutOfMemoryError(env, "native heap");
- return -1;
- }
+ } else {
+ struct passwd pwent;
+ struct passwd* p = NULL;
+ int res = 0;
+ const char* name = (const char*)jlong_to_ptr(nameAddress);
-#ifdef __solaris__
- p = getpwnam_r(name, &pwent, pwbuf, (size_t)buflen);
-#else
- res = getpwnam_r(name, &pwent, pwbuf, (size_t)buflen, &p);
-#endif
+ errno = 0;
+ #ifdef __solaris__
+ RESTARTABLE_RETURN_PTR(getpwnam_r(name, &pwent, pwbuf, (size_t)buflen), p);
+ #else
+ RESTARTABLE(getpwnam_r(name, &pwent, pwbuf, (size_t)buflen, &p), res);
+ #endif
- if (res != 0 || p == NULL || p->pw_name == NULL || *(p->pw_name) == '\0') {
- /* not found or error */
- } else {
- uid = p->pw_uid;
+ if (res != 0 || p == NULL || p->pw_name == NULL || *(p->pw_name) == '\0') {
+ /* not found or error */
+ if (errno != 0 && errno != ENOENT)
+ throwUnixException(env, errno);
+ } else {
+ uid = p->pw_uid;
+ }
+ free(pwbuf);
}
- free(pwbuf);
-
return uid;
}
@@ -976,36 +1011,52 @@
jlong nameAddress)
{
jint gid = -1;
- int buflen;
- char* grbuf;
- struct group grent;
- struct group* g;
- int res = 0;
- const char* name = (const char*)jlong_to_ptr(nameAddress);
+ int buflen, retry;
+ /* initial size of buffer for group record */
buflen = (int)sysconf(_SC_GETGR_R_SIZE_MAX);
- if (buflen == -1) {
- throwUnixException(env, errno);
- return -1;
- }
- grbuf = (char*)malloc(buflen);
- if (grbuf == NULL) {
- JNU_ThrowOutOfMemoryError(env, "native heap");
- return -1;
- }
+ if (buflen == -1)
+ buflen = ENT_BUF_SIZE;
+
+ do {
+ struct group grent;
+ struct group* g = NULL;
+ int res = 0;
+ char *grbuf;
+ const char* name = (const char*)jlong_to_ptr(nameAddress);
+
+ grbuf = (char*)malloc(buflen);
+ if (grbuf == NULL) {
+ JNU_ThrowOutOfMemoryError(env, "native heap");
+ return -1;
+ }
-#ifdef __solaris__
- g = getgrnam_r(name, &grent, grbuf, (size_t)buflen);
-#else
- res = getgrnam_r(name, &grent, grbuf, (size_t)buflen, &g);
-#endif
+ errno = 0;
+ #ifdef __solaris__
+ RESTARTABLE_RETURN_PTR(getgrnam_r(name, &grent, grbuf, (size_t)buflen), g);
+ #else
+ RESTARTABLE(getgrnam_r(name, &grent, grbuf, (size_t)buflen, &g), res);
+ #endif
- if (res != 0 || g == NULL || g->gr_name == NULL || *(g->gr_name) == '\0') {
- /* not found or error */
- } else {
- gid = g->gr_gid;
- }
- free(grbuf);
+ retry = 0;
+ if (res != 0 || g == NULL || g->gr_name == NULL || *(g->gr_name) == '\0') {
+ /* not found or error */
+ if (errno != 0 && errno != ENOENT) {
+ if (errno == ERANGE) {
+ /* insufficient buffer size so need larger buffer */
+ buflen += ENT_BUF_SIZE;
+ retry = 1;
+ } else {
+ throwUnixException(env, errno);
+ }
+ }
+ } else {
+ gid = g->gr_gid;
+ }
+
+ free(grbuf);
+
+ } while (retry);
return gid;
}