diff --git a/include/pathrs.h b/include/pathrs.h index fd2812c..26278ed 100644 --- a/include/pathrs.h +++ b/include/pathrs.h @@ -163,6 +163,9 @@ pathrs_root_t *pathrs_open(const char *path); * It should be noted that the use of O_CREAT *is not* supported (and will * result in an error). Handles only refer to *existing* files. Instead you * need to use inroot_creat(). + * In addition, O_NOCTTY is automatically set when opening the path. If you + * want to use the path as a controlling terminal, you will have to do + * ioctl(fd, TIOCSCTTY, 0) yourself. */ int pathrs_reopen(const pathrs_handle_t *handle, int flags); diff --git a/src/ffi/cabi.rs b/src/ffi/cabi.rs index a8e9e86..9b0adce 100644 --- a/src/ffi/cabi.rs +++ b/src/ffi/cabi.rs @@ -164,6 +164,10 @@ pub extern "C" fn pathrs_rfree(root: Option<&mut CRoot>) { /// It should be noted that the use of O_CREAT *is not* supported (and will /// result in an error). Handles only refer to *existing* files. Instead you /// need to use inroot_creat(). +/// +/// In addition, O_NOCTTY is automatically set when opening the path. If you +/// want to use the path as a controlling terminal, you will have to do +/// ioctl(fd, TIOCSCTTY, 0) yourself. #[no_mangle] pub extern "C" fn pathrs_reopen(handle: &CHandle, flags: c_int) -> RawFd { let flags = OpenFlags(flags); diff --git a/src/handle.rs b/src/handle.rs index a77c152..31fdbe7 100644 --- a/src/handle.rs +++ b/src/handle.rs @@ -106,6 +106,15 @@ impl Handle { /// and writing. This does not consume the original handle (allowing for it /// to be used many times). /// + /// The handle will be opened with `O_NOCTTY` and `O_CLOEXEC` set, + /// regardless of whether those flags are present in the `flags` argument. + /// You can correct these yourself if these defaults are not ideal for you: + /// + /// 1. `fcntl(fd, F_SETFD, 0)` will let you unset `O_CLOEXEC`. + /// 2. `ioctl(fd, TIOCSCTTY, 0)` will set the fd as the controlling + /// terminal (if you don't have one already, and the fd references a + /// TTY). + /// /// [`File`]: https://doc.rust-lang.org/std/fs/struct.File.html /// [`Root::create`]: struct.Root.html#method.create pub fn reopen(&self, flags: OpenFlags) -> Result { diff --git a/src/syscalls.rs b/src/syscalls.rs index d552ccd..4e383af 100644 --- a/src/syscalls.rs +++ b/src/syscalls.rs @@ -107,7 +107,7 @@ pub fn fcntl_unset_cloexec(fd: RawFd) -> Result<(), FailureError> { } } -/// Wrapper for `openat(2)` which auto-sets `O_CLOEXEC`. +/// Wrapper for `openat(2)` which auto-sets `O_CLOEXEC | O_NOCTTY`. /// /// This is needed because Rust doesn't provide a way to access the dirfd /// argument of `openat(2)`. We need the dirfd argument, so we need a wrapper. @@ -122,7 +122,7 @@ pub fn openat_follow>( libc::openat( dirfd, path.to_c_string().as_ptr(), - libc::O_CLOEXEC | flags, + libc::O_CLOEXEC | libc::O_NOCTTY | flags, mode, ) }; @@ -144,7 +144,7 @@ pub fn openat_follow>( } } -/// Wrapper for `openat(2)` which auto-sets `O_CLOEXEC | O_NOFOLLOW`. +/// Wrapper for `openat(2)` which auto-sets `O_CLOEXEC | O_NOCTTY | O_NOFOLLOW`. /// /// This is needed because Rust doesn't provide a way to access the dirfd /// argument of `openat(2)`. We need the dirfd argument, so we need a wrapper.