d66c4db
--- coreutils-6.7/src/su.c.setsid	2007-01-09 17:26:26.000000000 +0000
d66c4db
+++ coreutils-6.7/src/su.c	2007-01-09 17:26:57.000000000 +0000
d66c4db
@@ -176,9 +176,13 @@
9f2386c
 /* If true, change some environment vars to indicate the user su'd to.  */
9f2386c
 static bool change_environment;
9f2386c
 
9f2386c
+/* If true, then don't call setsid() with a command. */
9f2386c
+int same_session = 0;
9f2386c
+
9f2386c
 static struct option const longopts[] =
9f2386c
 {
9f2386c
   {"command", required_argument, NULL, 'c'},
9f2386c
+  {"session-command", required_argument, NULL, 'C'},
9f2386c
   {"fast", no_argument, NULL, 'f'},
9f2386c
   {"login", no_argument, NULL, 'l'},
9f2386c
   {"preserve-environment", no_argument, NULL, 'p'},
d66c4db
@@ -478,6 +482,8 @@
eb20fc6
   if (child == 0) {  /* child shell */
eb20fc6
   change_identity (pw);
eb20fc6
   pam_end(pamh, 0);
9f2386c
+  if (!same_session)
eb20fc6
+    setsid ();
eb20fc6
 #endif
eb20fc6
 
eb20fc6
   if (simulate_login)
d66c4db
@@ -532,13 +538,27 @@
eb20fc6
     sigemptyset(&action.sa_mask);
eb20fc6
     action.sa_flags = 0;
eb20fc6
     sigemptyset(&ourset);
eb20fc6
-    if (sigaddset(&ourset, SIGTERM)
eb20fc6
-        || sigaddset(&ourset, SIGALRM)
eb20fc6
-        || sigaction(SIGTERM, &action, NULL)
eb20fc6
-        || sigprocmask(SIG_UNBLOCK, &ourset, NULL)) {
9f2386c
+    if (!same_session)
eb20fc6
+      {
eb20fc6
+	if (sigaddset(&ourset, SIGINT) || sigaddset(&ourset, SIGQUIT))
eb20fc6
+	  {
eb20fc6
+	    fprintf(stderr, "%s: signal masking malfunction\n", PROGRAM_NAME);
eb20fc6
+	    caught = 1;
eb20fc6
+	  }
eb20fc6
+      }
eb20fc6
+    if (!caught && (sigaddset(&ourset, SIGTERM)
eb20fc6
+		    || sigaddset(&ourset, SIGALRM)
eb20fc6
+		    || sigaction(SIGTERM, &action, NULL)
eb20fc6
+		    || sigprocmask(SIG_UNBLOCK, &ourset, NULL))) {
eb20fc6
       fprintf(stderr, "%s: signal masking malfunction\n", PROGRAM_NAME);
eb20fc6
       caught = 1;
eb20fc6
     }
9f2386c
+    if (!caught && !same_session && (sigaction(SIGINT, &action, NULL)
9f2386c
+				     || sigaction(SIGQUIT, &action, NULL)))
eb20fc6
+      {
eb20fc6
+	fprintf(stderr, "%s: signal masking malfunction\n", PROGRAM_NAME);
eb20fc6
+	caught = 1;
eb20fc6
+      }
eb20fc6
   }
eb20fc6
   if (!caught) {
eb20fc6
     do {
d66c4db
@@ -609,6 +629,8 @@
9f2386c
 \n\
9f2386c
   -, -l, --login               make the shell a login shell\n\
d66c4db
   -c, --command=COMMAND        pass a single COMMAND to the shell with -c\n\
9f2386c
+  --session-command=COMMAND    pass a single COMMAND to the shell with -c\n\
9f2386c
+                               and do not create a new session\n\
9f2386c
   -f, --fast                   pass -f to the shell (for csh or tcsh)\n\
9f2386c
   -m, --preserve-environment   do not reset environment variables\n\
9f2386c
   -p                           same as -m\n\
d66c4db
@@ -631,6 +653,7 @@
9f2386c
   int optc;
9f2386c
   const char *new_user = DEFAULT_USER;
9f2386c
   char *command = NULL;
9f2386c
+  int request_same_session = 0;
9f2386c
   char *shell = NULL;
9f2386c
   struct passwd *pw;
9f2386c
   struct passwd pw_copy;
d66c4db
@@ -656,6 +679,11 @@
9f2386c
 	  command = optarg;
9f2386c
 	  break;
9f2386c
 
9f2386c
+	case 'C':
9f2386c
+	  command = optarg;
9f2386c
+	  request_same_session = 1;
9f2386c
+	  break;
9f2386c
+
9f2386c
 	case 'f':
9f2386c
 	  fast_startup = true;
9f2386c
 	  break;
d66c4db
@@ -725,6 +753,9 @@
9f2386c
     }
9f2386c
 #endif
9f2386c
 
9f2386c
+  if (request_same_session || !command || !pw->pw_uid)
9f2386c
+    same_session = 1;
9f2386c
+
9f2386c
   if (!shell && !change_environment)
9f2386c
     shell = getenv ("SHELL");
9f2386c
   if (shell && getuid () != 0 && restricted_shell (pw->pw_shell))