From b18a28763c93ab493af8613abe08fed003ed112a Mon Sep 17 00:00:00 2001 From: "U-IBM394-PC055PQL\\sondhi" Date: Tue, 5 Apr 2016 20:51:57 +0530 Subject: [PATCH] Issue #61: Introducing a new Port Library API for obtaining open file count. Signed-off-by: Sondhi Chakraborty --- fvtest/porttest/si.cpp | 175 +++++++++++++++++++++++++++++++++++- include_core/omrport.h | 4 + include_core/omrporterror.h | 2 + port/common/omrport.c | 1 + port/common/omrport.tdf | 8 ++ port/common/omrsysinfo.c | 22 ++++- port/omrportpriv.h | 3 +- port/unix/omrsysinfo.c | 109 +++++++++++++++++++++- port/win32/omrsysinfo.c | 7 ++ 9 files changed, 327 insertions(+), 4 deletions(-) diff --git a/fvtest/porttest/si.cpp b/fvtest/porttest/si.cpp index 7c390951f9d..eedd54a0599 100644 --- a/fvtest/porttest/si.cpp +++ b/fvtest/porttest/si.cpp @@ -32,6 +32,13 @@ #if !(defined(WIN32) || defined(WIN64)) #include #include +#if defined(J9ZOS390) +#include +#else +#define __STDC_LIMIT_MACROS +#include /* For INT64_MAX. */ +#endif /* defined(J9ZOS390) */ +#include /* For RLIM_INFINITY */ #endif /* !(defined(WIN32) || defined(WIN64)) */ #if defined(J9ZOS390) @@ -49,6 +56,13 @@ #define J9DIRECTORY_SEPARATOR_CHARACTER '/' #endif +/* Under the standard compiler configuration, INT64_MAX is + * not available; instead, LONGLONG_MAX is defined by xLC. + */ +#if defined(J9ZOS390) && !defined(INT64_MAX) +#define INT64_MAX LONGLONG_MAX +#endif /* defined(J9ZOS390) && !defined(INT64_MAX) */ + /** * @brief Function takes an expected name for an executable and also the name that was actually * found using the Port API. It then tries to match these, in a OS specific manner. For example, @@ -872,7 +886,95 @@ TEST(PortSysinfoTest, sysinfo_test_sysinfo_set_limit_CORE_FLAGS) } #endif /* defined(AIXPPC) */ -#endif /* !defined(WIN32) || !defined(WIN64) */ +/** + * Test omrsysinfo_test_sysinfo_get_limit for resource OMRPORT_RESOURCE_FILE_DESCRIPTORS. + * API available on all Unix platforms. + */ +TEST(PortSysinfoTest, sysinfo_test_sysinfo_get_limit_FILE_DESCRIPTORS) +{ + OMRPORT_ACCESS_FROM_OMRPORT(portTestEnv->getPortLibrary()); + const char *testName = "omrsysinfo_test_sysinfo_get_limit_FILE_DESCRIPTORS"; + uint32_t rc = 0; + uint64_t curLimit = 0; + uint64_t maxLimit = 0; + + reportTestEntry(OMRPORTLIB, testName); + /* First, get the current (soft) limit on the resource nofiles. */ + rc = omrsysinfo_get_limit(OMRPORT_RESOURCE_FILE_DESCRIPTORS, &curLimit); + if (OMRPORT_LIMIT_UNLIMITED == rc) { /* Not an error, just that it is not configured. */ + /* If the API reported this limit as set to "unlimited", the resource limit must be + * set to implementation-defined limit, RLIM_INFINITY. + */ + if (RLIM_INFINITY == curLimit) { + outputComment(OMRPORTLIB, + "omrsysinfo_get_limit(nofiles): soft limit=RLIM_INFINITY (unlimited).\n"); + } else { + outputErrorMessage(PORTTEST_ERROR_ARGS, + "omrsysinfo_get_limit(nofiles): soft limit (unlimited), bad maximum reported %lld.\n", + ((int64_t) curLimit)); + reportTestExit(OMRPORTLIB, testName); + return; + } + } else if (OMRPORT_LIMIT_LIMITED == rc) { + if ((((int64_t) curLimit) > 0) && (((int64_t) curLimit) <= INT64_MAX)) { + outputComment(OMRPORTLIB, "omrsysinfo_get_limit(nofiles) soft limit: %lld.\n", + ((int64_t) curLimit)); + } else { + outputErrorMessage(PORTTEST_ERROR_ARGS, + "omrsysinfo_get_limit(nofiles) failed: bad limit received!\n"); + reportTestExit(OMRPORTLIB, testName); + return; + } + } else { /* The port library failed! */ + outputErrorMessage(PORTTEST_ERROR_ARGS, + "omrsysinfo_get_limit(nofiles): failed with error code=%d.\n", + omrerror_last_error_number()); + reportTestExit(OMRPORTLIB, testName); + return; + } + + /* Now, for the hard limit. */ + rc = omrsysinfo_get_limit(OMRPORT_RESOURCE_FILE_DESCRIPTORS | OMRPORT_LIMIT_HARD, &maxLimit); + if (OMRPORT_LIMIT_UNLIMITED == rc) { + /* Not an error, just that it is not configured. Ok to compare!. */ + if (RLIM_INFINITY == maxLimit) { + outputComment(OMRPORTLIB, + "omrsysinfo_get_limit(nofiles): hard limit = RLIM_INFINITY (unlimited).\n"); + } else { + outputErrorMessage(PORTTEST_ERROR_ARGS, + "omrsysinfo_get_limit(nofiles): hard limit (unlimited), bad maximum reported %lld.\n", + ((int64_t) curLimit)); + reportTestExit(OMRPORTLIB, testName); + return; + } + } else if (OMRPORT_LIMIT_LIMITED == rc) { + if ((((int64_t) maxLimit) > 0) && (((int64_t) maxLimit) <= INT64_MAX)) { + outputComment(OMRPORTLIB, "omrsysinfo_get_limit(nofiles) hard limit: %lld.\n", + ((int64_t) maxLimit)); + } else { + outputErrorMessage(PORTTEST_ERROR_ARGS, + "omrsysinfo_get_limit(nofiles) failed: bad limit received!\n"); + reportTestExit(OMRPORTLIB, testName); + return; + } + } else { /* The port library failed! */ + outputErrorMessage(PORTTEST_ERROR_ARGS, + "omrsysinfo_get_limit(nofiles): failed with error code=%d.\n", + omrerror_last_error_number()); + reportTestExit(OMRPORTLIB, testName); + return; + } + + /* Ensure that the resource's current (soft) limit does not exceed the hard limit. */ + if (curLimit > maxLimit) { + outputErrorMessage(PORTTEST_ERROR_ARGS, + "omrsysinfo_get_limit(nofiles): current limit exceeds the hard limit.\n"); + reportTestExit(OMRPORTLIB, testName); + return; + } + reportTestExit(OMRPORTLIB, testName); +} +#endif /* !(defined(WIN32) || defined(WIN64)) */ /* Since the processor and memory usage port library APIs are not available on zOS (neither * 31-bit not 64-bit) yet, so we exclude these tests from running on zOS. When the zOS @@ -1845,4 +1947,75 @@ TEST(PortSysinfoTest, sysinfo_test_get_groups) } reportTestExit(OMRPORTLIB, testName); } + +#if defined(LINUX) || defined(AIXPPC) +/** + * Test omrsysinfo_test_get_open_file_count. + * Available only on Linux and AIX. + */ +TEST(PortSysinfoTest, sysinfo_test_get_open_file_count) +{ + OMRPORT_ACCESS_FROM_OMRPORT(portTestEnv->getPortLibrary()); + const char *testName = "omrsysinfo_test_get_open_file_count"; + int32_t ret = 0; + uint64_t openCount = 0; + uint64_t curLimit = 0; + uint32_t rc = 0; + + reportTestEntry(OMRPORTLIB, testName); + /* Get the number of files opened till this point. */ + ret = omrsysinfo_get_open_file_count(&openCount); + if (ret < 0) { + outputErrorMessage(PORTTEST_ERROR_ARGS, "omrsysinfo_get_open_file_count() failed.\n"); + reportTestExit(OMRPORTLIB, testName); + return; + } + outputComment(OMRPORTLIB, "omrsysinfo_get_open_file_count(): Files opened by this process=%lld\n", + openCount); + + /* Now, get the current (soft) limit on the resource "nofiles". We check the current + * number of files opened, against this. + */ + rc = omrsysinfo_get_limit(OMRPORT_RESOURCE_FILE_DESCRIPTORS, &curLimit); + if (OMRPORT_LIMIT_UNLIMITED == rc) { + /* Not really an error, just a sentinel. Comparisons can still work! */ + if (RLIM_INFINITY == curLimit) { + outputComment(OMRPORTLIB, + "omrsysinfo_get_limit(nofiles): soft limit=RLIM_INFINITY (unlimited).\n"); + } else { + outputErrorMessage(PORTTEST_ERROR_ARGS, + "omrsysinfo_get_limit(nofiles): soft limit (unlimited), bad maximum reported=%lld.\n", + ((int64_t) curLimit)); + reportTestExit(OMRPORTLIB, testName); + return; + } + } else if (OMRPORT_LIMIT_LIMITED == rc) { + /* Check that the limits received are sane, before comparing against files opened. */ + if ((((int64_t) curLimit) > 0) && (((int64_t) curLimit) <= INT64_MAX)) { + outputComment(OMRPORTLIB, "omrsysinfo_get_limit(nofiles): soft limit=%lld.\n", + ((int64_t) curLimit)); + } else { + outputErrorMessage(PORTTEST_ERROR_ARGS, + "omrsysinfo_get_limit(nofiles) failed: bad limits received!\n"); + reportTestExit(OMRPORTLIB, testName); + return; + } + } else { /* The port library failed! */ + outputErrorMessage(PORTTEST_ERROR_ARGS, + "omrsysinfo_get_limit(nofiles): failed with error code=%d.\n", + omrerror_last_error_number()); + reportTestExit(OMRPORTLIB, testName); + return; + } + /* Sanity check: are more files reported as opened than the limit? */ + if (((int64_t) openCount) > ((int64_t) curLimit)) { + outputErrorMessage(PORTTEST_ERROR_ARGS, + "omrsysinfo_get_open_file_count() failed: reports more files opened than allowed!\n"); + reportTestExit(OMRPORTLIB, testName); + return; + } + reportTestExit(OMRPORTLIB, testName); + return; +} +#endif /* defined(LINUX) || defined(AIXPPC) */ #endif /* !(defined(WIN32) || defined(WIN64)) */ diff --git a/include_core/omrport.h b/include_core/omrport.h index 11eccd3f5d1..a99dc65c744 100644 --- a/include_core/omrport.h +++ b/include_core/omrport.h @@ -128,6 +128,7 @@ #define OMRPORT_RESOURCE_ADDRESS_SPACE ((uintptr_t) 2) #define OMRPORT_RESOURCE_CORE_FILE ((uintptr_t) 3) #define OMRPORT_RESOURCE_CORE_FLAGS ((uintptr_t) 4) +#define OMRPORT_RESOURCE_FILE_DESCRIPTORS ((uintptr_t) 5) /** @} */ /** @@ -1323,6 +1324,8 @@ typedef struct OMRPortLibrary { intptr_t (*sysinfo_get_tmp)(struct OMRPortLibrary *portLibrary, char *buf, uintptr_t bufLen, BOOLEAN ignoreEnvVariable) ; /** see @ref omrsysinfo.c::omrsysinfo_get_number_CPUs_by_type "omrsysinfo_get_number_CPUs_by_type"*/ void (*sysinfo_set_number_entitled_CPUs)(struct OMRPortLibrary *portLibrary, uintptr_t number) ; + /** see @ref omrsysinfo.c::omrsysinfo_get_open_file_count "omrsysinfo_get_open_file_count"*/ + int32_t (*sysinfo_get_open_file_count)(struct OMRPortLibrary *portLibrary, uint64_t *count) ; /** see @ref omrport.c::omrport_init_library "omrport_init_library"*/ int32_t (*port_init_library)(struct OMRPortLibrary *portLibrary, uintptr_t size) ; /** see @ref omrport.c::omrport_startup_library "omrport_startup_library"*/ @@ -1745,6 +1748,7 @@ extern J9_CFUNC int32_t omrport_getVersion(struct OMRPortLibrary *portLibrary); #define omrsysinfo_get_number_CPUs_by_type(param1) privateOmrPortLibrary->sysinfo_get_number_CPUs_by_type(privateOmrPortLibrary, (param1)) #define omrsysinfo_get_cwd(param1,param2) privateOmrPortLibrary->sysinfo_get_cwd(privateOmrPortLibrary, (param1), (param2)) #define omrsysinfo_get_tmp(param1,param2,param3) privateOmrPortLibrary->sysinfo_get_tmp(privateOmrPortLibrary, (param1), (param2), (param3)) +#define omrsysinfo_get_open_file_count(param1) privateOmrPortLibrary->sysinfo_get_open_file_count(privateOmrPortLibrary, (param1)) #define omrintrospect_startup() privateOmrPortLibrary->introspect_startup(privateOmrPortLibrary) #define omrintrospect_shutdown() privateOmrPortLibrary->introspect_shutdown(privateOmrPortLibrary) #define omrintrospect_set_suspend_signal_offset(param1) privateOmrPortLibrary->introspect_set_suspend_signal_offset(privateOmrPortLibrary, param1) diff --git a/include_core/omrporterror.h b/include_core/omrporterror.h index efd703332be..c4a47bb47dc 100644 --- a/include_core/omrporterror.h +++ b/include_core/omrporterror.h @@ -164,6 +164,7 @@ #define OMRPORT_ERROR_FILE_IO_PENDING (OMRPORT_ERROR_FILE_BASE-38) #define OMRPORT_ERROR_FILE_READ_NO_BYTES_READ (OMRPORT_ERROR_FILE_BASE-39) #define OMRPORT_ERROR_FILE_FAILED_TO_ALLOCATE_TLS (OMRPORT_ERROR_FILE_BASE-40) +#define OMRPORT_ERROR_FILE_TOO_MANY_OPEN_FILES (OMRPORT_ERROR_FILE_BASE-41) /** @} */ @@ -265,6 +266,7 @@ #define OMRPORT_ERROR_SYSINFO_ERROR_EINVAL (OMRPORT_ERROR_SYSINFO_BASE-13) #define OMRPORT_ERROR_SYSINFO_ERROR_EFAULT (OMRPORT_ERROR_SYSINFO_BASE-14) #define OMRPORT_ERROR_SYSINFO_PROCESSOR_COUNT_UNSTABLE (OMRPORT_ERROR_SYSINFO_BASE-15) +#define OMRPORT_ERROR_SYSINFO_GET_OPEN_FILES_NOT_SUPPORTED (OMRPORT_ERROR_SYSINFO_BASE-16) /** * @name Port library initialization return codes diff --git a/port/common/omrport.c b/port/common/omrport.c index 51007ec0442..b9753908ef6 100644 --- a/port/common/omrport.c +++ b/port/common/omrport.c @@ -233,6 +233,7 @@ static OMRPortLibrary MasterPortLibraryTable = { omrsysinfo_get_cwd, /* sysinfo_get_cwd */ omrsysinfo_get_tmp, /* sysinfo_get_tmp */ omrsysinfo_set_number_entitled_CPUs, /* sysinfo_set_number_entitled_CPUs */ + omrsysinfo_get_open_file_count, /* sysinfo_get_open_file_count */ omrport_init_library, /* port_init_library */ omrport_startup_library, /* port_startup_library */ omrport_create_library, /* port_create_library */ diff --git a/port/common/omrport.tdf b/port/common/omrport.tdf index edfcf169983..68317754851 100644 --- a/port/common/omrport.tdf +++ b/port/common/omrport.tdf @@ -929,3 +929,11 @@ TraceException=Trc_PRT_cuda_initDeviceData_fail2 Group=cuda Level=1 NoEnv Overhe TraceException=Trc_PRT_cuda_reset_fail1 Group=cuda Level=1 NoEnv Overhead=1 Template="omrcuda resetDevices: failed to %s current device, error=%d" TraceException=Trc_PRT_cuda_reset_fail2 Group=cuda Level=1 NoEnv Overhead=1 Template="omrcuda resetDevices: failed to reset device=%u, error=%d" + +TraceEntry=Trc_PRT_sysinfo_get_open_file_count_Entry Group=sysinfo Overhead=1 Level=5 NoEnv Template="omrsysinfo_get_open_file_count: Entry." +TraceException=Trc_PRT_sysinfo_get_open_file_count_invalidArgRecvd Group=sysinfo Level=1 NoEnv Overhead=1 Template="omrsysinfo_get_open_file_count received invalid argument: %s." +TraceException=Trc_PRT_sysinfo_get_open_file_count_failedOpeningProcFS Group=sysinfo Level=1 NoEnv Overhead=1 Template="omrsysinfo_get_open_file_count failed opening /proc = %d." +TraceException=Trc_PRT_sysinfo_get_open_file_count_failedReadingProcFS Group=sysinfo Level=1 NoEnv Overhead=1 Template="omrsysinfo_get_open_file_count failed reading /proc = %d." +TraceEvent=Trc_PRT_sysinfo_get_open_file_count_fileCount Group=sysinfo Overhead=1 Level=5 NoEnv Template="omrsysinfo_get_open_file_count files opened by this process=%llu." +TraceExit=Trc_PRT_sysinfo_get_open_file_count_Exit Group=sysinfo Overhead=1 Level=5 NoEnv Template="omrsysinfo_get_open_file_count: Return = %d." + diff --git a/port/common/omrsysinfo.c b/port/common/omrsysinfo.c index 2d084ab9148..5eb446851d6 100644 --- a/port/common/omrsysinfo.c +++ b/port/common/omrsysinfo.c @@ -1,6 +1,6 @@ /******************************************************************************* * - * (c) Copyright IBM Corp. 1991, 2015 + * (c) Copyright IBM Corp. 1991, 2016 * * This program and the accompanying materials are made available * under the terms of the Eclipse Public License v1.0 and @@ -413,6 +413,8 @@ omrsysinfo_get_groupname(struct OMRPortLibrary *portLibrary, char *buffer, uintp * Operating system specific core information * On AIX limit is set to the sys_parm fullcore value * Not defined on other operating systems + * OMRPORT_RESOURCE_FILE_DESCRIPTORS + * Gets the maximum number of file descriptors that can opened in a process. * * resourceID may be bit-wise or'ed with one of: * OMRPORT_LIMIT_SOFT @@ -718,3 +720,21 @@ omrsysinfo_get_tmp(struct OMRPortLibrary *portLibrary, char *buf, uintptr_t bufL { return -1; } + +/** + * Returns the number of files opened in the current process or an error, in + * case of failure. + * + * @param[in] portLibrary instance of port library + * @param[out] count The number of files in opened state in the process. + * + * @return Returns 0 on success or a negative value for failure, setting the + * last error. If OMRPORT_ERROR_SYSINFO_GET_OPEN_FILES_NOT_SUPPORTED is returned, + * last error is not set, as it simply indicates unavailability of the API. + */ +int32_t +omrsysinfo_get_open_file_count(struct OMRPortLibrary *portLibrary, uint64_t *count) +{ + return OMRPORT_ERROR_SYSINFO_GET_OPEN_FILES_NOT_SUPPORTED; +} + diff --git a/port/omrportpriv.h b/port/omrportpriv.h index ee4be9753e5..2ede62d3da4 100644 --- a/port/omrportpriv.h +++ b/port/omrportpriv.h @@ -465,11 +465,12 @@ extern J9_CFUNC intptr_t omrsysinfo_get_CPU_utilization(struct OMRPortLibrary *portLibrary, struct J9SysinfoCPUTime *cpuTime); extern J9_CFUNC void omrsysinfo_set_number_entitled_CPUs(struct OMRPortLibrary *portLibrary, uintptr_t number); - extern J9_CFUNC intptr_t omrsysinfo_get_cwd(struct OMRPortLibrary *portLibrary, char *buf, uintptr_t bufLen); extern J9_CFUNC intptr_t omrsysinfo_get_tmp(struct OMRPortLibrary *portLibrary, char *buf, uintptr_t bufLen, BOOLEAN ignoreEnvVariable); +extern J9_CFUNC int32_t +omrsysinfo_get_open_file_count(struct OMRPortLibrary *portLibrary, uint64_t *count); /* J9SourceJ9Signal*/ extern J9_CFUNC int32_t diff --git a/port/unix/omrsysinfo.c b/port/unix/omrsysinfo.c index 9f42532dd3d..9692f503569 100644 --- a/port/unix/omrsysinfo.c +++ b/port/unix/omrsysinfo.c @@ -270,6 +270,18 @@ findError(int32_t errorCode) return OMRPORT_ERROR_FILE_EFAULT; case EINVAL: return OMRPORT_ERROR_FILE_INVAL; + case EBADF: + return OMRPORT_ERROR_FILE_BADF; + case ENOENT: + return OMRPORT_ERROR_FILE_NOENT; + case ENOTDIR: + return OMRPORT_ERROR_FILE_NOTDIR; + case ENOMEM: + return OMRPORT_ERROR_FILE_INSUFFICIENT_BUFFER; + case EMFILE: + /* FALLTHROUGH */ + case ENFILE: + return OMRPORT_ERROR_FILE_TOO_MANY_OPEN_FILES; default: return OMRPORT_ERROR_FILE_OPFAILED; } @@ -1038,7 +1050,7 @@ omrsysinfo_get_number_CPUs_by_type(struct OMRPortLibrary *portLibrary, uintptr_t cpu_set_t cpuSet; int32_t size = sizeof(cpuSet); /* Size in bytes */ pid_t mainProcess = getpid(); - I_32 error = sched_getaffinity(mainProcess, size, &cpuSet); + int32_t error = sched_getaffinity(mainProcess, size, &cpuSet); if (0 == error) { int32_t count = 0; @@ -1648,6 +1660,33 @@ omrsysinfo_get_limit(struct OMRPortLibrary *portLibrary, uint32_t resourceID, ui *limit = OMRPORT_LIMIT_UNKNOWN_VALUE; rc = OMRPORT_LIMIT_UNKNOWN; #endif + } + break; + /* Get the limit on maximum number of files that may be opened in any + * process, in the current configuration of the operating system. This + * must match "ulimit -n". + */ + case OMRPORT_RESOURCE_FILE_DESCRIPTORS: { +#if defined(AIXPPC) || defined(LINUX) || defined(OSX) || defined(J9ZOS390) + /* getrlimit(2) is a POSIX routine. */ + if (0 == getrlimit(RLIMIT_NOFILE, &lim)) { + *limit = (uint64_t) (hardLimitRequested ? lim.rlim_max : lim.rlim_cur); + if (RLIM_INFINITY == *limit) { + rc = OMRPORT_LIMIT_UNLIMITED; + } else { + rc = OMRPORT_LIMIT_LIMITED; + } + } else { + *limit = OMRPORT_LIMIT_UNKNOWN_VALUE; + portLibrary->error_set_last_error(portLibrary, errno, findError(errno)); + Trc_PRT_sysinfo_getrlimit_error(resource, findError(errno)); + rc = OMRPORT_LIMIT_UNKNOWN; + } +#else + /* unsupported on other platforms (just in case). */ + *limit = OMRPORT_LIMIT_UNKNOWN_VALUE; + rc = OMRPORT_LIMIT_UNKNOWN; +#endif /* defined(AIXPPC) || defined(LINUX) || defined(OSX) || defined(J9ZOS390) */ } break; default: @@ -2849,3 +2888,71 @@ setPortableError(OMRPortLibrary *portLibrary, const char *funcName, int32_t port return; } + +int32_t +omrsysinfo_get_open_file_count(struct OMRPortLibrary *portLibrary, uint64_t *count) +{ + int32_t ret = 0; +#if defined(LINUX) || defined(AIXPPC) + uint64_t fdCount = 0; + char buffer[PATH_MAX] = {0}; + const char *procDirectory = "/proc/%d/fd/"; + struct dirent *dp = NULL; + DIR *dir = NULL; + + Trc_PRT_sysinfo_get_open_file_count_Entry(); + /* Check whether a valid pointee exists, to write to. */ + if (NULL == count) { + portLibrary->error_set_last_error(portLibrary, EINVAL, findError(EINVAL)); + Trc_PRT_sysinfo_get_open_file_count_invalidArgRecvd("count"); + ret = -1; + goto leave_routine; + } + /* On Linux, "/proc/self" is as good as "/proc//", but not on + * AIX, where the current process's PID must be specified. + */ + portLibrary->str_printf(portLibrary, buffer, sizeof(buffer), procDirectory, getpid()); + dir = opendir(buffer); + if (NULL == dir) { + int32_t rc = findError(errno); + portLibrary->error_set_last_error(portLibrary, errno, rc); + Trc_PRT_sysinfo_get_open_file_count_failedOpeningProcFS(rc); + ret = -1; + goto leave_routine; + } + /* opendir(3) was successful; look into the directory for fds. */ + errno = 0; /* readdir(3) will set this, if an error occurs. */ + dp = readdir(dir); + while (NULL != dp) { + /* Skip "." and ".." */ + if (!(('.' == dp->d_name[0] && '\0' == dp->d_name[1]) + || ('.' == dp->d_name[0] && '.' == dp->d_name[1] && '\0' == dp->d_name[2])) + ) { + fdCount++; + } + dp = readdir(dir); + } + /* readdir(3) would eventually return NULL; check whether there was an + * error and readdir returned prematurely. + */ + if (0 != errno) { + int32_t rc = findError(errno); + portLibrary->error_set_last_error(portLibrary, errno, rc); + Trc_PRT_sysinfo_get_open_file_count_failedReadingProcFS(rc); + ret = -1; + } else { + /* Successfully counted up the files opened. */ + *count = fdCount; + Trc_PRT_sysinfo_get_open_file_count_fileCount(fdCount); + } + closedir(dir); /* Done reading the /proc file-system. */ +leave_routine: + /* Clean-ups, setting-error (if any), etc, done. */ +#elif defined(OSX) || defined(J9ZOS390) + /* TODO: stub where z/OS || OSX code goes in. */ + ret = OMRPORT_ERROR_SYSINFO_GET_OPEN_FILES_NOT_SUPPORTED; +#endif + Trc_PRT_sysinfo_get_open_file_count_Exit(ret); + return ret; +} + diff --git a/port/win32/omrsysinfo.c b/port/win32/omrsysinfo.c index 4e018ac4aed..3c825c59d9c 100644 --- a/port/win32/omrsysinfo.c +++ b/port/win32/omrsysinfo.c @@ -1555,3 +1555,10 @@ omrsysinfo_get_tmp(struct OMRPortLibrary *portLibrary, char *buf, uintptr_t bufL portLibrary->mem_free_memory(portLibrary, unicodeBuffer); return 0; } + +int32_t +omrsysinfo_get_open_file_count(struct OMRPortLibrary *portLibrary, uint64_t *count) +{ + return OMRPORT_ERROR_SYSINFO_GET_OPEN_FILES_NOT_SUPPORTED; +} +