@Override protected int setPlatformSocketOption(int sockfd, int level, int optName, TCPSocketOptions opt, Integer optVal, int optSize) throws NativeErrorException { try { switch (optName) { case OPT_TCP_KEEPALIVE_THRESHOLD: // value required is in millis final IntByReference timeout = new IntByReference(optVal.intValue() * 1000); int result = setsockopt(sockfd, level, optName, timeout, optSize); if (result == 0) { // setting ABORT_THRESHOLD to be same as KEEPALIVE_THRESHOLD return setsockopt(sockfd, level, OPT_TCP_KEEPALIVE_ABORT_THRESHOLD, timeout, optSize); } else { return result; } default: throw new UnsupportedOperationException("unsupported option " + opt); } } catch (LastErrorException le) { throw new NativeErrorException(le.getMessage(), le.getErrorCode(), le.getCause()); } }
/** * @see NativeCalls#isProcessActive(int) */ @Override public boolean isProcessActive(final int processId) { try { final Pointer procHandle = Kernel32.OpenProcess(Kernel32.PROCESS_QUERY_INFORMATION, false, processId); final long hval; if (procHandle == null || (hval = Pointer.nativeValue(procHandle)) == Kernel32.INVALID_HANDLE || hval == 0) { return false; } else { final IntByReference status = new IntByReference(); final boolean result = Kernel32.GetExitCodeProcess(procHandle, status) && status != null && status.getValue() == Kernel32.STILL_ACTIVE; Kernel32.CloseHandle(procHandle); return result; } } catch (LastErrorException le) { // some problem in getting process status return false; } }
/** * @see NativeCalls#killProcess(int) */ @Override public boolean killProcess(final int processId) { try { final Pointer procHandle = Kernel32.OpenProcess(Kernel32.PROCESS_TERMINATE, false, processId); final long hval; if (procHandle == null || (hval = Pointer.nativeValue(procHandle)) == Kernel32.INVALID_HANDLE || hval == 0) { return false; } else { final boolean result = Kernel32.TerminateProcess(procHandle, -1); Kernel32.CloseHandle(procHandle); return result; } } catch (LastErrorException le) { // some problem in killing the process return false; } }
/** * @see NativeCalls#isProcessActive(int) */ @Override public boolean isProcessActive(final int processId) { try { final Pointer procHandle = Kernel32.OpenProcess( Kernel32.PROCESS_QUERY_INFORMATION, false, processId); final long hval; if (procHandle == null || (hval = Pointer.nativeValue(procHandle)) == Kernel32.INVALID_HANDLE || hval == 0) { return false; } else { final IntByReference status = new IntByReference(); final boolean result = Kernel32.GetExitCodeProcess(procHandle, status) && status != null && status.getValue() == Kernel32.STILL_ACTIVE; Kernel32.CloseHandle(procHandle); return result; } } catch (LastErrorException le) { // some problem in getting process status return false; } }
/** * @see NativeCalls#killProcess(int) */ @Override public boolean killProcess(final int processId) { try { final Pointer procHandle = Kernel32.OpenProcess( Kernel32.PROCESS_TERMINATE, false, processId); final long hval; if (procHandle == null || (hval = Pointer.nativeValue(procHandle)) == Kernel32.INVALID_HANDLE || hval == 0) { return false; } else { final boolean result = Kernel32.TerminateProcess(procHandle, -1); Kernel32.CloseHandle(procHandle); return result; } } catch (LastErrorException le) { // some problem in killing the process return false; } }
public void lockFile(Path path) { String absolutefilepath = path.toAbsolutePath().toString(); long fileSize = path.toFile().length(); if (fileSize == 0) { return; } int fd = -1; try { fd = CLibrary.open(absolutefilepath, CLibrary.O_RDONLY, 0); Pointer addr = CLibrary.mmap(null, new SizeT(fileSize), CLibrary.PROT_READ, CLibrary.MAP_SHARED, fd, new CLibrary.OffT()); CLibrary.mlock(addr, new SizeT(fileSize)); lockedFiles.put(absolutefilepath, new LockedFileInfo(fd, addr, fileSize)); ExceptionShutdown.log("Locked "+absolutefilepath); } catch (LastErrorException e) { if (fd != -1) { CLibrary.close(fd); } ExceptionShutdown.err("Failed to lock file "+absolutefilepath + ", err code: "+e.getErrorCode()); } }
@Override public int read(byte[] b, int off, int len) throws IOException { if (b == null) { throw new NullPointerException(); } if (off < 0 || len < 0 || len > b.length - off) { throw new IndexOutOfBoundsException(); } if (len == 0) { return 0; } int n; try { n = cLib.recv(fd, b, len, 0); } catch (LastErrorException e) { throw new IOException("error: " + cLib.strerror(e.getErrorCode())); } if (n == 0) { return -1; } return n; }
@Override public int read(byte[] bytesEntry, int off, int len) throws IOException { try { if (off > 0) { int bytes = 0; int remainingLength = len; int size; byte[] data = new byte[(len < 10240) ? len : 10240]; do { size = recv(fd, data, (remainingLength < 10240) ? remainingLength : 10240, 0); if (size > 0) { System.arraycopy(data, 0, bytesEntry, off, size); bytes += size; off += size; remainingLength -= size; } } while ((remainingLength > 0) && (size > 0)); return bytes; } else { return recv(fd, bytesEntry, len, 0); } } catch (LastErrorException lee) { throw new IOException("native read() failed : " + formatError(lee)); } }
/** * @see NativeCalls#setEnvironment(String, String) */ @Override public synchronized void setEnvironment(final String name, final String value) { if (name == null) { throw new UnsupportedOperationException("setEnvironment() for name=NULL"); } int res = -1; Throwable cause = null; try { if (value != null) { res = setenv(name, value, 1); } else { res = unsetenv(name); } } catch (LastErrorException le) { cause = new NativeErrorException(le.getMessage(), le.getErrorCode(), le.getCause()); } if (res != 0) { throw new IllegalArgumentException( "setEnvironment: given name=" + name + " (value=" + value + ')', cause); } // also change in java cached map if (javaEnv != null) { if (value != null) { javaEnv.put(name, value); } else { javaEnv.remove(name); } } }
/** * @see NativeCalls#isProcessActive(int) */ @Override public boolean isProcessActive(final int processId) { try { return kill(processId, 0) == 0; } catch (LastErrorException le) { if (le.getErrorCode() == EPERM) { // Process exists; it probably belongs to another user (bug 27698). return true; } } return false; }
/** * @see NativeCalls#killProcess(int) */ @Override public boolean killProcess(final int processId) { try { return kill(processId, 9) == 0; } catch (LastErrorException le) { return false; } }
/** * {@inheritDoc} */ @Override public void daemonize(RehashServerOnSIGHUP callback) throws UnsupportedOperationException { UnsupportedOperationException err = null; try { setsid(); } catch (LastErrorException le) { // errno=EPERM indicates already group leader if (le.getErrorCode() != EPERM) { err = new UnsupportedOperationException("Failed in setsid() in daemonize() due to " + le.getMessage() + " (errno=" + le.getErrorCode() + ')'); } } // set umask to something consistent for servers final int newMask = 022; int oldMask = umask(newMask); // check if old umask was more restrictive, and if so then set it back if ((oldMask & 077) > newMask) { umask(oldMask); } // catch the SIGHUP signal and invoke any callback provided this.rehashCallback = callback; this.hupHandler = new SignalHandler() { @Override public void callback(int signum) { // invoke the rehash function if provided final RehashServerOnSIGHUP rehashCb = rehashCallback; if (signum == Signal.SIGHUP.getNumber() && rehashCb != null) { rehashCb.rehash(); } } }; signal(Signal.SIGHUP.getNumber(), this.hupHandler); // ignore SIGCHLD and SIGINT signal(Signal.SIGCHLD.getNumber(), this.hupHandler); signal(Signal.SIGINT.getNumber(), this.hupHandler); if (err != null) { throw err; } }
@Override protected int setPlatformSocketOption(int sockfd, int level, int optName, TCPSocketOptions opt, Integer optVal, int optSize) throws NativeErrorException { try { return setsockopt(sockfd, level, optName, new IntByReference(optVal.intValue()), optSize); } catch (LastErrorException le) { throw new NativeErrorException(le.getMessage(), le.getErrorCode(), le.getCause()); } }
@Override protected void fallocateFD(int fd, long offset, long len) throws LastErrorException { int errno = posix_fallocate64(fd, offset, len); if (errno != 0) { throw new LastErrorException(errno); } }
/** * @see NativeCalls#setEnvironment(String, String) */ @Override public synchronized void setEnvironment(final String name, final String value) { if (name == null) { throw new UnsupportedOperationException("setEnvironment() for name=NULL"); } boolean res = false; Throwable cause = null; try { res = Kernel32.SetEnvironmentVariableA(name, value); } catch (LastErrorException le) { // error code ERROR_ENVVAR_NOT_FOUND (203) indicates variable was not // found so ignore if (value == null && le.getErrorCode() == 203) { res = true; } else { cause = new NativeErrorException(le.getMessage(), le.getErrorCode(), le.getCause()); } } if (!res) { throw new IllegalArgumentException( "setEnvironment: given name=" + name + " (value=" + value + ')', cause); } // also change in java cached map if (javaEnv != null) { if (value != null) { javaEnv.put(name, value); } else { javaEnv.remove(name); } } }
private static Termios getTerminalAttrs (int fd) throws IOException { Termios termios = new Termios(); try { int rc = libc.tcgetattr(fd, termios); if (rc != 0) { throw new RuntimeException("tcgetattr() failed."); }} catch (LastErrorException e) { throw new IOException("tcgetattr() failed.", e); } return termios; }
private static void setTerminalAttrs (int fd, Termios termios) throws IOException { try { int rc = libc.tcsetattr(fd, LibcDefs.TCSANOW, termios); if (rc != 0) { throw new RuntimeException("tcsetattr() failed."); }} catch (LastErrorException e) { throw new IOException("tcsetattr() failed.", e); }}
/** * Finds the URL for the Proxy Auto-Configuration (PAC) file using WPAD. * This is merely a wrapper around * {@link WinHttp#WinHttpDetectAutoProxyConfigUrl(com.sun.jna.platform.win32.WinDef.DWORD, com.github.markusbernhardt.proxy.jna.win.WTypes2.LPWSTRByReference) * WinHttpDetectAutoProxyConfigUrl} * * <p> * This method is blocking and may take some time to execute. * * @param dwAutoDetectFlags * @return the url of the PAC file or {@code null} if it cannot be located * using WPAD method. */ public static String detectAutoProxyConfigUrl(WinDef.DWORD dwAutoDetectFlags) { WTypes2.LPWSTRByReference ppwszAutoConfigUrl = new WTypes2.LPWSTRByReference(); boolean result = false; try { result = WinHttp.INSTANCE.WinHttpDetectAutoProxyConfigUrl(dwAutoDetectFlags, ppwszAutoConfigUrl); } catch (LastErrorException ex) { if (ex.getErrorCode() == WinHttp.ERROR_WINHTTP_AUTODETECTION_FAILED) { // This error is to be expected. It just means that the lookup // using either DHCP, DNS or both, failed because there wasn't // a useful reply from DHCP / DNS. (meaning the site hasn't // configured their DHCP Server or their DNS Server for WPAD) return null; } // Something more serious is wrong. There isn't much we can do // about it but at least we would like to log it. Logger.log(WinHttpHelpers.class, Logger.LogLevel.ERROR, "Windows function WinHttpDetectAutoProxyConfigUrl returned error : {0}", ex.getMessage()); return null; } if (result) { return ppwszAutoConfigUrl.getString(); } else { return null; } }
/** * Gets {@link VS_FIXEDFILEINFO} from the Windows API for a specified * {@link Path}. * <p> * <b>Must only be called on Windows</b> * * @param path the {@link Path} the get file information for. * @param throwLastError whether or not to throw a * {@link LastErrorException} if it occurs during the operation. * @return The generated {@link VS_FIXEDFILEINFO} instance or {@code null} * @throws IllegalStateException If called on a non-Windows platform. * @throws LastErrorException If {@code throwLastError} is {@code true} and * {@code LastError} has a non-zero return value during the * operation. */ @Nullable public static VS_FIXEDFILEINFO getWindowsFileInfo(@Nonnull Path path, boolean throwLastError) { if (!Platform.isWindows()) { throw new IllegalStateException("getWindowsFileInfo() can only be called on Windows"); } VS_FIXEDFILEINFO fixedFileInfo = null; IntByReference ignored = new IntByReference(); try { int infoSize = WindowsVersion.INSTANCE.GetFileVersionInfoSizeW(path.toString(), ignored); if (infoSize > 0) { Memory data = new Memory(infoSize); if (WindowsVersion.INSTANCE.GetFileVersionInfoW(path.toString(), 0, infoSize, data)) { PointerByReference lplpBuffer = new PointerByReference(); IntByReference puLen = new IntByReference(); if (WindowsVersion.INSTANCE.VerQueryValueW(data, "\\", lplpBuffer, puLen) && puLen.getValue() > 0) { fixedFileInfo = new VS_FIXEDFILEINFO(lplpBuffer.getValue()); } } } } catch (LastErrorException e) { if (throwLastError) { throw e; } LOGGER.debug("getWindowsFileInfo for \"{}\" failed with: {}", path, e.getMessage()); LOGGER.trace("", e); } return fixedFileInfo; }
/** * @see NativeCalls#setEnvironment(String, String) */ @Override public synchronized void setEnvironment(final String name, final String value) { if (name == null) { throw new UnsupportedOperationException( "setEnvironment() for name=NULL"); } int res = -1; Throwable cause = null; try { if (value != null) { res = setenv(name, value, 1); } else { res = unsetenv(name); } } catch (LastErrorException le) { cause = new NativeErrorException(le.getMessage(), le.getErrorCode(), le.getCause()); } if (res != 0) { throw new IllegalArgumentException("setEnvironment: given name=" + name + " (value=" + value + ')', cause); } // also change in java cached map if (javaEnv != null) { if (value != null) { javaEnv.put(name, value); } else { javaEnv.remove(name); } } }
@Override protected int setPlatformSocketOption(int sockfd, int level, int optName, TCPSocketOptions opt, Integer optVal, int optSize) throws NativeErrorException { try { switch (optName) { case OPT_TCP_KEEPALIVE_THRESHOLD: // value required is in millis final IntByReference timeout = new IntByReference( optVal.intValue() * 1000); int result = setsockopt(sockfd, level, optName, timeout, optSize); if (result == 0) { // setting ABORT_THRESHOLD to be same as KEEPALIVE_THRESHOLD return setsockopt(sockfd, level, OPT_TCP_KEEPALIVE_ABORT_THRESHOLD, timeout, optSize); } else { return result; } default: throw new UnsupportedOperationException("unsupported option " + opt); } } catch (LastErrorException le) { throw new NativeErrorException(le.getMessage(), le.getErrorCode(), le.getCause()); } }
/** * @see NativeCalls#setEnvironment(String, String) */ @Override public synchronized void setEnvironment(final String name, final String value) { if (name == null) { throw new UnsupportedOperationException( "setEnvironment() for name=NULL"); } boolean res = false; Throwable cause = null; try { res = Kernel32.SetEnvironmentVariableA(name, value); } catch (LastErrorException le) { // error code ERROR_ENVVAR_NOT_FOUND (203) indicates variable was not // found so ignore if (value == null && le.getErrorCode() == 203) { res = true; } else { cause = new NativeErrorException(le.getMessage(), le.getErrorCode(), le.getCause()); } } if (!res) { throw new IllegalArgumentException("setEnvironment: given name=" + name + " (value=" + value + ')', cause); } // also change in java cached map if (javaEnv != null) { if (value != null) { javaEnv.put(name, value); } else { javaEnv.remove(name); } } }
private static void setCurrentThreadAffinityWin32(int coreId) { final CLibrary lib = CLibrary.INSTANCE; try { WinDef.DWORD mask = new WinDef.DWORD(1L << coreId); lib.SetThreadAffinityMask(lib.GetCurrentThread(), mask); } catch (LastErrorException e) { System.err.format("Error setting thread affinity; last error: %d", e.getErrorCode()); } }
public long getAffinity() { final CLibrary lib = CLibrary.INSTANCE; // TODO where are systems with 64+ cores... final long cpuset[] = new long[16]; try { final int ret = lib.sched_getaffinity(0, 16 * (Long.SIZE / 8), cpuset); if (ret < 0) throw new IllegalStateException("sched_getaffinity((" + Long.SIZE / 8 + ") , &(" + cpuset + ") ) return " + ret); return cpuset[0]; } catch (LastErrorException e) { throw new IllegalStateException("sched_getaffinity((" + Long.SIZE / 8 + ") , &(" + cpuset + ") ) errorNo=" + e.getErrorCode(), e); } }
public void setAffinity(final long affinity) { final CLibrary lib = CLibrary.INSTANCE; try { //fixme: where are systems with more then 64 cores... long affinityMask[] = new long[16]; affinityMask[0] = affinity; final int ret = lib.sched_setaffinity(0, 16 * (Long.SIZE / 8), affinityMask); if (ret < 0) { throw new IllegalStateException("sched_setaffinity((" + Long.SIZE / 8 + ") , &(" + affinity + ") ) return " + ret); } } catch (LastErrorException e) { throw new IllegalStateException("sched_getaffinity((" + Long.SIZE / 8 + ") , &(" + affinity + ") ) errorNo=" + e.getErrorCode(), e); } }
public void chmod(File f, int mode) throws IOException { try { byte[] encodedFilePath = encoder.encode(f); libc.chmod(encodedFilePath, mode); } catch (LastErrorException exception) { throw new IOException(String.format("Failed to set file permissions %s on file %s. errno: %d", mode, f.getName(), exception.getErrorCode())); } }
public void symlink(File link, File target) throws IOException { link.getParentFile().mkdirs(); try { libC.symlink(target.getPath(), link.getPath()); } catch (LastErrorException e) { throw new IOException(String.format("Could not create symlink from '%s' to '%s'. Errno is %s.", link.getPath(), target.getPath(), e.getErrorCode())); } }
/** * Returns a completed request. * <p> * A <code>Request</code> object returned by this method has been removed from the queue and can be re-used by calling {@link Request#initialize} and {@link Request#submit}. * * @param wait <code>true</code> to wait until a completed request is available. <code>false</code> to return immediately when no * completed request is available. * @return A <code>Request</code> object representing a completed request, or <code>null</code> if * <code>wait</code> is <code>false</code> and no completed request is available at the time. */ public Request reapRequest(boolean wait) throws IOException { PointerByReference urbPointer = new PointerByReference(); int func = wait ? USBDEVFS_REAPURB : USBDEVFS_REAPURBNDELAY; int rc; try { rc = libc.ioctl(fileDescriptor, func, urbPointer); } catch (LastErrorException e) { if (e.getErrorCode() == EAGAIN && !wait) { return null; } throw e; } if (rc != 0) { throw new IOException("ioctl(USBDEVFS_REAPURB*) failed, rc=" + rc + "."); } int urbNdx = Urb.getUserContext(urbPointer.getValue()); if (urbNdx < 0 || urbNdx >= requests.size()) { throw new IOException("URB.userContext returned by ioctl(USBDEVFS_REAPURB*) is out of range."); } Request req = requests.get(urbNdx); if (req.urbAddr != Pointer.nativeValue(urbPointer.getValue())) { throw new IOException("Address of URB returned by ioctl(USBDEVFS_REAPURB*) does not match."); } if (!req.queued) { throw new IOException("URB returned by ioctl(USBDEVFS_REAPURB*) was not queued."); } req.queued = false; req.initialized = false; return req; }