Skip to content
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

Fallback to getpwuid() if $HOME is unset #562

Merged
merged 1 commit into from
Dec 23, 2024

Conversation

suve
Copy link
Contributor

@suve suve commented Dec 22, 2024

Recently, commit 7621899 added some fallback code for the rare case when $HOME is unset. However, that code simply falls to using the root directory as the home. This PR makes the game use the getpwuid()1 function instead, which retrieves information about the user profile - including the home directory - from the OS.

One minor issue with this PR is that (at least on Fedora Linux) it causes some "duplicate definition" warnings:

prboom2/BUILD/config.h:18:9: warning: "HAVE_SYS_TYPES_H" redefined
   18 | #define HAVE_SYS_TYPES_H
      |         ^~~~~~~~~~~~~~~~
In file included from /usr/include/SDL2/SDL_config.h:58,
                 from /usr/include/SDL2/SDL_stdinc.h:31,
                 from /usr/include/SDL2/SDL_main.h:25,
                 from /usr/include/SDL2/SDL.h:32,
                 from prboom2/src/SDL/i_sound.c:43:
/usr/include/SDL2/SDL_config-x86_64.h:73:9: note: this is the location of the previous definition

There are a couple of different ways this could be solved:

  1. Hide the #cmakedefine behind an #ifdef, so it only defines the symbol if not already present.

  2. Move the "are all three headers present?" check to CMakeLists and then have only #cmakedefine GETPWUID_FALLBACK in the config file.

  3. Probably something else I haven't considered.

Each has its pros and cons, so I thought it's best to discuss first.

Footnotes

  1. https://linux.die.net/man/3/getpwuid

This commit makes the game fallback to using getpwuid() for retrieving
information about the user's home directory, should $HOME be unset.
@fabiangreffrath
Copy link
Collaborator

Check for the symbol being available instead of the headers:

diff --git a/prboom2/CMakeLists.txt b/prboom2/CMakeLists.txt
index e6ce9a85e..0d60ad7c4 100644
--- a/prboom2/CMakeLists.txt
+++ b/prboom2/CMakeLists.txt
@@ -91,13 +91,12 @@ check_symbol_exists(mmap "sys/mman.h" HAVE_MMAP)
 check_symbol_exists(CreateFileMapping "windows.h" HAVE_CREATE_FILE_MAPPING)
 check_symbol_exists(strsignal "string.h" HAVE_STRSIGNAL)
 check_symbol_exists(mkstemp "stdlib.h" HAVE_MKSTEMP)
+check_symbol_exists(getpwuid "unistd.h;sys/types.h;pwd.h" HAVE_GETPWUID)
 
 include(CheckIncludeFile)
 
-check_include_file("sys/types.h" HAVE_SYS_TYPES_H)
 check_include_file("sys/wait.h" HAVE_SYS_WAIT_H)
 check_include_file("unistd.h" HAVE_UNISTD_H)
-check_include_file("pwd.h" HAVE_PWD_H)
 check_include_file("asm/byteorder.h" HAVE_ASM_BYTEORDER_H)
 check_include_file("dirent.h" HAVE_DIRENT_H)
 
diff --git a/prboom2/cmake/config.h.cin b/prboom2/cmake/config.h.cin
index b25f09bb2..f24fb1e52 100644
--- a/prboom2/cmake/config.h.cin
+++ b/prboom2/cmake/config.h.cin
@@ -14,11 +14,10 @@
 #cmakedefine HAVE_CREATE_FILE_MAPPING
 #cmakedefine HAVE_STRSIGNAL
 #cmakedefine HAVE_MKSTEMP
+#cmakedefine HAVE_GETPWUID
 
-#cmakedefine HAVE_SYS_TYPES_H
 #cmakedefine HAVE_SYS_WAIT_H
 #cmakedefine HAVE_UNISTD_H
-#cmakedefine HAVE_PWD_H
 #cmakedefine HAVE_ASM_BYTEORDER_H
 #cmakedefine HAVE_DIRENT_H
 
diff --git a/prboom2/src/SDL/i_system.c b/prboom2/src/SDL/i_system.c
index be6e4f1de..323aa82b4 100644
--- a/prboom2/src/SDL/i_system.c
+++ b/prboom2/src/SDL/i_system.c
@@ -56,12 +56,9 @@
 
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
-#ifdef HAVE_PWD_H
-#ifdef HAVE_SYS_TYPES_H
-#include <pwd.h>
+#ifdef HAVE_GETPWUID
 #include <sys/types.h>
-#define GETPWUID_FALLBACK
-#endif
+#include <pwd.h>
 #endif
 #endif
 
@@ -324,7 +321,7 @@ const char *I_ConfigDir(void)
     {
       home = "/";
 
-#ifdef GETPWUID_FALLBACK
+#ifdef HAVE_GETPWUID
       struct passwd *user_info = getpwuid(getuid());
       if (user_info != NULL) {
         home = user_info->pw_dir;

@fabiangreffrath
Copy link
Collaborator

Also:

diff --git a/prboom2/src/SDL/i_system.c b/prboom2/src/SDL/i_system.c
index 323aa82b4..9d70c8c94 100644
--- a/prboom2/src/SDL/i_system.c
+++ b/prboom2/src/SDL/i_system.c
@@ -319,14 +319,13 @@ const char *I_ConfigDir(void)
     const char *home = M_getenv("HOME");
     if (!home)
     {
-      home = "/";
-
 #ifdef HAVE_GETPWUID
       struct passwd *user_info = getpwuid(getuid());
-      if (user_info != NULL) {
+      if (user_info != NULL)
         home = user_info->pw_dir;
-      }
+      else
 #endif
+        home = "/";
     }
 
     // First, try legacy directory.

@suve suve force-pushed the getpwuid-fallback branch from 136ce7b to 73c99b6 Compare December 23, 2024 10:44
@suve
Copy link
Contributor Author

suve commented Dec 23, 2024

Check for the symbol being available instead of the headers

I somehow completely missed the check_symbol_exists() call above. Think that's called tunnel vision...

Also:

Heh, that was how I wrote it originally, but I know a lot of people are very much against splitting if-else blocks across conditional compilation boundaries, so I changed it.

Thanks for the suggestions; I've amended the commit to include them.

@suve suve marked this pull request as ready for review December 23, 2024 14:20
Copy link
Collaborator

@fabiangreffrath fabiangreffrath left a comment

Choose a reason for hiding this comment

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

LGTM, thank you!

@Pedro-Beirao Pedro-Beirao merged commit fe0dfa0 into kraflab:master Dec 23, 2024
5 checks passed
@Pedro-Beirao
Copy link
Collaborator

Thank you both!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants