Skip to content

std: don't reference libc::O_NOFOLLOW on VxWorks in set_perm_nofollow - #162065

Open
physwkim wants to merge 1 commit into
rust-lang:mainfrom
physwkim:vxworks-set-perm-nofollow
Open

std: don't reference libc::O_NOFOLLOW on VxWorks in set_perm_nofollow#162065
physwkim wants to merge 1 commit into
rust-lang:mainfrom
physwkim:vxworks-set-perm-nofollow

Conversation

@physwkim

@physwkim physwkim commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

set_permissions_nofollow was consolidated into sys/fs/unix.rs::set_perm_nofollow by #160170, which dropped the not(target_os = "vxworks") guard the previous sys/fs/mod.rs implementation carried. VxWorks' libc defines no O_NOFOLLOW (the platform's <sys/fcntlcom.h> stops at O_CLOEXEC, and rust-lang/libc correctly does not bind it for vxworks), so building std for x86_64-wrs-vxworks now fails:

error[E0425]: cannot find value `O_NOFOLLOW` in crate `libc`
    --> library/std/src/sys/fs/unix.rs:1916
     |
     |             options.read(true).custom_flags(libc::O_NOFOLLOW);
     |                                                    ^^^^^^^^^^ not found in `libc`

x86_64-wrs-vxworks is tier 3 and isn't built in CI, so this wasn't caught. set_perm_nofollow is the only O_NOFOLLOW reference compiled for VxWorks — the remove_dir_all "modern" path already lists vxworks in its fallback set, and the remaining occurrences are a doc example and comments.

Unlike ESP-IDF and Horizon (which skip O_NOFOLLOW because their filesystems have no symbolic links), VxWorks does have symlinks, so it can't just drop O_NOFOLLOW and follow the link silently. This returns ErrorKind::Unsupported, matching the existing Android stub.

Unsupported is the platform-correct result

Verified on-target against the shipped VxWorks 7 SDK (wrsdk-vxworks7-qemu-1.17.0, the QEMU BSP). VxWorks has no way to express a no-follow permission change:

  • No O_NOFOLLOW. The only related flag is O_NOLINK ("open the symlink itself"), which is different semantics and not what the open + fchmod path wants.
  • fchmodat is provided — by the UTILS_UNIX component in libunix, not core libc — and AT_SYMLINK_NOFOLLOW is defined as 0x100. But the shipped libunix.so rejects the flag with ENOTSUP:
0000000000009300 <fchmodat>:            ; (dirfd=edi, path=rsi, mode=edx, flag=ecx)
    cmpl   $0x100,-0x18(%rbp)           ; flag == AT_SYMLINK_NOFOLLOW ?
    jne    9340 <fchmodat+0x40>
    mov    $0x23,%edi                   ; errno = 0x23 (35 = ENOTSUP)
    call   errnoSet
    movl   $0xffffffff,-0x4(%rbp)       ; return -1
    ...
9340:                                   ; flag == 0
    call   taskSafe
    ...  atCatPath(dirfd, path)
    call   chmod                        ; plain chmod -> follows the symlink

So fchmodat(.., AT_SYMLINK_NOFOLLOW) returns -1/ENOTSUP, and flag == 0 degrades to chmod, which follows symlinks. A fchmodat-based implementation is not viable on this release — the platform's own fchmodat reports ENOTSUP for exactly this request, which is why Unsupported is correct rather than merely conservative. cc @biabbas @hax0kartik

Build verification

On 1.100.0-nightly (908501772 2026-08-30) + rust-src (stock libc 0.2.189):

  • Before: cargo +nightly build -Zbuild-std=std,panic_abort --target x86_64-wrs-vxworks fails with the E0425 above (1 error).
  • After this patch: the same command finishes successfully.

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Aug 31, 2026
@rustbot

rustbot commented Aug 31, 2026

Copy link
Copy Markdown
Collaborator

r? @ChrisDenton

rustbot has assigned @ChrisDenton.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: @ChrisDenton, libs
  • @ChrisDenton, libs expanded to 13 candidates
  • Random selection from 6 candidates

@rustbot

This comment has been minimized.

@physwkim
physwkim force-pushed the vxworks-set-perm-nofollow branch from 4e8c17a to 74a9f8c Compare August 31, 2026 13:23

@ChrisDenton ChrisDenton left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't verify on-target that VxWorks honors AT_SYMLINK_NOFOLLOW, so this only restores the build with conservative semantics.

It would be nice to verify this one way or another, even if we don't implement it just yet. cc @biabbas @hax0kartik

View changes since this review

Comment thread library/std/src/sys/fs/unix.rs Outdated
@physwkim

physwkim commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

Tested on VxWorks 7 under QEMU: fchmodat(AT_FDCWD, path, mode, AT_SYMLINK_NOFOLLOW) returns -1/ENOTSUP, while flag = 0 falls through to chmod (which follows the symlink). So VxWorks does not honor AT_SYMLINK_NOFOLLOW, and Unsupported is the correct result.

…low`

VxWorks' libc defines no `O_NOFOLLOW`, so building std for
x86_64-wrs-vxworks stopped compiling once `set_perm_nofollow` was
consolidated into `sys/fs/unix.rs` without a vxworks guard. VxWorks also
has no way to express a no-follow permission change: its `fchmodat`
rejects `AT_SYMLINK_NOFOLLOW` with `ENOTSUP`. Return `Unsupported`,
matching the existing Android stub.
@ChrisDenton

Copy link
Copy Markdown
Member

Good to know, thanks! Could you squish your commits into one please.

@physwkim
physwkim force-pushed the vxworks-set-perm-nofollow branch from fdc5faa to cb5e3df Compare September 1, 2026 14:59
@ChrisDenton

Copy link
Copy Markdown
Member

@bors r+ rollup

@rust-bors

rust-bors Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

📌 Commit cb5e3df has been approved by ChrisDenton

It is now in the queue for this repository.

@rust-bors rust-bors Bot added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Sep 1, 2026
Zalathar added a commit to Zalathar/rust that referenced this pull request Sep 2, 2026
…, r=ChrisDenton

std: don't reference `libc::O_NOFOLLOW` on VxWorks in `set_perm_nofollow`

`set_permissions_nofollow` was consolidated into `sys/fs/unix.rs::set_perm_nofollow` by rust-lang#160170, which dropped the `not(target_os = "vxworks")` guard the previous `sys/fs/mod.rs` implementation carried. VxWorks' libc defines no `O_NOFOLLOW` (the platform's `<sys/fcntlcom.h>` stops at `O_CLOEXEC`, and `rust-lang/libc` correctly does not bind it for `vxworks`), so building `std` for `x86_64-wrs-vxworks` now fails:

```
error[E0425]: cannot find value `O_NOFOLLOW` in crate `libc`
    --> library/std/src/sys/fs/unix.rs:1916
     |
     |             options.read(true).custom_flags(libc::O_NOFOLLOW);
     |                                                    ^^^^^^^^^^ not found in `libc`
```

`x86_64-wrs-vxworks` is tier 3 and isn't built in CI, so this wasn't caught. `set_perm_nofollow` is the only `O_NOFOLLOW` reference compiled for VxWorks — the `remove_dir_all` "modern" path already lists `vxworks` in its fallback set, and the remaining occurrences are a doc example and comments.

Unlike ESP-IDF and Horizon (which skip `O_NOFOLLOW` because their filesystems have no symbolic links), VxWorks *does* have symlinks, so it can't just drop `O_NOFOLLOW` and follow the link silently. This returns `ErrorKind::Unsupported`, matching the existing Android stub.

## `Unsupported` is the platform-correct result

Verified on-target against the shipped VxWorks 7 SDK (`wrsdk-vxworks7-qemu-1.17.0`, the QEMU BSP). VxWorks has no way to express a no-follow permission change:

- No `O_NOFOLLOW`. The only related flag is `O_NOLINK` ("open the symlink itself"), which is different semantics and not what the `open` + `fchmod` path wants.
- `fchmodat` *is* provided — by the UTILS_UNIX component in `libunix`, not core `libc` — and `AT_SYMLINK_NOFOLLOW` is defined as `0x100`. But the shipped `libunix.so` **rejects the flag with `ENOTSUP`**:

```asm
0000000000009300 <fchmodat>:            ; (dirfd=edi, path=rsi, mode=edx, flag=ecx)
    cmpl   $0x100,-0x18(%rbp)           ; flag == AT_SYMLINK_NOFOLLOW ?
    jne    9340 <fchmodat+0x40>
    mov    $0x23,%edi                   ; errno = 0x23 (35 = ENOTSUP)
    call   errnoSet
    movl   $0xffffffff,-0x4(%rbp)       ; return -1
    ...
