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 {