New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Capture `Command` environment at spawn #46789

Merged
merged 1 commit into from Dec 24, 2017

Conversation

Projects
None yet
8 participants
@Diggsey
Contributor

Diggsey commented Dec 17, 2017

Fixes #28975

This tracks a set of changes to the environment and then replays them at spawn time.

@rust-highfive

This comment has been minimized.

Show comment
Hide comment
@rust-highfive

rust-highfive Dec 17, 2017

Collaborator

r? @TimNN

(rust_highfive has picked a reviewer for you, use r? to override)

Collaborator

rust-highfive commented Dec 17, 2017

r? @TimNN

(rust_highfive has picked a reviewer for you, use r? to override)

@Diggsey

This comment has been minimized.

Show comment
Hide comment
@Diggsey

Diggsey Dec 17, 2017

Contributor

While writing this, I found a few potential issues which I didn't attempt to fix as part of this PR:

  • The case conversion on windows assumes only ascii characters are compared case-insensitively. I couldn't find any documentation detailing whether this is correct, but my suspicion is that it's not (case insensitivity in the file-system does not work this way).

  • On windows, if any environment variables are modified, then all environment variables are upper-cased before being passed to the child process. Ideally case would be preserved. It should be relatively easy to implement this change following this PR, but it relies on the AsciiExt trait gaining a case-insensitive ordering method (at the moment it only allows testing for case-insensitive equality).

  • On linux, the exec implementation is very unsafe as it assigns a short-lived heap-allocated string to the global variable environ without taking a lock #46775

  • On fuchsia, when the environment is unchanged the code calls launchpad_set_environ(..) with a null pointer, and I couldn't find any details about whether that is correct.

Contributor

Diggsey commented Dec 17, 2017

While writing this, I found a few potential issues which I didn't attempt to fix as part of this PR:

  • The case conversion on windows assumes only ascii characters are compared case-insensitively. I couldn't find any documentation detailing whether this is correct, but my suspicion is that it's not (case insensitivity in the file-system does not work this way).

  • On windows, if any environment variables are modified, then all environment variables are upper-cased before being passed to the child process. Ideally case would be preserved. It should be relatively easy to implement this change following this PR, but it relies on the AsciiExt trait gaining a case-insensitive ordering method (at the moment it only allows testing for case-insensitive equality).

  • On linux, the exec implementation is very unsafe as it assigns a short-lived heap-allocated string to the global variable environ without taking a lock #46775

  • On fuchsia, when the environment is unchanged the code calls launchpad_set_environ(..) with a null pointer, and I couldn't find any details about whether that is correct.

@TimNN

This comment has been minimized.

Show comment
Hide comment
@TimNN

TimNN Dec 17, 2017

Contributor

r? @dtolnay since you already commented on the issue and I don't feel like I have enough understanding of the whole topic.

Contributor

TimNN commented Dec 17, 2017

r? @dtolnay since you already commented on the issue and I don't feel like I have enough understanding of the whole topic.

@rust-highfive rust-highfive assigned dtolnay and unassigned TimNN Dec 17, 2017

@dtolnay

This is exactly what I had in mind. Nicely done, and thanks for flagging the confusing previous behavior.

@dtolnay

This comment has been minimized.

Show comment
Hide comment
@dtolnay

dtolnay Dec 17, 2017

Member

@rust-lang/libs As of Rust 1.22 the behavior of modifying environment variables on a Command is that the parent process environment is captured at the first call to env/env_remove/env_clear, otherwise captured during spawn. There is no way to explicitly trigger the environment capture without making a change to the child process environment or spawning. The result is confusing and unpredictable behavior.

// Is this visible to child process? I would hope so.
os::set_var("A", "A");

let mut command = Command::new("...");

// Is this visible? Basically arbitrary, but currently yes.
os::set_var("B", "B");

if cond() {
    // Set in child env but not parent process.
    command.env("C", "C");
}

