about summary refs log tree commit diff
path: root/library/std/src
diff options
context:
space:
mode:
Diffstat (limited to 'library/std/src')
-rw-r--r--library/std/src/os/aix/fs.rs348
-rw-r--r--library/std/src/os/aix/mod.rs6
-rw-r--r--library/std/src/os/aix/raw.rs9
-rw-r--r--library/std/src/os/mod.rs2
-rw-r--r--library/std/src/os/unix/mod.rs2
-rw-r--r--library/std/src/sys/unix/args.rs1
-rw-r--r--library/std/src/sys/unix/env.rs11
-rw-r--r--library/std/src/sys/unix/fs.rs35
-rw-r--r--library/std/src/sys/unix/mod.rs1
-rw-r--r--library/std/src/sys/unix/os.rs36
-rw-r--r--library/std/src/sys/unix/thread.rs2
-rw-r--r--library/std/src/sys/unix/thread_local_dtor.rs7
12 files changed, 457 insertions, 3 deletions
diff --git a/library/std/src/os/aix/fs.rs b/library/std/src/os/aix/fs.rs
new file mode 100644
index 00000000000..ac9dd45f054
--- /dev/null
+++ b/library/std/src/os/aix/fs.rs
@@ -0,0 +1,348 @@
+//! AIX specific extensions to primitives in the [`std::fs`] module.
+//!
+//! [`std::fs`]: crate::fs
+
+#![stable(feature = "metadata_ext", since = "1.1.0")]
+
+use crate::fs::Metadata;
+use crate::sys_common::AsInner;
+
+/// OS-specific extensions to [`fs::Metadata`].
+///
+/// [`fs::Metadata`]: crate::fs::Metadata
+#[stable(feature = "metadata_ext", since = "1.1.0")]
+pub trait MetadataExt {
+    /// Returns the device ID on which this file resides.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::aix::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_dev());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_dev(&self) -> u64;
+    /// Returns the inode number.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::aix::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_ino());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_ino(&self) -> u64;
+    /// Returns the file type and mode.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::aix::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_mode());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_mode(&self) -> u32;
+    /// Returns the number of hard links to file.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::aix::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_nlink());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_nlink(&self) -> u64;
+    /// Returns the user ID of the file owner.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::aix::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_uid());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_uid(&self) -> u32;
+    /// Returns the group ID of the file owner.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::aix::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_gid());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_gid(&self) -> u32;
+    /// Returns the device ID that this file represents. Only relevant for special file.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::aix::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_rdev());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_rdev(&self) -> u64;
+    /// Returns the size of the file (if it is a regular file or a symbolic link) in bytes.
+    ///
+    /// The size of a symbolic link is the length of the pathname it contains,
+    /// without a terminating null byte.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::aix::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_size());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_size(&self) -> u64;
+    /// Returns the last access time of the file, in seconds since Unix Epoch.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::aix::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_atime());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_atime(&self) -> i64;
+    /// Returns the last access time of the file, in nanoseconds since [`st_atime`].
+    ///
+    /// [`st_atime`]: Self::st_atime
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::aix::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_atime_nsec());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_atime_nsec(&self) -> i64;
+    /// Returns the last modification time of the file, in seconds since Unix Epoch.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::aix::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_mtime());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_mtime(&self) -> i64;
+    /// Returns the last modification time of the file, in nanoseconds since [`st_mtime`].
+    ///
+    /// [`st_mtime`]: Self::st_mtime
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::aix::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_mtime_nsec());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_mtime_nsec(&self) -> i64;
+    /// Returns the last status change time of the file, in seconds since Unix Epoch.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::aix::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_ctime());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_ctime(&self) -> i64;
+    /// Returns the last status change time of the file, in nanoseconds since [`st_ctime`].
+    ///
+    /// [`st_ctime`]: Self::st_ctime
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::aix::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_ctime_nsec());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_ctime_nsec(&self) -> i64;
+    /// Returns the "preferred" block size for efficient filesystem I/O.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::aix::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_blksize());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_blksize(&self) -> u64;
+    /// Returns the number of blocks allocated to the file, 512-byte units.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::aix::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_blocks());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_blocks(&self) -> u64;
+}
+
+#[stable(feature = "metadata_ext", since = "1.1.0")]
+impl MetadataExt for Metadata {
+    fn st_dev(&self) -> u64 {
+        self.as_inner().as_inner().st_dev as u64
+    }
+    fn st_ino(&self) -> u64 {
+        self.as_inner().as_inner().st_ino as u64
+    }
+    fn st_mode(&self) -> u32 {
+        self.as_inner().as_inner().st_mode as u32
+    }
+    fn st_nlink(&self) -> u64 {
+        self.as_inner().as_inner().st_nlink as u64
+    }
+    fn st_uid(&self) -> u32 {
+        self.as_inner().as_inner().st_uid as u32
+    }
+    fn st_gid(&self) -> u32 {
+        self.as_inner().as_inner().st_gid as u32
+    }
+    fn st_rdev(&self) -> u64 {
+        self.as_inner().as_inner().st_rdev as u64
+    }
+    fn st_size(&self) -> u64 {
+        self.as_inner().as_inner().st_size as u64
+    }
+    fn st_atime(&self) -> i64 {
+        self.as_inner().as_inner().st_atime.tv_sec as i64
+    }
+    fn st_atime_nsec(&self) -> i64 {
+        self.as_inner().as_inner().st_atime.tv_nsec as i64
+    }
+    fn st_mtime(&self) -> i64 {
+        self.as_inner().as_inner().st_mtime.tv_sec as i64
+    }
+    fn st_mtime_nsec(&self) -> i64 {
+        self.as_inner().as_inner().st_mtime.tv_nsec as i64
+    }
+    fn st_ctime(&self) -> i64 {
+        self.as_inner().as_inner().st_ctime.tv_sec as i64
+    }
+    fn st_ctime_nsec(&self) -> i64 {
+        self.as_inner().as_inner().st_ctime.tv_nsec as i64
+    }
+    fn st_blksize(&self) -> u64 {
+        self.as_inner().as_inner().st_blksize as u64
+    }
+    fn st_blocks(&self) -> u64 {
+        self.as_inner().as_inner().st_blocks as u64
+    }
+}
diff --git a/library/std/src/os/aix/mod.rs b/library/std/src/os/aix/mod.rs
new file mode 100644
index 00000000000..7f86a3c77f2
--- /dev/null
+++ b/library/std/src/os/aix/mod.rs
@@ -0,0 +1,6 @@
+//! AIX specific definitions.
+
+#![stable(feature = "raw_ext", since = "1.1.0")]
+
+pub mod fs;
+pub mod raw;
diff --git a/library/std/src/os/aix/raw.rs b/library/std/src/os/aix/raw.rs
new file mode 100644
index 00000000000..b4c8dc72cfe
--- /dev/null
+++ b/library/std/src/os/aix/raw.rs
@@ -0,0 +1,9 @@
+//! AIX specific raw type definitions.
+
+#![stable(feature = "raw_ext", since = "1.1.0")]
+
+#[stable(feature = "pthread_t", since = "1.8.0")]
+pub use libc::pthread_t;
+
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub use libc::{blkcnt_t, blksize_t, dev_t, ino_t, mode_t, nlink_t, off_t, stat, time_t};
diff --git a/library/std/src/os/mod.rs b/library/std/src/os/mod.rs
index 11ad21515fd..6e11b92b618 100644
--- a/library/std/src/os/mod.rs
+++ b/library/std/src/os/mod.rs
@@ -97,6 +97,8 @@ pub mod wasi;
 pub mod windows;
 
 // Others.