9340:                                   ; flag == 0
    call   taskSafe
    ...  atCatPath(dirfd, path)
    call   chmod                        ; plain chmod -> follows the symlink
```

So `fchmodat(.., AT_SYMLINK_NOFOLLOW)` returns `-1`/`ENOTSUP`, and `flag == 0` degrades to `chmod`, which follows symlinks. A `fchmodat`-based implementation is not viable on this release — the platform's own `fchmodat` reports `ENOTSUP` for exactly this request, which is why `Unsupported` is correct rather than merely conservative. cc @biabbas @hax0kartik

## Build verification

On `1.100.0-nightly (9085017 2026-08-30)` + `rust-src` (stock `libc` 0.2.189):

- Before: `cargo +nightly build -Zbuild-std=std,panic_abort --target x86_64-wrs-vxworks` fails with the E0425 above (1 error).
- After this patch: the same command finishes successfully.
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Sep 2, 2026
…, r=ChrisDenton

std: don't reference `libc::O_NOFOLLOW` on VxWorks in `set_perm_nofollow`

`set_permissions_nofollow` was consolidated into `sys/fs/unix.rs::set_perm_nofollow` by rust-lang#160170, which dropped the `not(target_os = "vxworks")` guard the previous `sys/fs/mod.rs` implementation carried. VxWorks' libc defines no `O_NOFOLLOW` (the platform's `<sys/fcntlcom.h>` stops at `O_CLOEXEC`, and `rust-lang/libc` correctly does not bind it for `vxworks`), so building `std` for `x86_64-wrs-vxworks` now fails:

```
error[E0425]: cannot find value `O_NOFOLLOW` in crate `libc`
    --> library/std/src/sys/fs/unix.rs:1916
     |
     |             options.read(true).custom_flags(libc::O_NOFOLLOW);
     |                                                    ^^^^^^^^^^ not found in `libc`
```

`x86_64-wrs-vxworks` is tier 3 and isn't built in CI, so this wasn't caught. `set_perm_nofollow` is the only `O_NOFOLLOW` reference compiled for VxWorks — the `remove_dir_all` "modern" path already lists `vxworks` in its fallback set, and the remaining occurrences are a doc example and comments.

Unlike ESP-IDF and Horizon (which skip `O_NOFOLLOW` because their filesystems have no symbolic links), VxWorks *does* have symlinks, so it can't just drop `O_NOFOLLOW` and follow the link silently. This returns `ErrorKind::Unsupported`, matching the existing Android stub.

## `Unsupported` is the platform-correct result

Verified on-target against the shipped VxWorks 7 SDK (`wrsdk-vxworks7-qemu-1.17.0`, the QEMU BSP). VxWorks has no way to express a no-follow permission change:

- No `O_NOFOLLOW`. The only related flag is `O_NOLINK` ("open the symlink itself"), which is different semantics and not what the `open` + `fchmod` path wants.
- `fchmodat` *is* provided — by the UTILS_UNIX component in `libunix`, not core `libc` — and `AT_SYMLINK_NOFOLLOW` is defined as `0x100`. But the shipped `libunix.so` **rejects the flag with `ENOTSUP`**:

```asm
0000000000009300 <fchmodat>:            ; (dirfd=edi, path=rsi, mode=edx, flag=ecx)
    cmpl   $0x100,-0x18(%rbp)           ; flag == AT_SYMLINK_NOFOLLOW ?
    jne    9340 <fchmodat+0x40>
    mov    $0x23,%edi                   ; errno = 0x23 (35 = ENOTSUP)
    call   errnoSet
    movl   $0xffffffff,-0x4(%rbp)       ; return -1
    ...
9340:                                   ; flag == 0
    call   taskSafe
    ...  atCatPath(dirfd, path)
    call   chmod                        ; plain chmod -> follows the symlink
