zipfuse: OsString -> CString
libfuse uses CString. In order to avoid conversion between OsString and
CString, zipfuse also internally uses CString.
Bug: 186377508
Test: atest ZipFuseTest
Change-Id: I48cfc294d3d897ab89179205465e652d8ffbeeee
diff --git a/zipfuse/src/inode.rs b/zipfuse/src/inode.rs
index ec00565..e6c0254 100644
--- a/zipfuse/src/inode.rs
+++ b/zipfuse/src/inode.rs
@@ -15,8 +15,9 @@
*/
use anyhow::{anyhow, bail, Result};
use std::collections::HashMap;
-use std::ffi::{OsStr, OsString};
+use std::ffi::{CStr, CString};
use std::io;
+use std::os::unix::ffi::OsStrExt;
/// `InodeTable` is a table of `InodeData` indexed by `Inode`.
#[derive(Debug)]
@@ -51,7 +52,7 @@
/// can be used to retrieve `ZipFile` that provides access to the content of the file.
#[derive(Debug)]
enum InodeDataData {
- Directory(HashMap<OsString, DirectoryEntry>),
+ Directory(HashMap<CString, DirectoryEntry>),
File(ZipIndex),
}
@@ -72,7 +73,7 @@
matches!(&self.data, InodeDataData::Directory(_))
}
- pub fn get_directory(&self) -> Option<&HashMap<OsString, DirectoryEntry>> {
+ pub fn get_directory(&self) -> Option<&HashMap<CString, DirectoryEntry>> {
match &self.data {
InodeDataData::Directory(hash) => Some(hash),
_ => None,
@@ -101,7 +102,7 @@
}
}
- fn add_to_directory(&mut self, name: OsString, entry: DirectoryEntry) {
+ fn add_to_directory(&mut self, name: CString, entry: DirectoryEntry) {
match &mut self.data {
InodeDataData::Directory(hashtable) => {
let existing = hashtable.insert(name, entry);
@@ -138,7 +139,7 @@
/// Finds the inode number of a file named `name` in the `parent` inode. The `parent` inode
/// must exist and be a directory.
- fn find(&self, parent: Inode, name: &OsStr) -> Option<Inode> {
+ fn find(&self, parent: Inode, name: &CStr) -> Option<Inode> {
let data = self.get(parent).unwrap();
match data.get_directory().unwrap().get(name) {
Some(DirectoryEntry { inode, .. }) => Some(*inode),
@@ -148,17 +149,15 @@
// Adds the inode `data` to the inode table and also links it to the `parent` inode as a file
// named `name`. The `parent` inode must exist and be a directory.
- fn add(&mut self, parent: Inode, name: &OsStr, data: InodeData) -> Inode {
- assert!(self.find(parent, name).is_none());
+ fn add(&mut self, parent: Inode, name: CString, data: InodeData) -> Inode {
+ assert!(self.find(parent, &name).is_none());
let kind = if data.is_dir() { InodeKind::Directory } else { InodeKind::File };
// Add the inode to the table
let inode = self.put(data);
// ... and then register it to the directory of the parent inode
- self.get_mut(parent)
- .unwrap()
- .add_to_directory(OsString::from(name), DirectoryEntry { inode, kind });
+ self.get_mut(parent).unwrap().add_to_directory(name, DirectoryEntry { inode, kind });
inode
}
@@ -195,7 +194,8 @@
// The happy path; the inode for `name` is already in the `parent` inode. Move on
// to the next path element.
- if let Some(found) = table.find(parent, name) {
+ let name = CString::new(name.as_bytes()).unwrap();
+ if let Some(found) = table.find(parent, &name) {
parent = found;
// Update the mode if this is a directory leaf.
if !is_file && is_leaf {
@@ -245,7 +245,8 @@
}
fn check_dir(it: &InodeTable, parent: Inode, name: &str) -> Inode {
- let inode = it.find(parent, &OsString::from(name));
+ let name = CString::new(name.as_bytes()).unwrap();
+ let inode = it.find(parent, &name);
assert!(inode.is_some());
let inode = inode.unwrap();
let inode_data = it.get(inode);
@@ -257,7 +258,8 @@
}
fn check_file<'a>(it: &'a InodeTable, parent: Inode, name: &str) -> &'a InodeData {
- let inode = it.find(parent, &OsString::from(name));
+ let name = CString::new(name.as_bytes()).unwrap();
+ let inode = it.find(parent, &name);
assert!(inode.is_some());
let inode = inode.unwrap();
let inode_data = it.get(inode);
diff --git a/zipfuse/src/main.rs b/zipfuse/src/main.rs
index d6710d6..d0792d5 100644
--- a/zipfuse/src/main.rs
+++ b/zipfuse/src/main.rs
@@ -26,11 +26,10 @@
use fuse::mount::*;
use std::collections::HashMap;
use std::convert::TryFrom;
-use std::ffi::{CStr, CString, OsStr};
+use std::ffi::{CStr, CString};
use std::fs::{File, OpenOptions};
use std::io;
use std::io::Read;
-use std::os::unix::ffi::OsStrExt;
use std::os::unix::io::AsRawFd;
use std::path::Path;
use std::sync::Mutex;
@@ -159,7 +158,6 @@
fn lookup(&self, _ctx: Context, parent: Self::Inode, name: &CStr) -> io::Result<Entry> {
let inode = self.find_inode(parent)?;
let directory = inode.get_directory().ok_or_else(ebadf)?;
- let name = OsStr::from_bytes(name.to_bytes());
let entry = directory.get(name);
match entry {
Some(e) => Ok(Entry {