Mercurial > hg > xemacs-beta
diff src/process-unix.c @ 371:cc15677e0335 r21-2b1
Import from CVS: tag r21-2b1
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:03:08 +0200 |
parents | 1d62742628b6 |
children | 6240c7796c7a |
line wrap: on
line diff
--- a/src/process-unix.c Mon Aug 13 11:01:58 2007 +0200 +++ b/src/process-unix.c Mon Aug 13 11:03:08 2007 +0200 @@ -735,7 +735,7 @@ /* Nothing below here GCs so our string pointers shouldn't move. */ new_argv = alloca_array (char *, nargv + 2); - GET_C_STRING_FILENAME_DATA_ALLOCA (program, new_argv[0]); + new_argv[0] = (char *) XSTRING_DATA (program); for (i = 0; i < nargv; i++) { Lisp_Object tem = argv[i]; @@ -743,7 +743,7 @@ new_argv[i + 1] = (char *) XSTRING_DATA (tem); } new_argv[i + 1] = 0; - GET_C_STRING_FILENAME_DATA_ALLOCA (cur_dir, current_dir); + current_dir = (char *) XSTRING_DATA (cur_dir); #ifdef HAVE_PTYS if (!NILP (Vprocess_connection_type)) @@ -817,15 +817,17 @@ int xforkin = forkin; int xforkout = forkout; + if (!pty_flag) + EMACS_SEPARATE_PROCESS_GROUP (); +#ifdef HAVE_PTYS + else + { /* Disconnect the current controlling terminal, pursuant to making the pty be the controlling terminal of the process. Also put us in our own process group. */ disconnect_controlling_terminal (); -#ifdef HAVE_PTYS - if (pty_flag) - { /* Open the pty connection and make the pty's terminal our controlling terminal. @@ -918,14 +920,12 @@ EMACS_SET_TTY_PROCESS_GROUP (xforkin, &piddly); } +# ifdef AIX /* On AIX, we've disabled SIGHUP above once we start a child on a pty. Now reenable it in the child, so it - will die when we want it to. - JV: This needs to be done ALWAYS as we might have inherited - a SIG_IGN handling from our parent (nohup) and we are in new - process group. - */ + will die when we want it to. */ signal (SIGHUP, SIG_DFL); +# endif /* AIX */ } #endif /* HAVE_PTYS */ @@ -952,9 +952,7 @@ if (pid < 0) { - int save_errno = errno; close_descriptor_pair (forkin, forkout); - errno = save_errno; report_file_error ("Doing fork", Qnil); } @@ -1153,14 +1151,6 @@ volatile Lisp_Object vol_proc = proc; struct Lisp_Process *volatile p = XPROCESS (proc); - /* #### JV: layering violation? - - This function knows too much about the relation between the encodingstream - (DATA_OUTSTREAM) and te actual output stream p->output_stream. - - If encoding streams properly forwarded all calls, we could simply - use DATA_OUTSTREAM everywhere. */ - if (!SETJMP (send_process_frame)) { /* use a reasonable-sized buffer (somewhere around the size of the @@ -1196,9 +1186,6 @@ that may allow the program to finish doing output and read more. */ Faccept_process_output (Qnil, make_int (1), Qnil); - /* It could have *really* finished, deleting the process */ - if (NILP(p->pipe_outstream)) - return; old_sigpipe = (SIGTYPE (*) (int)) signal (SIGPIPE, send_process_trap); Lstream_flush (XLSTREAM (p->pipe_outstream)); @@ -1209,10 +1196,6 @@ else { /* We got here from a longjmp() from the SIGPIPE handler */ signal (SIGPIPE, old_sigpipe); - /* Close the file lstream so we don't attempt to write to it further */ - /* #### There is controversy over whether this might cause fd leakage */ - /* my tests say no. -slb */ - XLSTREAM (p->pipe_outstream)->flags &= ~LSTREAM_FL_IS_OPEN; p->status_symbol = Qexit; p->exit_code = 256; /* #### SIGPIPE ??? */ p->core_dumped = 0; @@ -1287,17 +1270,7 @@ return usid; } -/* If the subtty field of the process data is not filled in, do so now. */ -static void -try_to_initialize_subtty (struct unix_process_data *upd) -{ - if (upd->pty_flag - && (upd->subtty == -1 || ! isatty (upd->subtty)) - && STRINGP (upd->tty_name)) - upd->subtty = open ((char *) XSTRING_DATA (upd->tty_name), O_RDWR, 0); -} - -/* Send signal number SIGNO to PROCESS. +/* send a signal number SIGNO to PROCESS. CURRENT_GROUP means send to the process group that currently owns the terminal being used to communicate with PROCESS. This is used for various commands in shell mode. @@ -1306,18 +1279,70 @@ If we can, we try to signal PROCESS by sending control characters down the pty. This allows us to signal inferiors who have changed - their uid, for which killpg would return an EPERM error, - or processes running on other machines via remote login. + their uid, for which killpg would return an EPERM error. - The method signals an error if the given SIGNO is not valid. */ + The method signals an error if the given SIGNO is not valid +*/ static void unix_kill_child_process (Lisp_Object proc, int signo, int current_group, int nomsg) { - pid_t pgid = -1; + int gid; + int no_pgrp = 0; + int kill_retval; struct Lisp_Process *p = XPROCESS (proc); - struct unix_process_data *d = UNIX_DATA (p); + + if (!UNIX_DATA(p)->pty_flag) + current_group = 0; + + /* If we are using pgrps, get a pgrp number and make it negative. */ + if (current_group) + { +#ifdef SIGNALS_VIA_CHARACTERS + /* If possible, send signals to the entire pgrp + by sending an input character to it. */ + { + char sigchar = process_signal_char(UNIX_DATA(p)->subtty, signo); + if (sigchar) { + send_process (proc, Qnil, (Bufbyte *) &sigchar, 0, 1); + return; + } + } +#endif /* ! defined (SIGNALS_VIA_CHARACTERS) */ + +#ifdef TIOCGPGRP + /* Get the pgrp using the tty itself, if we have that. + Otherwise, use the pty to get the pgrp. + On pfa systems, saka@pfu.fujitsu.co.JP writes: + "TIOCGPGRP symbol defined in sys/ioctl.h at E50. + But, TIOCGPGRP does not work on E50 ;-P works fine on E60" + His patch indicates that if TIOCGPGRP returns an error, then + we should just assume that p->pid is also the process group id. */ + { + int err; + + err = ioctl ( (UNIX_DATA(p)->subtty != -1 + ? UNIX_DATA(p)->subtty + : UNIX_DATA(p)->infd), TIOCGPGRP, &gid); + +#ifdef pfa + if (err == -1) + gid = - XINT (p->pid); +#endif /* ! defined (pfa) */ + } + if (gid == -1) + no_pgrp = 1; + else + gid = - gid; +#else /* ! defined (TIOCGPGRP ) */ + /* Can't select pgrps on this system, so we know that + the child itself heads the pgrp. */ + gid = - XINT (p->pid); +#endif /* ! defined (TIOCGPGRP ) */ + } + else + gid = - XINT (p->pid); switch (signo) { @@ -1334,100 +1359,38 @@ case SIGINT: case SIGQUIT: case SIGKILL: - flush_pending_output (d->infd); + flush_pending_output (UNIX_DATA(p)->infd); break; } - if (! d->pty_flag) - current_group = 0; - - /* If current_group is true, we want to send a signal to the - foreground process group of the terminal our child process is - running on. You would think that would be easy. - - The BSD people invented the TIOCPGRP ioctl to get the foreground - process group of a tty. That, combined with killpg, gives us - what we want. - - However, the POSIX standards people, in their infinite wisdom, - have seen fit to only allow this for processes which have the - terminal as controlling terminal, which doesn't apply to us. - - Sooo..., we have to do something non-standard. The ioctls - TIOCSIGNAL, TIOCSIG, and TIOCSIGSEND send the signal directly on - many systems. POSIX tcgetpgrp(), since it is *documented* as not - doing what we want, is actually less likely to work than the BSD - ioctl TIOCGPGRP it is supposed to obsolete. Sometimes we have to - use TIOCGPGRP on the master end, sometimes the slave end - (probably an AIX bug). So we better get a fd for the slave if we - haven't got it yet. - - Anal operating systems like SGI Irix and Compaq Tru64 adhere - strictly to the letter of the law, so our hack doesn't work. - The following fragment from an Irix header file is suggestive: - - #ifdef __notdef__ - // this is not currently supported - #define TIOCSIGNAL (tIOC|31) // pty: send signal to slave - #endif - - On those systems where none of our tricks work, we just fall back - to the non-current_group behavior and kill the process group of - the child. - */ - if (current_group) + /* If we don't have process groups, send the signal to the immediate + subprocess. That isn't really right, but it's better than any + obvious alternative. */ + if (no_pgrp) { - try_to_initialize_subtty (d); - -#ifdef SIGNALS_VIA_CHARACTERS - /* If possible, send signals to the entire pgrp - by sending an input character to it. */ + kill_retval = kill (XINT (p->pid), signo) ? errno : 0; + } + else { - char sigchar = process_signal_char (d->subtty, signo); - if (sigchar) - { - send_process (proc, Qnil, (Bufbyte *) &sigchar, 0, 1); - return; - } - } -#endif /* SIGNALS_VIA_CHARACTERS */ - -#ifdef TIOCGPGRP - if (pgid == -1) - ioctl (d->infd, TIOCGPGRP, &pgid); /* BSD */ - if (pgid == -1 && d->subtty != -1) - ioctl (d->subtty, TIOCGPGRP, &pgid); /* Only this works on AIX! */ -#endif /* TIOCGPGRP */ - - if (pgid == -1) + /* gid may be a pid, or minus a pgrp's number */ +#if defined (TIOCSIGNAL) || defined (TIOCSIGSEND) + if (current_group) { - /* Many systems provide an ioctl to send a signal directly */ -#ifdef TIOCSIGNAL /* Solaris, HP-UX */ - if (ioctl (d->infd, TIOCSIGNAL, signo) != -1) - return; -#endif /* TIOCSIGNAL */ - -#ifdef TIOCSIG /* BSD */ - if (ioctl (d->infd, TIOCSIG, signo) != -1) - return; -#endif /* TIOCSIG */ +#ifdef TIOCSIGNAL + kill_retval = ioctl (UNIX_DATA(p)->infd, TIOCSIGNAL, signo); +#else /* ! defined (TIOCSIGNAL) */ + kill_retval = ioctl (UNIX_DATA(p)->infd, TIOCSIGSEND, signo); +#endif /* ! defined (TIOCSIGNAL) */ } - } /* current_group */ + else + kill_retval = kill (- XINT (p->pid), signo) ? errno : 0; +#else /* ! (defined (TIOCSIGNAL) || defined (TIOCSIGSEND)) */ + kill_retval = EMACS_KILLPG (-gid, signo) ? errno : 0; +#endif /* ! (defined (TIOCSIGNAL) || defined (TIOCSIGSEND)) */ + } - if (pgid == -1) - /* Either current_group is 0, or we failed to get the foreground - process group using the trickery above. So we fall back to - sending the signal to the process group of our child process. - Since this is often a shell that ignores signals like SIGINT, - the shell's subprocess is killed, which is the desired effect. - The process group of p->pid is always p->pid, since it was - created as a process group leader. */ - pgid = XINT (p->pid); - - /* Finally send the signal. */ - if (EMACS_KILLPG (pgid, signo) == -1) - error ("kill (%ld, %ld) failed: %s", - (long) pgid, (long) signo, strerror (errno)); + if (kill_retval < 0 && errno == EINVAL) + error ("Signal number %d is invalid for this system", signo); } /*