src/solaris/native/sun/nio/fs/UnixNativeDispatcher.c
Print this page
rev 8725 : 8024854: Basic changes and files to build the class library on AIX
Contributed-by: luchsh@linux.vnet.ibm.com, spoole@linux.vnet.ibm.com, thomas.stuefe@sap.com
Reviewed-by: alanb, prr, sla, chegar, michaelm, mullan
@@ -40,11 +40,11 @@
#ifdef __solaris__
#include <strings.h>
#endif
-#ifdef __linux__
+#if defined(__linux__) || defined(_AIX)
#include <string.h>
#endif
#ifdef _ALLBSD_SOURCE
#include <string.h>
@@ -292,11 +292,17 @@
{
char* msg;
jsize len;
jbyteArray bytes;
+#ifdef _AIX
+ /* strerror() is not thread-safe on AIX so we have to use strerror_r() */
+ char buffer[256];
+ msg = (strerror_r((int)error, buffer, 256) == 0) ? buffer : "Error while calling strerror_r";
+#else
msg = strerror((int)error);
+#endif
len = strlen(msg);
bytes = (*env)->NewByteArray(env, len);
if (bytes != NULL) {
(*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)msg);
}
@@ -672,10 +678,19 @@
DIR* dirp = jlong_to_ptr(value);
/* EINTR not listed as a possible error */
/* TDB: reentrant version probably not required here */
res = readdir64_r(dirp, ptr, &result);
+
+#ifdef _AIX
+ /* On AIX, readdir_r() returns EBADF (i.e. '9') and sets 'result' to NULL for the */
+ /* directory stream end. Otherwise, 'errno' will contain the error code. */
+ if (res != 0) {
+ res = (result == NULL && res == EBADF) ? 0 : errno;
+ }
+#endif
+
if (res != 0) {
throwUnixException(env, res);
return NULL;
} else {
if (result == NULL) {
@@ -875,10 +890,22 @@
RESTARTABLE(statvfs64(path, &buf), err);
if (err == -1) {
throwUnixException(env, errno);
} else {
+#ifdef _AIX
+ /* AIX returns ULONG_MAX in buf.f_blocks for the /proc file system. */
+ /* This is too big for a Java signed long and fools various tests. */
+ if (buf.f_blocks == ULONG_MAX) {
+ buf.f_blocks = 0;
+ }
+ /* The number of free or available blocks can never exceed the total number of blocks */
+ if (buf.f_blocks == 0) {
+ buf.f_bfree = 0;
+ buf.f_bavail = 0;
+ }
+#endif
(*env)->SetLongField(env, attrs, attrs_f_frsize, long_to_jlong(buf.f_frsize));
(*env)->SetLongField(env, attrs, attrs_f_blocks, long_to_jlong(buf.f_blocks));
(*env)->SetLongField(env, attrs, attrs_f_bfree, long_to_jlong(buf.f_bfree));
(*env)->SetLongField(env, attrs, attrs_f_bavail, long_to_jlong(buf.f_bavail));
}
@@ -951,11 +978,16 @@
#endif
if (res != 0 || p == NULL || p->pw_name == NULL || *(p->pw_name) == '\0') {
/* not found or error */
if (errno == 0)
+#ifdef _AIX
+ /* On AIX, getpwuid_r returns ESRCH if user does not exist. */
+ errno = ESRCH;
+#else
errno = ENOENT;
+#endif
throwUnixException(env, errno);
} else {
jsize len = strlen(p->pw_name);
result = (*env)->NewByteArray(env, len);
if (result != NULL) {
@@ -1006,11 +1038,16 @@
/* insufficient buffer size so need larger buffer */
buflen += ENT_BUF_SIZE;
retry = 1;
} else {
if (errno == 0)
+#ifdef _AIX
+ /* On AIX, getgrgid_r returns ESRCH if group does not exist. */
+ errno = ESRCH;
+#else
errno = ENOENT;
+#endif
throwUnixException(env, errno);
}
} else {
jsize len = strlen(g->gr_name);
result = (*env)->NewByteArray(env, len);