+#[cfg(target_os = "aix")]
+pub mod aix;
 #[cfg(target_os = "android")]
 pub mod android;
 #[cfg(target_os = "dragonfly")]
diff --git a/library/std/src/os/unix/mod.rs b/library/std/src/os/unix/mod.rs
index 3724e90afbd..5ba8719e6ff 100644
--- a/library/std/src/os/unix/mod.rs
+++ b/library/std/src/os/unix/mod.rs
@@ -37,6 +37,8 @@ use crate::os::linux as platform;
 
 #[cfg(not(doc))]
 mod platform {
+    #[cfg(target_os = "aix")]
+    pub use crate::os::aix::*;
     #[cfg(target_os = "android")]
     pub use crate::os::android::*;
     #[cfg(target_os = "dragonfly")]
diff --git a/library/std/src/sys/unix/args.rs b/library/std/src/sys/unix/args.rs
index 19334e2aff2..2da17fabcd6 100644
--- a/library/std/src/sys/unix/args.rs
+++ b/library/std/src/sys/unix/args.rs
@@ -70,6 +70,7 @@ impl DoubleEndedIterator for Args {
     target_os = "redox",
     target_os = "vxworks",
     target_os = "horizon",
+    target_os = "aix",
     target_os = "nto",
     target_os = "hurd",
 ))]
