Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 3831e77

Browse files
committedAug 8, 2023
Support AIX in Rust standard library
1 parent 443c316 commit 3831e77

File tree

14 files changed

+463
-4
lines changed

14 files changed

+463
-4
lines changed
 

‎library/std/build.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ fn main() {
3636
|| target.contains("solid")
3737
|| target.contains("nintendo-3ds")
3838
|| target.contains("vita")
39+
|| target.contains("aix")
3940
|| target.contains("nto")
4041
// See src/bootstrap/synthetic_targets.rs
4142
|| env::var("RUSTC_BOOTSTRAP_SYNTHETIC_TARGET").is_ok()

‎library/std/src/os/aix/fs.rs

Lines changed: 348 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,348 @@
1+
//! AIX specific extensions to primitives in the [`std::fs`] module.
2+
//!
3+
//! [`std::fs`]: crate::fs
4+
5+
#![stable(feature = "metadata_ext", since = "1.1.0")]
6+
7+
use crate::fs::Metadata;
8+
use crate::sys_common::AsInner;
9+
10+
/// OS-specific extensions to [`fs::Metadata`].
11+
///
12+
/// [`fs::Metadata`]: crate::fs::Metadata
13+
#[stable(feature = "metadata_ext", since = "1.1.0")]
14+
pub trait MetadataExt {
15+
/// Returns the device ID on which this file resides.
16+
///
17+
/// # Examples
18+
///
19+
/// ```no_run
20+
/// use std::fs;
21+
/// use std::io;
22+
/// use std::os::aix::fs::MetadataExt;
23+
///
24+
/// fn main() -> io::Result<()> {
25+
/// let meta = fs::metadata("some_file")?;
26+
/// println!("{}", meta.st_dev());
27+
/// Ok(())
28+
/// }
29+
/// ```
30+
#[stable(feature = "metadata_ext2", since = "1.8.0")]
31+
fn st_dev(&self) -> u64;
32+
/// Returns the inode number.
33+
///
34+
/// # Examples
35+
///
36+
/// ```no_run
37+
/// use std::fs;
38+
/// use std::io;
39+
/// use std::os::aix::fs::MetadataExt;
40+
///
41+
/// fn main() -> io::Result<()> {
42+
/// let meta = fs::metadata("some_file")?;
43+
/// println!("{}", meta.st_ino());
44+
/// Ok(())
45+
/// }
46+
/// ```
47+
#[stable(feature = "metadata_ext2", since = "1.8.0")]
48+
fn st_ino(&self) -> u64;
49+
/// Returns the file type and mode.
50+
///
51+
/// # Examples
52+
///
53+
/// ```no_run
54+
/// use std::fs;
55+
/// use std::io;
56+
/// use std::os::aix::fs::MetadataExt;
57+
///
58+
/// fn main() -> io::Result<()> {
59+
/// let meta = fs::metadata("some_file")?;
60+
/// println!("{}", meta.st_mode());
61+
/// Ok(())
62+
/// }
63+
/// ```
64+
#[stable(feature = "metadata_ext2", since = "1.8.0")]
65+
fn st_mode(&self) -> u32;
66+
/// Returns the number of hard links to file.
67+
///
68+
/// # Examples
69+
///
70+
/// ```no_run
71+
/// use std::fs;
72+
/// use std::io;
73+
/// use std::os::aix::fs::MetadataExt;
74+
///
75+
/// fn main() -> io::Result<()> {
76+
/// let meta = fs::metadata("some_file")?;
77+
/// println!("{}", meta.st_nlink());
78+
/// Ok(())
79+
/// }
80+
/// ```
81+
#[stable(feature = "metadata_ext2", since = "1.8.0")]
82+
fn st_nlink(&self) -> u64;
83+
/// Returns the user ID of the file owner.
84+
///
85+
/// # Examples
86+
///
87+
/// ```no_run
88+
/// use std::fs;
89+
/// use std::io;
90+
/// use std::os::aix::fs::MetadataExt;
91+
///
92+
/// fn main() -> io::Result<()> {
93+
/// let meta = fs::metadata("some_file")?;
94+
/// println!("{}", meta.st_uid());
95+
/// Ok(())
96+
/// }
97+
/// ```
98+
#[stable(feature = "metadata_ext2", since = "1.8.0")]
99+
fn st_uid(&self) -> u32;
100+
/// Returns the group ID of the file owner.
101+
///
102+
/// # Examples
103+
///
104+
/// ```no_run
105+
/// use std::fs;
106+
/// use std::io;
107+
/// use std::os::aix::fs::MetadataExt;
108+
///
109+
/// fn main() -> io::Result<()> {
110+
/// let meta = fs::metadata("some_file")?;
111+
/// println!("{}", meta.st_gid());
112+
/// Ok(())
113+
/// }
114+
/// ```
115+
#[stable(feature = "metadata_ext2", since = "1.8.0")]
116+
fn st_gid(&self) -> u32;
117+
/// Returns the device ID that this file represents. Only relevant for special file.
118+
///
119+
/// # Examples
120+
///
121+
/// ```no_run
122+
/// use std::fs;
123+
/// use std::io;
124+
/// use std::os::aix::fs::MetadataExt;
125+
///
126+
/// fn main() -> io::Result<()> {
127+
/// let meta = fs::metadata("some_file")?;
128+
/// println!("{}", meta.st_rdev());
129+
/// Ok(())
130+
/// }
131+
/// ```
132+
#[stable(feature = "metadata_ext2", since = "1.8.0")]
133+
fn st_rdev(&self) -> u64;
134+
/// Returns the size of the file (if it is a regular file or a symbolic link) in bytes.
135+
///
136+
/// The size of a symbolic link is the length of the pathname it contains,
137+
/// without a terminating null byte.
138+
///
139+
/// # Examples
140+
///
141+
/// ```no_run
142+
/// use std::fs;
143+
/// use std::io;
144+
/// use std::os::aix::fs::MetadataExt;
145+
///
146+
/// fn main() -> io::Result<()> {
147+
/// let meta = fs::metadata("some_file")?;
148+
/// println!("{}", meta.st_size());
149+
/// Ok(())
150+
/// }
151+
/// ```
152+
#[stable(feature = "metadata_ext2", since = "1.8.0")]
153+
fn st_size(&self) -> u64;
154+
/// Returns the last access time of the file, in seconds since Unix Epoch.
155+
///
156+
/// # Examples
157+
///
158+
/// ```no_run
159+
/// use std::fs;
160+
/// use std::io;
161+
/// use std::os::aix::fs::MetadataExt;
162+
///
163+
/// fn main() -> io::Result<()> {
164+
/// let meta = fs::metadata("some_file")?;
165+
/// println!("{}", meta.st_atime());
166+
/// Ok(())
167+
/// }
168+
/// ```
169+
#[stable(feature = "metadata_ext2", since = "1.8.0")]
170+
fn st_atime(&self) -> i64;
171+
/// Returns the last access time of the file, in nanoseconds since [`st_atime`].
172+
///
173+
/// [`st_atime`]: Self::st_atime
174+
///
175+
/// # Examples
176+
///
177+
/// ```no_run
178+
/// use std::fs;
179+
/// use std::io;
180+
/// use std::os::aix::fs::MetadataExt;
181+
///
182+
/// fn main() -> io::Result<()> {
183+
/// let meta = fs::metadata("some_file")?;
184+
/// println!("{}", meta.st_atime_nsec());
185+
/// Ok(())
186+
/// }
187+
/// ```
188+
#[stable(feature = "metadata_ext2", since = "1.8.0")]
189+
fn st_atime_nsec(&self) -> i64;
190+
/// Returns the last modification time of the file, in seconds since Unix Epoch.
191+
///
192+
/// # Examples
193+
///
194+
/// ```no_run
195+
/// use std::fs;
196+
/// use std::io;
197+
/// use std::os::aix::fs::MetadataExt;
198+
///
199+
/// fn main() -> io::Result<()> {
200+
/// let meta = fs::metadata("some_file")?;
201+
/// println!("{}", meta.st_mtime());
202+
/// Ok(())
203+
/// }
204+
/// ```
205+
#[stable(feature = "metadata_ext2", since = "1.8.0")]
206+
fn st_mtime(&self) -> i64;
207+
/// Returns the last modification time of the file, in nanoseconds since [`st_mtime`].
208+
///
209+
/// [`st_mtime`]: Self::st_mtime
210+
///
211+
/// # Examples
212+
///
213+
/// ```no_run
214+
/// use std::fs;
215+
/// use std::io;
216+
/// use std::os::aix::fs::MetadataExt;
217+
///
218+
/// fn main() -> io::Result<()> {
219+
/// let meta = fs::metadata("some_file")?;
220+
/// println!("{}", meta.st_mtime_nsec());
221+
/// Ok(())
222+
/// }
223+
/// ```
224+
#[stable(feature = "metadata_ext2", since = "1.8.0")]
225+
fn st_mtime_nsec(&self) -> i64;
226+
/// Returns the last status change time of the file, in seconds since Unix Epoch.
227+
///
228+
/// # Examples
229+
///
230+
/// ```no_run
231+
/// use std::fs;
232+
/// use std::io;
233+
/// use std::os::aix::fs::MetadataExt;
234+
///
235+
/// fn main() -> io::Result<()> {
236+
/// let meta = fs::metadata("some_file")?;
237+
/// println!("{}", meta.st_ctime());
238+
/// Ok(())
239+
/// }
240+
/// ```
241+
#[stable(feature = "metadata_ext2", since = "1.8.0")]
242+
fn st_ctime(&self) -> i64;
243+
/// Returns the last status change time of the file, in nanoseconds since [`st_ctime`].
244+
///
245+
/// [`st_ctime`]: Self::st_ctime
246+
///
247+
/// # Examples
248+
///
249+
/// ```no_run
250+
/// use std::fs;
251+
/// use std::io;
252+
/// use std::os::aix::fs::MetadataExt;
253+
///
254+
/// fn main() -> io::Result<()> {
255+
/// let meta = fs::metadata("some_file")?;
256+
/// println!("{}", meta.st_ctime_nsec());
257+
/// Ok(())
258+
/// }
259+
/// ```
260+
#[stable(feature = "metadata_ext2", since = "1.8.0")]
261+
fn st_ctime_nsec(&self) -> i64;
262+
/// Returns the "preferred" block size for efficient filesystem I/O.
263+
///
264+
/// # Examples
265+
///
266+
/// ```no_run
267+
/// use std::fs;
268+
/// use std::io;
269+
/// use std::os::aix::fs::MetadataExt;
270+
///
271+
/// fn main() -> io::Result<()> {
272+
/// let meta = fs::metadata("some_file")?;
273+
/// println!("{}", meta.st_blksize());
274+
/// Ok(())
275+
/// }
276+
/// ```
277+
#[stable(feature = "metadata_ext2", since = "1.8.0")]
278+
fn st_blksize(&self) -> u64;
279+
/// Returns the number of blocks allocated to the file, 512-byte units.
280+
///
281+
/// # Examples
282+
///
283+
/// ```no_run
284+
/// use std::fs;
285+
/// use std::io;
286+
/// use std::os::aix::fs::MetadataExt;
287+
///
288+
/// fn main() -> io::Result<()> {
289+
/// let meta = fs::metadata("some_file")?;
290+
/// println!("{}", meta.st_blocks());
291+
/// Ok(())
292+
/// }
293+
/// ```
294+
#[stable(feature = "metadata_ext2", since = "1.8.0")]
295+
fn st_blocks(&self) -> u64;
296+
}
297+
298+
#[stable(feature = "metadata_ext", since = "1.1.0")]
299+
impl MetadataExt for Metadata {
300+
fn st_dev(&self) -> u64 {
301+
self.as_inner().as_inner().st_dev as u64
302+
}
303+
fn st_ino(&self) -> u64 {
304+
self.as_inner().as_inner().st_ino as u64
305+
}
306+
fn st_mode(&self) -> u32 {
307+
self.as_inner().as_inner().st_mode as u32
308+
}
309+
fn st_nlink(&self) -> u64 {
310+
self.as_inner().as_inner().st_nlink as u64
311+
}
312+
fn st_uid(&self) -> u32 {
313+
self.as_inner().as_inner().st_uid as u32
314+
}
315+
fn st_gid(&self) -> u32 {
316+
self.as_inner().as_inner().st_gid as u32
317+
}
318+
fn st_rdev(&self) -> u64 {
319+
self.as_inner().as_inner().st_rdev as u64
320+
}
321+
fn st_size(&self) -> u64 {
322+
self.as_inner().as_inner().st_size as u64
323+
}
324+
fn st_atime(&self) -> i64 {
325+
self.as_inner().as_inner().st_atime.tv_sec as i64
326+
}
327+
fn st_atime_nsec(&self) -> i64 {
328+
self.as_inner().as_inner().st_atime.tv_nsec as i64
329+
}
330+
fn st_mtime(&self) -> i64 {
331+
self.as_inner().as_inner().st_mtime.tv_sec as i64
332+
}
333+
fn st_mtime_nsec(&self) -> i64 {
334+
self.as_inner().as_inner().st_mtime.tv_nsec as i64
335+
}
336+
fn st_ctime(&self) -> i64 {
337+
self.as_inner().as_inner().st_ctime.tv_sec as i64
338+
}
339+
fn st_ctime_nsec(&self) -> i64 {
340+
self.as_inner().as_inner().st_ctime.tv_nsec as i64
341+
}
342+
fn st_blksize(&self) -> u64 {
343+
self.as_inner().as_inner().st_blksize as u64
344+
}
345+
fn st_blocks(&self) -> u64 {
346+
self.as_inner().as_inner().st_blocks as u64
347+
}
348+
}

‎library/std/src/os/aix/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
//! AIX specific definitions.
2+
3+
#![stable(feature = "raw_ext", since = "1.1.0")]
4+
5+
pub mod fs;
6+
pub mod raw;

‎library/std/src/os/aix/raw.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
//! AIX specific raw type definitions.
2+
3+
#![stable(feature = "raw_ext", since = "1.1.0")]
4+
5+
#[stable(feature = "pthread_t", since = "1.8.0")]
6+
pub use libc::pthread_t;
7+
8+
#[stable(feature = "raw_ext", since = "1.1.0")]
9+
pub use libc::{blkcnt_t, blksize_t, dev_t, ino_t, mode_t, nlink_t, off_t, stat, time_t};

‎library/std/src/os/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ pub mod wasi;
9797
pub mod windows;
9898

9999
// Others.
100+
#[cfg(target_os = "aix")]
101+
pub mod aix;
100102
#[cfg(target_os = "android")]
101103
pub mod android;
102104
#[cfg(target_os = "dragonfly")]

‎library/std/src/os/unix/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ use crate::os::linux as platform;
3737

3838
#[cfg(not(doc))]
3939
mod platform {
40+
#[cfg(target_os = "aix")]
41+
pub use crate::os::aix::*;
4042
#[cfg(target_os = "android")]
4143
pub use crate::os::android::*;
4244
#[cfg(target_os = "dragonfly")]

‎library/std/src/sys/unix/args.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ impl DoubleEndedIterator for Args {
7070
target_os = "redox",
7171
target_os = "vxworks",
7272
target_os = "horizon",
73+
target_os = "aix",
7374
target_os = "nto",
7475
))]
7576
mod imp {

‎library/std/src/sys/unix/env.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,3 +250,14 @@ pub mod os {
250250
pub const EXE_SUFFIX: &str = "";
251251
pub const EXE_EXTENSION: &str = "";
252252
}
253+
254+
#[cfg(target_os = "aix")]
255+
pub mod os {
256+
pub const FAMILY: &str = "unix";
257+
pub const OS: &str = "aix";
258+
pub const DLL_PREFIX: &str = "lib";
259+
pub const DLL_SUFFIX: &str = ".a";
260+
pub const DLL_EXTENSION: &str = "a";
261+
pub const EXE_SUFFIX: &str = "";
262+
pub const EXE_EXTENSION: &str = "";
263+
}

‎library/std/src/sys/unix/fs.rs

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ use libc::fstatat64;
4949
target_os = "fuchsia",
5050
target_os = "redox",
5151
target_os = "illumos",
52+
target_os = "aix",
5253
target_os = "nto",
5354
target_os = "vita",
5455
))]
@@ -66,6 +67,7 @@ use libc::readdir64_r;
6667
target_os = "l4re",
6768
target_os = "fuchsia",
6869
target_os = "redox",
70+
target_os = "aix",
6971
target_os = "nto",
7072
target_os = "vita",
7173
)))]
@@ -276,6 +278,7 @@ unsafe impl Sync for Dir {}
276278
target_os = "illumos",
277279
target_os = "fuchsia",
278280
target_os = "redox",
281+
target_os = "aix",
279282
target_os = "nto",
280283
target_os = "vita"
281284
))]
@@ -298,6 +301,7 @@ pub struct DirEntry {
298301
target_os = "illumos",
299302
target_os = "fuchsia",
300303
target_os = "redox",
304+
target_os = "aix",
301305
target_os = "nto",
302306
target_os = "vita",
303307
))]
@@ -306,8 +310,9 @@ struct dirent64_min {
306310
#[cfg(not(any(
307311
target_os = "solaris",
308312
target_os = "illumos",
313+
target_os = "aix",
309314
target_os = "nto",
310-
target_os = "vita"
315+
target_os = "vita",
311316
)))]
312317
d_type: u8,
313318
}
@@ -319,6 +324,7 @@ struct dirent64_min {
319324
target_os = "illumos",
320325
target_os = "fuchsia",
321326
target_os = "redox",
327+
target_os = "aix",
322328
target_os = "nto",
323329
target_os = "vita",
324330
)))]
@@ -449,7 +455,22 @@ impl FileAttr {
449455
}
450456
}
451457