```

So `fchmodat(.., AT_SYMLINK_NOFOLLOW)` returns `-1`/`ENOTSUP`, and `flag == 0` degrades to `chmod`, which follows symlinks. A `fchmodat`-based implementation is not viable on this release — the platform's own `fchmodat` reports `ENOTSUP` for exactly this request, which is why `Unsupported` is correct rather than merely conservative. cc @biabbas @hax0kartik

## Build verification

On `1.100.0-nightly (9085017 2026-08-30)` + `rust-src` (stock `libc` 0.2.189):

- Before: `cargo +nightly build -Zbuild-std=std,panic_abort --target x86_64-wrs-vxworks` fails with the E0425 above (1 error).
- After this patch: the same command finishes successfully.
Zalathar added a commit to Zalathar/rust that referenced this pull request Sep 2, 2026
…, r=ChrisDenton

std: don't reference `libc::O_NOFOLLOW` on VxWorks in `set_perm_nofollow`

`set_permissions_nofollow` was consolidated into `sys/fs/unix.rs::set_perm_nofollow` by rust-lang#160170, which dropped the `not(target_os = "vxworks")` guard the previous `sys/fs/mod.rs` implementation carried. VxWorks' libc defines no `O_NOFOLLOW` (the platform's `<sys/fcntlcom.h>` stops at `O_CLOEXEC`, and `rust-lang/libc` correctly does not bind it for `vxworks`), so building `std` for `x86_64-wrs-vxworks` now fails:

```
error[E0425]: cannot find value `O_NOFOLLOW` in crate `libc`
    --> library/std/src/sys/fs/unix.rs:1916
     |
     |             options.read(true).custom_flags(libc::O_NOFOLLOW);
     |                                                    ^^^^^^^^^^ not found in `libc`
```

`x86_64-wrs-vxworks` is tier 3 and isn't built in CI, so this wasn't caught. `set_perm_nofollow` is the only `O_NOFOLLOW` reference compiled for VxWorks — the `remove_dir_all` "modern" path already lists `vxworks` in its fallback set, and the remaining occurrences are a doc example and comments.

Unlike ESP-IDF and Horizon (which skip `O_NOFOLLOW` because their filesystems have no symbolic links), VxWorks *does* have symlinks, so it can't just drop `O_NOFOLLOW` and follow the link silently. This returns `ErrorKind::Unsupported`, matching the existing Android stub.

## `Unsupported` is the platform-correct result

Verified on-target against the shipped VxWorks 7 SDK (`wrsdk-vxworks7-qemu-1.17.0`, the QEMU BSP). VxWorks has no way to express a no-follow permission change:

- No `O_NOFOLLOW`. The only related flag is `O_NOLINK` ("open the symlink itself"), which is different semantics and not what the `open` + `fchmod` path wants.
- `fchmodat` *is* provided — by the UTILS_UNIX component in `libunix`, not core `libc` — and `AT_SYMLINK_NOFOLLOW` is defined as `0x100`. But the shipped `libunix.so` **rejects the flag with `ENOTSUP`**:

```asm
0000000000009300 <fchmodat>:            ; (dirfd=edi, path=rsi, mode=edx, flag=ecx)
    cmpl   $0x100,-0x18(%rbp)           ; flag == AT_SYMLINK_NOFOLLOW ?
    jne    9340 <fchmodat+0x40>
    mov    $0x23,%edi                   ; errno = 0x23 (35 = ENOTSUP)
    call   errnoSet
    movl   $0xffffffff,-0x4(%rbp)       ; return -1
    ...
9340:                                   ; flag == 0
    call   taskSafe
    ...  atCatPath(dirfd, path)
    call   chmod                        ; plain chmod -> follows the symlink
