Hi -

I noticed that -m (-p, --preserve-environment) and -l (- --login) can't be
used together.

Attached is a patch to give a warning if they are and to indicate which
option is used. In the code, I opted for the earlier option ignoring the
later option. In the code --login has precedence over
--preserve-environment.
From 8a74ea72e7718fac9bcf1c33a17f675adb6a1987 Mon Sep 17 00:00:00 2001
From: R. Bernstein <ro...@gnu.org>
Date: Sat, 17 Dec 2011 15:37:48 -0500
Subject: [PATCH] su: Warn that --login and --preserve environment are mutually exclusive

coreutils.texi: document that -l and -m are mutually exclusive.
---
 doc/coreutils.texi |    4 ++++
 src/su.c           |   19 +++++++++++++++++--
 2 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/doc/coreutils.texi b/doc/coreutils.texi
index c26a53d..d874519 100644
--- a/doc/coreutils.texi
+++ b/doc/coreutils.texi
@@ -15636,6 +15636,8 @@ environment variables except @env{TERM}, @env{HOME}, and @env{SHELL}
 directory.  Prepend @samp{-} to the shell's name, intended to make it
 read its login startup file(s).
 
+Note that this option and the next one @option{-m} are mutually exclusive.
+
 @item -m
 @itemx -p
 @itemx --preserve-environment
@@ -15654,6 +15656,8 @@ is not listed in the file @file{/etc/shells}, or in a compiled-in list
 if that file does not exist.  Parts of what this option does can be
 overridden by @option{--login} and @option{--shell}.
 
+Note that this option and the previous one @option{-l} are mutually exclusive.
+
 @item -s @var{shell}
 @itemx --shell=@var{shell}
 @opindex -s
diff --git a/src/su.c b/src/su.c
index b1ba2a7..75931d7 100644
--- a/src/su.c
+++ b/src/su.c
@@ -400,6 +400,7 @@ main (int argc, char **argv)
   char *shell = NULL;
   struct passwd *pw;
   struct passwd pw_copy;
+  static bool seen_login_change_env = false ;
 
   initialize_main (&argc, &argv);
   set_program_name (argv[0]);
@@ -427,12 +428,26 @@ main (int argc, char **argv)
           break;
 
         case 'l':
-          simulate_login = true;
+	  if (seen_login_change_env && !simulate_login) {
+	      fprintf (stderr, _("%s: already seen --preserve-environment; --login ignored.\n"),
+		       program_name);
+	  } else {
+	      simulate_login = true;
+	      seen_login_change_env = true;
+	  }
+
           break;
 
         case 'm':
         case 'p':
-          change_environment = false;
+	  if (seen_login_change_env && change_environment) {
+	      fprintf (stderr, _("%s: already seen option --login; --preserve-environment ignored.\n"),
+		       program_name);
+	  } else {
+	      change_environment = false;
+	      seen_login_change_env = true;
+	  }
+
           break;
 
         case 's':
-- 
1.7.4.1

Reply via email to