# HG changeset patch # User Simon Tooke # Date 1485799567 18000 # Node ID 902e2e96f4e8bb0c12e730a00e7c6dd15fb2bd7a # Parent cd5b08c320526f06530ca22a3c99511e1a05d0a6 A preliminary port of Thermostat to macos. It is quite usable except for statistics that query the OS (like memory and IO usage over time). The main unfinished business: - native code for memory and IO usage - JUnit - GUI often hangs on exit. - Mac .app bundle build Reviewed-by: neugens Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2017-January/022086.html diff -r cd5b08c32052 -r 902e2e96f4e8 agent/command/src/main/java/com/redhat/thermostat/agent/command/internal/ProcessUserInfoBuilder.java --- a/agent/command/src/main/java/com/redhat/thermostat/agent/command/internal/ProcessUserInfoBuilder.java Mon Jan 30 10:30:19 2017 -0500 +++ b/agent/command/src/main/java/com/redhat/thermostat/agent/command/internal/ProcessUserInfoBuilder.java Mon Jan 30 13:06:07 2017 -0500 @@ -36,6 +36,8 @@ package com.redhat.thermostat.agent.command.internal; +import com.redhat.thermostat.shared.config.OS; + import java.io.BufferedReader; import java.io.File; import java.io.FileReader; @@ -46,27 +48,27 @@ * Replace when this information is available from an API. */ class ProcessUserInfoBuilder { - + private static final String PROC_STATUS_SELF_PATH = "/proc/self/status"; private static final String PROC_STATUS_UID = "Uid:"; private final FileReaderCreator readerCreator; - + ProcessUserInfoBuilder() { this(new FileReaderCreator()); } - + ProcessUserInfoBuilder(FileReaderCreator readerCreator) { this.readerCreator = readerCreator; } - + private long getUid() throws IOException { FileReader reader = readerCreator.create(PROC_STATUS_SELF_PATH); long uid = getUidFromProcfs(new BufferedReader(reader)); return uid; } - + boolean isPrivilegedUser() throws IOException { - return (getUid() == 0); + return OS.IS_LINUX ? (getUid() == 0) : false; } /* diff -r cd5b08c32052 -r 902e2e96f4e8 common/portability/Makefile --- a/common/portability/Makefile Mon Jan 30 10:30:19 2017 -0500 +++ b/common/portability/Makefile Mon Jan 30 13:06:07 2017 -0500 @@ -7,17 +7,25 @@ CLASSPATH = target/classes/ TARGET_DIR = target -ifeq ($(OS),Windows_NT) +ifeq ($(JNI_PLATFORM),win32) JNI_PLATFORM = win32 SO_PREFIX = SO_SUFFIX = .dll else +ifeq ($(JNI_PLATFORM),darwin) + JNI_PLATFORM = darwin + SO_PREFIX = lib + SO_SUFFIX = .dylib + MYCFLAGS += + MYLDFLAGS += +else JNI_PLATFORM = linux SO_PREFIX = lib SO_SUFFIX = .so MYCFLAGS += -fPIC MYLDFLAGS += -fPIC endif +endif INCLUDE = -I $(TARGET_DIR) -I "$(JAVA_HOME)/include/" -I "$(JAVA_HOME)/include/$(JNI_PLATFORM)" @@ -31,31 +39,48 @@ USERNAME_OBJECTS = $(USERNAME_TARGET:.c=.o) USERNAME_EXECUTABLE = $(SO_PREFIX)UserNameUtilWrapper$(SO_SUFFIX) -WINHELPER_SOURCES = src/main/native/WindowsHelperImpl.c -WINHELPER_TARGET = $(TARGET_DIR)/WindowsHelperImpl.c -WINHELPER_OBJECTS = $(WINHELPER_TARGET:.c=.o) -WINHELPER_EXECUTABLE = $(SO_PREFIX)WindowsHelperWrapper$(SO_SUFFIX) +ifeq ($(JNI_PLATFORM),win32) +HELPER_SOURCES = src/main/native/WindowsHelperImpl.c +HELPER_TARGET = $(TARGET_DIR)/WindowsHelperImpl.c +HELPER_OBJECTS = $(HELPER_TARGET:.c=.o) +HELPER_EXECUTABLE = $(SO_PREFIX)WindowsHelperWrapper$(SO_SUFFIX) +endif + +ifeq ($(JNI_PLATFORM),darwin) +HELPER_SOURCES = src/main/native/MacOSHelperImpl.c +HELPER_TARGET = $(TARGET_DIR)/MacOSHelperImpl.c +HELPER_OBJECTS = $(HELPER_TARGET:.c=.o) +HELPER_EXECUTABLE = $(SO_PREFIX)MacOSHelperWrapper$(SO_SUFFIX) +endif EXECUTABLES = $(HOSTNAME_EXECUTABLE) $(USERNAME_EXECUTABLE) .PHONY:UserNameUtilImpl JNI_LIST = com.redhat.thermostat.common.portability.HostName com.redhat.thermostat.common.portability.internal.linux.UserNameUtilImpl -ifeq ($(OS),Windows_NT) - EXECUTABLES += $(WINHELPER_EXECUTABLE) +ifeq ($(JNI_PLATFORM),win32) + EXECUTABLES += $(HELPER_EXECUTABLE) JNI_LIST += com.redhat.thermostat.common.portability.internal.windows.WindowsHelperImpl + HELPER_LIBS += -l psapi +endif + +ifeq ($(JNI_PLATFORM),darwin) + EXECUTABLES += $(HELPER_EXECUTABLE) + JNI_LIST += com.redhat.thermostat.common.portability.internal.macos.MacOSHelperImpl endif $(JNI_LIST): $(JAVAH) -force -classpath $(CLASSPATH) -d $(TARGET_DIR) $(JNI_LIST) -all: $(JNI_LIST) init $(HOSTNAME_SOURCES) $(USERNAME_SOURCES) $(WINHELPER_SOURCES) $(EXECUTABLES) +all: $(JNI_LIST) init $(HOSTNAME_SOURCES) $(USERNAME_SOURCES) $(HELPER_SOURCES) $(EXECUTABLES) .PHONY: init: $(COPY) $(HOSTNAME_SOURCES) $(HOSTNAME_TARGET) $(COPY) $(USERNAME_SOURCES) $(USERNAME_TARGET) - $(COPY) $(WINHELPER_SOURCES) $(WINHELPER_TARGET) +ifneq ($(strip $(HELPER_SOURCES)),) + $(COPY) $(HELPER_SOURCES) $(HELPER_TARGET) +endif $(HOSTNAME_EXECUTABLE): $(HOSTNAME_OBJECTS) $(CC) $(MYLDFLAGS) $(LDFLAGS) $(HOSTNAME_OBJECTS) $(PLATFORM_LIBS) -o $(TARGET_DIR)/$@ @@ -63,8 +88,8 @@ $(USERNAME_EXECUTABLE): $(USERNAME_OBJECTS) $(CC) $(MYLDFLAGS) $(LDFLAGS) $(USERNAME_OBJECTS) $(PLATFORM_LIBS) -o $(TARGET_DIR)/$@ -$(WINHELPER_EXECUTABLE): $(WINHELPER_OBJECTS) - $(CC) $(MYLDFLAGS) $(LDFLAGS) $(WINHELPER_OBJECTS) $(PLATFORM_LIBS) -l psapi -o $(TARGET_DIR)/$@ +$(HELPER_EXECUTABLE): $(HELPER_OBJECTS) + $(CC) $(MYLDFLAGS) $(LDFLAGS) $(HELPER_OBJECTS) $(PLATFORM_LIBS) $(HELPER_LIBS) -o $(TARGET_DIR)/$@ .c.o: $(CC) $(MYCFLAGS) $(CFLAGS) $(INCLUDE) $< -o $@ @@ -75,12 +100,12 @@ clean-lib: rm -f $(TARGET_DIR)/$(HOSTNAME_EXECUTABLE) rm -f $(TARGET_DIR)/$(USERNAME_EXECUTABLE) - rm -f $(TARGET_DIR)/$(WINHELPER_EXECUTABLE) + rm -f $(TARGET_DIR)/$(HELPER_EXECUTABLE) clean-obj: rm -f $(HOSTNAME_OBJECTS) $(HOSTNAME_TARGET) rm -f $(USERNAME_OBJECTS) $(USERNAME_TARGET) - rm -f $(WINHELPER_OBJECTS) $(WINHELPER_TARGET) + rm -f $(HELPER_OBJECTS) $(HELPER_TARGET) clean: clean-obj clean-lib diff -r cd5b08c32052 -r 902e2e96f4e8 common/portability/pom.xml --- a/common/portability/pom.xml Mon Jan 30 10:30:19 2017 -0500 +++ b/common/portability/pom.xml Mon Jan 30 13:06:07 2017 -0500 @@ -61,7 +61,7 @@ linux - Unix + linux @@ -69,6 +69,17 @@ + macos + + mac + + + + .dylib + + + + windows Windows @@ -140,7 +151,8 @@ com.redhat.thermostat.common.portability.internal, com.redhat.thermostat.common.portability.internal.linux, com.redhat.thermostat.common.portability.internal.linux.vmio, - com.redhat.thermostat.common.portability.internal.windows + com.redhat.thermostat.common.portability.internal.windows, + com.redhat.thermostat.common.portability.internal.macos <_nouses>true diff -r cd5b08c32052 -r 902e2e96f4e8 common/portability/src/main/java/com/redhat/thermostat/common/portability/PortableHostImpl.java --- a/common/portability/src/main/java/com/redhat/thermostat/common/portability/PortableHostImpl.java Mon Jan 30 10:30:19 2017 -0500 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/PortableHostImpl.java Mon Jan 30 13:06:07 2017 -0500 @@ -37,6 +37,7 @@ package com.redhat.thermostat.common.portability; import com.redhat.thermostat.common.portability.internal.linux.LinuxPortableHostImpl; +import com.redhat.thermostat.common.portability.internal.macos.MacOSHostImpl; import com.redhat.thermostat.common.portability.internal.windows.WindowsPortableHostImpl; import com.redhat.thermostat.shared.config.OS; @@ -46,7 +47,7 @@ private static PortableHost createInstance() { return OS.IS_LINUX ? LinuxPortableHostImpl.createInstance() - : OS.IS_WINDOWS ? WindowsPortableHostImpl.createInstance() : null; + : OS.IS_WINDOWS ? WindowsPortableHostImpl.createInstance() : MacOSHostImpl.INSTANCE; } public static PortableHost getInstance() { diff -r cd5b08c32052 -r 902e2e96f4e8 common/portability/src/main/java/com/redhat/thermostat/common/portability/PortableProcessImpl.java --- a/common/portability/src/main/java/com/redhat/thermostat/common/portability/PortableProcessImpl.java Mon Jan 30 10:30:19 2017 -0500 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/PortableProcessImpl.java Mon Jan 30 13:06:07 2017 -0500 @@ -37,6 +37,7 @@ package com.redhat.thermostat.common.portability; import com.redhat.thermostat.common.portability.internal.linux.LinuxPortableProcessImpl; +import com.redhat.thermostat.common.portability.internal.macos.MacOSProcessImpl; import com.redhat.thermostat.common.portability.internal.windows.WindowsPortableProcessImpl; import com.redhat.thermostat.shared.config.OS; @@ -46,7 +47,7 @@ private static PortableProcess createInstance() { return OS.IS_LINUX ? LinuxPortableProcessImpl.createInstance() - : OS.IS_WINDOWS ? WindowsPortableProcessImpl.createInstance() : null; + : OS.IS_WINDOWS ? WindowsPortableProcessImpl.createInstance() : MacOSProcessImpl.INSTANCE; } public static PortableProcess getInstance() { diff -r cd5b08c32052 -r 902e2e96f4e8 common/portability/src/main/java/com/redhat/thermostat/common/portability/ProcessChecker.java --- a/common/portability/src/main/java/com/redhat/thermostat/common/portability/ProcessChecker.java Mon Jan 30 10:30:19 2017 -0500 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/ProcessChecker.java Mon Jan 30 13:06:07 2017 -0500 @@ -36,13 +36,14 @@ package com.redhat.thermostat.common.portability; +import com.redhat.thermostat.common.portability.internal.macos.MacOSHelperImpl; import com.redhat.thermostat.common.portability.internal.windows.WindowsHelperImpl; import com.redhat.thermostat.shared.config.OS; import java.io.File; /** * Utility for checking whether a process exists or not. - * + * * Implementation note: This is Linux specific. * */ @@ -51,7 +52,7 @@ private static final boolean is_linux = OS.IS_LINUX; public boolean exists(int pid) { - return is_linux ? existsLinux(pid) : existsWindows(pid); + return OS.IS_LINUX ? existsLinux(pid) : (OS.IS_WINDOWS ? existsWindows(pid) : existsMacOS(pid)); } private boolean existsLinux(int pid) { @@ -59,13 +60,17 @@ return procFile.exists(); } + private boolean existsMacOS(int pid) { + return MacOSHelperImpl.INSTANCE.exists(pid); + } + private boolean existsWindows(int pid) { return WindowsHelperImpl.INSTANCE.exists(pid); } - + // testing-hook File mapToFile(int pid) { return new File("/proc/" + pid); } - + } diff -r cd5b08c32052 -r 902e2e96f4e8 common/portability/src/main/java/com/redhat/thermostat/common/portability/ProcessUserInfo.java --- a/common/portability/src/main/java/com/redhat/thermostat/common/portability/ProcessUserInfo.java Mon Jan 30 10:30:19 2017 -0500 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/ProcessUserInfo.java Mon Jan 30 13:06:07 2017 -0500 @@ -36,7 +36,9 @@ package com.redhat.thermostat.common.portability; +import com.redhat.thermostat.common.portability.internal.UnimplementedError; import com.redhat.thermostat.common.portability.internal.linux.LinuxProcessUserInfoBuilderImpl; +import com.redhat.thermostat.common.portability.internal.macos.MacOSUserInfoBuilderImpl; import com.redhat.thermostat.common.portability.linux.ProcDataSource; import com.redhat.thermostat.common.portability.internal.windows.WindowsUserInfoBuilderImpl; import com.redhat.thermostat.shared.config.OS; @@ -65,10 +67,33 @@ } public static ProcessUserInfoBuilder createBuilder(ProcDataSource source, UserNameUtil userNameUtil) { - return OS.IS_LINUX ? new LinuxProcessUserInfoBuilderImpl(source, userNameUtil) : new WindowsUserInfoBuilderImpl(); + final ProcessUserInfoBuilder builder; + if (OS.IS_LINUX) { + builder = new LinuxProcessUserInfoBuilderImpl(source, userNameUtil); + } + else if (OS.IS_WINDOWS) { + builder = new WindowsUserInfoBuilderImpl(); + } + else if (OS.IS_MACOS) { + builder = new MacOSUserInfoBuilderImpl(); + } + else { + throw new UnimplementedError("ProcessUserInfo"); + } + return builder; } public static ProcessUserInfoBuilder createBuilder() { - return OS.IS_LINUX ? new LinuxProcessUserInfoBuilderImpl() : new WindowsUserInfoBuilderImpl(); + final ProcessUserInfoBuilder builder; + if (OS.IS_LINUX) { + builder = new LinuxProcessUserInfoBuilderImpl(); + } + else if (OS.IS_WINDOWS) { + builder = new WindowsUserInfoBuilderImpl(); + } + else { + builder = new MacOSUserInfoBuilderImpl(); + } + return builder; } } diff -r cd5b08c32052 -r 902e2e96f4e8 common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/macos/MacOSHelperImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/macos/MacOSHelperImpl.java Mon Jan 30 13:06:07 2017 -0500 @@ -0,0 +1,210 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.common.portability.internal.macos; + +import com.redhat.thermostat.common.utils.LoggingUtils; +import com.redhat.thermostat.shared.config.NativeLibraryResolver; +import com.redhat.thermostat.shared.config.OS; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.logging.Logger; + +/** + * Utility class to access Windows native code + */ +public class MacOSHelperImpl { + + private static final Logger logger = LoggingUtils.getLogger(MacOSHelperImpl.class); + + private static int pagesize = 0; + + public static MacOSHelperImpl INSTANCE; + + static { + if (OS.IS_MACOS) { + String lib = NativeLibraryResolver.getAbsoluteLibraryPath("MacOSHelperWrapper"); + try { + System.load(lib); + INSTANCE = new MacOSHelperImpl(); + pagesize = (int)getLongSysctl0("vm.pagesize"); + } catch (UnsatisfiedLinkError e) { + logger.severe("Could not load MacOSHelperWrapper DLL:" + lib); + INSTANCE = null; + // do not throw here, because you'll get a NoClassDefFound thrown when running other tests that Mock this class + } + } else { + INSTANCE = null; + } + } + + private MacOSHelperImpl() { + } + // local host-wide information + + public String getHostName() { + return getHostName0(); + } + + String getOSName() { + return System.getProperty("os.name") + " " + System.getProperty("os.version"); + } + + String getOSVersion() { + final String ostype = getStringSysctl0("kern.ostype"); + final String osrelease = getStringSysctl0("kern.osrelease"); + return ostype + " (Build " + osrelease + ")"; + } + + String getCPUModel() { + return getStringSysctl0("machdep.cpu.brand_string"); + } + + public int getCPUCount() { + return (int)getLongSysctl0("hw.logicalcpu"); // factors in hyperthreads + //return (int)getLongSysctl0("hw.physicalcpu"); (excludes hyperthreading) + } + + public long getTotalMemory() { + return getLongSysctl0("hw.memsize"); + } + + long[] getMemoryInfo() { + /* + public PortableMemoryStat(long timeStamp, + long total, long free, long buffers, + long cached, long swapTotal, long swapFree, long commitLimit) + */ + final long[] mi = new long[8]; + getGlobalMemoryStatus0(mi); + return mi; + } + + public long getClockTicksPerSecond() { + // we "know" this is 10E7 (units from getProcessStat) + // but calculate it anyways from current process + final long[] info = INSTANCE.getProcessCPUInfo(0); + return info[4]; + } + + // local process-specific information + + public boolean exists(int pid) { + return getUid(pid) >= 0; + } + + public String getUserName(int pid) { + return getUserName0(pid); + } + + public int getUid(int pid) { + final long uid = getProcessUid0(pid); + return (int)uid; + } + + Map getEnvironment(int pid) { + // the environment is returned as a 1D array of alternating env names and values + final String[] envArray = getEnvironment0(pid); + if (envArray == null || envArray.length == 0) { + return Collections.emptyMap(); + } + + if (envArray.length % 2 != 0) { + throw new AssertionError("environment array length not even"); + } + + final Map env = new HashMap<>(envArray.length/2); + for (int i = 0; i < envArray.length / 2; i++) { + env.put(envArray[i * 2], envArray[i * 2 + 1]); + } + return env; + } + + /** + * fetch process counters + * @param pid process id + * @return long[] working set size, user time, kernel time, (todo: elapsed time), ticks per second + */ + long[] getProcessCPUInfo(int pid) { + final long[] info = new long[5]; + getProcessInfo0(pid, info); + return info; + } + + long[] getProcessMemInfo(int pid) { + final long[] info = new long[5]; + getProcessInfo0(pid, info); + return info; + } + + long[] getProcessIOInfo(int pid) { + final long info[] = new long[6]; + getProcessIOInfo0(pid,info); + return info; + } + + boolean terminateProcess(int pid) { + return terminateProcess0(pid,0, -1); + } + + boolean terminateProcess(int pid, boolean wait) { + return terminateProcess0(pid,0, 0); + } + + boolean terminateProcess(int pid, int exitcode, int waitMillis) { + return terminateProcess0(pid, exitcode, waitMillis); + } + + public static native long getLongSysctl0( String name ); + public static native String getStringSysctl0( String name ); + + private static native String getHostName0(); + private static native boolean getGlobalMemoryStatus0(long[] info); + private static native boolean getPerformanceInfo0(long[] info); + private static native long queryPerformanceFrequency0(); + + private static native String getUserName0(int pid); + private static native long getProcessUid0(int pid); + private static native String[] getEnvironment0(int pid); + private static native boolean getProcessInfo0(int pid, long[] info); + private static native boolean getProcessIOInfo0(int pid, long[] info); + + private static native long getCurrentProcessPid0(); + + private static native boolean terminateProcess0(int pid, int exitCode, int waitMillis); +} diff -r cd5b08c32052 -r 902e2e96f4e8 common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/macos/MacOSHostImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/macos/MacOSHostImpl.java Mon Jan 30 13:06:07 2017 -0500 @@ -0,0 +1,86 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.common.portability.internal.macos; + +import com.redhat.thermostat.common.portability.PortableHost; +import com.redhat.thermostat.common.portability.PortableMemoryStat; + +public class MacOSHostImpl implements PortableHost { + + public static final MacOSHostImpl INSTANCE = new MacOSHostImpl(); + private static final MacOSHelperImpl helper = MacOSHelperImpl.INSTANCE; + + @Override + public String getHostName() { + return helper.getHostName(); + } + + @Override + public String getOSName() { + return helper.getOSName(); + } + + @Override + public String getOSVersion() { + return helper.getOSVersion(); + } + + @Override + public String getCPUModel() { + return helper.getCPUModel(); + } + + @Override + public int getCPUCount() { + return helper.getCPUCount(); + } + + @Override + public long getTotalMemory() { + return helper.getTotalMemory(); + } + + @Override + public long getClockTicksPerSecond() { + return helper.getClockTicksPerSecond(); + } + + @Override + public PortableMemoryStat getMemoryStat() { + return new MacOSMemoryStat(); + } +} diff -r cd5b08c32052 -r 902e2e96f4e8 common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/macos/MacOSMemoryStat.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/macos/MacOSMemoryStat.java Mon Jan 30 13:06:07 2017 -0500 @@ -0,0 +1,51 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.common.portability.internal.macos; + +import com.redhat.thermostat.common.portability.PortableMemoryStat; + +class MacOSMemoryStat extends PortableMemoryStat { + + MacOSMemoryStat() { + this(MacOSHelperImpl.INSTANCE.getMemoryInfo()); + } + + // public PortableMemoryStat(long timeStamp, long total, long free, long buffers, long cached, long swapTotal, long swapFree, long commitLimit) + private MacOSMemoryStat(final long[] info) { + super(System.currentTimeMillis(), info[1], info[2], 0, 0, info[3], info[4], 0); + } +} diff -r cd5b08c32052 -r 902e2e96f4e8 common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/macos/MacOSProcessImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/macos/MacOSProcessImpl.java Mon Jan 30 13:06:07 2017 -0500 @@ -0,0 +1,98 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.common.portability.internal.macos; + +import com.redhat.thermostat.common.Clock; +import com.redhat.thermostat.common.portability.PortableProcess; +import com.redhat.thermostat.common.portability.PortableProcessStat; +import com.redhat.thermostat.common.portability.PortableVmIoStat; + +import java.util.Map; + +public class MacOSProcessImpl implements PortableProcess { + + public static final MacOSProcessImpl INSTANCE = new MacOSProcessImpl(); + private static final MacOSHelperImpl helper = MacOSHelperImpl.INSTANCE; + + @Override + public boolean exists(int pid) { + return helper.exists(pid); + } + + @Override + public String getUserName(int pid) { + return helper.getUserName(pid); + } + + @Override + public int getUid(int pid) { + return helper.getUid(pid); + } + + @Override + public Map getEnvironment(int pid) { + return helper.getEnvironment(pid); + } + + @Override + public PortableProcessStat getProcessStat(int pid) { + final long[] info = helper.getProcessCPUInfo(pid); + final long utime = info[1]; + final long stime = info[2]; + return new PortableProcessStat(pid, utime, stime); + } + + @Override + public PortableVmIoStat getVmIoStat(Clock clock, int pid) { + return new MacOSVmIoStat(clock, pid); + } + + @Override + public boolean terminateProcess(int pid) { + return helper.terminateProcess(pid); + } + + @Override + public boolean terminateProcess(int pid, boolean wait) { + return helper.terminateProcess(pid, wait); + } + + @Override + public boolean terminateProcess(int pid, int exitcode, int waitMillis) { + return helper.terminateProcess(pid, exitcode, waitMillis); + } +} diff -r cd5b08c32052 -r 902e2e96f4e8 common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/macos/MacOSUserInfoBuilderImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/macos/MacOSUserInfoBuilderImpl.java Mon Jan 30 13:06:07 2017 -0500 @@ -0,0 +1,79 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.common.portability.internal.macos; + +import com.redhat.thermostat.common.portability.PortableProcess; +import com.redhat.thermostat.common.portability.PortableProcessImpl; +import com.redhat.thermostat.common.portability.ProcessUserInfo; +import com.redhat.thermostat.common.portability.ProcessUserInfoBuilder; +import com.redhat.thermostat.common.utils.LoggingUtils; + +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Build User information via Windows helper classes + */ +public class MacOSUserInfoBuilderImpl implements ProcessUserInfoBuilder { + + private final PortableProcess procHelper; + + private static final ProcessUserInfo NON_EXISTENT_USER = new ProcessUserInfo(); + private static final Logger logger = LoggingUtils.getLogger(MacOSUserInfoBuilderImpl.class); + + public MacOSUserInfoBuilderImpl() { + this(PortableProcessImpl.getInstance()); + } + + MacOSUserInfoBuilderImpl(PortableProcess helper) { + this.procHelper = helper; + } + + @Override + public ProcessUserInfo build(int pid) { + ProcessUserInfo info = NON_EXISTENT_USER; + try { + final long uid = procHelper.getUid(pid); + final String name = procHelper.getUserName(pid); + info = new ProcessUserInfo(uid, name); + } catch (Exception e) { + logger.log(Level.WARNING, "Unable to read user info for " + pid, e); + } + + return info; + } +} diff -r cd5b08c32052 -r 902e2e96f4e8 common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/macos/MacOSVmIoStat.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/macos/MacOSVmIoStat.java Mon Jan 30 13:06:07 2017 -0500 @@ -0,0 +1,51 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.common.portability.internal.macos; + +import com.redhat.thermostat.common.Clock; +import com.redhat.thermostat.common.portability.PortableVmIoStat; + +class MacOSVmIoStat extends PortableVmIoStat { + + MacOSVmIoStat(Clock clock, int pid) { + this(clock, MacOSHelperImpl.INSTANCE.getProcessIOInfo(pid)); + } + + private MacOSVmIoStat(Clock clock, final long info[]) { + super(clock.getRealTimeMillis(), info[0], info[1], info[2], info[3]); + } +} diff -r cd5b08c32052 -r 902e2e96f4e8 common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/windows/WindowsHelperImpl.java --- a/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/windows/WindowsHelperImpl.java Mon Jan 30 10:30:19 2017 -0500 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/windows/WindowsHelperImpl.java Mon Jan 30 13:06:07 2017 -0500 @@ -129,17 +129,22 @@ } long[] getMemoryInfo() { + /** + * + data[0] = statex.dwMemoryLoad; + data[1] = statex.ullTotalPhys; + data[2] = statex.ullAvailPhys; + data[3] = statex.ullTotalPageFile; + data[4] = statex.ullAvailPageFile; + data[5] = statex.ullTotalVirtual; + data[6] = statex.ullAvailVirtual; + data[7] = statex.ullAvailExtendedVirtual; + */ final long[] mi = new long[8]; getGlobalMemoryStatus0(mi); return mi; } - private long[] getPerformanceInfo() { - final long[] mi = new long[13]; - getPerformanceInfo0(mi); - return mi; - } - public long getClockTicksPerSecond() { // we "know" this is 10E7 (units from getProcessStat) // but calculate it anyways from current process @@ -235,7 +240,6 @@ private static native String getHostName0(boolean prependDomain); private static native void getOSVersion0(long[] versionAndBuild); private static native boolean getGlobalMemoryStatus0(long[] info); - private static native boolean getPerformanceInfo0(long[] info); private static native String getCPUString0(); private static native int getCPUCount0(); private static native long queryPerformanceFrequency0(); diff -r cd5b08c32052 -r 902e2e96f4e8 common/portability/src/main/native/MacOSHelperImpl.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/native/MacOSHelperImpl.c Mon Jan 30 13:06:07 2017 -0500 @@ -0,0 +1,320 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +#include "com_redhat_thermostat_common_portability_internal_macos_MacOSHelperImpl.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_NAME 256 +#ifndef NI_MAXHOST +#define NI_MAXHOST 1025 +#endif /* NI_MAXHOST */ + +#if defined(DEBUG) +static void testLength(JNIEnv* env, jlongArray array, int minLength) { + // sanity test + jsize len = (*env)->GetArrayLength(env, array); + assert(len >= minLength); +} +#else +static void testLength(JNIEnv* env, jlongArray array, int minLength) {} +#endif + +#if !defined(TRUE) +# define TRUE 1 +# define FALSE 0 +#endif + +static jint throw_IOException(JNIEnv *env, const char *message) { + const char *class_name = "java/io/IOException"; + jclass class = (*env)->FindClass(env, class_name); + if (class == NULL) { + return -1; + } + return (*env)->ThrowNew(env, class, message); +} + +/* + * Class: com_redhat_thermostat_common_portability_internal_macos_MacOSHelperImpl + * Method: getHostName0 + * Signature: ()Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL +Java_com_redhat_thermostat_common_portability_internal_macos_MacOSHelperImpl_getHostName0 + (JNIEnv *env, jclass winHelperClass) +{ + char hostname[NI_MAXHOST]; + memset(hostname, 0, sizeof(hostname)); + + if (gethostname(hostname, sizeof(hostname)) == 0) { + return (*env)->NewStringUTF(env, hostname); + } + return NULL; +} + +/* + * Class: com_redhat_thermostat_common_portability_internal_macos_MacOSHelperImpl + * Method: getGlobalMemoryStatus0 + * Signature: ([J)V + */ +JNIEXPORT jboolean JNICALL Java_com_redhat_thermostat_common_portability_internal_macos_MacOSHelperImpl_getGlobalMemoryStatus0 + (JNIEnv *env, jclass winHelperClass, jlongArray array) +{ + testLength(env, array, 8); + + // Get the element pointer + jlong* data = (*env)->GetLongArrayElements(env, array, 0); + + + (*env)->ReleaseLongArrayElements(env, array, data, 0); + return TRUE; +} + +/* + * Class: com_redhat_thermostat_common_portability_internal_macos_MacOSHelperImpl + * Method: getPerformanceInfo0 + * Signature: ([J)V + */ +JNIEXPORT jboolean JNICALL Java_com_redhat_thermostat_common_portability_internal_macos_MacOSHelperImpl_getPerformanceInfo0 + (JNIEnv *env, jclass winHelperClass, jlongArray array) +{ + testLength(env, array, 13); + + // Get the element pointer + jlong* data = (*env)->GetLongArrayElements(env, array, 0); + + (*env)->ReleaseLongArrayElements(env, array, data, 0); + return TRUE; +} + +/* + * Class: com_redhat_thermostat_common_portability_internal_macos_MacOSHelperImpl + * Method: queryPerformanceFrequency0 + * Signature: ()I + */ +JNIEXPORT jlong JNICALL Java_com_redhat_thermostat_common_portability_internal_macos_MacOSHelperImpl_queryPerformanceFrequency0 + (JNIEnv *env, jclass winHelperClass) +{ + return (jlong)(9999); +} + +uid_t uidFromPid(pid_t pid) +{ + uid_t uid = -1; + + struct kinfo_proc process; + size_t procBufferSize = sizeof(process); + + // Compose search path for sysctl. Here you can specify PID directly. + const u_int pathLenth = 4; + int path[pathLenth] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid}; + + int sysctlResult = sysctl(path, pathLenth, &process, &procBufferSize, NULL, 0); + + // If sysctl did not fail and process with PID available - take UID. + if ((sysctlResult == 0) && (procBufferSize != 0)) + { + uid = process.kp_eproc.e_ucred.cr_uid; + } + + return uid; +} + +/* + * Class: com_redhat_thermostat_common_portability_internal_macos_MacOSHelperImpl + * Method: getUserName0 + * Signature: (I)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL +Java_com_redhat_thermostat_common_portability_internal_macos_MacOSHelperImpl_getUserName0 + (JNIEnv *env, jclass winHelperClass, jint pid) +{ + uid_t uid = uidFromPid(pid); + + struct passwd pwdbuf; + struct passwd* pwdPtr; + char buf[1024]; + + int rc = getpwuid_r(uid, &pwdbuf, buf, sizeof(buf), &pwdPtr); + + if (rc) { + throw_IOException(env, "getpwuid_r() error"); + } + else if (pwdPtr == NULL) { + // no such entry + return NULL; + } + return (*env)->NewStringUTF(env, pwdbuf.pw_name); +} + +/* + * Class: com_redhat_thermostat_common_portability_internal_macos_MacOSHelperImpl + * Method: getEnvironment0 + * Signature: ()[Ljava/lang/String; + */ +JNIEXPORT jobjectArray JNICALL +Java_com_redhat_thermostat_common_portability_internal_macos_MacOSHelperImpl_getEnvironment0 + (JNIEnv *env, jclass winHelperClass, jint pid) +{ + // TODO - implement this stub - not eay (have to open the process memory and poke around) + // for now, return an empty array + jobjectArray ret = (jobjectArray)(*env)->NewObjectArray(env, 0, (*env)->FindClass(env, "java/lang/String"), (*env)->NewStringUTF(env, "")); + return ret; +} + +/* + * Class: com_redhat_thermostat_common_portability_internal_macos_MacOSHelperImpl + * Method: getProcessMemoryInfo0 + * Signature: (I[J)V + */ +JNIEXPORT jboolean JNICALL Java_com_redhat_thermostat_common_portability_internal_macos_MacOSHelperImpl_getProcessInfo0 + (JNIEnv *env, jclass winHelperClass, jint pid, jlongArray array) +{ + testLength(env, array, 4); + + // Get the element pointer + jlong* data = (*env)->GetLongArrayElements(env, array, 0); + (*env)->ReleaseLongArrayElements(env, array, data, 0); + return TRUE; +} + +/* + * Class: com_redhat_thermostat_common_portability_internal_macos_MacOSHelperImpl + * Method: getProcessIOInfo0 + * Signature: (I[J)V + */ +JNIEXPORT jboolean JNICALL Java_com_redhat_thermostat_common_portability_internal_macos_MacOSHelperImpl_getProcessIOInfo0 + (JNIEnv *env, jclass winHelperClass, jint pid, jlongArray array) +{ + testLength(env, array, 6); + + // Get the element pointer + jlong* data = (*env)->GetLongArrayElements(env, array, 0); + (*env)->ReleaseLongArrayElements(env, array, data, 0); + return TRUE; +} + +/* + * Class: com_redhat_thermostat_common_portability_internal_macos_MacOSHelperImpl + * Method: getProcessHandle0 + * Signature: (I)J + */ +JNIEXPORT jlong JNICALL Java_com_redhat_thermostat_common_portability_internal_macos_MacOSHelperImpl_getCurrentProcessPid0 + (JNIEnv *env, jclass winHelperClass) { + + return (jlong) getpid(); +} + +/* + * Class: com_redhat_thermostat_common_portability_internal_macos_MacOSHelperImpl + * Method: getProcessHandle0 + * Signature: (I)J + */ +JNIEXPORT jlong JNICALL Java_com_redhat_thermostat_common_portability_internal_macos_MacOSHelperImpl_getProcessUid0 + (JNIEnv *env, jclass winHelperClass, jint pid) { + return (jlong) uidFromPid(pid); +} + +/* + * Class: com_redhat_thermostat_common_portability_internal_macos_MacOSHelperImpl + * Method: terminateProcess0 + * Signature: (IIB)V + */ +JNIEXPORT jboolean JNICALL Java_com_redhat_thermostat_common_portability_internal_macos_MacOSHelperImpl_terminateProcess0 + (JNIEnv *env, jclass winHelperClass, jint pid, jint exitCode, jint waitMillis) { + + return TRUE; +} + +/* + * Class: com_redhat_thermostat_common_portability_internal_macos_MacOSHelperImpl + * Method: getLongSysctl0 + * Signature: (Ljava/lang/String;)J + */ +JNIEXPORT jlong JNICALL Java_com_redhat_thermostat_common_portability_internal_macos_MacOSHelperImpl_getLongSysctl0 + (JNIEnv *env, jclass winHelperClass, jstring info) { + + const char* info_cstr = (*env)->GetStringUTFChars(env, info, NULL); + + jlong ret = 0; + size_t size = sizeof(ret); + + if (sysctlbyname(info_cstr, &ret, &size, NULL, 0) < 0) { + throw_IOException(env, "bad sysctl() string"); + } + + return ret; +} + +/* + * Class: com_redhat_thermostat_common_portability_internal_macos_MacOSHelperImpl + * Method: getStringSysctl0 + * Signature: (Ljava/lang/String;)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_com_redhat_thermostat_common_portability_internal_macos_MacOSHelperImpl_getStringSysctl0 + (JNIEnv *env, jclass winHelperClass, jstring info) { + + const char* info_cstr = (*env)->GetStringUTFChars(env, info, NULL); + + size_t size = 0; + + if (sysctlbyname(info_cstr, NULL, &size, NULL, 0) < 0) { + throw_IOException(env, "bad sysctl() string"); + } + + char* buffer = malloc(size); + + if (sysctlbyname(info_cstr, buffer, &size, NULL, 0) < 0) { + throw_IOException(env, "bad sysctl() string"); + } + + jstring ret = (*env)->NewStringUTF(env, buffer); + + free(buffer); + + return ret; +} + + diff -r cd5b08c32052 -r 902e2e96f4e8 common/portability/src/main/native/WindowsHelperImpl.c --- a/common/portability/src/main/native/WindowsHelperImpl.c Mon Jan 30 10:30:19 2017 -0500 +++ b/common/portability/src/main/native/WindowsHelperImpl.c Mon Jan 30 13:06:07 2017 -0500 @@ -134,58 +134,6 @@ return TRUE; } -/* - * Class: com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl - * Method: getPerformanceInfo0 - * Signature: ([J)V - */ -JNIEXPORT boolean JNICALL Java_com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl_getPerformanceInfo0 - (JNIEnv *env, jclass winHelperClass, jlongArray array) -{ - testLength(env, array, 13); - - // Get the element pointer - jlong* data = (*env)->GetLongArrayElements(env, array, 0); - - /** - // from PERFORMANCE_INFORMATION (13 values) - SIZE_T CommitTotal; - SIZE_T CommitLimit; - SIZE_T CommitPeak; - SIZE_T PhysicalTotal; - SIZE_T PhysicalAvailable; - SIZE_T SystemCache; - SIZE_T KernelTotal; - SIZE_T KernelPaged; - SIZE_T KernelNonpaged; - SIZE_T PageSize; - DWORD HandleCount; - DWORD ProcessCount; - DWORD ThreadCount; - */ - - // get the memeory info - PERFORMANCE_INFORMATION statex; - statex.cb = sizeof(statex); - GetPerformanceInfo(&statex, statex.cb); - data[0] = statex.CommitTotal; - data[1] = statex.CommitLimit; - data[2] = statex.CommitPeak; - data[3] = statex.PhysicalTotal; - data[4] = statex.PhysicalAvailable; - data[5] = statex.SystemCache; - data[6] = statex.KernelTotal; - data[7] = statex.KernelPaged; - data[8] = statex.KernelNonpaged; - data[9] = statex.PageSize; - data[10] = statex.HandleCount; - data[11] = statex.ProcessCount; - data[12] = statex.ThreadCount; - - (*env)->ReleaseLongArrayElements(env, array, data, 0); - return TRUE; -} - /* * Class: com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl diff -r cd5b08c32052 -r 902e2e96f4e8 distribution/config/thermostatrc --- a/distribution/config/thermostatrc Mon Jan 30 10:30:19 2017 -0500 +++ b/distribution/config/thermostatrc Mon Jan 30 13:06:07 2017 -0500 @@ -48,7 +48,7 @@ # #JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk -if [ "$(expr substr $(uname -s) 1 6)" == "CYGWIN" ]; then +if [ "$(uname -s | cut -b1-6)" == "CYGWIN" ]; then ##echo "Running under Cygwin" export CYGWIN_MODE=1 else diff -r cd5b08c32052 -r 902e2e96f4e8 distribution/pom.xml --- a/distribution/pom.xml Mon Jan 30 10:30:19 2017 -0500 +++ b/distribution/pom.xml Mon Jan 30 13:06:07 2017 -0500 @@ -73,7 +73,7 @@ linux - Unix + linux @@ -111,13 +111,88 @@ prepare-package - + - + - + + + run + + + + + + org.codehaus.mojo + exec-maven-plugin + + + integration-test + + exec + + + + + ${project.basedir}/tools/verify-bash-completion.sh + + + + + + + + + macos + + mac + + + + ,com.redhat.thermostat.agent.ipc.unixsocket.server=${project.version}, \ + ${jffi-native.bundle.symbolic.name}=${jffi.version} + ,com.redhat.thermostat.agent.ipc.unixsocket.server=${project.version}, \ + ${jffi-native.bundle.symbolic.name}=${jffi.version} + + + + com.redhat.thermostat + thermostat-keyring + ${project.version} + + + com.redhat.thermostat + thermostat-agent-ipc-unixsocket-server + ${project.version} + + + com.redhat.thermostat + thermostat-agent-ipc-unixsocket-client + ${project.version} + + + + + + org.apache.maven.plugins + maven-antrun-plugin + + + + directory-structure-linux + prepare-package + + + - + @@ -169,11 +244,11 @@ - - - diff -r cd5b08c32052 -r 902e2e96f4e8 distribution/scripts/thermostat-command-channel --- a/distribution/scripts/thermostat-command-channel Mon Jan 30 10:30:19 2017 -0500 +++ b/distribution/scripts/thermostat-command-channel Mon Jan 30 13:06:07 2017 -0500 @@ -78,14 +78,19 @@ # Determine owner of this file THIS_SCRIPT="$CWD/thermostat-command-channel" -SCRIPT_OWNER=$(stat -c '%U' "${THIS_SCRIPT}") +if [ $DARWIN_MODE -eq 0 ]; then + SCRIPT_OWNER=$(stat -c '%U' "${THIS_SCRIPT}") +else + # posix + SCRIPT_OWNER=$(stat -f '%Su' "${THIS_SCRIPT}") +fi # Start server if [ $CYGWIN_MODE -eq 1 ]; then CONFIG_FILE_ARG="-DipcConfigFile=`cygpath -w ${CONFIG_FILE}`" # Drop permissions, if root if [ "$(id -u)" -eq 0 ]; then - exec /bin/su -s /bin/bash -c "${JAVA} ${CONFIG_FILE_ARG} ${LOGGING_ARGS} -cp `cygpath -w -p ${IPC_CLASSPATH}` ${DEBUG_OPTS} ${CMD_CHANNEL_CLASS} ${HOSTNAME} ${PORT}" "${SCRIPT_OWNER}" + exec /bin/su -s /bin/bash -c "${JAVA} ${CONFIG_FILE_ARG} ${LOGGING_ARGS} -cp `cygpath -w -p ${IPC_CLASSPATH}` ${DEBUG_OPTS} ${CMD_CHANNEL_CLASS} ${HOSTNAME} ${PORT}" "${SCRIPT_OWNER}" else exec ${JAVA} "${CONFIG_FILE_ARG}" ${LOGGING_ARGS} -cp "`cygpath -w -p ${IPC_CLASSPATH}`" ${DEBUG_OPTS} "${CMD_CHANNEL_CLASS}" "${HOSTNAME}" "${PORT}" fi @@ -93,7 +98,7 @@ CONFIG_FILE_ARG="-DipcConfigFile=${CONFIG_FILE}" # Drop permissions, if root if [ "$(id -u)" -eq 0 ]; then - exec /bin/su -s /bin/bash -c "${JAVA} ${CONFIG_FILE_ARG} ${LOGGING_ARGS} -cp ${IPC_CLASSPATH} ${DEBUG_OPTS} ${CMD_CHANNEL_CLASS} ${HOSTNAME} ${PORT}" "${SCRIPT_OWNER}" + exec /bin/su -s /bin/bash -c "${JAVA} ${CONFIG_FILE_ARG} ${LOGGING_ARGS} -cp ${IPC_CLASSPATH} ${DEBUG_OPTS} ${CMD_CHANNEL_CLASS} ${HOSTNAME} ${PORT}" "${SCRIPT_OWNER}" else exec ${JAVA} "${CONFIG_FILE_ARG}" ${LOGGING_ARGS} -cp ${IPC_CLASSPATH} ${DEBUG_OPTS} "${CMD_CHANNEL_CLASS}" "${HOSTNAME}" "${PORT}" fi diff -r cd5b08c32052 -r 902e2e96f4e8 distribution/scripts/thermostat-common --- a/distribution/scripts/thermostat-common Mon Jan 30 10:30:19 2017 -0500 +++ b/distribution/scripts/thermostat-common Mon Jan 30 13:06:07 2017 -0500 @@ -51,11 +51,11 @@ } # set global variable for Cygwin testing -# between all shell files, we pass cygwin-compatible paths, +# between all shell files, we pass cygwin-compatible paths, # and let each script decide when to convert them. # an exception is command line args for java programs, which # need to be converted to windows format at creation time -if [ "$(expr substr $(uname -s) 1 6)" == "CYGWIN" ]; then +if [ "$(uname -s | cut -b1-6)" == "CYGWIN" ]; then ##echo "Running under Cygwin" export CYGWIN_MODE=1 else @@ -63,6 +63,14 @@ export CYGWIN_MODE=0 fi +if [ "$(uname -s | cut -b1-6)" == "Darwin" ]; then + ##echo "Running under Darwin" + export DARWIN_MODE=1 +else + ##echo "Running under Linux" + export DARWIN_MODE=0 +fi + # Thermostat home if [[ "${THERMOSTAT_HOME}" = "" ]]; then THERMOSTAT_HOME="$(_find_thermostat_home)" @@ -103,7 +111,7 @@ fi # Source system thermostat profile -. ${THERMOSTAT_HOME}/etc/thermostatrc +. ${THERMOSTAT_HOME}/etc/thermostatrc # Source user thermostat profile (if any) if [[ -f ${USER_THERMOSTAT_HOME}/etc/thermostatrc ]]; then . ${USER_THERMOSTAT_HOME}/etc/thermostatrc diff -r cd5b08c32052 -r 902e2e96f4e8 keyring/pom.xml --- a/keyring/pom.xml Mon Jan 30 10:30:19 2017 -0500 +++ b/keyring/pom.xml Mon Jan 30 13:06:07 2017 -0500 @@ -43,12 +43,13 @@ com.redhat.thermostat 1.99.12-SNAPSHOT - + thermostat-keyring bundle Thermostat Keyring API + linux @@ -109,6 +110,7 @@ + @@ -131,7 +133,7 @@ - + org.apache.maven.plugins maven-surefire-plugin @@ -142,7 +144,7 @@ - + @@ -180,7 +182,7 @@ junit test - + org.osgi org.osgi.core @@ -198,13 +200,13 @@ ${project.version} compile - + com.redhat.thermostat thermostat-shared-config ${project.version} compile - + diff -r cd5b08c32052 -r 902e2e96f4e8 laf-utils/pom.xml --- a/laf-utils/pom.xml Mon Jan 30 10:30:19 2017 -0500 +++ b/laf-utils/pom.xml Mon Jan 30 13:06:07 2017 -0500 @@ -43,7 +43,7 @@ com.redhat.thermostat 1.99.12-SNAPSHOT - + thermostat-laf-utils bundle Thermostat Look And Feel Utils @@ -114,9 +114,9 @@ - + - + @@ -153,7 +153,7 @@ junit test - + org.osgi org.osgi.core @@ -169,7 +169,7 @@ thermostat-shared-config ${project.version} - + com.redhat.thermostat thermostat-client-core diff -r cd5b08c32052 -r 902e2e96f4e8 pom.xml --- a/pom.xml Mon Jan 30 10:30:19 2017 -0500 +++ b/pom.xml Mon Jan 30 13:06:07 2017 -0500 @@ -74,6 +74,21 @@ + macos + + mac + + + .sh + gcc + + darwin + lib + .dylib + + + + windows Windows @@ -84,7 +99,7 @@ -std=c99 c:/cygwin64 win32 - + .dll @@ -109,7 +124,7 @@ perf-tests @@ -211,9 +226,9 @@ - - ${project.basedir} - + + ${project.basedir} + yyyy-MM-dd ${maven.build.timestamp} thermostat@icedtea.classpath.org @@ -265,7 +280,7 @@ 1.7.0 1.2.2 - + com.github.jnr.unixsocket 0.12 @@ -748,7 +763,6 @@ gson ${gson.version} - com.github.jnr diff -r cd5b08c32052 -r 902e2e96f4e8 process-handler/src/main/java/com/redhat/thermostat/service/internal/unix/UnixProcessUtilities.java --- a/process-handler/src/main/java/com/redhat/thermostat/service/internal/unix/UnixProcessUtilities.java Mon Jan 30 10:30:19 2017 -0500 +++ b/process-handler/src/main/java/com/redhat/thermostat/service/internal/unix/UnixProcessUtilities.java Mon Jan 30 13:06:07 2017 -0500 @@ -38,6 +38,7 @@ import com.redhat.thermostat.service.internal.ProcessUtilitiesBase; import com.redhat.thermostat.service.process.UNIXSignal; +import com.redhat.thermostat.shared.config.OS; import java.io.BufferedReader; import java.io.IOException; @@ -55,7 +56,10 @@ protected List buildCommandLine(Integer pid) { final List commandLine = new ArrayList<>(); commandLine.add("ps"); - commandLine.add("--no-heading"); + if (!OS.IS_MACOS) + commandLine.add("--no-heading"); + else + commandLine.add("-ocomm="); commandLine.add("-p"); commandLine.add(String.valueOf(pid)); return commandLine;