```

So `fchmodat(.., AT_SYMLINK_NOFOLLOW)` returns `-1`/`ENOTSUP`, and `flag == 0` degrades to `chmod`, which follows symlinks. A `fchmodat`-based implementation is not viable on this release — the platform's own `fchmodat` reports `ENOTSUP` for exactly this request, which is why `Unsupported` is correct rather than merely conservative. cc @biabbas @hax0kartik

## Build verification

On `1.100.0-nightly (9085017 2026-08-30)` + `rust-src` (stock `libc` 0.2.189):

- Before: `cargo +nightly build -Zbuild-std=std,panic_abort --target x86_64-wrs-vxworks` fails with the E0425 above (1 error).
- After this patch: the same command finishes successfully.
Zalathar added a commit to Zalathar/rust that referenced this pull request Sep 2, 2026
…, r=ChrisDenton

std: don't reference `libc::O_NOFOLLOW` on VxWorks in `set_perm_nofollow`

`set_permissions_nofollow` was consolidated into `sys/fs/unix.rs::set_perm_nofollow` by rust-lang#160170, which dropped the `not(target_os = "vxworks")` guard the previous `sys/fs/mod.rs` implementation carried. VxWorks' libc defines no `O_NOFOLLOW` (the platform's `<sys/fcntlcom.h>` stops at `O_CLOEXEC`, and `rust-lang/libc` correctly does not bind it for `vxworks`), so building `std` for `x86_64-wrs-vxworks` now fails:

```
error[E0425]: cannot find value `O_NOFOLLOW` in crate `libc`
    --> library/std/src/sys/fs/unix.rs:1916
     |
     |             options.read(true).custom_flags(libc::O_NOFOLLOW);
     |                                                    ^^^^^^^^^^ not found in `libc`
```

`x86_64-wrs-vxworks` is tier 3 and isn't built in CI, so this wasn't caught. `set_perm_nofollow` is the only `O_NOFOLLOW` reference compiled for VxWorks — the `remove_dir_all` "modern" path already lists `vxworks` in its fallback set, and the remaining occurrences are a doc example and comments.

Unlike ESP-IDF and Horizon (which skip `O_NOFOLLOW` because their filesystems have no symbolic links), VxWorks *does* have symlinks, so it can't just drop `O_NOFOLLOW` and follow the link silently. This returns `ErrorKind::Unsupported`, matching the existing Android stub.

## `Unsupported` is the platform-correct result

Verified on-target against the shipped VxWorks 7 SDK (`wrsdk-vxworks7-qemu-1.17.0`, the QEMU BSP). VxWorks has no way to express a no-follow permission change:

- No `O_NOFOLLOW`. The only related flag is `O_NOLINK` ("open the symlink itself"), which is different semantics and not what the `open` + `fchmod` path wants.
- `fchmodat` *is* provided — by the UTILS_UNIX component in `libunix`, not core `libc` — and `AT_SYMLINK_NOFOLLOW` is defined as `0x100`. But the shipped `libunix.so` **rejects the flag with `ENOTSUP`**:

```asm
0000000000009300 <fchmodat>:            ; (dirfd=edi, path=rsi, mode=edx, flag=ecx)
    cmpl   $0x100,-0x18(%rbp)           ; flag == AT_SYMLINK_NOFOLLOW ?
    jne    9340 <fchmodat+0x40>
    mov    $0x23,%edi                   ; errno = 0x23 (35 = ENOTSUP)
    call   errnoSet
    movl   $0xffffffff,-0x4(%rbp)       ; return -1
    ...
9340:                                   ; flag == 0
    call   taskSafe
    ...  atCatPath(dirfd, path)
    call   chmod                        ; plain chmod -> follows the symlink
```

So `fchmodat(.., AT_SYMLINK_NOFOLLOW)` returns `-1`/`ENOTSUP`, and `flag == 0` degrades to `chmod`, which follows symlinks. A `fchmodat`-based implementation is not viable on this release — the platform's own `fchmodat` reports `ENOTSUP` for exactly this request, which is why `Unsupported` is correct rather than merely conservative. cc @biabbas @hax0kartik

## Build verification

On `1.100.0-nightly (9085017 2026-08-30)` + `rust-src` (stock `libc` 0.2.189):

- Before: `cargo +nightly build -Zbuild-std=std,panic_abort --target x86_64-wrs-vxworks` fails with the E0425 above (1 error).
- After this patch: the same command finishes successfully.
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Sep 2, 2026
…, r=ChrisDenton

std: don't reference `libc::O_NOFOLLOW` on VxWorks in `set_perm_nofollow`

`set_permissions_nofollow` was consolidated into `sys/fs/unix.rs::set_perm_nofollow` by rust-lang#160170, which dropped the `not(target_os = "vxworks")` guard the previous `sys/fs/mod.rs` implementation carried. VxWorks' libc defines no `O_NOFOLLOW` (the platform's `<sys/fcntlcom.h>` stops at `O_CLOEXEC`, and `rust-lang/libc` correctly does not bind it for `vxworks`), so building `std` for `x86_64-wrs-vxworks` now fails:

```
error[E0425]: cannot find value `O_NOFOLLOW` in crate `libc`
    --> library/std/src/sys/fs/unix.rs:1916
     |
     |             options.read(true).custom_flags(libc::O_NOFOLLOW);
     |                                                    ^^^^^^^^^^ not found in `libc`
