Skip to content

Commit 10f1bc7

Browse files
committed
Some tweaks
1 parent c787fe3 commit 10f1bc7

File tree

1 file changed

+44
-49
lines changed

1 file changed

+44
-49
lines changed

src/libstd/sys/unix/fs.rs

+44-49
Original file line numberDiff line numberDiff line change
@@ -124,64 +124,59 @@ cfg_has_statx! {{
124124
}
125125

126126
match STATX_STATE.load(Ordering::Relaxed) {
127-
// For the first time, we try to call on current working directory
128-
// to check if it is available.
129127
0 => {
130-
let mut buf: libc::statx = mem::zeroed();
131-
let err = cvt(statx(
132-
libc::AT_FDCWD,
133-
b".\0".as_ptr().cast(),
134-
0,
135-
libc::STATX_ALL,
136-
&mut buf,
137-
))
128+
// It is a trick to call `statx` with NULL pointers to check if the syscall
129+
// is available. According to the manual, it is expected to fail with EFAULT.
130+
// We do this mainly for performance, since it is nearly hundreds times
131+
// faster than a normal successfull call.
132+
let err = cvt(statx(0, ptr::null(), 0, libc::STATX_ALL, ptr::null_mut()))
138133
.err()
139134
.and_then(|e| e.raw_os_error());
140-
// `seccomp` will emit `EPERM` on denied syscall.
135+
// We don't check `err == Some(libc::ENOSYS)` because the syscall may be limited
136+
// and returns `EPERM`. Listing all possible errors seems not a good idea.
141137
// See: https://github.com/rust-lang/rust/issues/65662
142-
if err == Some(libc::ENOSYS) || err == Some(libc::EPERM) {
138+
if err != Some(libc::EFAULT) {
143139
STATX_STATE.store(1, Ordering::Relaxed);
144-
} else {
145-
STATX_STATE.store(2, Ordering::Relaxed);
140+
return None;
146141
}
147-
try_statx(fd, path, flags, mask)
142+
STATX_STATE.store(2, Ordering::Relaxed);
148143
}
149-
1 => None,
150-
_ => {
151-
let mut buf: libc::statx = mem::zeroed();
152-
if let Err(err) = cvt(statx(fd, path, flags, mask, &mut buf)) {
153-
return Some(Err(err));
154-
}
155-
156-
// We cannot fill `stat64` exhaustively because of private padding fields.
157-
let mut stat: stat64 = mem::zeroed();
158-
// `c_ulong` on gnu-mips, `dev_t` otherwise
159-
stat.st_dev = libc::makedev(buf.stx_dev_major, buf.stx_dev_minor) as _;
160-
stat.st_ino = buf.stx_ino as libc::ino64_t;
161-
stat.st_nlink = buf.stx_nlink as libc::nlink_t;
162-
stat.st_mode = buf.stx_mode as libc::mode_t;
163-
stat.st_uid = buf.stx_uid as libc::uid_t;
164-
stat.st_gid = buf.stx_gid as libc::gid_t;
165-
stat.st_rdev = libc::makedev(buf.stx_rdev_major, buf.stx_rdev_minor) as _;
166-
stat.st_size = buf.stx_size as off64_t;
167-
stat.st_blksize = buf.stx_blksize as libc::blksize_t;
168-
stat.st_blocks = buf.stx_blocks as libc::blkcnt64_t;
169-
stat.st_atime = buf.stx_atime.tv_sec as libc::time_t;
170-
// `i64` on gnu-x86_64-x32, `c_ulong` otherwise.
171-
stat.st_atime_nsec = buf.stx_atime.tv_nsec as _;
172-
stat.st_mtime = buf.stx_mtime.tv_sec as libc::time_t;
173-
stat.st_mtime_nsec = buf.stx_mtime.tv_nsec as _;
174-
stat.st_ctime = buf.stx_ctime.tv_sec as libc::time_t;
175-
stat.st_ctime_nsec = buf.stx_ctime.tv_nsec as _;
176-
177-
let extra = StatxExtraFields {
178-
stx_mask: buf.stx_mask,
179-
stx_btime: buf.stx_btime,
180-
};
144+
1 => return None,
145+
_ => {}
146+
}
181147

182-
Some(Ok(FileAttr { stat, statx_extra_fields: Some(extra) }))
183-
}
148+
let mut buf: libc::statx = mem::zeroed();
149+
if let Err(err) = cvt(statx(fd, path, flags, mask, &mut buf)) {
150+
return Some(Err(err));
184151
}
152+
153+
// We cannot fill `stat64` exhaustively because of private padding fields.
154+
let mut stat: stat64 = mem::zeroed();
155+
// `c_ulong` on gnu-mips, `dev_t` otherwise
156+
stat.st_dev = libc::makedev(buf.stx_dev_major, buf.stx_dev_minor) as _;
157+
stat.st_ino = buf.stx_ino as libc::ino64_t;
158+
stat.st_nlink = buf.stx_nlink as libc::nlink_t;
159+
stat.st_mode = buf.stx_mode as libc::mode_t;
160+
stat.st_uid = buf.stx_uid as libc::uid_t;
161+
stat.st_gid = buf.stx_gid as libc::gid_t;
162+
stat.st_rdev = libc::makedev(buf.stx_rdev_major, buf.stx_rdev_minor) as _;
163+
stat.st_size = buf.stx_size as off64_t;
164+
stat.st_blksize = buf.stx_blksize as libc::blksize_t;
165+
stat.st_blocks = buf.stx_blocks as libc::blkcnt64_t;
166+
stat.st_atime = buf.stx_atime.tv_sec as libc::time_t;
167+
// `i64` on gnu-x86_64-x32, `c_ulong` otherwise.
168+
stat.st_atime_nsec = buf.stx_atime.tv_nsec as _;
169+
stat.st_mtime = buf.stx_mtime.tv_sec as libc::time_t;
170+
stat.st_mtime_nsec = buf.stx_mtime.tv_nsec as _;
171+
stat.st_ctime = buf.stx_ctime.tv_sec as libc::time_t;
172+
stat.st_ctime_nsec = buf.stx_ctime.tv_nsec as _;
173+
174+
let extra = StatxExtraFields {
175+
stx_mask: buf.stx_mask,
176+
stx_btime: buf.stx_btime,
177+
};
178+
179+
Some(Ok(FileAttr { stat, statx_extra_fields: Some(extra) }))
185180
}
186181

187182
} else {

0 commit comments

Comments
 (0)