diff --git a/library/std/src/sys/unix/env.rs b/library/std/src/sys/unix/env.rs
index c6d8578a629..3bb492fa98b 100644
--- a/library/std/src/sys/unix/env.rs
+++ b/library/std/src/sys/unix/env.rs
@@ -261,3 +261,14 @@ pub mod os {
     pub const EXE_SUFFIX: &str = "";
     pub const EXE_EXTENSION: &str = "";
 }
+
+#[cfg(target_os = "aix")]
+pub mod os {
+    pub const FAMILY: &str = "unix";
+    pub const OS: &str = "aix";
+    pub const DLL_PREFIX: &str = "lib";
+    pub const DLL_SUFFIX: &str = ".a";
+    pub const DLL_EXTENSION: &str = "a";
+    pub const EXE_SUFFIX: &str = "";
+    pub const EXE_EXTENSION: &str = "";
+}
diff --git a/library/std/src/sys/unix/fs.rs b/library/std/src/sys/unix/fs.rs
index 5ed2bdd7fe3..e1c58f2ba3c 100644
--- a/library/std/src/sys/unix/fs.rs
+++ b/library/std/src/sys/unix/fs.rs
@@ -54,6 +54,7 @@ use libc::fstatat64;
     target_os = "fuchsia",
     target_os = "redox",
     target_os = "illumos",
+    target_os = "aix",
     target_os = "nto",
     target_os = "vita",
 ))]
@@ -71,6 +72,7 @@ use libc::readdir64_r;
     target_os = "l4re",
     target_os = "fuchsia",
     target_os = "redox",
+    target_os = "aix",
     target_os = "nto",
     target_os = "vita",
     target_os = "hurd",
@@ -288,6 +290,7 @@ unsafe impl Sync for Dir {}
     target_os = "illumos",
     target_os = "fuchsia",
     target_os = "redox",
+    target_os = "aix",
     target_os = "nto",
     target_os = "vita",
     target_os = "hurd",
@@ -311,6 +314,7 @@ pub struct DirEntry {
     target_os = "illumos",
     target_os = "fuchsia",
     target_os = "redox",
+    target_os = "aix",
     target_os = "nto",
     target_os = "vita",
     target_os = "hurd",
@@ -320,8 +324,9 @@ struct dirent64_min {
     #[cfg(not(any(
         target_os = "solaris",
         target_os = "illumos",
+        target_os = "aix",
         target_os = "nto",
-        target_os = "vita"
+        target_os = "vita",
     )))]
     d_type: u8,
 }
@@ -333,6 +338,7 @@ struct dirent64_min {
     target_os = "illumos",
     target_os = "fuchsia",
     target_os = "redox",
+    target_os = "aix",
     target_os = "nto",
     target_os = "vita",
     target_os = "hurd",
@@ -464,7 +470,22 @@ impl FileAttr {
     }
 }
 