```

`x86_64-wrs-vxworks` is tier 3 and isn't built in CI, so this wasn't caught. `set_perm_nofollow` is the only `O_NOFOLLOW` reference compiled for VxWorks — the `remove_dir_all` "modern" path already lists `vxworks` in its fallback set, and the remaining occurrences are a doc example and comments.

Unlike ESP-IDF and Horizon (which skip `O_NOFOLLOW` because their filesystems have no symbolic links), VxWorks *does* have symlinks, so it can't just drop `O_NOFOLLOW` and follow the link silently. This returns `ErrorKind::Unsupported`, matching the existing Android stub.

## `Unsupported` is the platform-correct result

Verified on-target against the shipped VxWorks 7 SDK (`wrsdk-vxworks7-qemu-1.17.0`, the QEMU BSP). VxWorks has no way to express a no-follow permission change:

- No `O_NOFOLLOW`. The only related flag is `O_NOLINK` ("open the symlink itself"), which is different semantics and not what the `open` + `fchmod` path wants.
- `fchmodat` *is* provided — by the UTILS_UNIX component in `libunix`, not core `libc` — and `AT_SYMLINK_NOFOLLOW` is defined as `0x100`. But the shipped `libunix.so` **rejects the flag with `ENOTSUP`**:

```asm
0000000000009300 <fchmodat>:            ; (dirfd=edi, path=rsi, mode=edx, flag=ecx)
    cmpl   $0x100,-0x18(%rbp)           ; flag == AT_SYMLINK_NOFOLLOW ?
    jne    9340 <fchmodat+0x40>
    mov    $0x23,%edi                   ; errno = 0x23 (35 = ENOTSUP)
    call   errnoSet
    movl   $0xffffffff,-0x4(%rbp)       ; return -1
    ...
9340:                                   ; flag == 0
    call   taskSafe
    ...  atCatPath(dirfd, path)
    call   chmod                        ; plain chmod -> follows the symlink
```

So `fchmodat(.., AT_SYMLINK_NOFOLLOW)` returns `-1`/`ENOTSUP`, and `flag == 0` degrades to `chmod`, which follows symlinks. A `fchmodat`-based implementation is not viable on this release — the platform's own `fchmodat` reports `ENOTSUP` for exactly this request, which is why `Unsupported` is correct rather than merely conservative. cc @biabbas @hax0kartik

## Build verification

On `1.100.0-nightly (9085017 2026-08-30)` + `rust-src` (stock `libc` 0.2.189):

- Before: `cargo +nightly build -Zbuild-std=std,panic_abort --target x86_64-wrs-vxworks` fails with the E0425 above (1 error).
- After this patch: the same command finishes successfully.
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Sep 2, 2026
…, r=ChrisDenton

std: don't reference `libc::O_NOFOLLOW` on VxWorks in `set_perm_nofollow`

`set_permissions_nofollow` was consolidated into `sys/fs/unix.rs::set_perm_nofollow` by rust-lang#160170, which dropped the `not(target_os = "vxworks")` guard the previous `sys/fs/mod.rs` implementation carried. VxWorks' libc defines no `O_NOFOLLOW` (the platform's `<sys/fcntlcom.h>` stops at `O_CLOEXEC`, and `rust-lang/libc` correctly does not bind it for `vxworks`), so building `std` for `x86_64-wrs-vxworks` now fails:

```
error[E0425]: cannot find value `O_NOFOLLOW` in crate `libc`
    --> library/std/src/sys/fs/unix.rs:1916
     |
     |             options.read(true).custom_flags(libc::O_NOFOLLOW);
     |                                                    ^^^^^^^^^^ not found in `libc`
