1 use std
::ffi
::{OsStr, OsString}
;
2 use std
::os
::unix
::io
::{AsRawFd, RawFd}
;
3 use std
::path
::PathBuf
;
5 use anyhow
::{format_err, Error}
;
8 use nix
::sys
::stat
::Mode
;
11 use super::format_definition
::{PxarAttributes, PxarEntry}
;
14 pub filename
: OsString
,
16 pub attr
: PxarAttributes
,
17 pub dir
: Option
<nix
::dir
::Dir
>,
20 pub struct PxarDirStack
{
26 pub fn new(filename
: &OsStr
, entry
: PxarEntry
, attr
: PxarAttributes
) -> Self {
28 filename
: filename
.to_os_string(),
35 fn create_dir(&self, parent
: RawFd
, create_new
: bool
) -> Result
<nix
::dir
::Dir
, nix
::Error
> {
38 .with_nix_path(|cstr
| unsafe { libc::mkdirat(parent, cstr.as_ptr(), libc::S_IRWXU) }
)?
;
40 match Errno
::result(res
) {
43 if err
== nix
::Error
::Sys(nix
::errno
::Errno
::EEXIST
) {
53 let dir
= nix
::dir
::Dir
::openat(
55 self.filename
.as_os_str(),
65 pub fn new(parent
: RawFd
) -> Self {
72 pub fn push(&mut self, dir
: PxarDir
) {
76 pub fn pop(&mut self) -> Option
<PxarDir
> {
80 pub fn as_path_buf(&self) -> PathBuf
{
81 let path
: PathBuf
= self.data
.iter().map(|d
| d
.filename
.clone()).collect();
85 pub fn last(&self) -> Option
<&PxarDir
> {
89 pub fn last_mut(&mut self) -> Option
<&mut PxarDir
> {
93 pub fn last_dir_fd(&self) -> Option
<RawFd
> {
94 let last_dir
= self.data
.last()?
;
96 Some(d
) => Some(d
.as_raw_fd()),
101 pub fn create_all_dirs(&mut self, create_new
: bool
) -> Result
<RawFd
, Error
> {
102 let mut current_fd
= self.root
;
103 for d
in &mut self.data
{
105 Some(dir
) => current_fd
= dir
.as_raw_fd(),
108 .create_dir(current_fd
, create_new
)
109 .map_err(|err
| format_err
!("create dir failed - {}", err
))?
;
110 current_fd
= dir
.as_raw_fd();