// Is this visible? It seems obvious to me that the answer should be the same
// as for B. Currently the answer is maybe! Depends on cond(). Child process
// sees either C or D but not both.
os::set_var("D", "D");

command.spawn()

This PR makes A, B, C, D all visible to the child process. The behavior is as if every environment modification to the Command were evaluated eagerly against the parent environment, with the result being captured for the child at the call to spawn.

Member

dtolnay commented Dec 17, 2017

@rust-lang/libs As of Rust 1.22 the behavior of modifying environment variables on a Command is that the parent process environment is captured at the first call to env/env_remove/env_clear, otherwise captured during spawn. There is no way to explicitly trigger the environment capture without making a change to the child process environment or spawning. The result is confusing and unpredictable behavior.

// Is this visible to child process? I would hope so.
os::set_var("A", "A");

let mut command = Command::new("...");

// Is this visible? Basically arbitrary, but currently yes.
os::set_var("B", "B");

if cond() {
    // Set in child env but not parent process.
    command.env("C", "C");
}

// Is this visible? It seems obvious to me that the answer should be the same
// as for B. Currently the answer is maybe! Depends on cond(). Child process
// sees either C or D but not both.
os::set_var("D", "D");

command.spawn()

This PR makes A, B, C, D all visible to the child process. The behavior is as if every environment modification to the Command were evaluated eagerly against the parent environment, with the result being captured for the child at the call to spawn.

@dtolnay

This comment has been minimized.

Show comment
Hide comment
@dtolnay

dtolnay Dec 18, 2017

Member

@rfcbot fcp merge

Member

dtolnay commented Dec 18, 2017

@rfcbot fcp merge

@rfcbot

This comment has been minimized.

Show comment
Hide comment
@rfcbot

rfcbot Dec 18, 2017

Team member @dtolnay has proposed to merge this. The next step is review by the rest of the tagged teams:

No concerns currently listed.

Once these reviewers reach consensus, this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

See this document for info about what commands tagged team members can give me.

rfcbot commented Dec 18, 2017

Team member @dtolnay has proposed to merge this. The next step is review by the rest of the tagged teams:

No concerns currently listed.

Once these reviewers reach consensus, this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

See this document for info about what commands tagged team members can give me.

@bors

This comment has been minimized.

Show comment
Hide comment
@bors

bors Dec 18, 2017

Contributor

