delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2010/10/18/16:18:56

X-Recipient: archive-cygwin AT delorie DOT com
X-Spam-Check-By: sourceware.org
Date: Mon, 18 Oct 2010 16:18:06 -0400
From: Christopher Faylor <cgf-use-the-mailinglist-please AT cygwin DOT com>
To: cygwin AT cygwin DOT com
Subject: Re: Sending signals to a subprocess
Message-ID: <20101018201805.GA26254@ednor.casa.cgf.cx>
Reply-To: cygwin AT cygwin DOT com
Mail-Followup-To: cygwin AT cygwin DOT com
References: <4CB9DE15 DOT 8010308 AT cornell DOT edu> <4CB9E9C0 DOT 3000509 AT cornell DOT edu> <20101018183438 DOT GA25878 AT ednor DOT casa DOT cgf DOT cx> <4CBCA2A5 DOT 4010601 AT cornell DOT edu>
MIME-Version: 1.0
In-Reply-To: <4CBCA2A5.4010601@cornell.edu>
User-Agent: Mutt/1.5.20 (2009-06-14)
Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm
List-Id: <cygwin.cygwin.com>
List-Unsubscribe: <mailto:cygwin-unsubscribe-archive-cygwin=delorie DOT com AT cygwin DOT com>
List-Subscribe: <mailto:cygwin-subscribe AT cygwin DOT com>
List-Archive: <http://sourceware.org/ml/cygwin/>
List-Post: <mailto:cygwin AT cygwin DOT com>
List-Help: <mailto:cygwin-help AT cygwin DOT com>, <http://sourceware.org/ml/#faqs>
Sender: cygwin-owner AT cygwin DOT com
Mail-Followup-To: cygwin AT cygwin DOT com
Delivered-To: mailing list cygwin AT cygwin DOT com

On Mon, Oct 18, 2010 at 03:40:21PM -0400, Ken Brown wrote:
>On 10/18/2010 2:34 PM, Christopher Faylor wrote:
>> On Sat, Oct 16, 2010 at 02:06:56PM -0400, Ken Brown wrote:
>>> On 10/16/2010 1:17 PM, Ken Brown wrote:
>>>> I could use some help fixing a longstanding bug in the Cygwin build of
>>>> emacs, in which emacs is unable to send signals to subprocesses.  A
>>>> symptom from the user's point of view is that one cannot interrupt a
>>>> process in shell mode by typing C-c C-c.  I've found a workaround that
>>>> handles that case (SIGINT), as well as SIGQUIT and SIGTSTP.  But as long
>>>> as I'm fixing this, I'd like to do it right and figure out how to handle
>>>> all signals.
>>>>
>>>> This boils down to finding the right process group ID to pass to 'kill'.
>>>> On systems that have TIOCGPGRP, emacs uses the following code (in
>>>> src/process.c) to get this ID:
>>>>
>>>> /* Return the foreground process group for the tty/pty that
>>>>       the process P uses.  */
>>>> static int
>>>> emacs_get_tty_pgrp (p)
>>>>         struct Lisp_Process *p;
>>>> {
>>>>      int gid = -1;
>>>>
>>>> #ifdef TIOCGPGRP
>>>>      if (ioctl (p->infd, TIOCGPGRP,&gid) == -1&&   ! NILP (p->tty_name))
>>>>        {
>>>>          int fd;
>>>>          /* Some OS:es (Solaris 8/9) does not allow TIOCGPGRP from the
>>>> 	 master side.  Try the slave side.  */
>>>>          fd = emacs_open (SDATA (p->tty_name), O_RDONLY, 0);
>>>>
>>>>          if (fd != -1)
>>>> 	{
>>>> 	  ioctl (fd, TIOCGPGRP,&gid);
>>>> 	  emacs_close (fd);
>>>> 	}
>>>>        }
>>>> #endif /* defined (TIOCGPGRP ) */
>>>>
>>>>      return gid;
>>>> }
>>>>
>>>> What's the right way to do this in Cygwin?
>>>
>>> I guess it's clear from the context, but I should have said that the
>>> problem only arises when emacs has to communicate with the subprocess
>>> through a tty that is not the controlling tty of emacs.  So tcgetpgrp()
>>> doesn't work.
>>
>> I am a little confused as to the difference between tcgetpgrp and
>> TIOCGPGRP given this man page description from "man 4 tty_ioctl" on
>> linux:
>>
>>         TIOCGPGRP pid_t *argp
>>                When successful, equivalent to *argp = tcgetpgrp(fd).
>>                Get the process group ID of the foreground process group on this terminal.
>>
>>         TIOCSPGRP const pid_t *argp
>>                Equivalent to tcsetpgrp(fd, *argp).
>>                Set the foreground process group ID of this terminal.
>>
>> Do you have a simple test case which demonstrates the difference between
>> the calls?  It seems odd that TIOCGPGRP would allow more access to a tty
>> than tcgetpgrp.
>
>The difference is that, according to POSIX, tcgetpgrp is required to 
>fail unless fd references the controlling terminal of the calling 
>process.  Ironically, Cygwin's tcgetpgrp used to succeed in this 
>situation until Corinna fixed it a year ago:
>
>   http://www.cygwin.com/ml/cygwin-patches/2009-q4/msg00045.html

Yes, I got that but TIOCGPGRP seems to have that same limitation on
Linux.  That's why I quoted the above man page.  A simple test case
(tm) seems to bear out the fact that the two are the same.

If you compile/link the below on linux and provide, e.g., /dev/tty0 as
an argument, then the command fails, even when run as root.  If you give
it no argument or give it the fd of the current controlling tty then
both tcgetpgrp and TIOCGPGRP both succeed.

cgf

#include <termios.h>
#include <sys/fcntl.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <stdlib.h>
int
main (int argc, char **argv)
{
  int res;
  pid_t pid;
  const char tty[100];
  int fd;
  if (argc == 1)
    {
      int fds;
      res = openpty (&fd, &fds, tty, NULL, NULL);
      if (fd < 0)
	{
	  fprintf (stderr, "openpty failed: %s\n", strerror (errno));
	  exit (1);
	}
    }
  else
    {
      fd = open (argv[1], O_RDONLY);
      if (fd < 0)
	{
	  fprintf (stderr, "open failed: %s\n", strerror (errno));
	  exit (1);
	}
    }
  printf ("%d = tcgetpgrp(%d)", res = tcgetpgrp (fd), fd);
  if (res < 0)
    printf (" - %s", strerror (errno));
  puts ("");
  printf ("%d = ioctl(fd, TIOCGPGRP, &pid)", res = ioctl(fd, TIOCGPGRP, &pid));
  if (res < 0)
    printf (" - %s", strerror (errno));
  else 
    printf (", pid = %d", pid);
  puts ("");
  exit (0);
}

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019