```

`x86_64-wrs-vxworks` is tier 3 and isn't built in CI, so this wasn't caught. `set_perm_nofollow` is the only `O_NOFOLLOW` reference compiled for VxWorks — the `remove_dir_all` "modern" path already lists `vxworks` in its fallback set, and the remaining occurrences are a doc example and comments.

Unlike ESP-IDF and Horizon (which skip `O_NOFOLLOW` because their filesystems have no symbolic links), VxWorks *does* have symlinks, so it can't just drop `O_NOFOLLOW` and follow the link silently. This returns `ErrorKind::Unsupported`, matching the existing Android stub.

## `Unsupported` is the platform-correct result

Verified on-target against the shipped VxWorks 7 SDK (`wrsdk-vxworks7-qemu-1.17.0`, the QEMU BSP). VxWorks has no way to express a no-follow permission change:

- No `O_NOFOLLOW`. The only related flag is `O_NOLINK` ("open the symlink itself"), which is different semantics and not what the `open` + `fchmod` path wants.
- `fchmodat` *is* provided — by the UTILS_UNIX component in `libunix`, not core `libc` — and `AT_SYMLINK_NOFOLLOW` is defined as `0x100`. But the shipped `libunix.so` **rejects the flag with `ENOTSUP`**:

```asm
0000000000009300 <fchmodat>:            ; (dirfd=edi, path=rsi, mode=edx, flag=ecx)
    cmpl   $0x100,-0x18(%rbp)           ; flag == AT_SYMLINK_NOFOLLOW ?
    jne    9340 <fchmodat+0x40>
    mov    $0x23,%edi                   ; errno = 0x23 (35 = ENOTSUP)
    call   errnoSet
    movl   $0xffffffff,-0x4(%rbp)       ; return -1
    ...
9340:                                   ; flag == 0
    call   taskSafe
    ...  atCatPath(dirfd, path)
    call   chmod                        ; plain chmod -> follows the symlink
```

So `fchmodat(.., AT_SYMLINK_NOFOLLOW)` returns `-1`/`ENOTSUP`, and `flag == 0` degrades to `chmod`, which follows symlinks. A `fchmodat`-based implementation is not viable on this release — the platform's own `fchmodat` reports `ENOTSUP` for exactly this request, which is why `Unsupported` is correct rather than merely conservative. cc @biabbas @hax0kartik

## Build verification

On `1.100.0-nightly (9085017 2026-08-30)` + `rust-src` (stock `libc` 0.2.189):

- Before: `cargo +nightly build -Zbuild-std=std,panic_abort --target x86_64-wrs-vxworks` fails with the E0425 above (1 error).
- After this patch: the same command finishes successfully.
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Sep 2, 2026
…, r=ChrisDenton

std: don't reference `libc::O_NOFOLLOW` on VxWorks in `set_perm_nofollow`

`set_permissions_nofollow` was consolidated into `sys/fs/unix.rs::set_perm_nofollow` by rust-lang#160170, which dropped the `not(target_os = "vxworks")` guard the previous `sys/fs/mod.rs` implementation carried. VxWorks' libc defines no `O_NOFOLLOW` (the platform's `<sys/fcntlcom.h>` stops at `O_CLOEXEC`, and `rust-lang/libc` correctly does not bind it for `vxworks`), so building `std` for `x86_64-wrs-vxworks` now fails:

```
error[E0425]: cannot find value `O_NOFOLLOW` in crate `libc`
    --> library/std/src/sys/fs/unix.rs:1916
     |
     |             options.read(true).custom_flags(libc::O_NOFOLLOW);
     |                                                    ^^^^^^^^^^ not found in `libc`
