From dbb6e2a76f975ca4ccf294a7cfb09e00bc801b2d Mon Sep 17 00:00:00 2001 From: Basil Crow Date: Mon, 21 Feb 2022 23:00:19 -0800 Subject: [PATCH] Revert "Remove JNR (#5979)" (#6299) This reverts commit 899d9fb584689a85f5c4f80e392d1314009529d4. --- bom/pom.xml | 5 +++ core/pom.xml | 4 ++ core/src/main/java/hudson/os/PosixAPI.java | 37 +++++++++++++++++++ .../main/java/hudson/os/PosixException.java | 1 + .../java/hudson/util/jna/GNUCLibrary.java | 3 ++ core/src/test/java/hudson/FilePathTest.java | 20 ++++++++++ 6 files changed, 70 insertions(+) create mode 100644 core/src/main/java/hudson/os/PosixAPI.java diff --git a/bom/pom.xml b/bom/pom.xml index 0bfd8a49e0..2fd2d43209 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -218,6 +218,11 @@ THE SOFTWARE. asm-util ${asm.version} + + com.github.jnr + jnr-posix + 3.1.15 + org.kohsuke windows-package-checker diff --git a/core/pom.xml b/core/pom.xml index 23b4294fc7..af1529aa61 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -100,6 +100,10 @@ THE SOFTWARE. org.connectbot.jbcrypt jbcrypt + + com.github.jnr + jnr-posix + org.ow2.asm asm diff --git a/core/src/main/java/hudson/os/PosixAPI.java b/core/src/main/java/hudson/os/PosixAPI.java new file mode 100644 index 0000000000..ba1c9aecb9 --- /dev/null +++ b/core/src/main/java/hudson/os/PosixAPI.java @@ -0,0 +1,37 @@ +package hudson.os; + +import jnr.constants.platform.Errno; +import jnr.posix.POSIX; +import jnr.posix.POSIXFactory; +import jnr.posix.util.DefaultPOSIXHandler; + +/** + * POSIX API wrapper. + * @author Kohsuke Kawaguchi + */ +public class PosixAPI { + + private static POSIX posix; + + /** + * Load the JNR implementation of the POSIX APIs for the current platform. + * Runtime exceptions will be of type {@link PosixException}. + * {@link IllegalStateException} will be thrown for methods not implemented on this platform. + * @return some implementation (even on Windows or unsupported Unix) + * @since 1.518 + */ + public static synchronized POSIX jnr() { + if (posix == null) { + posix = POSIXFactory.getPOSIX(new DefaultPOSIXHandler() { + @Override public void error(Errno error, String extraData) { + throw new PosixException("native error " + error.description() + " " + extraData); + } + + @Override public void error(Errno error, String methodName, String extraData) { + throw new PosixException("native error calling " + methodName + ": " + error.description() + " " + extraData); + } + }, true); + } + return posix; + } +} diff --git a/core/src/main/java/hudson/os/PosixException.java b/core/src/main/java/hudson/os/PosixException.java index be10886825..c32b9a3e6b 100644 --- a/core/src/main/java/hudson/os/PosixException.java +++ b/core/src/main/java/hudson/os/PosixException.java @@ -2,6 +2,7 @@ package hudson.os; /** * Indicates an error during POSIX API call. + * @see PosixAPI * @author Kohsuke Kawaguchi */ public class PosixException extends RuntimeException { diff --git a/core/src/main/java/hudson/util/jna/GNUCLibrary.java b/core/src/main/java/hudson/util/jna/GNUCLibrary.java index afa2729d6e..b195e11d04 100644 --- a/core/src/main/java/hudson/util/jna/GNUCLibrary.java +++ b/core/src/main/java/hudson/util/jna/GNUCLibrary.java @@ -33,6 +33,8 @@ import com.sun.jna.Pointer; import com.sun.jna.StringArray; import com.sun.jna.ptr.IntByReference; import com.sun.jna.ptr.NativeLongByReference; +import hudson.os.PosixAPI; +import jnr.posix.POSIX; /** * GNU C library. @@ -40,6 +42,7 @@ import com.sun.jna.ptr.NativeLongByReference; *

* Not available on all platforms (such as Linux/PPC, IBM mainframe, etc.), so the caller should recover gracefully * in case of {@link LinkageError}. See JENKINS-4820. + *

Consider deprecating all methods present also in {@link POSIX} (as obtained by {@link PosixAPI#jnr}). * @author Kohsuke Kawaguchi */ public interface GNUCLibrary extends Library { diff --git a/core/src/test/java/hudson/FilePathTest.java b/core/src/test/java/hudson/FilePathTest.java index 33a6e8484b..031537fc46 100644 --- a/core/src/test/java/hudson/FilePathTest.java +++ b/core/src/test/java/hudson/FilePathTest.java @@ -40,6 +40,7 @@ import static org.mockito.Mockito.when; import hudson.FilePath.TarCompression; import hudson.model.TaskListener; +import hudson.os.PosixAPI; import hudson.os.WindowsUtil; import hudson.remoting.VirtualChannel; import hudson.slaves.WorkspaceList; @@ -478,6 +479,25 @@ public class FilePathTest { } } + @Test public void copyToWithPermissionSpecialPermissions() throws IOException, InterruptedException { + assumeFalse(Functions.isWindows() || Platform.isDarwin()); + File tmp = temp.getRoot(); + File original = new File(tmp, "original"); + FilePath originalP = new FilePath(channels.french, original.getPath()); + originalP.touch(0); + PosixAPI.jnr().chmod(original.getAbsolutePath(), 02777); // Read/write/execute for everyone and setuid. + + File sameChannelCopy = new File(tmp, "sameChannelCopy"); + FilePath sameChannelCopyP = new FilePath(channels.french, sameChannelCopy.getPath()); + originalP.copyToWithPermission(sameChannelCopyP); + assertEquals("Special permissions should be copied on the same machine", 02777, PosixAPI.jnr().stat(sameChannelCopy.getAbsolutePath()).mode() & 07777); + + File diffChannelCopy = new File(tmp, "diffChannelCopy"); + FilePath diffChannelCopyP = new FilePath(channels.british, diffChannelCopy.getPath()); + originalP.copyToWithPermission(diffChannelCopyP); + assertEquals("Special permissions should not be copied across machines", 00777, PosixAPI.jnr().stat(diffChannelCopy.getAbsolutePath()).mode() & 07777); + } + @Test public void symlinkInTar() throws Exception { assumeFalse(Functions.isWindows());