comparison lib-src/emacsclient.c @ 53229:33c3c7c16e13

lib-src/emacsclient.c: Implemented --here option (open a new Emacs tty). Needs more work. (here): New variable. (decode_options): Use it. (ec_get_tty, ec_set_tty, init_tty, window_change, hang_up_signal): New functions. (window_change_signal, init_signals, reset_tty, init_pty, copy_from_to): Ditto. (pty_conversation): Ditto. (main): Use them. (master, pty_name, old_tty, tty, old_tty_valid, tty_erase_char): New variables. (flow_control, meta_key, _sobuf, in_conversation, quit_conversation): Ditto. lisp/server.el (server-process-filter): Added support for opening a new terminal frame. dispextern.h (get_frame_size): Renamed to get_tty_size, added tty_output parameter. dispnew.c (Fredraw_frame): fflush the current terminal instead of stdout. (direct_output_for_insert, direct_output_forward_char, update_frame_1): Ditto. (Fding, bitch_at_user): Ditto. (update_frame_1): Count pending output for current terminal instead of stdout. (window_change_signal): Resize all terminals. (change_frame_size): Don't resize all terminals to the same size. frame.c (Vterminal_frame): Removed. (syms_of_frame): Removed declaration of Vterminal_frame. (make_terminal_frame): Set the top frame of the terminal to the new frame. (Fmake_terminal_frame): Get a new frame size from get_tty_size, don't copy it. (do_switch_frame): Handle terminal frame visibility. (next_frame, prev_frame): Skip over frames on different terminals. frame.h (Vterminal_frame): Removed. keyboard.c (input_fd): Removed. (read_avail_input): Removed first argument from read_socket_hook. Try to read from each available tty, until one succeeds. (Fsuspend_emacs): Don't suspend if there are multiple terminals. lisp.h (get_frame_size): Removed superflous declaration. xterm.c (Xtread_socket): Removed first parameter. macterm.h (XTread_socket): Ditto. w32inevt.c (w32_console_read_socket): Ditto. w32term.c (w32_read_socket): Ditto. sysdep.c (input_fd): Removed. (change_input_fd): Removed. (discard_tty_input): Discard pending input on _all_ input descriptors. (stuff_char, tabs_safe_p): Use current terminal instead of input_fd. (init_baud_rate, request_sigio, unrequest_sigio): Ditto. (init_sys_modes, reset_sys_modes): Ditto. (narrow_foreground_group, widen_foreground_group): Use stdin. (init_sys_modes, reset_sys_modes): otty parameter renamed to tty_out. (get_frame_size): Renamed to get_tty_size, added tty_out parameter. term.c (read_socket_hook): Removed first parameter. (clear_end_of_line): Use updating_frame, if possible. (write_glyphs, insert_glyphs, ins_del_lines): Ditto. (term_init): Renamed get_frame_size to get_tty_size. termchar.h (struct tty_output): New entries: top_frame, previous_terminal_frame. termhooks.h (read_socket_hook): Removed first parameter. window.c (init_window_once): Removed reference to Vterminal_frame. xdisp.c (previous_terminal_frame): Moved to struct tty_output. (redisplay_internal): Updated to use previous_terminal_frame in tty_output. Allow for simultaneous refresh of multiple ttys. git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-5
author Karoly Lorentey <lorentey@elte.hu>
date Fri, 26 Dec 2003 04:24:54 +0000
parents 5c74e66d6c36
children 22aaf1e5fbe6
comparison
equal deleted inserted replaced
53228:c5b253fd2504 53229:33c3c7c16e13
39 # include "vms-pwd.h" 39 # include "vms-pwd.h"
40 #else 40 #else
41 # include <pwd.h> 41 # include <pwd.h>
42 #endif /* not VMS */ 42 #endif /* not VMS */
43 43
44
45 /****************************************/
46
47 #include <errno.h>
48 #include <signal.h>
49
50 #ifndef INCLUDED_FCNTL
51 #define INCLUDED_FCNTL
52 #include <fcntl.h>
53 #endif
54
55 #ifdef HAVE_TERMIOS
56 #ifndef NO_TERMIO
57 #include <termio.h>
58 #endif
59 #include <termios.h>
60 #endif /* not HAVE_TERMIOS */
61
62 #ifdef __GNU_LIBRARY__
63 #include <sys/ioctl.h>
64 #include <termios.h>
65 #endif
66
67 #if (defined (POSIX) || defined (NEED_UNISTD_H)) && defined (HAVE_UNISTD_H)
68 #include <unistd.h>
69 #endif
70
71
72
73 /* Try to establish the correct character to disable terminal functions
74 in a system-independent manner. Note that USG (at least) define
75 _POSIX_VDISABLE as 0! */
76
77 #ifdef _POSIX_VDISABLE
78 #define CDISABLE _POSIX_VDISABLE
79 #else /* not _POSIX_VDISABLE */
80 #ifdef CDEL
81 #undef CDISABLE
82 #define CDISABLE CDEL
83 #else /* not CDEL */
84 #define CDISABLE 255
85 #endif /* not CDEL */
86 #endif /* not _POSIX_VDISABLE */
87
88
89
90 /****************************************/
91
44 char *getenv (), *getwd (); 92 char *getenv (), *getwd ();
45 char *getcwd (); 93 char *getcwd ();
46 94
47 /* This is defined with -D from the compilation command, 95 /* This is defined with -D from the compilation command,
48 which extracts it from ../lisp/version.el. */ 96 which extracts it from ../lisp/version.el. */
60 /* Nonzero means args are expressions to be evaluated. --eval. */ 108 /* Nonzero means args are expressions to be evaluated. --eval. */
61 int eval = 0; 109 int eval = 0;
62 110
63 /* The display on which Emacs should work. --display. */ 111 /* The display on which Emacs should work. --display. */
64 char *display = NULL; 112 char *display = NULL;
113
114 /* Nonzero means open a new Emacs frame on the current terminal. */
115 int here = 0;
65 116
66 /* If non-NULL, the name of an editor to fallback to if the server 117 /* If non-NULL, the name of an editor to fallback to if the server
67 is not running. --alternate-editor. */ 118 is not running. --alternate-editor. */
68 const char * alternate_editor = NULL; 119 const char * alternate_editor = NULL;
69 120
76 { 127 {
77 { "no-wait", no_argument, NULL, 'n' }, 128 { "no-wait", no_argument, NULL, 'n' },
78 { "eval", no_argument, NULL, 'e' }, 129 { "eval", no_argument, NULL, 'e' },
79 { "help", no_argument, NULL, 'H' }, 130 { "help", no_argument, NULL, 'H' },
80 { "version", no_argument, NULL, 'V' }, 131 { "version", no_argument, NULL, 'V' },
132 { "here", no_argument, NULL, 'h' },
81 { "alternate-editor", required_argument, NULL, 'a' }, 133 { "alternate-editor", required_argument, NULL, 'a' },
82 { "socket-name", required_argument, NULL, 's' }, 134 { "socket-name", required_argument, NULL, 's' },
83 { "display", required_argument, NULL, 'd' }, 135 { "display", required_argument, NULL, 'd' },
84 { 0, 0, 0, 0 } 136 { 0, 0, 0, 0 }
85 }; 137 };
93 char **argv; 145 char **argv;
94 { 146 {
95 while (1) 147 while (1)
96 { 148 {
97 int opt = getopt_long (argc, argv, 149 int opt = getopt_long (argc, argv,
98 "VHnea:s:d:", longopts, 0); 150 "VHnea:s:d:h", longopts, 0);
99 151
100 if (opt == EOF) 152 if (opt == EOF)
101 break; 153 break;
102 154
103 alternate_editor = getenv ("ALTERNATE_EDITOR"); 155 alternate_editor = getenv ("ALTERNATE_EDITOR");
132 case 'V': 184 case 'V':
133 printf ("emacsclient %s\n", VERSION); 185 printf ("emacsclient %s\n", VERSION);
134 exit (0); 186 exit (0);
135 break; 187 break;
136 188
189 case 'h':
190 here = 1;
191 break;
192
137 case 'H': 193 case 'H':
138 print_help_and_exit (); 194 print_help_and_exit ();
139 break; 195 break;
140 196
141 default: 197 default:
142 fprintf (stderr, "Try `%s --help' for more information\n", progname); 198 fprintf (stderr, "Try `%s --help' for more information\n", progname);
143 exit (1); 199 exit (1);
144 break; 200 break;
145 } 201 }
146 } 202 }
203
204 if (here) {
205 nowait = 0;
206 display = 0;
207 }
208
147 } 209 }
148 210
149 void 211 void
150 print_help_and_exit () 212 print_help_and_exit ()
151 { 213 {
155 Every FILE can be either just a FILENAME or [+LINE[:COLUMN]] FILENAME.\n\ 217 Every FILE can be either just a FILENAME or [+LINE[:COLUMN]] FILENAME.\n\
156 \n\ 218 \n\
157 The following OPTIONS are accepted:\n\ 219 The following OPTIONS are accepted:\n\
158 -V, --version Just print a version info and return\n\ 220 -V, --version Just print a version info and return\n\
159 -H, --help Print this usage information message\n\ 221 -H, --help Print this usage information message\n\
222 -h, --here Open a new Emacs frame on the current terminal\n\
160 -n, --no-wait Don't wait for the server to return\n\ 223 -n, --no-wait Don't wait for the server to return\n\
161 -e, --eval Evaluate the FILE arguments as ELisp expressions\n\ 224 -e, --eval Evaluate the FILE arguments as ELisp expressions\n\
162 -d, --display=DISPLAY Visit the file in the given display\n\ 225 -d, --display=DISPLAY Visit the file in the given display\n\
163 -s, --socket-name=FILENAME\n\ 226 -s, --socket-name=FILENAME\n\
164 Set the filename of the UNIX socket for communication\n\ 227 Set the filename of the UNIX socket for communication\n\
245 { 308 {
246 exit (1); 309 exit (1);
247 } 310 }
248 } 311 }
249 312
313
314 #ifdef HAVE_TERMIOS
315
316 /* Adapted from emacs_get_tty() in sysdep.c. */
317 int
318 ec_get_tty (int fd, struct termios *settings)
319 {
320 bzero (settings, sizeof (struct termios));
321 if (tcgetattr (fd, settings) < 0)
322 return -1;
323 return 0;
324 }
325
326 /* Adapted from emacs_set_tty() in sysdep.c. */
327 int
328 ec_set_tty (int fd, struct termios *settings, int flushp)
329 {
330 /* Set the primary parameters - baud rate, character size, etcetera. */
331
332 int i;
333 /* We have those nifty POSIX tcmumbleattr functions.
334 William J. Smith <wjs@wiis.wang.com> writes:
335 "POSIX 1003.1 defines tcsetattr to return success if it was
336 able to perform any of the requested actions, even if some
337 of the requested actions could not be performed.
338 We must read settings back to ensure tty setup properly.
339 AIX requires this to keep tty from hanging occasionally." */
340 /* This make sure that we don't loop indefinitely in here. */
341 for (i = 0 ; i < 10 ; i++)
342 if (tcsetattr (fd, flushp ? TCSAFLUSH : TCSADRAIN, settings) < 0)
343 {
344 if (errno == EINTR)
345 continue;
346 else
347 return -1;
348 }
349 else
350 {
351 struct termios new;
352
353 bzero (&new, sizeof (new));
354 /* Get the current settings, and see if they're what we asked for. */
355 tcgetattr (fd, &new);
356 /* We cannot use memcmp on the whole structure here because under
357 * aix386 the termios structure has some reserved field that may
358 * not be filled in.
359 */
360 if ( new.c_iflag == settings->c_iflag
361 && new.c_oflag == settings->c_oflag
362 && new.c_cflag == settings->c_cflag
363 && new.c_lflag == settings->c_lflag
364 && memcmp (new.c_cc, settings->c_cc, NCCS) == 0)
365 break;
366 else
367 continue;
368 }
369 return 0;
370 }
371
372 int master;
373 char *pty_name;
374
375 struct termios old_tty;
376 struct termios tty;
377 int old_tty_valid;
378
379 int tty_erase_char;
380 int flow_control = 0;
381 int meta_key = 0;
382 char _sobuf[BUFSIZ];
383
384 /* Adapted from init_sys_modes() in sysdep.c. */
385 int
386 init_tty ()
387 {
388 if (! isatty (0))
389 {
390 fprintf (stderr, "%s: Input is not a terminal", "init_tty");
391 return 0;
392 }
393
394 ec_get_tty (0, &old_tty);
395 old_tty_valid = 1;
396 tty = old_tty;
397
398 tty_erase_char = old_tty.c_cc[VERASE];
399
400 tty.c_iflag |= (IGNBRK); /* Ignore break condition */
401 tty.c_iflag &= ~ICRNL; /* Disable map of CR to NL on input */
402 #ifdef INLCR
403 tty.c_iflag &= ~INLCR; /* Disable map of NL to CR on input */
404 #endif
405 #ifdef ISTRIP
406 tty.c_iflag &= ~ISTRIP; /* don't strip 8th bit on input */
407 #endif
408 tty.c_lflag &= ~ECHO; /* Disable echo */
409 tty.c_lflag &= ~ICANON; /* Disable erase/kill processing */
410 #ifdef IEXTEN
411 tty.c_lflag &= ~IEXTEN; /* Disable other editing characters. */
412 #endif
413 tty.c_lflag |= ISIG; /* Enable signals */
414 if (flow_control)
415 {
416 tty.c_iflag |= IXON; /* Enable start/stop output control */
417 #ifdef IXANY
418 tty.c_iflag &= ~IXANY;
419 #endif /* IXANY */
420 }
421 else
422 tty.c_iflag &= ~IXON; /* Disable start/stop output control */
423 tty.c_oflag &= ~ONLCR; /* Disable map of NL to CR-NL
424 on output */
425 tty.c_oflag &= ~TAB3; /* Disable tab expansion */
426 #ifdef CS8
427 if (meta_key)
428 {
429 tty.c_cflag |= CS8; /* allow 8th bit on input */
430 tty.c_cflag &= ~PARENB; /* Don't check parity */
431 }
432 #endif
433 tty.c_cc[VINTR] = CDISABLE;
434 tty.c_cc[VQUIT] = CDISABLE;
435 tty.c_cc[VMIN] = 1; /* Input should wait for at least 1 char */
436 tty.c_cc[VTIME] = 0; /* no matter how long that takes. */
437 #ifdef VSWTCH
438 tty.c_cc[VSWTCH] = CDISABLE; /* Turn off shell layering use of C-z */
439 #endif
440
441 #ifdef VSUSP
442 tty.c_cc[VSUSP] = CDISABLE; /* Turn off mips handling of C-z. */
443 #endif /* VSUSP */
444 #ifdef V_DSUSP
445 tty.c_cc[V_DSUSP] = CDISABLE; /* Turn off mips handling of C-y. */
446 #endif /* V_DSUSP */
447 #ifdef VDSUSP /* Some systems have VDSUSP, some have V_DSUSP. */
448 tty.c_cc[VDSUSP] = CDISABLE;
449 #endif /* VDSUSP */
450 #ifdef VLNEXT
451 tty.c_cc[VLNEXT] = CDISABLE;
452 #endif /* VLNEXT */
453 #ifdef VREPRINT
454 tty.c_cc[VREPRINT] = CDISABLE;
455 #endif /* VREPRINT */
456 #ifdef VWERASE
457 tty.c_cc[VWERASE] = CDISABLE;
458 #endif /* VWERASE */
459 #ifdef VDISCARD
460 tty.c_cc[VDISCARD] = CDISABLE;
461 #endif /* VDISCARD */
462
463 if (flow_control)
464 {
465 #ifdef VSTART
466 tty.c_cc[VSTART] = '\021';
467 #endif /* VSTART */
468 #ifdef VSTOP
469 tty.c_cc[VSTOP] = '\023';
470 #endif /* VSTOP */
471 }
472 else
473 {
474 #ifdef VSTART
475 tty.c_cc[VSTART] = CDISABLE;
476 #endif /* VSTART */
477 #ifdef VSTOP
478 tty.c_cc[VSTOP] = CDISABLE;
479 #endif /* VSTOP */
480 }
481
482 #ifdef SET_LINE_DISCIPLINE
483 /* Need to explicitly request TERMIODISC line discipline or
484 Ultrix's termios does not work correctly. */
485 tty.c_line = SET_LINE_DISCIPLINE;
486 #endif
487
488 #ifdef AIX
489 #ifndef IBMR2AIX
490 /* AIX enhanced edit loses NULs, so disable it. */
491 tty.c_line = 0;
492 tty.c_iflag &= ~ASCEDIT;
493 #else
494 tty.c_cc[VSTRT] = 255;
495 tty.c_cc[VSTOP] = 255;
496 tty.c_cc[VSUSP] = 255;
497 tty.c_cc[VDSUSP] = 255;
498 #endif /* IBMR2AIX */
499 if (flow_control)
500 {
501 #ifdef VSTART
502 tty.c_cc[VSTART] = '\021';
503 #endif /* VSTART */
504 #ifdef VSTOP
505 tty.c_cc[VSTOP] = '\023';
506 #endif /* VSTOP */
507 }
508 /* Also, PTY overloads NUL and BREAK.
509 don't ignore break, but don't signal either, so it looks like NUL.
510 This really serves a purpose only if running in an XTERM window
511 or via TELNET or the like, but does no harm elsewhere. */
512 tty.c_iflag &= ~IGNBRK;
513 tty.c_iflag &= ~BRKINT;
514 #endif /* AIX */
515
516 ec_set_tty (0, &tty, 0);
517
518 /* This code added to insure that, if flow-control is not to be used,
519 we have an unlocked terminal at the start. */
520
521 #ifdef TCXONC
522 if (!flow_control) ioctl (0, TCXONC, 1);
523 #endif
524 #ifndef APOLLO
525 #ifdef TIOCSTART
526 if (!flow_control) ioctl (0, TIOCSTART, 0);
527 #endif
528 #endif
529
530 #if defined (HAVE_TERMIOS) || defined (HPUX9)
531 #ifdef TCOON
532 if (!flow_control) tcflow (0, TCOON);
533 #endif
534 #endif
535
536 #ifdef _IOFBF
537 /* This symbol is defined on recent USG systems.
538 Someone says without this call USG won't really buffer the file
539 even with a call to setbuf. */
540 setvbuf (stdout, (char *) _sobuf, _IOFBF, sizeof _sobuf);
541 #else
542 setbuf (stdout, (char *) _sobuf);
543 #endif
544
545 return 1;
546 }
547
548 void
549 window_change ()
550 {
551 int width, height;
552
553 #ifdef TIOCGWINSZ
554 {
555 /* BSD-style. */
556 struct winsize size;
557
558 if (ioctl (0, TIOCGWINSZ, &size) == -1)
559 width = height = 0;
560 else
561 {
562 width = size.ws_col;
563 height = size.ws_row;
564 }
565 }
566 #else
567 #ifdef TIOCGSIZE
568 {
569 /* SunOS - style. */
570 struct ttysize size;
571
572 if (ioctl (0, TIOCGSIZE, &size) == -1)
573 width = height = 0;
574 else
575 {
576 width = size.ts_cols;
577 height = size.ts_lines;
578 }
579 }
580 #endif /* not SunOS-style */
581 #endif /* not BSD-style */
582
583 #ifdef TIOCSWINSZ
584 {
585 /* BSD-style. */
586 struct winsize size;
587 size.ws_row = height;
588 size.ws_col = width;
589
590 ioctl (master, TIOCSWINSZ, &size);
591 }
592 #else
593 #ifdef TIOCSSIZE
594 {
595 /* SunOS - style. */
596 struct ttysize size;
597 size.ts_lines = height;
598 size.ts_cols = width;
599
600 ioctl (master, TIOCGSIZE, &size);
601 }
602 #endif /* not SunOS-style */
603 #endif /* not BSD-style */
604 }
605
606 int in_conversation = 0;
607 int quit_conversation = 0;
608
609 SIGTYPE
610 hang_up_signal (int signalnum)
611 {
612 int old_errno = errno;
613
614 if (! in_conversation)
615 return;
616
617 quit_conversation = 1;
618
619 errno = old_errno;
620 }
621
622 SIGTYPE
623 window_change_signal (int signalnum)
624 {
625 int old_errno = errno;
626
627 if (! in_conversation)
628 goto end;
629
630 window_change();
631
632 end:
633 signal (SIGWINCH, window_change_signal);
634 errno = old_errno;
635 }
636
637 int
638 init_signals ()
639 {
640 /* Set up signal handlers. */
641 signal (SIGWINCH, window_change_signal);
642 signal (SIGHUP, hang_up_signal);
643
644 return 1;
645 }
646
647
648
649 /* Adapted from reset_sys_modes in sysdep.c. */
650 int
651 reset_tty ()
652 {
653 fflush (stdout);
654 #ifdef BSD_SYSTEM
655 #ifndef BSD4_1
656 /* Avoid possible loss of output when changing terminal modes. */
657 fsync (fileno (stdout));
658 #endif
659 #endif
660
661 #ifdef F_SETFL
662 #ifdef O_NDELAY
663 fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~O_NDELAY);
664 #endif
665 #endif /* F_SETFL */
666
667 if (old_tty_valid)
668 while (ec_set_tty (0, &old_tty, 0) < 0 && errno == EINTR)
669 ;
670
671 return 1;
672 }
673
674
675 int
676 init_pty ()
677 {
678 master = getpt ();
679 if (master < 0)
680 return 0;
681
682 if (grantpt (master) < 0 || unlockpt (master) < 0)
683 goto close_master;
684 pty_name = strdup (ptsname (master));
685 if (! pty_name)
686 goto close_master;
687
688 /* Propagate window size. */
689 window_change ();
690
691 return 1;
692
693 close_master:
694 close (master);
695 return 0;
696 }
697
698 int
699 copy_from_to (int in, int out)
700 {
701 static char buf[BUFSIZ];
702 int nread = read (in, &buf, BUFSIZ);
703 if (nread == 0)
704 return 1; /* EOF */
705 else if (nread < 0 && errno != EAGAIN)
706 return 0; /* Error */
707 else if (nread > 0)
708 {
709 int r = 0;
710 int written = 0;
711
712 do {
713 r = write (out, &buf, nread);
714 } while ((r < 0 && errno == EAGAIN)
715 || (r > 0 && (written += r) && written != nread));
716
717 if (r < 0)
718 return 0; /* Error */
719 }
720 return 1;
721 }
722
723 int
724 pty_conversation ()
725 {
726 fd_set set;
727
728 in_conversation = 1;
729
730 while (! quit_conversation) {
731 int res;
732
733 FD_ZERO (&set);
734 FD_SET (master, &set);
735 FD_SET (1, &set);
736 res = select (FD_SETSIZE, &set, NULL, NULL, NULL);
737 if (res < 0)
738 {
739 if (errno != EINTR)
740 return 0;
741 }
742 else if (res > 0)
743 {
744 if (FD_ISSET (master, &set))
745 {
746 /* Copy Emacs output to stdout. */
747 if (! copy_from_to (master, 0))
748 return 1;
749 }
750 if (FD_ISSET (1, &set))
751 {
752 /* Forward user input to Emacs. */
753 if (! copy_from_to (1, master))
754 return 1;
755 }
756 }
757 }
758 return 1;
759 }
760
761 #endif /* HAVE_TERMIOS */
250 762
251 763
252 #if !defined (HAVE_SOCKETS) || defined (NO_SOCKETS_IN_FILE_SYSTEM) 764 #if !defined (HAVE_SOCKETS) || defined (NO_SOCKETS_IN_FILE_SYSTEM)
253 765
254 int 766 int
310 progname = argv[0]; 822 progname = argv[0];
311 823
312 /* Process options. */ 824 /* Process options. */
313 decode_options (argc, argv); 825 decode_options (argc, argv);
314 826
315 if ((argc - optind < 1) && !eval) 827 if ((argc - optind < 1) && !eval && !here)
316 { 828 {
317 fprintf (stderr, "%s: file name or argument required\n", progname); 829 fprintf (stderr, "%s: file name or argument required\n", progname);
318 fprintf (stderr, "Try `%s --help' for more information\n", progname); 830 fprintf (stderr, "Try `%s --help' for more information\n", progname);
319 exit (1); 831 exit (1);
320 } 832 }
482 fprintf (out, "-display "); 994 fprintf (out, "-display ");
483 quote_file_name (display, out); 995 quote_file_name (display, out);
484 fprintf (out, " "); 996 fprintf (out, " ");
485 } 997 }
486 998
999 if (here)
1000 {
1001 if (! init_signals ())
1002 {
1003 fprintf (stderr, "%s: ", argv[0]);
1004 perror ("fdopen");
1005 fail (argc, argv);
1006 }
1007
1008 if (! init_tty ())
1009 {
1010 reset_tty ();
1011 fprintf (stderr, "%s: ", argv[0]);
1012 perror ("fdopen");
1013 fail (argc, argv);
1014 }
1015
1016 if (! init_pty ())
1017 {
1018 reset_tty ();
1019 fprintf (stderr, "%s: ", argv[0]);
1020 perror ("fdopen");
1021 fail (argc, argv);
1022 }
1023
1024 fprintf (out, "-pty ");
1025 quote_file_name (pty_name, out);
1026 fprintf (out, " ");
1027 quote_file_name (getenv("TERM"), out);
1028 fprintf (out, " ");
1029 }
1030
487 if ((argc - optind > 0)) 1031 if ((argc - optind > 0))
488 { 1032 {
489 for (i = optind; i < argc; i++) 1033 for (i = optind; i < argc; i++)
490 { 1034 {
491 if (eval) 1035 if (eval)
510 fprintf (out, " "); 1054 fprintf (out, " ");
511 } 1055 }
512 } 1056 }
513 else 1057 else
514 { 1058 {
515 while ((str = fgets (string, BUFSIZ, stdin))) 1059 if (!here)
516 { 1060 {
517 quote_file_name (str, out); 1061 while ((str = fgets (string, BUFSIZ, stdin)))
518 } 1062 {
519 fprintf (out, " "); 1063 quote_file_name (str, out);
1064 }
1065 fprintf (out, " ");
1066 }
520 } 1067 }
521 1068
522 fprintf (out, "\n"); 1069 fprintf (out, "\n");
523 fflush (out); 1070 fflush (out);
524 1071
525 /* Maybe wait for an answer. */ 1072 /* Maybe wait for an answer. */
526 if (nowait) 1073 if (nowait)
527 return 0; 1074 {
528 1075 reset_tty ();
1076 return 0;
1077 }
1078
1079 if (here)
1080 {
1081 if (! pty_conversation ())
1082 {
1083 reset_tty ();
1084 fprintf (stderr, "%s: ", argv[0]);
1085 perror ("fdopen");
1086 fail (argc, argv);
1087 }
1088 close (master);
1089 reset_tty ();
1090 return 0;
1091 }
1092
529 if (!eval) 1093 if (!eval)
530 { 1094 {
531 printf ("Waiting for Emacs..."); 1095 printf ("Waiting for Emacs...");
532 needlf = 2; 1096 needlf = 2;
533 } 1097 }
544 1108
545 if (needlf) 1109 if (needlf)
546 printf ("\n"); 1110 printf ("\n");
547 fflush (stdout); 1111 fflush (stdout);
548 1112
1113 reset_tty ();
549 return 0; 1114 return 0;
550 } 1115 }
551 1116
552 #endif /* HAVE_SOCKETS */ 1117 #endif /* HAVE_SOCKETS */
553 1118