☔️ The latest upstream changes (presumably #46798) made this pull request unmergeable. Please resolve the merge conflicts.

Contributor

bors commented Dec 18, 2017

☔️ The latest upstream changes (presumably #46798) made this pull request unmergeable. Please resolve the merge conflicts.

@rfcbot

This comment has been minimized.

Show comment
Hide comment
@rfcbot

rfcbot Dec 19, 2017

🔔 This is now entering its final comment period, as per the review above. 🔔

rfcbot commented Dec 19, 2017

🔔 This is now entering its final comment period, as per the review above. 🔔

@alexcrichton

This comment has been minimized.

Show comment
Hide comment
@alexcrichton

alexcrichton Dec 19, 2017

Member

@bors: r=dtolnay

Member

alexcrichton commented Dec 19, 2017

@bors: r=dtolnay

@bors

This comment has been minimized.

Show comment
Hide comment
@bors

bors Dec 19, 2017

Contributor

📌 Commit 6679768 has been approved by dtolnay

Contributor

bors commented Dec 19, 2017

📌 Commit 6679768 has been approved by dtolnay

@bors

This comment has been minimized.

Show comment
Hide comment
@bors

bors Dec 22, 2017

Contributor

⌛️ Testing commit 6679768 with merge 97e576b...

Contributor

bors commented Dec 22, 2017

⌛️ Testing commit 6679768 with merge 97e576b...

bors added a commit that referenced this pull request Dec 22, 2017

Auto merge of #46789 - Diggsey:command-env-capture, r=dtolnay
Capture `Command` environment at spawn

Fixes #28975

This tracks a set of changes to the environment and then replays them at spawn time.
@bors

This comment has been minimized.

Show comment
Hide comment
@bors

bors Dec 22, 2017

Contributor

💔 Test failed - status-travis

Contributor

bors commented Dec 22, 2017

💔 Test failed - status-travis

@kennytm

wasm32-unknown failed, legit.

Show outdated Hide outdated src/libstd/sys/wasm/process.rs Outdated
@kennytm

This comment has been minimized.

Show comment
Hide comment
@kennytm

kennytm Dec 23, 2017

Member

@bors r=dtolnay

Member

kennytm commented Dec 23, 2017

@bors r=dtolnay

@bors

This comment has been minimized.

Show comment
Hide comment
@bors

bors Dec 23, 2017

Contributor

📌 Commit da90b1d has been approved by dtolnay

Contributor

bors commented Dec 23, 2017

📌 Commit da90b1d has been approved by dtolnay

@bors

This comment has been minimized.

Show comment
Hide comment
@bors

bors Dec 23, 2017

Contributor

⌛️ Testing commit da90b1d with merge faecf24...

Contributor

bors commented Dec 23, 2017

⌛️ Testing commit da90b1d with merge faecf24...

bors added a commit that referenced this pull request Dec 23, 2017

Auto merge of #46789 - Diggsey:command-env-capture, r=dtolnay
Capture `Command` environment at spawn

Fixes #28975

This tracks a set of changes to the environment and then replays them at spawn time.
@bors

This comment has been minimized.

Show comment
Hide comment
@bors

bors Dec 23, 2017

Contributor

💔 Test failed - status-travis

Contributor

bors commented Dec 23, 2017

💔 Test failed - status-travis

Show outdated Hide outdated src/libstd/sys/wasm/process.rs Outdated
@Diggsey

This comment has been minimized.

Show comment
Hide comment
@Diggsey

Diggsey Dec 24, 2017

Contributor

@kennytm think I've got it this time...

Contributor

Diggsey commented Dec 24, 2017

@kennytm think I've got it this time...

@kennytm

This comment has been minimized.

Show comment
Hide comment
@kennytm

kennytm Dec 24, 2017

Member

@bors r=dtolnay

Member

kennytm commented Dec 24, 2017

@bors r=dtolnay

@bors

This comment has been minimized.

Show comment
Hide comment
@bors

bors Dec 24, 2017

Contributor

📌 Commit ccc91d7 has been approved by dtolnay

Contributor

bors commented Dec 24, 2017

📌 Commit ccc91d7 has been approved by dtolnay

@bors

This comment has been minimized.

Show comment
Hide comment
@bors

bors Dec 24, 2017

Contributor

⌛️ Testing commit ccc91d7 with merge c284f88...

Contributor

bors commented Dec 24, 2017

⌛️ Testing commit ccc91d7 with merge c284f88...

bors added a commit that referenced this pull request Dec 24, 2017

Auto merge of #46789 - Diggsey:command-env-capture, r=dtolnay
Capture `Command` environment at spawn

Fixes #28975

This tracks a set of changes to the environment and then replays them at spawn time.
@bors

This comment has been minimized.

Show comment
Hide comment
@bors

bors Dec 24, 2017

Contributor

☀️ Test successful - status-appveyor, status-travis
Approved by: dtolnay
Pushing c284f88 to master...

Contributor

bors commented Dec 24, 2017

☀️ Test successful - status-appveyor, status-travis
Approved by: dtolnay
Pushing c284f88 to master...

@bors bors merged commit ccc91d7 into rust-lang:master Dec 24, 2017

2 checks passed

continuous-integration/travis-ci/pr The Travis CI build passed
Details
homu Test successful
Details

@Diggsey Diggsey deleted the Diggsey:command-env-capture branch Dec 27, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment