rust-lang / rust-lang/libc

Newtypes for all C enums

Open
#5,066 7 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
2.6k
Forks
1.3k
Avg merge
1d 22h
Merged PRs (30d)
69

Description

For libc 1.0, we should consider whether all C enums should be exposed as a newtype struct rather than an integer typedef. For example, the header file on my laptop declares idtype_t like this:

/* The following values are used by the `waitid' function.  */
typedef enum
{
  P_ALL,		/* Wait for any child.  */
  P_PID,		/* Wait for specified process.  */
  P_PGID,		/* Wait for members of process group.  */
  P_PIDFD,		/* Wait for the child referred by the PID file
                   descriptor.  */
} idtype_t;

whereas libc declares the above type as:

https://github.com/rust-lang/libc/blob/088a28455a81c6f9cf770cea42b94380d3cc9b05/src/unix/linux_like/linux/mod.rs#L21

Defining a C enum as a typedef for an integer has consequences for the CFI (Control Flow Integrity) sanitizer. When using that sanitizer, enums do not have the same ABI as the underlying integer type. Using a newtype struct allows libc to declare a type with an ABI that actually matches what CFI expects.

#[repr(transparent)]
#[cfi_encoding="8idtype_t"]
pub struct idtype_t(pub c_uint);

impl idtype_t {
    pub const P_ALL: Self = Self(0);
    pub const P_PID: Self = Self(1);
    pub const P_PGID: Self = Self(2);
    pub const P_PIDFD: Self = Self(3);
}

The consequence of calling a method with an enum declared as a typedefd integer is that the program will crash if the call is dynamic. Static function calls work like normal.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the idtype_t declaration in src/unix/linux_like/linux/mod.rs and compare it with the referenced C header definition. Review how the repository represents other C enums and how #[repr(transparent)] and cfi_encoding are used. Done means determining and implementing a consistent newtype representation for the applicable C enums with matching constants and CFI-compatible ABI.

Written by the indexing model from the issue text.

Assessment

Tech stack
c, rust
Domain
backend-api-design, operating-systems
Issue type
Refactor
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.