452-
#[cfg(not(any(target_os = "netbsd", target_os = "nto")))]
458+
#[cfg(target_os = "aix")]
459+
impl FileAttr {
460+
pub fn modified(&self) -> io::Result<SystemTime> {
461+
Ok(SystemTime::new(self.stat.st_mtime.tv_sec as i64, self.stat.st_mtime.tv_nsec as i64))
462+
}
463+
464+
pub fn accessed(&self) -> io::Result<SystemTime> {
465+
Ok(SystemTime::new(self.stat.st_atime.tv_sec as i64, self.stat.st_atime.tv_nsec as i64))
466+
}
467+
468+
pub fn created(&self) -> io::Result<SystemTime> {
469+
Ok(SystemTime::new(self.stat.st_ctime.tv_sec as i64, self.stat.st_ctime.tv_nsec as i64))
470+
}
471+
}
472+
473+
#[cfg(not(any(target_os = "netbsd", target_os = "nto", target_os = "aix")))]
453474
impl FileAttr {
454475
#[cfg(not(any(
455476
target_os = "vxworks",
@@ -654,6 +675,7 @@ impl Iterator for ReadDir {
654675
target_os = "fuchsia",
655676
target_os = "redox",
656677
target_os = "illumos",
678+
target_os = "aix",
657679
target_os = "nto",
658680
target_os = "vita",
659681
))]
@@ -730,6 +752,7 @@ impl Iterator for ReadDir {
730752
#[cfg(not(any(
731753
target_os = "solaris",
732754
target_os = "illumos",
755+
target_os = "aix",
733756
target_os = "nto",
734757
)))]
735758
d_type: *offset_ptr!(entry_ptr, d_type) as u8,
@@ -754,6 +777,7 @@ impl Iterator for ReadDir {
754777
target_os = "fuchsia",
755778
target_os = "redox",
756779
target_os = "illumos",
780+
target_os = "aix",
757781
target_os = "nto",
758782
target_os = "vita",
759783
)))]
@@ -845,6 +869,7 @@ impl DirEntry {
845869
target_os = "illumos",
846870
target_os = "haiku",
847871
target_os = "vxworks",
872+
target_os = "aix",
848873
target_os = "nto",
849874
target_os = "vita",
850875
))]
@@ -857,6 +882,7 @@ impl DirEntry {
857882
target_os = "illumos",
858883
target_os = "haiku",
859884
target_os = "vxworks",
885+
target_os = "aix",
860886
target_os = "nto",
861887
target_os = "vita",
862888
)))]
@@ -891,6 +917,7 @@ impl DirEntry {
891917
target_os = "espidf",
892918
target_os = "horizon",
893919
target_os = "vita",
920+
target_os = "aix",
894921
target_os = "nto",
895922
))]
896923
pub fn ino(&self) -> u64 {
@@ -947,6 +974,7 @@ impl DirEntry {
947974
target_os = "illumos",
948975
target_os = "fuchsia",
949976
target_os = "redox",
977+
target_os = "aix",
950978
target_os = "nto",
951979
target_os = "vita",
952980
)))]
@@ -960,6 +988,7 @@ impl DirEntry {
960988
target_os = "illumos",
961989
target_os = "fuchsia",
962990
target_os = "redox",
991+
target_os = "aix",
963992
target_os = "nto",
964993
target_os = "vita",
965994
))]
@@ -1988,6 +2017,7 @@ mod remove_dir_impl {
19882017
target_os = "illumos",
19892018
target_os = "haiku",
19902019
target_os = "vxworks",
2020+
target_os = "aix",
19912021
))]
19922022
fn is_dir(_ent: &DirEntry) -> Option<bool> {
19932023
None
@@ -1998,6 +2028,7 @@ mod remove_dir_impl {
19982028
target_os = "illumos",
19992029
target_os = "haiku",
20002030
target_os = "vxworks",
2031+
target_os = "aix",
20012032
)))]
20022033
fn is_dir(ent: &DirEntry) -> Option<bool> {
20032034
match ent.entry.d_type {

‎library/std/src/sys/unix/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@ pub fn decode_error_kind(errno: i32) -> ErrorKind {
269269
libc::ENETUNREACH => NetworkUnreachable,
270270
libc::ENOTCONN => NotConnected,
271271
libc::ENOTDIR => NotADirectory,
272+
#[cfg(not(target_os = "aix"))]
272273
libc::ENOTEMPTY => DirectoryNotEmpty,
273274
libc::EPIPE => BrokenPipe,
274275
libc::EROFS => ReadOnlyFilesystem,

‎library/std/src/sys/unix/os.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ extern "C" {
7373
link_name = "__error"
7474
)]
7575
#[cfg_attr(target_os = "haiku", link_name = "_errnop")]
76+
#[cfg_attr(target_os = "aix", link_name = "_Errno")]
7677
fn errno_location() -> *mut c_int;
7778
}
7879

@@ -250,6 +251,41 @@ impl StdError for JoinPathsError {
250251
}
251252
}
252253

