Skip to content

Commit

Permalink
Use getpwuid(3) in corehost for the $HOME-less user (#59036)
Browse files Browse the repository at this point in the history
  • Loading branch information
am11 authored Sep 16, 2021
1 parent e55a569 commit cef245d
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -223,14 +223,33 @@ private void Bundle_extraction_to_nonexisting_default()

[Fact]
[SkipOnPlatform(TestPlatforms.Windows, "On Windows the default extraction path is determined by calling GetTempPath which looks at multiple places and can't really be undefined.")]
private void Bundle_extraction_default_undefined()
private void Bundle_extraction_fallsback_to_getpwuid_when_HOME_env_var_is_undefined()
{
string home = Environment.GetEnvironmentVariable("HOME");
// suppose we are testing on a system where HOME is not set, use System.Environment (which also fallsback to getpwuid)
if (string.IsNullOrEmpty(home))
{
home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
}

DirectoryInfo sharedExtractDirInfo = BundleHelper.GetExtractionDir(sharedTestState.TestFixture, sharedTestState.DefaultBundledAppBundler);
string sharedExtractDir = sharedExtractDirInfo.FullName;
string extractDirSubPath = sharedExtractDir.Substring(sharedExtractDir.LastIndexOf("extract/") + "extract/".Length);
string realExtractDir = Path.Combine(home, ".net", extractDirSubPath);
var expectedExtractDir = new DirectoryInfo(realExtractDir);

Command.Create(sharedTestState.DefaultBundledAppExecutablePath)
.CaptureStdErr()
.CaptureStdOut()
.EnvironmentVariable("HOME", null)
.Execute().Should().Fail()
.And.HaveStdErrContaining("Failed to determine default extraction location. Environment variable '$HOME' is not defined.");
.Execute()
.Should()
.Pass()
.And
.HaveStdOutContaining("Hello World");

var extractedFiles = BundleHelper.GetExtractedFiles(sharedTestState.TestFixture, BundleOptions.BundleNativeBinaries);
expectedExtractDir.Should().HaveFiles(extractedFiles);
}

public class SharedTestState : SharedTestStateBase, IDisposable
Expand Down
25 changes: 24 additions & 1 deletion src/native/corehost/hostmisc/pal.unix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,30 @@ bool get_extraction_base_parent_directory(pal::string_t& directory)
}
else
{
trace::error(_X("Failed to determine default extraction location. Environment variable '$HOME' is not defined."));
// fallback to the POSIX standard getpwuid() library function
struct passwd* pwuid = NULL;
errno = 0;
do
{
pwuid = getpwuid(getuid());
} while (pwuid == NULL && errno == EINTR);

if (pwuid != NULL)
{
directory.assign(pwuid->pw_dir);
if (is_read_write_able_directory(directory))
{
return true;
}
else
{
trace::error(_X("Failed to determine default extraction location. Environment variable '$HOME' is not defined and directory reported by getpwuid() [%s] either doesn't exist or is not accessible for read/write."), pwuid->pw_dir);
}
}
else
{
trace::error(_X("Failed to determine default extraction location. Environment variable '$HOME' is not defined and getpwuid() returned NULL."));
}
}

return false;
Expand Down

0 comments on commit cef245d

Please sign in to comment.