-#[cfg(not(any(target_os = "netbsd", target_os = "nto")))]
+#[cfg(target_os = "aix")]
+impl FileAttr {
+    pub fn modified(&self) -> io::Result<SystemTime> {
+        Ok(SystemTime::new(self.stat.st_mtime.tv_sec as i64, self.stat.st_mtime.tv_nsec as i64))
+    }
+
+    pub fn accessed(&self) -> io::Result<SystemTime> {
+        Ok(SystemTime::new(self.stat.st_atime.tv_sec as i64, self.stat.st_atime.tv_nsec as i64))
+    }
+
+    pub fn created(&self) -> io::Result<SystemTime> {
+        Ok(SystemTime::new(self.stat.st_ctime.tv_sec as i64, self.stat.st_ctime.tv_nsec as i64))
+    }
+}
+
+#[cfg(not(any(target_os = "netbsd", target_os = "nto", target_os = "aix")))]
 impl FileAttr {
     #[cfg(not(any(
         target_os = "vxworks",
@@ -671,6 +692,7 @@ impl Iterator for ReadDir {
         target_os = "fuchsia",
         target_os = "redox",
         target_os = "illumos",
+        target_os = "aix",
         target_os = "nto",
         target_os = "vita",
         target_os = "hurd",
@@ -748,6 +770,7 @@ impl Iterator for ReadDir {
                     #[cfg(not(any(
                         target_os = "solaris",
                         target_os = "illumos",
+                        target_os = "aix",
                         target_os = "nto",
                     )))]
                     d_type: *offset_ptr!(entry_ptr, d_type) as u8,
@@ -772,6 +795,7 @@ impl Iterator for ReadDir {
         target_os = "fuchsia",
         target_os = "redox",
         target_os = "illumos",
+        target_os = "aix",
         target_os = "nto",
         target_os = "vita",
         target_os = "hurd",
@@ -874,6 +898,7 @@ impl DirEntry {
         target_os = "illumos",
         target_os = "haiku",
         target_os = "vxworks",
+        target_os = "aix",
         target_os = "nto",
         target_os = "vita",
     ))]
@@ -886,6 +911,7 @@ impl DirEntry {
         target_os = "illumos",
         target_os = "haiku",
         target_os = "vxworks",
+        target_os = "aix",
         target_os = "nto",
         target_os = "vita",
     )))]
@@ -920,6 +946,7 @@ impl DirEntry {
         target_os = "espidf",
         target_os = "horizon",
         target_os = "vita",
+        target_os = "aix",
         target_os = "nto",
         target_os = "hurd",
     ))]
@@ -977,6 +1004,7 @@ impl DirEntry {
         target_os = "illumos",
         target_os = "fuchsia",
         target_os = "redox",
+        target_os = "aix",
         target_os = "nto",
         target_os = "vita",
         target_os = "hurd",
@@ -991,6 +1019,7 @@ impl DirEntry {
         target_os = "illumos",
         target_os = "fuchsia",
         target_os = "redox",
+        target_os = "aix",
         target_os = "nto",
         target_os = "vita",
         target_os = "hurd",
@@ -2026,6 +2055,7 @@ mod remove_dir_impl {
         target_os = "illumos",
         target_os = "haiku",
         target_os = "vxworks",
+        target_os = "aix",
     ))]
     fn is_dir(_ent: &DirEntry) -> Option<bool> {
         None
@@ -2036,6 +2066,7 @@ mod remove_dir_impl {
         target_os = "illumos",
         target_os = "haiku",
         target_os = "vxworks",
+        target_os = "aix",
     )))]
     fn is_dir(ent: &DirEntry) -> Option<bool> {
         match ent.entry.d_type {
diff --git a/library/std/src/sys/unix/mod.rs b/library/std/src/sys/unix/mod.rs
index 3edafde71e9..01d8217342c 100644
--- a/library/std/src/sys/unix/mod.rs
+++ b/library/std/src/sys/unix/mod.rs
@@ -278,6 +278,7 @@ pub fn decode_error_kind(errno: i32) -> ErrorKind {
         libc::ENETUNREACH => NetworkUnreachable,
         libc::ENOTCONN => NotConnected,
         libc::ENOTDIR => NotADirectory,
+        #[cfg(not(target_os = "aix"))]
         libc::ENOTEMPTY => DirectoryNotEmpty,
         libc::EPIPE => BrokenPipe,
         libc::EROFS => ReadOnlyFilesystem,
diff --git a/library/std/src/sys/unix/os.rs b/library/std/src/sys/unix/os.rs
index 01ff375d215..dc3c037c0cb 100644
--- a/library/std/src/sys/unix/os.rs
+++ b/library/std/src/sys/unix/os.rs
@@ -74,6 +74,7 @@ extern "C" {
         link_name = "__error"
     )]
     #[cfg_attr(target_os = "haiku", link_name = "_errnop")]
+    #[cfg_attr(target_os = "aix", link_name = "_Errno")]
     fn errno_location() -> *mut c_int;
 }
 
@@ -254,6 +255,41 @@ impl StdError for JoinPathsError {
     }
 }
 