```

`x86_64-wrs-vxworks` is tier 3 and isn't built in CI, so this wasn't caught. `set_perm_nofollow` is the only `O_NOFOLLOW` reference compiled for VxWorks — the `remove_dir_all` "modern" path already lists `vxworks` in its fallback set, and the remaining occurrences are a doc example and comments.

Unlike ESP-IDF and Horizon (which skip `O_NOFOLLOW` because their filesystems have no symbolic links), VxWorks *does* have symlinks, so it can't just drop `O_NOFOLLOW` and follow the link silently. This returns `ErrorKind::Unsupported`, matching the existing Android stub.

## `Unsupported` is the platform-correct result

Verified on-target against the shipped VxWorks 7 SDK (`wrsdk-vxworks7-qemu-1.17.0`, the QEMU BSP). VxWorks has no way to express a no-follow permission change:

- No `O_NOFOLLOW`. The only related flag is `O_NOLINK` ("open the symlink itself"), which is different semantics and not what the `open` + `fchmod` path wants.
- `fchmodat` *is* provided — by the UTILS_UNIX component in `libunix`, not core `libc` — and `AT_SYMLINK_NOFOLLOW` is defined as `0x100`. But the shipped `libunix.so` **rejects the flag with `ENOTSUP`**:

```asm
0000000000009300 <fchmodat>:            ; (dirfd=edi, path=rsi, mode=edx, flag=ecx)
    cmpl   $0x100,-0x18(%rbp)           ; flag == AT_SYMLINK_NOFOLLOW ?
    jne    9340 <fchmodat+0x40>
    mov    $0x23,%edi                   ; errno = 0x23 (35 = ENOTSUP)
    call   errnoSet
    movl   $0xffffffff,-0x4(%rbp)       ; return -1
    ...
9340:                                   ; flag == 0
    call   taskSafe
    ...  atCatPath(dirfd, path)
    call   chmod                        ; plain chmod -> follows the symlink
```

So `fchmodat(.., AT_SYMLINK_NOFOLLOW)` returns `-1`/`ENOTSUP`, and `flag == 0` degrades to `chmod`, which follows symlinks. A `fchmodat`-based implementation is not viable on this release — the platform's own `fchmodat` reports `ENOTSUP` for exactly this request, which is why `Unsupported` is correct rather than merely conservative. cc @biabbas @hax0kartik

## Build verification

On `1.100.0-nightly (9085017 2026-08-30)` + `rust-src` (stock `libc` 0.2.189):

- Before: `cargo +nightly build -Zbuild-std=std,panic_abort --target x86_64-wrs-vxworks` fails with the E0425 above (1 error).
- After this patch: the same command finishes successfully.
rust-bors Bot pushed a commit that referenced this pull request Sep 2, 2026
…uwer

Rollup of 23 pull requests

Successful merges:

 - #162164 (Revert "Implement Debug for C-like enums with a concatenated string")
 - #160564 (volatile: allow accesses to non-AM memory to trap)
 - #161579 (suggest calling a fn item used as the iterator of a `for` loop)
 - #162044 (coverage: Resolve spans to file-coordinates in a separate step)
 - #162120 (Introduce `PerOwnerLoweringState`)
 - #162151 (Test itanium mangling of `f16` and `f128`)
 - #162162 (Don't special-case `!` in stability checks anymore)
 - #162181 (Remove wrong UnusedBraces lint for iterator loop in edition 2024 )
 - #162187 (Rename `thir::ExprKind::Use` to `ValueExpr`)
 - #158401 (mgca: Don't ICE when evaluating ValTrees that contain error constants)
 - #159873 (fuchsia: Add safestack as a supported sanitizer for x86_64 fuchsia)
 - #161847 (Preserve visibility in nested macro import suggestions)
 - #161972 (Improve tests for `#[track_caller]` in async)
 - #162008 (Render the `box` pattern removal diagnostic more actionable & remove `box` expression recovery)
 - #162065 (std: don't reference `libc::O_NOFOLLOW` on VxWorks in `set_perm_nofollow`)
 - #162076 (docs(num): clarify conditions under which error occurs in `impl TryFrom<int> for int`)
 - #162152 (Revert "retrieve supported GCC targets from the sysroot")
 - #162153 (Prefer `LLVMGetVersion` for runtime info)
 - #162168 (fix ICE in project_goals/inherent)
 - #162171 (Explain LoongArch f16 NaN-boxing in inline asm)
 - #162173 (fix supposedly unreachable `bug!` being reachable)
 - #162191 (core: mark float `ClampBounds` methods as `#[inline]`)
 - #162199 (docs(time): clarify exact seconds for hour and minute)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-libs Relevant to the library team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants