changeset 32352:be5db604940b

Avoid including <pwd.h> in C++ code (bug #64709). * liboctave/wrappers/pwd-wrappers.c, pwd-wrappers.h: Add wrappers for functions from <pwd.h>. * liboctave/warppers/module.mk: Add new files to build rules. * liboctave/system/oct-password.cc: Use new wrappers instead of directly including <pwd.h>.
author Markus Mützel <markus.muetzel@gmx.de>
date Wed, 27 Sep 2023 14:55:51 +0200
parents 469b078fe75b
children 9067c860e0f1
files liboctave/system/oct-password.cc liboctave/wrappers/module.mk liboctave/wrappers/pwd-wrappers.c liboctave/wrappers/pwd-wrappers.h
diffstat 4 files changed, 190 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/liboctave/system/oct-password.cc	Wed Sep 27 13:43:18 2023 +0200
+++ b/liboctave/system/oct-password.cc	Wed Sep 27 14:55:51 2023 +0200
@@ -29,12 +29,9 @@
 
 #include <sys/types.h>
 
-#if defined (HAVE_PWD_H)
-#  include <pwd.h>
-#endif
-
 #include "lo-error.h"
 #include "oct-password.h"
+#include "pwd-wrappers.h"
 
 #define NOT_SUPPORTED(nm)                       \
   nm ": not supported on this system"
@@ -125,7 +122,7 @@
 {
 #if defined HAVE_GETPWENT
   msg = "";
-  return password (::getpwent (), msg);
+  return password (octave_getpwent_wrapper (), msg);
 #else
   msg = NOT_SUPPORTED ("getpwent");
   return password ();
@@ -144,7 +141,7 @@
 {
 #if defined (HAVE_GETPWUID)
   msg = "";
-  return password (::getpwuid (uid), msg);
+  return password (octave_getpwuid_wrapper (uid), msg);
 #else
   octave_unused_parameter (uid);
 
@@ -165,7 +162,7 @@
 {
 #if defined (HAVE_GETPWNAM)
   msg = "";
-  return password (::getpwnam (nm.c_str ()), msg);
+  return password (octave_getpwnam_wrapper (nm.c_str ()), msg);
 #else
   octave_unused_parameter (nm);
 
@@ -186,7 +183,7 @@
 {
 #if defined (HAVE_SETPWENT)
   msg = "";
-  ::setpwent ();
+  octave_setpwent_wrapper ();
   return 0;
 #else
   msg = NOT_SUPPORTED ("setpwent");
@@ -206,7 +203,7 @@
 {
 #if defined (HAVE_ENDPWENT)
   msg = "";
-  ::endpwent ();
+  octave_endpwent_wrapper ();
   return 0;
 #else
   msg = NOT_SUPPORTED ("endpwent");
@@ -223,15 +220,16 @@
 
   if (p)
     {
-      struct ::passwd *pw = static_cast<struct ::passwd *> (p);
+      struct octave_passwd_wrapper pw;
+      octave_from_passwd (static_cast<struct ::passwd *> (p), &pw);
 
-      m_name = pw->pw_name;
-      m_passwd = pw->pw_passwd;
-      m_uid = pw->pw_uid;
-      m_gid = pw->pw_gid;
-      m_gecos = pw->pw_gecos;
-      m_dir = pw->pw_dir;
-      m_shell = pw->pw_shell;
+      m_name = pw.pw_name;
+      m_passwd = pw.pw_passwd;
+      m_uid = pw.pw_uid;
+      m_gid = pw.pw_gid;
+      m_gecos = pw.pw_gecos;
+      m_dir = pw.pw_dir;
+      m_shell = pw.pw_shell;
 
       m_valid = true;
     }
--- a/liboctave/wrappers/module.mk	Wed Sep 27 13:43:18 2023 +0200
+++ b/liboctave/wrappers/module.mk	Wed Sep 27 14:55:51 2023 +0200
@@ -21,6 +21,7 @@
   %reldir%/nproc-wrapper.h \
   %reldir%/octave-popen2.h \
   %reldir%/putenv-wrapper.h \
+  %reldir%/pwd-wrappers.h \
   %reldir%/set-program-name-wrapper.h \
   %reldir%/signal-wrappers.h \
   %reldir%/stat-wrappers.h \
@@ -65,6 +66,7 @@
   %reldir%/nproc-wrapper.c \
   %reldir%/octave-popen2.c \
   %reldir%/putenv-wrapper.c \
+  %reldir%/pwd-wrappers.c \
   %reldir%/set-program-name-wrapper.c \
   %reldir%/signal-wrappers.c \
   %reldir%/stat-wrappers.c \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/liboctave/wrappers/pwd-wrappers.c	Wed Sep 27 14:55:51 2023 +0200
@@ -0,0 +1,102 @@
+////////////////////////////////////////////////////////////////////////
+//
+// Copyright (C) 2023 The Octave Project Developers
+//
+// See the file COPYRIGHT.md in the top-level directory of this
+// distribution or <https://octave.org/copyright/>.
+//
+// This file is part of Octave.
+//
+// Octave is free software: you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Octave is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Octave; see the file COPYING.  If not, see
+// <https://www.gnu.org/licenses/>.
+//
+////////////////////////////////////////////////////////////////////////
+
+// pwd.h might set some preprocessor definitions that replace Octave functions
+// in compilation units where it is included.  Use these wrappers to avoid that.
+
+#if defined (HAVE_CONFIG_H)
+#  include "config.h"
+#endif
+
+#if defined (HAVE_PWD_H)
+#  include <pwd.h>
+#endif
+
+#include "pwd-wrappers.h"
+
+struct passwd *octave_getpwent_wrapper (void)
+{
+#if defined HAVE_GETPWENT
+  return getpwent ();
+#else
+  return NULL;
+#endif
+}
+
+struct passwd *octave_getpwuid_wrapper (uid_t uid)
+{
+#if defined (HAVE_GETPWUID)
+  return getpwuid (uid);
+#else
+  octave_unused_parameter (uid);
+
+  return NULL;
+#endif
+}
+
+struct passwd *octave_getpwnam_wrapper (const char *nam)
+{
+#if defined (HAVE_GETPWNAM)
+  return getpwnam (nam);
+#else
+  octave_unused_parameter (nam);
+
+  return NULL;
+#endif
+}
+
+void octave_setpwent_wrapper (void)
+{
+#if defined (HAVE_SETPWENT)
+  setpwent ();
+#endif
+  return;
+}
+
+void octave_endpwent_wrapper (void)
+{
+#if defined (HAVE_ENDPWENT)
+  endpwent ();
+#endif
+  return;
+}
+
+void octave_from_passwd (const struct passwd *pw,
+                         struct octave_passwd_wrapper *oct_pw)
+{
+#if defined (HAVE_PWD_H)
+  oct_pw->pw_name = pw->pw_name;
+  oct_pw->pw_passwd = pw->pw_passwd;
+  oct_pw->pw_uid = pw->pw_uid;
+  oct_pw->pw_gid = pw->pw_gid;
+  oct_pw->pw_gecos = pw->pw_gecos;
+  oct_pw->pw_dir = pw->pw_dir;
+  oct_pw->pw_shell = pw->pw_shell;
+#else
+  octave_unused_parameter (pw);
+  octave_unused_parameter (oct_pw);
+#endif
+  return;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/liboctave/wrappers/pwd-wrappers.h	Wed Sep 27 14:55:51 2023 +0200
@@ -0,0 +1,71 @@
+////////////////////////////////////////////////////////////////////////
+//
+// Copyright (C) 2023 The Octave Project Developers
+//
+// See the file COPYRIGHT.md in the top-level directory of this
+// distribution or <https://octave.org/copyright/>.
+//
+// This file is part of Octave.
+//
+// Octave is free software: you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Octave is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Octave; see the file COPYING.  If not, see
+// <https://www.gnu.org/licenses/>.
+//
+////////////////////////////////////////////////////////////////////////
+
+#if ! defined (octave_pwd_wrappers_h)
+#define octave_pwd_wrappers_h 1
+
+#include <sys/types.h>
+
+#if defined __cplusplus
+extern "C" {
+#endif
+
+struct passwd;
+
+// We can't include <pwd.h> without the risk of overwriting function names
+// with preprocessor deinitions.  Define a struct that can hold the needed
+// fields, and use a function to convert from struct passwd to it.
+struct octave_passwd_wrapper
+{
+  char *pw_name;
+  char *pw_passwd;
+  uid_t pw_uid;
+  gid_t pw_gid;
+  char *pw_gecos;
+  char *pw_dir;
+  char *pw_shell;
+};
+
+extern OCTAVE_API struct passwd *octave_getpwent_wrapper (void);
+
+extern OCTAVE_API struct passwd *octave_getpwuid_wrapper (uid_t uid);
+
+extern OCTAVE_API struct passwd *octave_getpwnam_wrapper (const char *nam);
+
+extern OCTAVE_API void octave_setpwent_wrapper (void);
+
+extern OCTAVE_API void octave_endpwent_wrapper (void);
+
+extern OCTAVE_API void octave_endpwent_wrapper (void);
+
+extern OCTAVE_API void
+octave_from_passwd (const struct passwd *pw,
+                    struct octave_passwd_wrapper *oct_pw);
+
+#if defined __cplusplus
+}
+#endif
+
+#endif