+#[cfg(target_os = "aix")]
+pub fn current_exe() -> io::Result<PathBuf> {
+    use crate::io::ErrorKind;
+
+    #[cfg(test)]
+    use realstd::env;
+
+    #[cfg(not(test))]
+    use crate::env;
+
+    let exe_path = env::args().next().ok_or(io::const_io_error!(
+        ErrorKind::NotFound,
+        "an executable path was not found because no arguments were provided through argv"
+    ))?;
+    let path = PathBuf::from(exe_path);
+    if path.is_absolute() {
+        return path.canonicalize();
+    }
+    // Search PWD to infer current_exe.
+    if let Some(pstr) = path.to_str() && pstr.contains("/") {
+        return getcwd().map(|cwd| cwd.join(path))?.canonicalize();
+    }
+    // Search PATH to infer current_exe.
+    if let Some(p) = getenv(OsStr::from_bytes("PATH".as_bytes())) {
+        for search_path in split_paths(&p) {
+            let pb = search_path.join(&path);
+            if pb.is_file() && let Ok(metadata) = crate::fs::metadata(&pb) &&
+               metadata.permissions().mode() & 0o111 != 0 {
+                return pb.canonicalize();
+            }
+        }
+    }
+    Err(io::const_io_error!(ErrorKind::NotFound, "an executable path was not found"))
+}
+
 #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
 pub fn current_exe() -> io::Result<PathBuf> {
     unsafe {
diff --git a/library/std/src/sys/unix/thread.rs b/library/std/src/sys/unix/thread.rs
index 311ed95022f..e667f34aece 100644
--- a/library/std/src/sys/unix/thread.rs
+++ b/library/std/src/sys/unix/thread.rs
@@ -218,6 +218,7 @@ impl Thread {
         target_os = "redox",
         target_os = "vxworks",
         target_os = "hurd",
+        target_os = "aix",
     ))]
     pub fn set_name(_name: &CStr) {
         // Newlib, Emscripten, and VxWorks have no way to set a thread name.
@@ -317,6 +318,7 @@ pub fn available_parallelism() -> io::Result<NonZeroUsize> {
             target_os = "macos",
             target_os = "solaris",
             target_os = "illumos",
+            target_os = "aix",
         ))] {
             #[allow(unused_assignments)]
             #[allow(unused_mut)]
diff --git a/library/std/src/sys/unix/thread_local_dtor.rs b/library/std/src/sys/unix/thread_local_dtor.rs
index 4a732a2cabd..a0117e1d165 100644
--- a/library/std/src/sys/unix/thread_local_dtor.rs
+++ b/library/std/src/sys/unix/thread_local_dtor.rs
@@ -102,7 +102,12 @@ pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) {
     }
 }
 
-#[cfg(any(target_os = "vxworks", target_os = "horizon", target_os = "emscripten"))]
+#[cfg(any(
+    target_os = "vxworks",
+    target_os = "horizon",
+    target_os = "emscripten",
+    target_os = "aix"
+))]
 #[cfg_attr(target_family = "wasm", allow(unused))] // might remain unused depending on target details (e.g. wasm32-unknown-emscripten)
 pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) {
     use crate::sys_common::thread_local_dtor::register_dtor_fallback;