Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
15cb3e08
R
Rust
项目概览
int
/
Rust
大约 1 年 前同步成功
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
Rust
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
15cb3e08
编写于
10月 14, 2019
作者:
O
oxalica
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Fix cfgs for current libc
上级
43f398be
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
139 addition
and
89 deletion
+139
-89
src/libstd/sys/unix/fs.rs
src/libstd/sys/unix/fs.rs
+139
-89
未找到文件。
src/libstd/sys/unix/fs.rs
浏览文件 @
15cb3e08
...
...
@@ -41,88 +41,137 @@
pub
struct
File
(
FileDesc
);
#[derive(Clone)]
pub
struct
FileAttr
{
stat
:
stat64
,
#[cfg(target_os
=
"linux"
)]
statx_extra_fields
:
Option
<
StatxExtraFields
>
,
}
#[cfg(target_os
=
"linux"
)]
#[derive(Clone)]
struct
StatxExtraFields
{
// This is needed to check if btime is supported by the filesystem.
stx_mask
:
u32
,
stx_btime
:
libc
::
statx_timestamp
,
// FIXME: This should be available on Linux with all `target_arch` and `target_env`.
// https://github.com/rust-lang/libc/issues/1545
macro_rules!
cfg_has_statx
{
({
$
(
$then_tt:tt
)
*
}
else
{
$
(
$else_tt:tt
)
*
})
=>
{
cfg_if
::
cfg_if!
{
if
#[cfg(all(target_os
=
"linux"
,
target_env
=
"gnu"
,
any(
target_arch
=
"x86"
,
target_arch
=
"arm"
,
// target_arch = "mips",
target_arch
=
"powerpc"
,
target_arch
=
"x86_64"
,
// target_arch = "aarch64",
target_arch
=
"powerpc64"
,
// target_arch = "mips64",
// target_arch = "s390x",
target_arch
=
"sparc64"
,
)))]
{
$
(
$then_tt
)
*
}
else
{
$
(
$else_tt
)
*
}
}
};
(
$
(
$block_inner:tt
)
*
)
=>
{
#[cfg(all(target_os
=
"linux"
,
target_env
=
"gnu"
,
any(
target_arch
=
"x86"
,
target_arch
=
"arm"
,
// target_arch = "mips",
target_arch
=
"powerpc"
,
target_arch
=
"x86_64"
,
// target_arch = "aarch64",
target_arch
=
"powerpc64"
,
// target_arch = "mips64",
// target_arch = "s390x",
target_arch
=
"sparc64"
,
)))]
{
$
(
$block_inner
)
*
}
};
}
// We prefer `statx` on Linux if available, which contains file creation time.
// Default `stat64` contains no creation time.
#[cfg(target_os
=
"linux"
)]
unsafe
fn
try_statx
(
fd
:
c_int
,
path
:
*
const
libc
::
c_char
,
flags
:
i32
,
mask
:
u32
,
)
->
Option
<
io
::
Result
<
FileAttr
>>
{
use
crate
::
sync
::
atomic
::{
AtomicBool
,
Ordering
};
cfg_has_statx!
{{
#[derive(Clone)]
pub
struct
FileAttr
{
stat
:
stat64
,
statx_extra_fields
:
Option
<
StatxExtraFields
>
,
}
#[derive(Clone)]
struct
StatxExtraFields
{
// This is needed to check if btime is supported by the filesystem.
stx_mask
:
u32
,
stx_btime
:
libc
::
statx_timestamp
,
}
// We prefer `statx` on Linux if available, which contains file creation time.
// Default `stat64` contains no creation time.
unsafe
fn
try_statx
(
fd
:
c_int
,
path
:
*
const
libc
::
c_char
,
flags
:
i32
,
mask
:
u32
,
)
->
Option
<
io
::
Result
<
FileAttr
>>
{
use
crate
::
sync
::
atomic
::{
AtomicBool
,
Ordering
};
// Linux kernel prior to 4.11 or glibc prior to glibc 2.28 don't support `statx`
// We store the availability in a global to avoid unnecessary syscalls
static
HAS_STATX
:
AtomicBool
=
AtomicBool
::
new
(
true
);
syscall!
{
fn
statx
(
fd
:
c_int
,
pathname
:
*
const
libc
::
c_char
,
flags
:
c_int
,
mask
:
libc
::
c_uint
,
statxbuf
:
*
mut
libc
::
statx
)
->
c_int
}
// Linux kernel prior to 4.11 or glibc prior to glibc 2.28 don't support `statx`
// We store the availability in a global to avoid unnecessary syscalls
static
HAS_STATX
:
AtomicBool
=
AtomicBool
::
new
(
true
);
syscall!
{
fn
statx
(
fd
:
c_int
,
pathname
:
*
const
libc
::
c_char
,
flags
:
c_int
,
mask
:
libc
::
c_uint
,
statxbuf
:
*
mut
libc
::
statx
)
->
c_int
}
if
!
HAS_STATX
.load
(
Ordering
::
Relaxed
)
{
return
None
;
}
if
!
HAS_STATX
.load
(
Ordering
::
Relaxed
)
{
return
None
;
}
let
mut
buf
:
libc
::
statx
=
mem
::
zeroed
();
let
ret
=
cvt
(
statx
(
fd
,
path
,
flags
,
mask
,
&
mut
buf
));
match
ret
{
Err
(
err
)
=>
match
err
.raw_os_error
()
{
Some
(
libc
::
ENOSYS
)
=>
{
HAS_STATX
.store
(
false
,
Ordering
::
Relaxed
);
return
None
;
}
_
=>
return
Some
(
Err
(
err
)),
}
Ok
(
_
)
=>
{
// We cannot fill `stat64` exhaustively because of private padding fields.
let
mut
stat
:
stat64
=
mem
::
zeroed
();
// `c_ulong` on gnu-mips, `dev_t` otherwise
stat
.st_dev
=
libc
::
makedev
(
buf
.stx_dev_major
,
buf
.stx_dev_minor
)
as
_
;
stat
.st_ino
=
buf
.stx_ino
as
libc
::
ino64_t
;
stat
.st_nlink
=
buf
.stx_nlink
as
libc
::
nlink_t
;
stat
.st_mode
=
buf
.stx_mode
as
libc
::
mode_t
;
stat
.st_uid
=
buf
.stx_uid
as
libc
::
uid_t
;
stat
.st_gid
=
buf
.stx_gid
as
libc
::
gid_t
;
stat
.st_rdev
=
libc
::
makedev
(
buf
.stx_rdev_major
,
buf
.stx_rdev_minor
)
as
_
;
stat
.st_size
=
buf
.stx_size
as
off64_t
;
stat
.st_blksize
=
buf
.stx_blksize
as
libc
::
blksize_t
;
stat
.st_blocks
=
buf
.stx_blocks
as
libc
::
blkcnt64_t
;
stat
.st_atime
=
buf
.stx_atime.tv_sec
as
libc
::
time_t
;
// `i64` on gnu-x86_64-x32, `c_ulong` otherwise.
stat
.st_atime_nsec
=
buf
.stx_atime.tv_nsec
as
_
;
stat
.st_mtime
=
buf
.stx_mtime.tv_sec
as
libc
::
time_t
;
stat
.st_mtime_nsec
=
buf
.stx_mtime.tv_nsec
as
_
;
stat
.st_ctime
=
buf
.stx_ctime.tv_sec
as
libc
::
time_t
;
stat
.st_ctime_nsec
=
buf
.stx_ctime.tv_nsec
as
_
;
let
extra
=
StatxExtraFields
{
stx_mask
:
buf
.stx_mask
,
stx_btime
:
buf
.stx_btime
,
};
let
mut
buf
:
libc
::
statx
=
mem
::
zeroed
();
let
ret
=
cvt
(
statx
(
fd
,
path
,
flags
,
mask
,
&
mut
buf
));
match
ret
{
Err
(
err
)
=>
match
err
.raw_os_error
()
{
Some
(
libc
::
ENOSYS
)
=>
{
HAS_STATX
.store
(
false
,
Ordering
::
Relaxed
);
return
None
;
Some
(
Ok
(
FileAttr
{
stat
,
statx_extra_fields
:
Some
(
extra
)
}))
}
_
=>
return
Some
(
Err
(
err
)),
}
Ok
(
_
)
=>
{
// We cannot fill `stat64` exhaustively because of private padding fields.
let
mut
stat
:
stat64
=
mem
::
zeroed
();
stat
.st_dev
=
libc
::
makedev
(
buf
.stx_dev_major
,
buf
.stx_dev_minor
);
stat
.st_ino
=
buf
.stx_ino
as
libc
::
ino64_t
;
stat
.st_nlink
=
buf
.stx_nlink
as
libc
::
nlink_t
;
stat
.st_mode
=
buf
.stx_mode
as
libc
::
mode_t
;
stat
.st_uid
=
buf
.stx_uid
as
libc
::
uid_t
;
stat
.st_gid
=
buf
.stx_gid
as
libc
::
gid_t
;
stat
.st_rdev
=
libc
::
makedev
(
buf
.stx_rdev_major
,
buf
.stx_rdev_minor
);
stat
.st_size
=
buf
.stx_size
as
off64_t
;
stat
.st_blksize
=
buf
.stx_blksize
as
libc
::
blksize_t
;
stat
.st_blocks
=
buf
.stx_blocks
as
libc
::
blkcnt64_t
;
stat
.st_atime
=
buf
.stx_atime.tv_sec
as
libc
::
time_t
;
stat
.st_atime_nsec
=
buf
.stx_atime.tv_nsec
as
libc
::
c_long
;
stat
.st_mtime
=
buf
.stx_mtime.tv_sec
as
libc
::
time_t
;
stat
.st_mtime_nsec
=
buf
.stx_mtime.tv_nsec
as
libc
::
c_long
;
stat
.st_ctime
=
buf
.stx_ctime.tv_sec
as
libc
::
time_t
;
stat
.st_ctime_nsec
=
buf
.stx_ctime.tv_nsec
as
libc
::
c_long
;
let
extra
=
StatxExtraFields
{
stx_mask
:
buf
.stx_mask
,
stx_btime
:
buf
.stx_btime
,
};
}
Some
(
Ok
(
FileAttr
{
stat
,
statx_extra_fields
:
Some
(
extra
)
}))
}
}
else
{
#[derive(Clone)]
pub
struct
FileAttr
{
stat
:
stat64
,
}
}
}
}
// all DirEntry's will have a reference to this struct
struct
InnerReadDir
{
...
...
@@ -175,15 +224,21 @@ pub struct FileType { mode: mode_t }
#[derive(Debug)]
pub
struct
DirBuilder
{
mode
:
mode_t
}
impl
FileAttr
{
fn
from_stat64
(
stat
:
stat64
)
->
Self
{
Self
{
stat
,
#[cfg(target_os
=
"linux"
)]
statx_extra_fields
:
None
,
cfg_has_statx!
{{
impl
FileAttr
{
fn
from_stat64
(
stat
:
stat64
)
->
Self
{
Self
{
stat
,
statx_extra_fields
:
None
}
}
}
}
else
{
impl
FileAttr
{
fn
from_stat64
(
stat
:
stat64
)
->
Self
{
Self
{
stat
}
}
}
}}
impl
FileAttr
{
pub
fn
size
(
&
self
)
->
u64
{
self
.stat.st_size
as
u64
}
pub
fn
perm
(
&
self
)
->
FilePermissions
{
FilePermissions
{
mode
:
(
self
.stat.st_mode
as
mode_t
)
}
...
...
@@ -250,8 +305,7 @@ pub fn created(&self) -> io::Result<SystemTime> {
target_os
=
"macos"
,
target_os
=
"ios"
)))]
pub
fn
created
(
&
self
)
->
io
::
Result
<
SystemTime
>
{
#[cfg(target_os
=
"linux"
)]
{
cfg_has_statx!
{
if
let
Some
(
ext
)
=
&
self
.statx_extra_fields
{
return
if
(
ext
.stx_mask
&
libc
::
STATX_BTIME
)
!=
0
{
Ok
(
SystemTime
::
from
(
libc
::
timespec
{
...
...
@@ -412,8 +466,7 @@ pub fn metadata(&self) -> io::Result<FileAttr> {
let
fd
=
cvt
(
unsafe
{
dirfd
(
self
.dir.inner.dirp
.0
)
})
?
;
let
name
=
self
.entry.d_name
.as_ptr
();
#[cfg(target_os
=
"linux"
)]
{
cfg_has_statx!
{
if
let
Some
(
ret
)
=
unsafe
{
try_statx
(
fd
,
name
,
...
...
@@ -636,8 +689,7 @@ fn ensure_cloexec(_: &FileDesc) -> io::Result<()> {
pub
fn
file_attr
(
&
self
)
->
io
::
Result
<
FileAttr
>
{
let
fd
=
self
.0
.raw
();
#[cfg(target_os
=
"linux"
)]
{
cfg_has_statx!
{
if
let
Some
(
ret
)
=
unsafe
{
try_statx
(
fd
,
b
"
\0
"
as
*
const
_
as
*
const
libc
::
c_char
,
...
...
@@ -930,8 +982,7 @@ pub fn link(src: &Path, dst: &Path) -> io::Result<()> {
pub
fn
stat
(
p
:
&
Path
)
->
io
::
Result
<
FileAttr
>
{
let
p
=
cstr
(
p
)
?
;
#[cfg(target_os
=
"linux"
)]
{
cfg_has_statx!
{
if
let
Some
(
ret
)
=
unsafe
{
try_statx
(
libc
::
AT_FDCWD
,
p
.as_ptr
(),
...
...
@@ -952,8 +1003,7 @@ pub fn stat(p: &Path) -> io::Result<FileAttr> {
pub
fn
lstat
(
p
:
&
Path
)
->
io
::
Result
<
FileAttr
>
{
let
p
=
cstr
(
p
)
?
;
#[cfg(target_os
=
"linux"
)]
{
cfg_has_statx!
{
if
let
Some
(
ret
)
=
unsafe
{
try_statx
(
libc
::
AT_FDCWD
,
p
.as_ptr
(),
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录