254+
#[cfg(target_os = "aix")]
255+
pub fn current_exe() -> io::Result<PathBuf> {
256+
use crate::io::ErrorKind;
257+
258+
#[cfg(test)]
259+
use realstd::env;
260+
261+
#[cfg(not(test))]
262+
use crate::env;
263+
264+
let exe_path = env::args().next().ok_or(io::const_io_error!(
265+
ErrorKind::Uncategorized,
266+
"an executable path was not found because no arguments were provided through argv"
267+
))?;
268+
let path = PathBuf::from(exe_path);
269+
if path.is_absolute() {
270+
return path.canonicalize();
271+
}
272+
// Search PWD to infer current_exe.
273+
if let Some(pstr) = path.to_str() && pstr.contains("/") {
274+
return getcwd().map(|cwd| cwd.join(path))?.canonicalize();
275+
}
276+
// Search PATH to infer current_exe.
277+
if let Some(p) = getenv(OsStr::from_bytes("PATH".as_bytes())) {
278+
for search_path in split_paths(&p) {
279+
let pb = search_path.join(&path);
280+
if pb.is_file() && let Ok(metadata) = crate::fs::metadata(&pb) &&
281+
metadata.permissions().mode() & 0o111 != 0 {
282+
return pb.canonicalize();
283+
}
284+
}
285+
}
286+
return Err(io::const_io_error!(ErrorKind::Uncategorized, "an executable path was not found"));
287+
}
288+
253289
#[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
254290
pub fn current_exe() -> io::Result<PathBuf> {
255291
unsafe {

‎library/std/src/sys/unix/thread.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,8 @@ impl Thread {
213213
target_os = "l4re",
214214
target_os = "emscripten",
215215
target_os = "redox",
216-
target_os = "vxworks"
216+
target_os = "vxworks",
217+
target_os = "aix"
217218
))]
218219
pub fn set_name(_name: &CStr) {
219220
// Newlib, Emscripten, and VxWorks have no way to set a thread name.
@@ -311,6 +312,7 @@ pub fn available_parallelism() -> io::Result<NonZeroUsize> {
311312
target_os = "macos",
312313
target_os = "solaris",
313314
target_os = "illumos",
315+
target_os = "aix",
314316
))] {
315317
#[cfg(any(target_os = "android", target_os = "linux"))]
316318
{

‎library/std/src/sys/unix/thread_local_dtor.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,12 @@ pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) {
8383
}
8484
}
8585

86-
#[cfg(any(target_os = "vxworks", target_os = "horizon", target_os = "emscripten"))]
86+
#[cfg(any(
87+
target_os = "vxworks",
88+
target_os = "horizon",
89+
target_os = "emscripten",
90+
target_os = "aix"
91+
))]
8792
#[cfg_attr(target_family = "wasm", allow(unused))] // might remain unused depending on target details (e.g. wasm32-unknown-emscripten)
8893
pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) {
8994
use crate::sys_common::thread_local_dtor::register_dtor_fallback;

‎library/unwind/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,10 @@ extern "C" {}
145145
#[link(name = "gcc_s")]
146146
extern "C" {}
147147

148+
#[cfg(target_os = "aix")]
149+
#[link(name = "unwind")]
150+
extern "C" {}
151+
148152
#[cfg(target_os = "nto")]
149153
#[link(name = "gcc_s")]
150154
extern "C" {}

0 commit comments

Comments
 (0)
Please sign in to comment.