mirror of
https://github.com/topjohnwu/libsu.git
synced 2024-10-07 09:13:23 +00:00
Better error handling
This commit is contained in:
parent
3ccd3cd57e
commit
11ed6e8034
@ -209,7 +209,7 @@ class FileSystemService extends IFileSystemService.Stub {
|
||||
if (e.errno == OsConstants.EEXIST) {
|
||||
p.add(null);
|
||||
} else {
|
||||
p.add(new IOException(e));
|
||||
p.add(e);
|
||||
}
|
||||
p.add(false);
|
||||
}
|
||||
@ -297,7 +297,7 @@ class FileSystemService extends IFileSystemService.Stub {
|
||||
}
|
||||
values.add(handle);
|
||||
} catch (ErrnoException e) {
|
||||
values.set(0, new IOException(e));
|
||||
values.set(0, e);
|
||||
h.close();
|
||||
}
|
||||
return values;
|
||||
@ -354,10 +354,8 @@ class FileSystemService extends IFileSystemService.Stub {
|
||||
}
|
||||
}
|
||||
values.add((int) result);
|
||||
} catch (IOException e) {
|
||||
} catch (IOException | ErrnoException e) {
|
||||
values.set(0, e);
|
||||
} catch (ErrnoException e) {
|
||||
values.set(0, new IOException(e));
|
||||
}
|
||||
return values;
|
||||
}
|
||||
@ -399,10 +397,8 @@ class FileSystemService extends IFileSystemService.Stub {
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
} catch (IOException | ErrnoException e) {
|
||||
values.set(0, e);
|
||||
} catch (ErrnoException e) {
|
||||
values.set(0, new IOException(e));
|
||||
}
|
||||
return values;
|
||||
}
|
||||
@ -417,10 +413,8 @@ class FileSystemService extends IFileSystemService.Stub {
|
||||
h.ensureOpen();
|
||||
values.add(Os.lseek(h.fd, offset, whence));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
} catch (IOException | ErrnoException e) {
|
||||
values.set(0, e);
|
||||
} catch (ErrnoException e) {
|
||||
values.set(0, new IOException(e));
|
||||
}
|
||||
return values;
|
||||
}
|
||||
@ -438,10 +432,8 @@ class FileSystemService extends IFileSystemService.Stub {
|
||||
values.add(Os.lseek(h.fd, 0, SEEK_CUR));
|
||||
Os.lseek(h.fd, cur, SEEK_SET);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
} catch (IOException | ErrnoException e) {
|
||||
values.set(0, e);
|
||||
} catch (ErrnoException e) {
|
||||
values.set(0, new IOException(e));
|
||||
}
|
||||
return values;
|
||||
}
|
||||
@ -456,10 +448,8 @@ class FileSystemService extends IFileSystemService.Stub {
|
||||
h.ensureOpen();
|
||||
Os.ftruncate(h.fd, length);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
} catch (IOException | ErrnoException e) {
|
||||
values.set(0, e);
|
||||
} catch (ErrnoException e) {
|
||||
values.set(0, new IOException(e));
|
||||
}
|
||||
return values;
|
||||
}
|
||||
@ -477,10 +467,8 @@ class FileSystemService extends IFileSystemService.Stub {
|
||||
else
|
||||
Os.fdatasync(h.fd);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
} catch (IOException | ErrnoException e) {
|
||||
values.set(0, e);
|
||||
} catch (ErrnoException e) {
|
||||
values.set(0, new IOException(e));
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
@ -40,6 +40,8 @@ import android.util.MutableLong;
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.file.OpenOption;
|
||||
@ -48,6 +50,8 @@ import java.util.Set;
|
||||
|
||||
class FileUtils {
|
||||
|
||||
private static final String REMOTE_ERR_MSG = "Exception thrown on remote process";
|
||||
|
||||
private static Object os;
|
||||
private static Method splice;
|
||||
private static Method sendfile;
|
||||
@ -189,4 +193,32 @@ class FileUtils {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void checkException(ParcelValues values) throws IOException {
|
||||
Throwable err = values.getTyped(0);
|
||||
if (err == null)
|
||||
return;
|
||||
if (err instanceof IOException) {
|
||||
try {
|
||||
// Wrap the exception with its own class so that the rethrown exception
|
||||
// has the same type. This wrapping is to make it clear that the exception
|
||||
// originates from a remote process, not local.
|
||||
Constructor<?> c = err.getClass().getConstructor(String.class);
|
||||
IOException e = (IOException) c.newInstance(REMOTE_ERR_MSG);
|
||||
e.initCause(err);
|
||||
throw e;
|
||||
} catch (ReflectiveOperationException e) {
|
||||
// In theory there should be no exception without a constructor that
|
||||
// accepts a single string as message. In this case, just rethrow.
|
||||
throw (IOException) err;
|
||||
}
|
||||
} else {
|
||||
throw new IOException(REMOTE_ERR_MSG, err);
|
||||
}
|
||||
}
|
||||
|
||||
static <T> T tryAndGet(ParcelValues values) throws IOException {
|
||||
checkException(values);
|
||||
return values.getTyped(1);
|
||||
}
|
||||
}
|
||||
|
@ -66,12 +66,7 @@ class RemoteFile extends FileImpl<RemoteFile> {
|
||||
@NonNull
|
||||
public String getCanonicalPath() throws IOException {
|
||||
try {
|
||||
ParcelValues b = fs.getCanonicalPath(getPath());
|
||||
IOException ex = b.getTyped(0);
|
||||
if (ex != null) {
|
||||
throw ex;
|
||||
}
|
||||
return b.getTyped(1);
|
||||
return FileUtils.tryAndGet(fs.getCanonicalPath(getPath()));
|
||||
} catch (RemoteException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
@ -198,12 +193,7 @@ class RemoteFile extends FileImpl<RemoteFile> {
|
||||
@Override
|
||||
public boolean createNewFile() throws IOException {
|
||||
try {
|
||||
ParcelValues b = fs.createNewFile(getPath());
|
||||
IOException ex = b.getTyped(0);
|
||||
if (ex != null) {
|
||||
throw ex;
|
||||
}
|
||||
return b.getTyped(1);
|
||||
return FileUtils.tryAndGet(fs.createNewFile(getPath()));
|
||||
} catch (RemoteException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
@ -212,12 +202,7 @@ class RemoteFile extends FileImpl<RemoteFile> {
|
||||
@Override
|
||||
public boolean createNewLink(String existing) throws IOException {
|
||||
try {
|
||||
ParcelValues b = fs.createLink(getPath(), existing, false);
|
||||
IOException ex = b.getTyped(0);
|
||||
if (ex != null) {
|
||||
throw ex;
|
||||
}
|
||||
return b.getTyped(1);
|
||||
return FileUtils.tryAndGet(fs.createLink(getPath(), existing, false));
|
||||
} catch (RemoteException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
@ -226,12 +211,7 @@ class RemoteFile extends FileImpl<RemoteFile> {
|
||||
@Override
|
||||
public boolean createNewSymlink(String target) throws IOException {
|
||||
try {
|
||||
ParcelValues b = fs.createLink(getPath(), target, true);
|
||||
IOException ex = b.getTyped(0);
|
||||
if (ex != null) {
|
||||
throw ex;
|
||||
}
|
||||
return b.getTyped(1);
|
||||
return FileUtils.tryAndGet(fs.createLink(getPath(), target, true));
|
||||
} catch (RemoteException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ class RemoteFileChannel extends FileChannel {
|
||||
Os.mkfifo(fifo.getPath(), 0644);
|
||||
|
||||
// Open the file on the remote process
|
||||
handle = checkAndGet(fs.open(file.getAbsolutePath(), mode, fifo.getPath()));
|
||||
handle = FileUtils.tryAndGet(fs.open(file.getAbsolutePath(), mode, fifo.getPath()));
|
||||
|
||||
// Since we do not have the machinery to interrupt native pthreads, we
|
||||
// have to make sure none of our I/O can block in all operations.
|
||||
@ -79,17 +79,6 @@ class RemoteFileChannel extends FileChannel {
|
||||
}
|
||||
}
|
||||
|
||||
private static void check(ParcelValues values) throws IOException {
|
||||
IOException ex = values.getTyped(0);
|
||||
if (ex != null)
|
||||
throw ex;
|
||||
}
|
||||
|
||||
private static <T> T checkAndGet(ParcelValues values) throws IOException {
|
||||
check(values);
|
||||
return values.getTyped(1);
|
||||
}
|
||||
|
||||
private void ensureOpen() throws IOException {
|
||||
if (!isOpen())
|
||||
throw new ClosedChannelException();
|
||||
@ -127,7 +116,7 @@ class RemoteFileChannel extends FileChannel {
|
||||
synchronized (fdLock) {
|
||||
if (!isOpen() || Thread.interrupted())
|
||||
return -1;
|
||||
len = checkAndGet(fs.pread(handle, limit - pos, offset));
|
||||
len = FileUtils.tryAndGet(fs.pread(handle, limit - pos, offset));
|
||||
if (len == 0)
|
||||
break;
|
||||
dst.limit(pos + len);
|
||||
@ -184,7 +173,7 @@ class RemoteFileChannel extends FileChannel {
|
||||
if (!isOpen() || Thread.interrupted())
|
||||
return -1;
|
||||
len = Os.write(write, src);
|
||||
check(fs.pwrite(handle, len, offset));
|
||||
FileUtils.checkException(fs.pwrite(handle, len, offset));
|
||||
}
|
||||
if (offset >= 0) {
|
||||
offset += len;
|
||||
@ -226,7 +215,7 @@ class RemoteFileChannel extends FileChannel {
|
||||
public long position() throws IOException {
|
||||
ensureOpen();
|
||||
try {
|
||||
return checkAndGet(fs.lseek(handle, 0, OsConstants.SEEK_CUR));
|
||||
return FileUtils.tryAndGet(fs.lseek(handle, 0, OsConstants.SEEK_CUR));
|
||||
} catch (RemoteException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
@ -238,7 +227,7 @@ class RemoteFileChannel extends FileChannel {
|
||||
if (newPosition < 0)
|
||||
throw new IllegalArgumentException();
|
||||
try {
|
||||
check(fs.lseek(handle, newPosition, OsConstants.SEEK_SET));
|
||||
FileUtils.checkException(fs.lseek(handle, newPosition, OsConstants.SEEK_SET));
|
||||
return this;
|
||||
} catch (RemoteException e) {
|
||||
throw new IOException(e);
|
||||
@ -249,7 +238,7 @@ class RemoteFileChannel extends FileChannel {
|
||||
public long size() throws IOException {
|
||||
ensureOpen();
|
||||
try {
|
||||
return checkAndGet(fs.size(handle));
|
||||
return FileUtils.tryAndGet(fs.size(handle));
|
||||
} catch (RemoteException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
@ -263,7 +252,7 @@ class RemoteFileChannel extends FileChannel {
|
||||
if (!writable())
|
||||
throw new NonWritableChannelException();
|
||||
try {
|
||||
check(fs.ftruncate(handle, size));
|
||||
FileUtils.checkException(fs.ftruncate(handle, size));
|
||||
return this;
|
||||
} catch (RemoteException e) {
|
||||
throw new IOException(e);
|
||||
@ -274,7 +263,7 @@ class RemoteFileChannel extends FileChannel {
|
||||
public void force(boolean metaData) throws IOException {
|
||||
ensureOpen();
|
||||
try {
|
||||
check(fs.sync(handle, metaData));
|
||||
FileUtils.checkException(fs.sync(handle, metaData));
|
||||
} catch (RemoteException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user