Index: src/su.c
===================================================================
--- src/su.c.orig	2012-03-27 02:58:11.403847528 +0200
+++ src/su.c	2012-03-27 03:07:01.495026162 +0200
@@ -163,9 +163,13 @@ static bool simulate_login;
 /* If true, change some environment vars to indicate the user su'd to.  */
 static bool change_environment;
 
+/* If true, then don't call setsid() with a command. */
+int same_session = 0;
+
 static struct option const longopts[] =
 {
   {"command", required_argument, NULL, 'c'},
+  {"session-command", required_argument, NULL, 'C'},
   {"fast", no_argument, NULL, 'f'},
   {"login", no_argument, NULL, 'l'},
   {"preserve-environment", no_argument, NULL, 'p'},
@@ -340,14 +344,29 @@ create_watching_parent (void)
       sigemptyset (&action.sa_mask);
       action.sa_flags = 0;
       sigemptyset (&ourset);
-      if (sigaddset (&ourset, SIGTERM)
-	  || sigaddset (&ourset, SIGALRM)
-	  || sigaction (SIGTERM, &action, NULL)
-	  || sigprocmask (SIG_UNBLOCK, &ourset, NULL))
-	{
+
+      if (!same_session)
+        {
+          if (sigaddset(&ourset, SIGINT) || sigaddset(&ourset, SIGQUIT))
+            {
+              error (0, errno, _("cannot set signal handler"));
+              caught_signal = true;
+            }
+        }
+      if (!caught_signal && (sigaddset(&ourset, SIGTERM)
+                      || sigaddset(&ourset, SIGALRM)
+                      || sigaction(SIGTERM, &action, NULL)
+                      || sigprocmask(SIG_UNBLOCK, &ourset, NULL)))
+        {
 	  error (0, errno, _("cannot set signal handler"));
 	  caught_signal = true;
 	}
+    if (!caught_signal && !same_session && (sigaction(SIGINT, &action, NULL)
+                                     || sigaction(SIGQUIT, &action, NULL)))
+      {
+        error (0, errno, _("cannot set signal handler"));
+        caught_signal = true;
+      }
     }
   if (!caught_signal)
     {
@@ -761,12 +780,15 @@ usage (int status)
       fputs (_("\
 Change the effective user id and group id to that of USER.\n\
 \n\
-  -, -l, --login               make the shell a login shell\n\
-  -c, --command=COMMAND        pass a single COMMAND to the shell with -c\n\
-  -f, --fast                   pass -f to the shell (for csh or tcsh)\n\
-  -m, --preserve-environment   do not reset environment variables\n\
-  -p                           same as -m\n\
-  -s, --shell=SHELL            run SHELL if /etc/shells allows it\n\
+  -, -l, --login                   make the shell a login shell\n\
+  -c, --commmand=COMMAND           pass a single COMMAND to the shell with -c\n\
+                                   and start a new session for it\n\
+  -C, --session-command=COMMAND    pass a single COMMAND to the shell with -c\n\
+                                   and do not create a new session\n\
+  -f, --fast                       pass -f to the shell (for csh or tcsh)\n\
+  -m, --preserve-environment       do not reset environment variables\n\
+  -p                               same as -m\n\
+  -s, --shell=SHELL                run SHELL if /etc/shells allows it\n\
 "), stdout);
       fputs (HELP_OPTION_DESCRIPTION, stdout);
       fputs (VERSION_OPTION_DESCRIPTION, stdout);
@@ -785,6 +807,7 @@ main (int argc, char **argv)
   int optc;
   const char *new_user = DEFAULT_USER;
   char *command = NULL;
+  int request_same_session = 0;
   char *shell = NULL;
   struct passwd *pw;
   struct passwd pw_copy;
@@ -802,12 +825,19 @@ main (int argc, char **argv)
   simulate_login = false;
   change_environment = true;
 
-  while ((optc = getopt_long (argc, argv, "c:flmps:", longopts, NULL)) != -1)
+  while ((optc = getopt_long (argc, argv, "c:C:flmps:", longopts, NULL)) != -1)
     {
       switch (optc)
 	{
 	case 'c':
 	  command = optarg;
+	  if (NULL != getenv ("SU_C_SAME_SESSION"))
+	    request_same_session = 1;
+	  break;
+
+	case 'C':
+	  command = optarg;
+	  request_same_session = 1;
 	  break;
 
 	case 'f':
@@ -880,6 +910,9 @@ main (int argc, char **argv)
     }
 #endif
 
+  if (request_same_session || !command || !pw->pw_uid)
+    same_session = 1;
+
   if (!shell && !change_environment)
     shell = getenv ("SHELL");
   if (shell && getuid () != 0 && restricted_shell (pw->pw_shell))
@@ -901,6 +934,8 @@ main (int argc, char **argv)
 #endif
 
   change_identity (pw);
+  if (!same_session)
+    setsid ();
 
   /* Set environment after pam_open_session, which may put KRB5CCNAME
      into the pam_env, etc.  */
Index: doc/coreutils.texi
===================================================================
--- doc/coreutils.texi.orig	2012-03-27 02:58:32.967325861 +0200
+++ doc/coreutils.texi	2012-03-27 03:10:50.949469314 +0200
@@ -13723,7 +13723,14 @@ The program accepts the following option
 @opindex -c
 @opindex --command
 Pass @var{command}, a single command line to run, to the shell with
-a @option{-c} option instead of starting an interactive shell.
+a @option{-c} option instead of starting an interactive shell. The shell
+is started in its own session unless @env{SU_C_SAME_SESSION} is set.
+
+@item -C @var{command}
+@itemx --session-command=@var{command}
+@opindex -C
+@opindex --session-command
+Like @option{-c} but do not start a new session for the command.
 
 @item -f
 @itemx --fast
