这是indexloc提供的服务,不要输入任何密码
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions app/src/main/java/com/termux/api/apis/UsbAPI.java
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,7 @@ public void writeResult(PrintWriter out) {
if (result < 0) {
out.append("Failed to open device\n");
} else {
this.setFd(result);
out.append("@"); // has to be non-empty
this.sendFd(out, result);
}
} else out.append("No permission\n");
}
Expand Down
65 changes: 49 additions & 16 deletions app/src/main/java/com/termux/api/util/ResultReturner.java
Original file line number Diff line number Diff line change
Expand Up @@ -103,14 +103,53 @@ public final void setInput(InputStream inputStream) throws Exception {
}

public static abstract class WithAncillaryFd implements ResultWriter {
private int fd = -1;
private LocalSocket outputSocket = null;
private final ParcelFileDescriptor[] pfds = { null };

public final void setFd(int newFd) {
fd = newFd;
public final void setOutputSocketForFds(LocalSocket outputSocket) {
this.outputSocket = outputSocket;
}

public final int getFd() {
return fd;
public final void sendFd(PrintWriter out, int fd) {
// If fd already sent, then error out as we only support sending one currently.
if (this.pfds[0] != null) {
Logger.logStackTraceWithMessage(LOG_TAG, "File descriptor already sent", new Exception());
return;
}

this.pfds[0] = ParcelFileDescriptor.adoptFd(fd);
FileDescriptor[] fds = { pfds[0].getFileDescriptor() };

// Set fd to be sent
outputSocket.setFileDescriptorsForSend(fds);

// As per the docs:
// > The file descriptors will be sent with the next write of normal data, and will be
// delivered in a single ancillary message.
// - https://developer.android.com/reference/android/net/LocalSocket#setFileDescriptorsForSend(java.io.FileDescriptor[])
// So we write the `@` character. It is not special, it is just the chosen character
// expected as the message by the native `termux-api` command when a fd is sent.
// - https://github.com/termux/termux-api-package/blob/e62bdadea3f26b60430bb85248f300fee68ecdcc/termux-api.c#L358
out.print("@");

// Actually send the by fd by flushing the data previously written (`@`) as PrintWriter is buffered.
out.flush();

// Clear existing fd after it has been sent, otherwise it will get sent for every data write,
// even though we are currently not writing anything else. Android will not clear it automatically.
// - https://cs.android.com/android/platform/superproject/main/+/main:frameworks/base/core/java/android/net/LocalSocketImpl.java;l=523?q=setFileDescriptorsForSend
// - https://cs.android.com/android/_/android/platform/frameworks/base/+/refs/tags/android-14.0.0_r1:core/jni/android_net_LocalSocketImpl.cpp;l=194
outputSocket.setFileDescriptorsForSend(null);
}

public final void cleanupFds() {
if (this.pfds[0] != null) {
try {
this.pfds[0].close();
} catch (IOException e) {
Logger.logStackTraceWithMessage(LOG_TAG, "Failed to close file descriptor", e);
}
}
}
}

Expand Down Expand Up @@ -152,7 +191,6 @@ public static void returnData(Object context, final Intent intent, final ResultW
PrintWriter writer = null;
LocalSocket outputSocket = null;
try {
final ParcelFileDescriptor[] pfds = { null };
outputSocket = new LocalSocket();
String outputSocketAdress = intent.getStringExtra(SOCKET_OUTPUT_EXTRA);
if (outputSocketAdress == null || outputSocketAdress.isEmpty())
Expand All @@ -162,6 +200,9 @@ public static void returnData(Object context, final Intent intent, final ResultW
writer = new PrintWriter(outputSocket.getOutputStream());

if (resultWriter != null) {
if(resultWriter instanceof WithAncillaryFd) {
((WithAncillaryFd) resultWriter).setOutputSocketForFds(outputSocket);
}
if (resultWriter instanceof BinaryOutput) {
BinaryOutput bout = (BinaryOutput) resultWriter;
bout.setOutput(outputSocket.getOutputStream());
Expand All @@ -178,19 +219,11 @@ public static void returnData(Object context, final Intent intent, final ResultW
} else {
resultWriter.writeResult(writer);
}
if(resultWriter instanceof WithAncillaryFd) {
int fd = ((WithAncillaryFd) resultWriter).getFd();
if (fd >= 0) {
pfds[0] = ParcelFileDescriptor.adoptFd(fd);
FileDescriptor[] fds = { pfds[0].getFileDescriptor() };
outputSocket.setFileDescriptorsForSend(fds);
}
if (resultWriter instanceof WithAncillaryFd) {
((WithAncillaryFd) resultWriter).cleanupFds();
}
}

if(pfds[0] != null) {
pfds[0].close();
}

if (asyncResult != null && receiver.isOrderedBroadcast()) {
asyncResult.setResultCode(0);
Expand Down