use of android.system.ErrnoException in project android_frameworks_base by DirtyUnicorns.
the class LocalTransport method performBackup.
@Override
public int performBackup(PackageInfo packageInfo, ParcelFileDescriptor data) {
if (DEBUG) {
try {
StructStat ss = Os.fstat(data.getFileDescriptor());
Log.v(TAG, "performBackup() pkg=" + packageInfo.packageName + " size=" + ss.st_size);
} catch (ErrnoException e) {
Log.w(TAG, "Unable to stat input file in performBackup() on " + packageInfo.packageName);
}
}
File packageDir = new File(mCurrentSetIncrementalDir, packageInfo.packageName);
packageDir.mkdirs();
// Each 'record' in the restore set is kept in its own file, named by
// the record key. Wind through the data file, extracting individual
// record operations and building a set of all the updates to apply
// in this update.
BackupDataInput changeSet = new BackupDataInput(data.getFileDescriptor());
try {
int bufSize = 512;
byte[] buf = new byte[bufSize];
while (changeSet.readNextHeader()) {
String key = changeSet.getKey();
String base64Key = new String(Base64.encode(key.getBytes()));
File entityFile = new File(packageDir, base64Key);
int dataSize = changeSet.getDataSize();
if (DEBUG)
Log.v(TAG, "Got change set key=" + key + " size=" + dataSize + " key64=" + base64Key);
if (dataSize >= 0) {
if (entityFile.exists()) {
entityFile.delete();
}
FileOutputStream entity = new FileOutputStream(entityFile);
if (dataSize > bufSize) {
bufSize = dataSize;
buf = new byte[bufSize];
}
changeSet.readEntityData(buf, 0, dataSize);
if (DEBUG) {
try {
long cur = Os.lseek(data.getFileDescriptor(), 0, SEEK_CUR);
Log.v(TAG, " read entity data; new pos=" + cur);
} catch (ErrnoException e) {
Log.w(TAG, "Unable to stat input file in performBackup() on " + packageInfo.packageName);
}
}
try {
entity.write(buf, 0, dataSize);
} catch (IOException e) {
Log.e(TAG, "Unable to update key file " + entityFile.getAbsolutePath());
return TRANSPORT_ERROR;
} finally {
entity.close();
}
} else {
entityFile.delete();
}
}
return TRANSPORT_OK;
} catch (IOException e) {
// oops, something went wrong. abort the operation and return error.
Log.v(TAG, "Exception reading backup input:", e);
return TRANSPORT_ERROR;
}
}
use of android.system.ErrnoException in project android_frameworks_base by DirtyUnicorns.
the class FullBackup method restoreFile.
/**
* Copy data from a socket to the given File location on permanent storage. The
* modification time and access mode of the resulting file will be set if desired,
* although group/all rwx modes will be stripped: the restored file will not be
* accessible from outside the target application even if the original file was.
* If the {@code type} parameter indicates that the result should be a directory,
* the socket parameter may be {@code null}; even if it is valid, no data will be
* read from it in this case.
* <p>
* If the {@code mode} argument is negative, then the resulting output file will not
* have its access mode or last modification time reset as part of this operation.
*
* @param data Socket supplying the data to be copied to the output file. If the
* output is a directory, this may be {@code null}.
* @param size Number of bytes of data to copy from the socket to the file. At least
* this much data must be available through the {@code data} parameter.
* @param type Must be either {@link BackupAgent#TYPE_FILE} for ordinary file data
* or {@link BackupAgent#TYPE_DIRECTORY} for a directory.
* @param mode Unix-style file mode (as used by the chmod(2) syscall) to be set on
* the output file or directory. group/all rwx modes are stripped even if set
* in this parameter. If this parameter is negative then neither
* the mode nor the mtime values will be applied to the restored file.
* @param mtime A timestamp in the standard Unix epoch that will be imposed as the
* last modification time of the output file. if the {@code mode} parameter is
* negative then this parameter will be ignored.
* @param outFile Location within the filesystem to place the data. This must point
* to a location that is writeable by the caller, preferably using an absolute path.
* @throws IOException
*/
public static void restoreFile(ParcelFileDescriptor data, long size, int type, long mode, long mtime, File outFile) throws IOException {
if (type == BackupAgent.TYPE_DIRECTORY) {
// drop down to the final metadata adjustment.
if (outFile != null)
outFile.mkdirs();
} else {
FileOutputStream out = null;
// Pull the data from the pipe, copying it to the output file, until we're done
try {
if (outFile != null) {
File parent = outFile.getParentFile();
if (!parent.exists()) {
// in practice this will only be for the default semantic directories,
// and using the default mode for those is appropriate.
// This can also happen for the case where a parent directory has been
// excluded, but a file within that directory has been included.
parent.mkdirs();
}
out = new FileOutputStream(outFile);
}
} catch (IOException e) {
Log.e(TAG, "Unable to create/open file " + outFile.getPath(), e);
}
byte[] buffer = new byte[32 * 1024];
final long origSize = size;
FileInputStream in = new FileInputStream(data.getFileDescriptor());
while (size > 0) {
int toRead = (size > buffer.length) ? buffer.length : (int) size;
int got = in.read(buffer, 0, toRead);
if (got <= 0) {
Log.w(TAG, "Incomplete read: expected " + size + " but got " + (origSize - size));
break;
}
if (out != null) {
try {
out.write(buffer, 0, got);
} catch (IOException e) {
// Problem writing to the file. Quit copying data and delete
// the file, but of course keep consuming the input stream.
Log.e(TAG, "Unable to write to file " + outFile.getPath(), e);
out.close();
out = null;
outFile.delete();
}
}
size -= got;
}
if (out != null)
out.close();
}
// Now twiddle the state to match the backup, assuming all went well
if (mode >= 0 && outFile != null) {
try {
// explicitly prevent emplacement of files accessible by outside apps
mode &= 0700;
Os.chmod(outFile.getPath(), (int) mode);
} catch (ErrnoException e) {
e.rethrowAsIOException();
}
outFile.setLastModified(mtime);
}
}
use of android.system.ErrnoException in project android_frameworks_base by DirtyUnicorns.
the class SharedPreferencesImpl method hasFileChangedUnexpectedly.
// Has the file changed out from under us? i.e. writes that
// we didn't instigate.
private boolean hasFileChangedUnexpectedly() {
synchronized (this) {
if (mDiskWritesInFlight > 0) {
// If we know we caused it, it's not unexpected.
if (DEBUG)
Log.d(TAG, "disk write in flight, not unexpected.");
return false;
}
}
final StructStat stat;
try {
/*
* Metadata operations don't usually count as a block guard
* violation, but we explicitly want this one.
*/
BlockGuard.getThreadPolicy().onReadFromDisk();
stat = Os.stat(mFile.getPath());
} catch (ErrnoException e) {
return true;
}
synchronized (this) {
return mStatTimestamp != stat.st_mtime || mStatSize != stat.st_size;
}
}
use of android.system.ErrnoException in project android_frameworks_base by DirtyUnicorns.
the class SharedPreferencesImpl method writeToFile.
// Note: must hold mWritingToDiskLock
private void writeToFile(MemoryCommitResult mcr, boolean isFromSyncCommit) {
// Rename the current file so it may be used as a backup during the next read
if (mFile.exists()) {
boolean needsWrite = false;
// Only need to write if the disk state is older than this commit
if (mDiskStateGeneration < mcr.memoryStateGeneration) {
if (isFromSyncCommit) {
needsWrite = true;
} else {
synchronized (this) {
// be persisted.
if (mCurrentMemoryStateGeneration == mcr.memoryStateGeneration) {
needsWrite = true;
}
}
}
}
if (!needsWrite) {
if (DEBUG) {
Log.d(TAG, "skipped " + mcr.memoryStateGeneration + " -> " + mFile.getName());
}
mcr.setDiskWriteResult(true);
return;
}
if (!mBackupFile.exists()) {
if (!mFile.renameTo(mBackupFile)) {
Log.e(TAG, "Couldn't rename file " + mFile + " to backup file " + mBackupFile);
mcr.setDiskWriteResult(false);
return;
}
} else {
mFile.delete();
}
}
// from the backup.
try {
FileOutputStream str = createFileOutputStream(mFile);
if (str == null) {
mcr.setDiskWriteResult(false);
return;
}
XmlUtils.writeMapXml(mcr.mapToWriteToDisk, str);
FileUtils.sync(str);
if (DEBUG) {
Log.d(TAG, "wrote " + mcr.memoryStateGeneration + " -> " + mFile.getName());
}
str.close();
ContextImpl.setFilePermissionsFromMode(mFile.getPath(), mMode, 0);
try {
final StructStat stat = Os.stat(mFile.getPath());
synchronized (this) {
mStatTimestamp = stat.st_mtime;
mStatSize = stat.st_size;
}
} catch (ErrnoException e) {
// Do nothing
}
// Writing was successful, delete the backup file if there is one.
mBackupFile.delete();
mDiskStateGeneration = mcr.memoryStateGeneration;
mcr.setDiskWriteResult(true);
return;
} catch (XmlPullParserException e) {
Log.w(TAG, "writeToFile: Got exception:", e);
} catch (IOException e) {
Log.w(TAG, "writeToFile: Got exception:", e);
}
// Clean up an unsuccessfully written file
if (mFile.exists()) {
if (!mFile.delete()) {
Log.e(TAG, "Couldn't clean up partially-written file " + mFile);
}
}
mcr.setDiskWriteResult(false);
}
use of android.system.ErrnoException in project android_frameworks_base by DirtyUnicorns.
the class ParcelFileDescriptor method createReliableSocketPair.
/**
* @hide
*/
public static ParcelFileDescriptor[] createReliableSocketPair(int type) throws IOException {
try {
final FileDescriptor[] comm = createCommSocketPair();
final FileDescriptor fd0 = new FileDescriptor();
final FileDescriptor fd1 = new FileDescriptor();
Os.socketpair(AF_UNIX, type, 0, fd0, fd1);
return new ParcelFileDescriptor[] { new ParcelFileDescriptor(fd0, comm[0]), new ParcelFileDescriptor(fd1, comm[1]) };
} catch (ErrnoException e) {
throw e.rethrowAsIOException();
}
}
Aggregations