# Deprecate (or break-fix) std::env::home\_dir

**URL:** <https://internals.rust-lang.org/t/deprecate-or-break-fix-std-env-home-dir/7315>\
**Category:** libs\
**Created:** [April 16, 2018, 1:55am UTC](https://internals.rust-lang.org/t/deprecate-or-break-fix-std-env-home-dir/7315 "2018-04-16T01:55:34Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![brson](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/brson/32/5197_2.png) [@brson](https://internals.rust-lang.org/u/brson)\
**Post date:** [April 16, 2018, 1:55am UTC](https://internals.rust-lang.org/t/deprecate-or-break-fix-std-env-home-dir/7315/1 "2018-04-16T01:55:34Z")

</div>

This has nagged me for a long time, but the definition of `home_dir` in std is pretty arguably incorrect on Windows, and both rustup and cargo use their [own custom definition](https://github.com/brson/home/blob/master/src/lib.rs#L64).

The [problem with it](https://github.com/rust-lang/rust/blob/e847f30f571e617990f7193665ab10127100e9df/src/libstd/sys/windows/os.rs#L297) is that it prioritizes the `HOME` variable, which basically has no meaning on windows (the correct variable is “USERPROFILE”).

The practical result of this is that calls to `home_dir` on most windows environments result in a path like `C:\Users\brson`, but _under cygwin_ and _mingw_ result in things like `/home/brian/`.

Now, I have no doubt that is useful in some case, but I have not found that case yet, and find the function extremely misleading. When we found it in rustup and cargo, we felt like it was completely bogus and confusing behavior.

There might be a place for this function in the world, but I do not believe it is `env::home_dir`, and suggest deprecating it.

Thoughts?

---

<div class="post-metadata">

**Author:** ![kennytm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kennytm/32/161_2.png) [@kennytm](https://internals.rust-lang.org/u/kennytm)\
**Post date:** [April 16, 2018, 3:00am UTC](https://internals.rust-lang.org/t/deprecate-or-break-fix-std-env-home-dir/7315/2 "2018-04-16T03:00:45Z")

</div>

We have tried to fix this function before at [https://github.com/rust-lang/rust/pull/46799](https://github.com/rust-lang/rust/pull/46799) but basically arrived at the same conclusion (deprecate it eventually, point to an external package instead.)

---

<div class="post-metadata">

**Author:** ![kornel](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kornel/32/2711_2.png) [@kornel](https://internals.rust-lang.org/u/kornel)\
**Post date:** [April 16, 2018, 3:26am UTC](https://internals.rust-lang.org/t/deprecate-or-break-fix-std-env-home-dir/7315/3 "2018-04-16T03:26:11Z")

</div>

It looks like there’s a universal agreement that the current implementation is wrong, and the proposed one is better.

Wouldn’t that technically-breaking change be perceived merely as a bug fix?

---

<div class="post-metadata">

**Author:** ![brson](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/brson/32/5197_2.png) [@brson](https://internals.rust-lang.org/u/brson)\
**Post date:** [April 16, 2018, 3:59am UTC](https://internals.rust-lang.org/t/deprecate-or-break-fix-std-env-home-dir/7315/4 "2018-04-16T03:59:52Z")

</div>

I [commented](https://github.com/rust-lang/rust/pull/46799#issuecomment-381473508) on @alexcrichton’s main objection to break-fixing home\_dir. Both cargo and multirust still use it for - at this point - ancient backcompat hacks, that I expect to be removed. In particularl, [https://github.com/rust-lang/cargo/pull/5183](https://github.com/rust-lang/cargo/pull/5183) rewrites how cargo home is discovered and does not take into account the hack.

Edit: the functions that cargo/rustup use are not `home_dir` - they are cargo/rustup specific. `home::home_dir` is exactly like `env::home_dir` but without considering `%HOME` on windows.

---

<div class="post-metadata">

**Author:** ![brson](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/brson/32/5197_2.png) [@brson](https://internals.rust-lang.org/u/brson)\
**Post date:** [April 16, 2018, 4:03am UTC](https://internals.rust-lang.org/t/deprecate-or-break-fix-std-env-home-dir/7315/5 "2018-04-16T04:03:10Z")

</div>

Anyway, just deprecating it is fine too. It’s just a bunk function and nobody should use it. And the `home` crate basically looks correct to me (for the `home` function specifically), besides the fact that on unix it calls std::env::home, and would need to be rewritten.

Once the cargo/rustup directory overhaul is done, the rest of the contents of the `home` crate will probably just be dead code, and `home` can literally contain one correct `home_dir` function.

On the other hand, we could just put a correct function in std - and I honestly doubt anybody is going to ding us for just fixing `env::home_dir`.

---

<div class="post-metadata">

**Author:** ![brson](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/brson/32/5197_2.png) [@brson](https://internals.rust-lang.org/u/brson)\
**Post date:** [April 16, 2018, 4:05am UTC](https://internals.rust-lang.org/t/deprecate-or-break-fix-std-env-home-dir/7315/6 "2018-04-16T04:05:53Z")

</div>

We could also point peaple at [https://github.com/soc/directories-rs](https://github.com/soc/directories-rs), though I don’t know if that is using a similar definition of `HOME` - I know it doesn’t care about `%USERPROFILE%` on windows, but stackoverflow also says not to use `%USERPROFILE%. My only doubt about that crate is that the scope is big, and its opinionated.

The definition of `home` though is probably fine, though I believe incomplete on some platforms Rust supports.

Edit: directories is MPL licensed :-/

Edit: heh, on unix, directories just defers to std::env::home(), just like `home`.

---

<div class="post-metadata">

**Author:** ![josh](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/josh/32/5934_2.png) [@josh](https://internals.rust-lang.org/u/josh)\
**Post date:** [April 16, 2018, 4:57am UTC](https://internals.rust-lang.org/t/deprecate-or-break-fix-std-env-home-dir/7315/7 "2018-04-16T04:57:23Z")

</div>

I do know that some people set `%HOME%` on Windows and expect that to work. And people who run programs under cygwin sometimes expect that behavior.

Perhaps we should just document the behavior very carefully, and also tell people what they should use if they don’t want that behavior?

---

<div class="post-metadata">

**Author:** ![brson](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/brson/32/5197_2.png) [@brson](https://internals.rust-lang.org/u/brson)\
**Post date:** [April 16, 2018, 5:37am UTC](https://internals.rust-lang.org/t/deprecate-or-break-fix-std-env-home-dir/7315/8 "2018-04-16T05:37:28Z")

</div>

I mean, we could, but I’m pretty convinced it’s the wrong default. Having this weird `home_dir` function in std and no “correct” function is a pretty big wart.

---

<div class="post-metadata">

**Author:** ![Screwtapello](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/screwtapello/32/1076_2.png) [@Screwtapello](https://internals.rust-lang.org/u/Screwtapello)\
**Post date:** [June 11, 2018, 7:39am UTC](https://internals.rust-lang.org/t/deprecate-or-break-fix-std-env-home-dir/7315/11 "2018-06-11T07:39:45Z")

</div>

> This means that everyone intentionally creating a user _without_ a home directory (for security reasons) gets a made-up home directory handed from `getpwuid_r`.

How do you create a user without a home directory? It's a required field in `/etc/passwd`. It doesn't have to be readable by the given user or even exist on disk, but whatever's in that field is by definition the user's home directory, and I'd expect it to be returned by a "get my home directory" function.

---

<div class="post-metadata">

**Author:** ![Screwtapello](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/screwtapello/32/1076_2.png) [@Screwtapello](https://internals.rust-lang.org/u/Screwtapello)\
**Post date:** [June 12, 2018, 1:36am UTC](https://internals.rust-lang.org/t/deprecate-or-break-fix-std-env-home-dir/7315/13 "2018-06-12T01:36:37Z")

</div>

> Do you have further information on the home directory being a required field in `/etc/passwd`?

`passwd(5)` says: "`/etc/passwd` contains one line for each user account, with seven fields delimited by colons", so it's not physically possible for the home directory field to be missing—or if it is, the record won't have enough fields to be valid.

When you mention "the `-r` option", I assume you're talking about the `useradd(8)` command, whose `-r` option means "create a system account" My `useradd(8)` says: "Note that useradd will not create a home directory for such a user, regardless of the default setting in /etc/login.defs (CREATE\_HOME)." I take that as meaning it won't create a home directory _on disk_; I don't know what it gets set to in the database.

On my Debian system, most service accounts seem to have their home directories set to various places in `/var` that don't exist; for example, the "uucp" user's home directory is the non-existent `/var/spool/uucp`. Two system users, "nobody" and "apt" have their home directory literally set to `/nonexistent`, which is [apparently the Debian convention](https://www.debian.org/doc/debian-policy/#non-existent-home-directories).

---

<div class="post-metadata">

**Author:** ![xfix](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/xfix/32/2726_2.png) [@xfix](https://internals.rust-lang.org/u/xfix)\
**Post date:** [June 13, 2018, 2:11pm UTC](https://internals.rust-lang.org/t/deprecate-or-break-fix-std-env-home-dir/7315/14 "2018-06-13T14:11:59Z")

</div>

On Arch Linux, the home for users who don’t care is `/` (a root directory), so yeah, it seems mandatory in a way. Of course, the value may be useless, but it exists, so providing it seems fine (it’s out of scope anyway for a language to try to determine what home paths are valid and which aren’t).

---

<div class="post-metadata">

**Author:** ![Screwtapello](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/screwtapello/32/1076_2.png) [@Screwtapello](https://internals.rust-lang.org/u/Screwtapello)\
**Post date:** [June 14, 2018, 2:24pm UTC](https://internals.rust-lang.org/t/deprecate-or-break-fix-std-env-home-dir/7315/17 "2018-06-14T14:24:47Z")

</div>

> what happens when the home dir is not set in `/etc/passwd`?

"set to an empty string" is not the same as "not set".

However, I can't think of a good reason to set it that way, and I can think of some reasons not to (for one, any app running as that user that tried to write something to "the home directory" would probably write it to the current directory, whatever it is, which I can imagine would be a pain in the ass to debug). In the interests of encouraging programs to behave sanely, I heartily endorse your suggested rules for when `home_dir()` should return `None`.

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [March 25, 2019, 8:30am UTC](https://internals.rust-lang.org/t/deprecate-or-break-fix-std-env-home-dir/7315/19 "2019-03-25T08:30:04Z")

</div>

Closed on March 25, 2019, 8:30am UTC

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
