mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-30 16:47:43 +08:00
GP-0: Do not use JNA's throws LastErrorException idiom
This commit is contained in:
@@ -0,0 +1,31 @@
|
|||||||
|
/* ###
|
||||||
|
* IP: GHIDRA
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package agent.gdb.pty.linux;
|
||||||
|
|
||||||
|
import com.sun.jna.LastErrorException;
|
||||||
|
import com.sun.jna.Native;
|
||||||
|
|
||||||
|
public interface Err {
|
||||||
|
PosixC BARE_POSIX = PosixC.BARE;
|
||||||
|
|
||||||
|
static int checkLt0(int result) {
|
||||||
|
if (result < 0) {
|
||||||
|
int errno = Native.getLastError();
|
||||||
|
throw new LastErrorException("[" + errno + "] " + BARE_POSIX.strerror(errno));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -27,13 +27,6 @@ public class LinuxPty implements Pty {
|
|||||||
|
|
||||||
static final PosixC LIB_POSIX = PosixC.INSTANCE;
|
static final PosixC LIB_POSIX = PosixC.INSTANCE;
|
||||||
|
|
||||||
static void checkErr(int result) {
|
|
||||||
if (result < 0) {
|
|
||||||
int errno = Native.getLastError();
|
|
||||||
throw new LastErrorException("[" + errno + "] " + LIB_POSIX.strerror(errno));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private final int aparent;
|
private final int aparent;
|
||||||
private final int achild;
|
private final int achild;
|
||||||
//private final String name;
|
//private final String name;
|
||||||
@@ -47,7 +40,7 @@ public class LinuxPty implements Pty {
|
|||||||
IntByReference p = new IntByReference();
|
IntByReference p = new IntByReference();
|
||||||
IntByReference c = new IntByReference();
|
IntByReference c = new IntByReference();
|
||||||
Memory n = new Memory(1024);
|
Memory n = new Memory(1024);
|
||||||
checkErr(Util.INSTANCE.openpty(p, c, n, null, null));
|
Util.INSTANCE.openpty(p, c, n, null, null);
|
||||||
return new LinuxPty(p.getValue(), c.getValue(), n.getString(0));
|
return new LinuxPty(p.getValue(), c.getValue(), n.getString(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
package agent.gdb.pty.linux;
|
package agent.gdb.pty.linux;
|
||||||
|
|
||||||
import com.sun.jna.*;
|
import com.sun.jna.*;
|
||||||
import com.sun.jna.platform.linux.LibC;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for POSIX functions in libc
|
* Interface for POSIX functions in libc
|
||||||
@@ -24,22 +23,69 @@ import com.sun.jna.platform.linux.LibC;
|
|||||||
* <p>
|
* <p>
|
||||||
* The functions are not documented here. Instead see the POSIX manual pages.
|
* The functions are not documented here. Instead see the POSIX manual pages.
|
||||||
*/
|
*/
|
||||||
public interface PosixC extends LibC {
|
public interface PosixC extends Library {
|
||||||
PosixC INSTANCE = Native.load("c", PosixC.class);
|
/**
|
||||||
|
* The bare library without error handling
|
||||||
|
*
|
||||||
|
* @see Util#BARE
|
||||||
|
*/
|
||||||
|
PosixC BARE = Native.load("c", PosixC.class);
|
||||||
|
|
||||||
|
PosixC INSTANCE = new PosixC() {
|
||||||
|
@Override
|
||||||
|
public String strerror(int errnum) {
|
||||||
|
return BARE.strerror(errnum);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int close(int fd) {
|
||||||
|
return Err.checkLt0(BARE.close(fd));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int read(int fd, Pointer buf, int len) {
|
||||||
|
return Err.checkLt0(BARE.read(fd, buf, len));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int write(int fd, Pointer buf, int i) {
|
||||||
|
return Err.checkLt0(BARE.write(fd, buf, i));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int setsid() {
|
||||||
|
return Err.checkLt0(BARE.setsid());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int open(String path, int mode, int flags) {
|
||||||
|
return Err.checkLt0(BARE.open(path, mode, flags));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int dup2(int oldfd, int newfd) {
|
||||||
|
return Err.checkLt0(BARE.dup2(oldfd, newfd));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int execv(String path, String[] argv) {
|
||||||
|
return Err.checkLt0(BARE.execv(path, argv));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
String strerror(int errnum);
|
String strerror(int errnum);
|
||||||
|
|
||||||
int close(int fd) throws LastErrorException;
|
int close(int fd);
|
||||||
|
|
||||||
int read(int fd, Pointer buf, int len) throws LastErrorException;
|
int read(int fd, Pointer buf, int len);
|
||||||
|
|
||||||
int write(int fd, Pointer buf, int i) throws LastErrorException;
|
int write(int fd, Pointer buf, int i);
|
||||||
|
|
||||||
int setsid() throws LastErrorException;
|
int setsid();
|
||||||
|
|
||||||
int open(String path, int mode, int flags) throws LastErrorException;
|
int open(String path, int mode, int flags);
|
||||||
|
|
||||||
int dup2(int oldfd, int newfd) throws LastErrorException;
|
int dup2(int oldfd, int newfd);
|
||||||
|
|
||||||
int execv(String path, String[] argv) throws LastErrorException;
|
int execv(String path, String[] argv);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,22 +25,38 @@ import com.sun.jna.ptr.IntByReference;
|
|||||||
* See the UNIX manual pages
|
* See the UNIX manual pages
|
||||||
*/
|
*/
|
||||||
public interface Util extends Library {
|
public interface Util extends Library {
|
||||||
Util INSTANCE = Native.load("util", Util.class);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NOTE: We cannot use {@link LastErrorException} here, because the idiom it applies is not
|
* The bare library without error handling
|
||||||
* correct for errno on UNIX. See https://man7.org/linux/man-pages/man3/errno.3.html, in
|
*
|
||||||
* particular:
|
* <p>
|
||||||
|
* For error handling, use {@link #INSTANCE}, or check for errors manually, perhaps using
|
||||||
|
* {@link Err}.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* We cannot just use {@code throws }{@link LastErrorException} to handle errors, because the
|
||||||
|
* idiom it applies is not correct for errno on UNIX. See
|
||||||
|
* https://man7.org/linux/man-pages/man3/errno.3.html, in particular:
|
||||||
*
|
*
|
||||||
* <blockquote>The value in errno is significant only when the return value of the call
|
* <blockquote>The value in errno is significant only when the return value of the call
|
||||||
* indicated an error (i.e., -1 from most system calls; -1 or NULL from most library functions);
|
* indicated an error (i.e., -1 from most system calls; -1 or NULL from most library functions);
|
||||||
* a function that succeeds is allowed to change errno.</blockquote>
|
* a function that succeeds is allowed to change errno.</blockquote>
|
||||||
*
|
*
|
||||||
|
* <p>
|
||||||
* This actually happens on our test setup when invoking the native {@code openpty} from a
|
* This actually happens on our test setup when invoking the native {@code openpty} from a
|
||||||
* Docker container. It returns 0, but sets errno. JNA will incorrectly interpret this as
|
* Docker container. It returns 0, but sets errno. JNA will incorrectly interpret this as
|
||||||
* failure. Thus, callers to this function must check the return value and handle the error
|
* failure.
|
||||||
* manually.
|
|
||||||
*/
|
*/
|
||||||
|
Util BARE = Native.load("util", Util.class);
|
||||||
|
|
||||||
|
Util INSTANCE = new Util() {
|
||||||
|
@Override
|
||||||
|
public int openpty(IntByReference amaster, IntByReference aslave, Pointer name,
|
||||||
|
Pointer termp, Pointer winp) {
|
||||||
|
return Err.checkLt0(BARE.openpty(amaster, aslave, name, termp, winp));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
int openpty(IntByReference amaster, IntByReference aslave, Pointer name, Pointer termp,
|
int openpty(IntByReference amaster, IntByReference aslave, Pointer name, Pointer termp,
|
||||||
Pointer winp);
|
Pointer winp);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user