comparison Wnn/uum/jhlp.c @ 0:bbc77ca4def5

initial import
author Yoshiki Yazawa <yaz@cc.rim.or.jp>
date Thu, 13 Dec 2007 04:30:14 +0900
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:bbc77ca4def5
1 /*
2 * $Id: jhlp.c,v 1.23 2006/09/25 17:31:36 aonoto Exp $
3 */
4
5 /*
6 * FreeWnn is a network-extensible Kana-to-Kanji conversion system.
7 * This file is part of FreeWnn.
8 *
9 * Copyright Kyoto University Research Institute for Mathematical Sciences
10 * 1987, 1988, 1989, 1990, 1991, 1992
11 * Copyright OMRON Corporation. 1987, 1988, 1989, 1990, 1991, 1992, 1999
12 * Copyright ASTEC, Inc. 1987, 1988, 1989, 1990, 1991, 1992
13 * Copyright FreeWnn Project 1999, 2000, 2002, 2003, 2006
14 * Copyright Canna Project 2002
15 * Copyright Taketo Kabe 2003
16 *
17 * Maintainer: FreeWnn Project
18 *
19 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation; either version 2 of the License, or
22 * (at your option) any later version.
23 *
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
28 *
29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32 */
33
34 #ifndef lint
35 static char *rcs_id = "$Id: jhlp.c,v 1.23 2006/09/25 17:31:36 aonoto Exp $";
36 #endif /* lint */
37
38 #ifdef HAVE_CONFIG_H
39 # include <config.h>
40 #endif
41
42 #include <stdio.h>
43 #include <sys/types.h>
44 #include <setjmp.h>
45 #include <signal.h>
46 #if STDC_HEADERS
47 # include <stdlib.h>
48 # include <string.h>
49 #else
50 # if HAVE_STRINGS_H
51 # include <strings.h>
52 # endif
53 # if HAVE_MALLOC_H
54 # include <malloc.h>
55 # endif
56 #endif /* STDC_HEADERS */
57 #include <errno.h>
58 #include <sys/ioctl.h>
59 #include <sys/stat.h>
60 #ifdef HAVE_SYS_PARAM_H
61 # include <sys/param.h>
62 #endif
63 #if TIME_WITH_SYS_TIME
64 # include <sys/time.h>
65 # include <time.h>
66 #else
67 # if HAVE_SYS_TIME_H
68 # include <sys/time.h>
69 # else
70 # include <time.h>
71 # endif /* HAVE_SYS_TIME_H */
72 #endif /* TIME_WITH_SYS_TIME */
73 #if HAVE_FCNTL_H
74 # include <fcntl.h>
75 #endif
76 #include <pwd.h>
77 #ifdef HAVE_UNISTD_H
78 # include <unistd.h>
79 #endif
80 #if HAVE_SYS_WAIT_H
81 # include <sys/wait.h>
82 #endif
83 #ifdef HAVE_LIBUTIL_H
84 # include <libutil.h>
85 #endif
86
87 /* Solaris 2.x needs termio.h , so include both. */
88 #if HAVE_TERMIOS_H
89 # include <termios.h>
90 #endif
91 #if HAVE_TERMIO_H
92 # include <termio.h>
93 #endif
94
95 #if defined(HAVE_TERMIOS_H)
96 /* # include <termios.h> */
97 # define USE_TERMIOS 1
98 #elif defined(HAVE_TERMIO_H)
99 /* # include <termio.h> */
100 # define USE_TERMIO 1
101 #elif defined(HAVE_SYS_TERMIO_H)
102 # include <sys/termio.h>
103 # define USE_TERMIO 1
104 #elif defined(HAVE_SGTTY_H)
105 # include <sgtty.h>
106 # define USE_SGTTY
107 #else
108 # error "No termio header."
109 #endif /* HAVE_TERMIOS_H */
110
111 #ifdef HAVE_LIBSPT
112 # include <libspt.h> /* lib from Canna. not used w/FreeWnn */
113 #endif
114
115 /*
116 * Enable old Linux specific code.
117 * We hope you don't have to use this #define ...
118 * (We will remove this #define and related code in near future.)
119 */
120 /* #define USE_LINUX_TERM */
121
122
123 #include "sdefine.h"
124
125 #include "jllib.h"
126 #include "commonhd.h"
127 #include "sheader.h"
128 #include "wnn_config.h"
129 #include "wnn_os.h"
130
131 /* old system check (don't know if it works) */
132 #ifdef nec_ews_svr2
133 # include <sys/jtermio.h>
134 #endif /* nec_ews_svr2 */
135 #if defined(uniosu)
136 # include <sys/pty.h>
137 #endif /* defined(uniosu) */
138 #ifdef SVR4
139 #include <sys/stropts.h>
140 #include <sys/euc.h>
141 #include <sys/eucioctl.h>
142 #endif /* SVR4 */
143
144 #define ERROR -1
145
146 jmp_buf kk_env;
147 #ifdef TIOCSSIZE
148 struct ttysize pty_rowcol;
149 #endif /* TIOCSSIZE */
150
151 int ttyfd; /* master tty */
152
153 char *tname; /* terminal name */
154 char *cmdnm = "csh"; /* char *cmdnm = "csh"; */
155
156 int child_id;
157 char *prog;
158 #ifdef HAVE_LIBSPT
159 spt_handle *spth = NULL;
160 #endif
161 int need_utmp_clear = 0;
162
163 static void save_signals (void);
164 static void restore_signals (void);
165 static RETSIGTYPE terminate_handler (void);
166 static void do_end (void);
167 static void open_pty (void);
168 static void open_pty_traditional (void);
169 static void open_ttyp (void);
170 static void do_main (void);
171 static void exec_cmd (char **);
172 static void parse_options (int, char **);
173 static void setsize (void);
174 static void get_rubout (void);
175 static void usage (char *);
176 static void change_size (void);
177 static void default_usage (void);
178 static void j_term_save (void);
179 static unsigned char keyin0 (void);
180
181 int
182 main (int argc, char **argv)
183 {
184 char *name;
185 char *p;
186 char nlspath[64];
187 FuncDataBase *f;
188 char *server_env;
189 char errprefix[1024] = "error";
190 int i;
191
192 prog = argv[0];
193 flow_control = FLOW_CONTROL;
194 code_trans = default_code_trans;
195
196 strcpy (username, getpwuid (getuid ())->pw_name);
197 if ((name = getenv (WNN_USERNAME_ENV)) != NULL)
198 {
199 strncpy(username, name, PATHNAMELEN-1);
200 username[PATHNAMELEN-1] = '\0';
201 }
202 for (i = 1; i < argc;)
203 {
204 if (!strcmp (argv[i++], "-L"))
205 {
206 if (i >= argc || argv[i][0] == '-')
207 default_usage ();
208 strncpy(lang_dir, argv[i++], LANGDIRLEN-1);
209 lang_dir[LANGDIRLEN-1] = '\0';
210 for (; i < argc; i++)
211 {
212 argv[i - 2] = argv[i];
213 }
214 argv[i - 2] = NULL;
215 argc -= 2;
216 break;
217 }
218 }
219
220 if (*lang_dir == '\0')
221 {
222 #ifndef CANNA
223 if ((p = getenv ("LANG")) != NULL)
224 {
225 if (strlen (p) >= 4)
226 {
227 strncpy (lang_dir, p, 5);
228 lang_dir[5] = '\0';
229 }
230 else
231 {
232 strcpy (lang_dir, p);
233 }
234 }
235 #else /* CANNA */
236 strcpy (lang_dir, WNN_DEFAULT_LANG);
237 #endif /* CANNA */
238 }
239 for (f = function_db; *lang_dir && f && f->lang; f++)
240 {
241 if (!strcmp (f->lang, lang_dir))
242 {
243 lang_db = f;
244 break;
245 }
246 }
247 if (lang_db == NULL)
248 {
249 if (*lang_dir)
250 fprintf (stderr, "Lang \"%s\" is wrong, use default lang \"%s\".\n", lang_dir, WNN_DEFAULT_LANG);
251 strcpy (lang_dir, WNN_DEFAULT_LANG);
252 for (f = function_db; *lang_dir && f && f->lang; f++)
253 {
254 if (!strcmp (f->lang, lang_dir))
255 {
256 lang_db = f;
257 break;
258 }
259 }
260 if (lang_db == NULL)
261 {
262 fprintf (stderr, "Default lang \"%s\" is wrong.\n", lang_dir);
263 exit (1);
264 }
265 }
266 f_table = &(lang_db->f_table);
267 code_trans = lang_db->code_trans;
268 tty_c_flag = lang_db->tty_code;
269 pty_c_flag = lang_db->pty_code;
270 internal_code = lang_db->internal_code;
271 file_code = lang_db->file_code;
272
273 parse_options (argc, argv);
274
275 strcpy (nlspath, LIBDIR);
276 strcat (nlspath, "/%L/%N");
277 cd = msg_open ("uum.msg", nlspath, lang_dir);
278
279 if (*def_servername == '\0')
280 {
281 if (!(server_env = get_server_env (lang_dir)))
282 {
283 server_env = WNN_DEF_SERVER_ENV;
284 }
285 if (name = getenv (server_env))
286 {
287 strncpy(def_servername, name, PATHNAMELEN-1);
288 def_servername[PATHNAMELEN-1] = '\0';
289 strcpy(def_reverse_servername, def_servername);
290 }
291 }
292
293 if (!isatty (0))
294 {
295 fprintf (stderr, "Input must be a tty.\n");
296 exit (1);
297 }
298
299 if ((p = getenv (WNN_COUNTDOWN_ENV)) == NULL)
300 {
301 if (setenv (WNN_COUNTDOWN_ENV, "0", 1) != 0)
302 {
303 #if HAVE_SNPRINTF
304 snprintf (errprefix, sizeof (errprefix),
305 "error at %s (%d)", __FILE__, __LINE__);
306 #endif /* HAVE_SNPRINTF */
307 perror (errprefix);
308 exit (1);
309 }
310 }
311 else if (atoi (p) <= 0)
312 {
313 puteustring (MSG_GET (4), stdout);
314 /*
315 puteustring("uumからuumは起こせません。\n",stdout);
316 */
317 exit (126);
318 }
319 else
320 {
321 sprintf (p, "%d", atoi (p) - 1);
322 if (setenv (WNN_COUNTDOWN_ENV, p, 1) != 0)
323 {
324 #if HAVE_SNPRINTF
325 snprintf (errprefix, sizeof (errprefix),
326 "error at %s (%d)", __FILE__, __LINE__);
327 #endif /* HAVE_SNPRINTF */
328 perror (errprefix);
329 exit (1);
330 }
331 }
332
333 if ((tname = getenv ("TERM")) == NULL)
334 {
335 fprintf (stderr, "Sorry. Please set your terminal type.\r\n");
336 exit (1);
337 }
338
339 /* 2003.06 should delete this? */
340 #ifndef HAVE_LIBSPT
341 /* saveutmp() does utmp handling if USE_UTMP is set to 1 */
342 if (saveutmp () < 0)
343 {
344 puts ("Can't save utmp\n");
345 }
346 #endif /* !HAVE_LIBSPT */
347
348
349 if (optind)
350 {
351 optind--;
352 argc -= optind;
353 argv += optind;
354 }
355 if (argc > 1)
356 {
357 cmdnm = *++argv;
358 }
359 else
360 {
361 if ((name = getenv ("SHELL")) != NULL)
362 {
363 cmdnm = name;
364 }
365 argv[0] = cmdnm;
366 argv[1] = NULL;
367 }
368
369 j_term_save ();
370 /* do_end () is allowed from here */
371 save_signals ();
372
373 #if HAVE_TERMINFO /* TERMINFO */
374 if (openTermData () == -1)
375 {
376 fprintf (stderr, "Sorry. Something is wrong with terminfo, maybe.\r\n");
377 exit (21);
378 }
379 maxlength = columns;
380 crow = lines - conv_lines;
381 #else /* Assume TERMCAP */
382 if (getTermData () == -1)
383 {
384 fprintf (stderr, "Sorry. Something is wrong with termcap, maybe.\r\n");
385 exit (21);
386 }
387 #endif /* HAVE_TERMINFO */
388 #if defined(BSD43) || defined(DGUX)
389 setsize ();
390 #endif /* BSD43 */
391
392 #if !HAVE_TERMINFO /* Assume TERMCAP */
393 if (set_TERMCAP () == -1)
394 {
395 fprintf (stderr, "Sorry. Something is wrong with termcap, maybe.\r\n");
396 exit (21);
397 }
398 #endif /* !HAVE_TERMINFO */
399
400 ttyfd = 0;
401 open_pty ();
402 /* It is normal to open tty here, before fork().
403 Don't know why linux is different.
404 So temporally comment it out to make it as other OSes. */
405 #ifndef USE_LINUX_TERM
406 open_ttyp ();
407 #endif
408 exec_cmd (argv);
409
410 get_rubout ();
411
412 switch (init_uum ())
413 { /* initialize of kana-kanji henkan */
414 case -1:
415 terminate_handler ();
416 break;
417 case -2:
418 epilogue ();
419 do_end ();
420 break;
421 }
422
423 fcntl (ttyfd, F_SETFL, O_NDELAY);
424
425 if (j_term_init () == ERROR)
426 {
427 uum_err ("term initialize fault.");
428 }
429
430 #ifndef CANNA
431 if (!jl_isconnect (bun_data_))
432 {
433 if (!servername || *servername == 0)
434 {
435 printf ("%s\r\n", wnn_perror ());
436 }
437 else
438 {
439 printf ("jserver(at %s):%s\r\n", servername, wnn_perror ());
440 }
441 flush ();
442 }
443 #endif /* CANNA */
444
445 puteustring (MSG_GET (1),
446 /*
447 "\ruum(かな漢字変換フロントエンドプロセッサ)\r\n",
448 */
449 stdout);
450 initial_message_out (); /* print message if exists. */
451
452 #if defined(uniosu)
453 if (setjmp (kk_env))
454 {
455 disconnect_jserver ();
456 ioctl_off ();
457 connect_jserver (0);
458 }
459 #endif /* defined(uniosu) */
460
461 do_main ();
462 return 0;
463 }
464
465 /*
466 each options handling functions
467 */
468
469 static int
470 do_h_opt (void)
471 {
472 henkan_off_flag = 1;
473 defined_by_option |= OPT_WAKING_UP_MODE;
474 return 0;
475 }
476
477 static int
478 do_H_opt (void)
479 {
480 henkan_off_flag = 0;
481 defined_by_option |= OPT_WAKING_UP_MODE;
482 return 0;
483 }
484
485 #ifdef JAPANESE
486 int
487 do_u_opt (void)
488 {
489 pty_c_flag = J_EUJIS;
490 return 0;
491 }
492
493 int
494 do_j_opt (void)
495 {
496 pty_c_flag = J_JIS;
497 return 0;
498 }
499
500 int
501 do_s_opt (void)
502 {
503 pty_c_flag = J_SJIS;
504 return 0;
505 }
506
507 int
508 do_U_opt (void)
509 {
510 tty_c_flag = J_EUJIS;
511 return 0;
512 }
513
514 int
515 do_J_opt (void)
516 {
517 tty_c_flag = J_JIS;
518 return 0;
519 }
520
521 int
522 do_S_opt (void)
523 {
524 tty_c_flag = J_SJIS;
525 return 0;
526 }
527 #endif /* JAPANESE */
528
529 #ifdef CHINESE
530 int
531 do_b_opt (void)
532 {
533 pty_c_flag = C_BIG5;
534 return 0;
535 }
536
537 int
538 do_t_opt (void)
539 {
540 pty_c_flag = C_ECNS11643;
541 return 0;
542 }
543
544 int
545 do_B_opt (void)
546 {
547 tty_c_flag = C_BIG5;
548 return 0;
549 }
550
551 int
552 do_T_opt (void)
553 {
554 tty_c_flag = C_ECNS11643;
555 return 0;
556 }
557 #endif /* CHINESE */
558
559 #ifdef KOREAN
560 int
561 do_u_opt (void)
562 {
563 pty_c_flag = K_EUKSC;
564 return 0;
565 }
566
567 int
568 do_U_opt (void)
569 {
570 tty_c_flag = K_EUKSC;
571 return 0;
572 }
573 #endif /* KOREAN */
574
575 static int
576 do_P_opt (void)
577 {
578 sleep (20);
579 return 0;
580 }
581
582 static int
583 do_x_opt (void)
584 {
585 flow_control = 0;
586 defined_by_option |= OPT_FLOW_CTRL;
587 return 0;
588 }
589
590 static int
591 do_X_opt (void)
592 {
593 flow_control = 1;
594 defined_by_option |= OPT_FLOW_CTRL;
595 return 0;
596 }
597
598 static int
599 do_k_opt (void)
600 {
601 strncpy(uumkey_name_in_uumrc, optarg, PATHNAMELEN-1);
602 uumkey_name_in_uumrc[PATHNAMELEN-1] = '\0';
603 if (*uumkey_name_in_uumrc == '\0')
604 {
605 return -1;
606 }
607 defined_by_option |= OPT_WNNKEY;
608 return 0;
609 }
610
611 static int
612 do_c_opt (void)
613 {
614 strncpy(convkey_name_in_uumrc, optarg, PATHNAMELEN-1);
615 convkey_name_in_uumrc[PATHNAMELEN-1] = '\0';
616 if (*convkey_name_in_uumrc == '\0')
617 {
618 return -1;
619 }
620 defined_by_option |= OPT_CONVKEY;
621 return 0;
622 }
623
624 static int
625 do_r_opt (void)
626 {
627 strncpy(rkfile_name_in_uumrc, optarg, PATHNAMELEN-1);
628 rkfile_name_in_uumrc[PATHNAMELEN-1] = '\0';
629 if (*rkfile_name_in_uumrc == '\0')
630 {
631 return -1;
632 }
633 defined_by_option |= OPT_RKFILE;
634 return 0;
635 }
636
637 static int
638 do_l_opt (void)
639 {
640 conv_lines = atoi (optarg);
641 return 0;
642 }
643
644 static int
645 do_D_opt (void)
646 {
647 strncpy(def_servername, optarg, PATHNAMELEN-1);
648 def_servername[PATHNAMELEN-1] = '\0';
649 strcpy(def_reverse_servername, def_servername);
650 if (*def_servername == '\0')
651 {
652 return -1;
653 }
654 return 0;
655 }
656
657 static int
658 do_n_opt (void)
659 {
660 strncpy(username, optarg, PATHNAMELEN-1);
661 username[PATHNAMELEN-1] = '\0';
662 if (*username == '\0')
663 {
664 return -1;
665 }
666 return 0;
667 }
668
669 static int
670 do_v_opt (void)
671 {
672 defined_by_option |= OPT_VERBOSE;
673 return 0;
674 }
675
676 static int (*do_opt[]) (void) =
677 {
678 do_h_opt, /* 'h' : waking_up_in_henkan_mode */
679 do_H_opt, /* 'H' : waking_up_no_henkan_mode */
680 do_P_opt, /* 'P' : sleep 20 seconds (for debug) */
681 do_x_opt, /* 'x' : disable tty's flow control */
682 do_X_opt, /* 'X' : enable tty's flow control */
683 do_k_opt, /* 'k' : specify uumkey file */
684 do_c_opt, /* 'c' : specify convert_key file */
685 do_r_opt, /* 'r' : specify romkan mode file */
686 do_l_opt, /* 'l' : specify # of lines used for henkan */
687 do_D_opt, /* 'D' : specify hostname of jserver */
688 do_n_opt, /* 'n' : specify username for jserver */
689 do_v_opt, /* 'v' : verbose */
690 };
691
692 static void
693 parse_options (argc, argv)
694 int argc;
695 char **argv;
696 {
697 register int c;
698 register char *default_getoptstr = GETOPTSTR;
699 register char *default_ostr = OPTIONS;
700 char ostr[64];
701 register char *p;
702
703 strcpy (ostr, default_getoptstr);
704 strcat (ostr, lang_db->getoptstr);
705 while ((c = getopt (argc, argv, ostr)) != EOF)
706 {
707 if (!(p = strchr (default_ostr, c)) || (*do_opt[p - default_ostr]) () < 0)
708 {
709 if (!(p = strchr (lang_db->ostr, c)) || (*lang_db->do_opt[p - lang_db->ostr]) () < 0)
710 {
711 strcpy (ostr, default_ostr);
712 strcat (ostr, lang_db->ostr);
713 usage (ostr);
714 }
715 }
716 }
717 }
718
719 /** tty に対する ioctl のセット */
720
721 #ifdef USE_SGTTY
722 # if defined(BSD43) || defined(DGUX) /* should be "defined(LPASS8)"? */
723 # define SET_PASS8 1
724 # endif
725
726 struct sgttyb savetmio;
727 struct sgttyb ttyb_def = { B9600, B9600, 0x7f, 0x15,
728 EVENP | ODDP | ECHO | CRMOD };
729 int local_mode_def = LCRTBS | LCRTERA | LCRTKIL | LCTLECH | LPENDIN | LDECCTQ;
730 /* added later */
731 struct tchars tcharsv;
732 struct ltchars ltcharsv;
733 struct sgttyb ttyb;
734 int local_mode;
735 # ifdef SET_PASS8
736 static int local_mode_sv;
737 # endif
738
739 static void
740 get_rubout (void)
741 {
742 rubout_code = savetmio.sg_erase;
743 }
744
745 int
746 j_term_init (void)
747 {
748 struct sgttyb buf;
749
750 buf = savetmio;
751 buf.sg_flags |= RAW;
752 buf.sg_flags &= ~ECHO;
753 ioctl (ttyfd, TIOCSETP, &buf);
754 # ifdef SET_PASS8
755 ioctl (ttyfd, TIOCLSET, &local_mode);
756 # endif
757
758 return 0;
759 }
760
761 static_void
762 j_term_save (void)
763 {
764 ioctl (ttyfd, TIOCGETC, &tcharsv);
765 ioctl (ttyfd, TIOCGLTC, &ltcharsv);
766 if (ioctl (ttyfd, TIOCGETP, &ttyb))
767 ttyb = ttyb_def;
768 savetmio = ttyb;
769 # ifdef SET_PASS8
770 if (ioctl (ttyfd, TIOCLGET, &local_mode_sv))
771 local_mode_sv = local_mode_def;
772 local_mode = local_mode_sv | LPASS8; /* set PASS8 */
773 # else /* !SET_PASS8 */
774 if (ioctl (ttyfd, TIOCLGET, &local_mode))
775 local_mode = local_mode_def;
776 # endif /* !SET_PASS8 */
777 }
778
779 static void
780 j_term_restore (void)
781 {
782 ioctl (ttyfd, TIOCSETP, &savetmio);
783 # ifdef SET_PASS8
784 ioctl (ttyfd, TIOCLSET, &local_mode_sv);
785 # endif /* SET_PASS8 */
786 }
787
788 static void
789 j_term_p_init (int ttypfd)
790 {
791 int word;
792 ioctl (ttypfd, TIOCSETC, &tcharsv);
793 ioctl (ttypfd, TIOCSLTC, &ltcharsv);
794 ioctl (ttypfd, TIOCSETP, &ttyb);
795 ioctl (ttypfd, TIOCLSET, &local_mode);
796 if (pty_c_flag == J_JIS)
797 {
798 word = LCTLECH;
799 ioctl (ttypfd, TIOCLBIC, &word);
800 }
801 }
802 #endif /* USE_SGTTY */
803
804 #if defined(USE_TERMIO) || defined(USE_TERMIOS)
805
806 #ifdef USE_TERMIOS
807 # define TERMIO termios
808 # define GET_TERMATTR(fd, tio) tcgetattr(fd, tio)
809 # define SET_TERMATTR(fd, tio) tcsetattr(fd, TCSADRAIN, tio)
810 # define UNDEF_STTY _POSIX_VDISABLE
811 # define SET_ATTR_ERROR "error in tcsetattr.\n"
812 #else /* !USE_TERMIOS */
813 # define TERMIO termio
814 # define GET_TERMATTR(fd, tio) ioctl(fd, TCGETA, tio)
815 # ifdef TCSETAW
816 # define SET_TERMATTR(fd, tio) ioctl(fd, TCSETAW, tio)
817 # define SET_ATTR_ERROR "error in ioctl TCSETAW.\n"
818 # else
819 # define SET_TERMATTR(fd, tio) ioctl(fd, TCSETA, tio)
820 # define SET_ATTR_ERROR "error in ioctl TCSETA.\n"
821 # endif
822 # define UNDEF_STTY 0xff
823 #endif /* !USE_TERMIOS */
824 #ifdef CERASE
825 # define WNN_CERASE CERASE
826 #else
827 # define WNN_CERASE 0x7f
828 #endif
829
830 struct TERMIO savetmio;
831
832 static void
833 set_default_termio (struct TERMIO *terms)
834 {
835 bzero (terms, sizeof *terms);
836 terms->c_iflag = IGNBRK | ICRNL | IXON;
837 terms->c_oflag = OPOST;
838 #ifdef ONLCR
839 terms->c_oflag |= ONLCR;
840 #endif
841 terms->c_cflag = CS8 | CSTOPB | CREAD | CLOCAL;
842 #ifndef USE_TERMIOS
843 terms->c_cflag |= B9600;
844 #endif
845 terms->c_lflag = ISIG | ICANON | ECHO | ECHOE | ECHOK;
846 #ifdef USE_TERMIOS
847 terms->c_cc[VINTR] = 0x3;
848 terms->c_cc[VQUIT] = 0x1c;
849 terms->c_cc[VERASE] = 0x8;
850 terms->c_cc[VKILL] = 0x15;
851 terms->c_cc[VEOF] = 0x4;
852 terms->c_cc[VEOL] = _POSIX_VDISABLE;
853 # ifdef VEOL2
854 terms->c_cc[VEOL2] = _POSIX_VDISABLE;
855 # endif
856 cfsetospeed (terms, B9600);
857 cfsetispeed (terms, B9600);
858 #else /* !USE_TERMIOS */
859 terms->c_line = 0;
860 terms->c_cc[0] = 0x3;
861 terms->c_cc[1] = 0x1c;
862 terms->c_cc[2] = 0x8;
863 terms->c_cc[3] = 0x15;
864 terms->c_cc[4] = 0x4;
865 terms->c_cc[5] = 0;
866 terms->c_cc[6] = 0;
867 terms->c_cc[7] = 0;
868 #endif /* !USE_TERMIOS */
869 }
870
871 #if defined(uniosu)
872 struct jtermio savejtmio;
873 struct auxtermio auxterm = {
874 0, /* -tostop */
875 {0x1a, 0, 0, 0, 0, 0, 0, 0} /* c_cc2 */
876 };
877 #endif /* defined(uniosu) */
878
879 static void
880 get_rubout (void)
881 {
882 if (savetmio.c_cc[VERASE] == UNDEF_STTY)
883 {
884 rubout_code = RUBOUT;
885 }
886 else
887 {
888 rubout_code = savetmio.c_cc[VERASE];
889 }
890 }
891
892 int
893 j_term_init (void)
894 {
895 struct TERMIO buf1;
896 #if defined(uniosu)
897 struct jtermio buf2;
898 #endif /* defined(uniosu) */
899
900 buf1 = savetmio;
901 #ifdef linux
902 buf1.c_lflag &= ~(ECHONL | ECHOK | ECHOE | ECHO | XCASE | ICANON | ISIG);
903 buf1.c_iflag = 0;
904 buf1.c_oflag &= ~OPOST;
905 buf1.c_cflag |= CS8;
906 buf1.c_cc[VMIN] = 1; /* cf. ICANON */
907 buf1.c_cc[VTIME] = 0;
908 buf1.c_iflag &= ~(ISTRIP | INLCR | IGNCR | ICRNL | IUCLC | IXON);
909 #else /* !linux */
910 buf1.c_iflag &= ~(ISTRIP | INLCR | IGNCR | ICRNL | IXON);
911 # ifdef IUCLC
912 buf1.c_iflag &= ~(IUCLC);
913 # endif
914 if (flow_control)
915 {
916 buf1.c_iflag |= IXON;
917 }
918 buf1.c_lflag &= ~(ECHONL | ECHOK | ECHOE | ECHO | ICANON | ISIG);
919 # ifdef XCASE
920 buf1.c_lflag &= ~(XCASE);
921 # endif
922 # ifdef IEXTEN
923 buf1.c_lflag &= ~(IEXTEN);
924 # endif
925 buf1.c_oflag = OPOST;
926 # ifdef USE_TERMIOS
927 buf1.c_cc[VMIN] = 1;
928 buf1.c_cc[VTIME] = 0;
929 cfsetispeed(&buf1, cfgetispeed(&savetmio));
930 cfsetospeed(&buf1, cfgetospeed(&savetmio));
931 # else /* !USE_TERMIOS */
932 buf1.c_cc[VEOF] = 1; /* cf. ICANON */
933 buf1.c_cc[VEOL] = 0;
934 /* not needed? cf.ISIG*/
935 buf1.c_cc[VINTR] = WNN_CERASE;
936 buf1.c_cc[VQUIT] = WNN_CERASE;
937 buf1.c_cc[VERASE] = WNN_CERASE;
938 buf1.c_cc[VKILL] = WNN_CERASE;
939 # endif /* !USE_TERMIOS */
940 #endif /* !linux */
941 if (SET_TERMATTR (ttyfd, &buf1) < 0)
942 {
943 fprintf (stderr, SET_ATTR_ERROR);
944 exit (1);
945 }
946
947 #if defined(uniosu)
948 buf2 = savejtmio;
949 buf2.j_flg = CONVTOEXT | WNN_EXIST;
950 buf2.j_level = jterm;
951 switch (jcode_set)
952 {
953 case 0:
954 buf2.j_ecode = JIS;
955 break;
956 case 1:
957 buf2.j_ecode = SJIS;
958 break;
959 case 2:
960 buf2.j_ecode = UJIS;
961 break;
962 default:
963 fprintf (stderr, "uum: kanji code set not supported in terminfo\n");
964 exit (1);
965 }
966 if (jis_kanji_in)
967 {
968 strcpy (buf2.j_jst, jis_kanji_in);
969 buf2.j_jstl = strlen (jis_kanji_in);
970 }
971 if (jis_kanji_out)
972 {
973 strcpy (buf2.j_jend, jis_kanji_out);
974 buf2.j_jendl = strlen (jis_kanji_out);
975 }
976 if (jgaiji_start_address)
977 {
978 *(short *) buf2.j_gcsa = jgaiji_start_address;
979 }
980 if (jgaiji_disp)
981 {
982 strcpy (buf2.j_gdsp, jgaiji_disp);
983 buf2.j_gdspl = strlen (jgaiji_disp);
984 }
985
986 if (ioctl (ttyfd, JTERMSET, &buf2) < 0)
987 {
988 fprintf (stderr, "error in ioctl JTERMSET.\n");
989 exit (1);
990 }
991 #endif /* defined(uniosu) */
992
993 return 0;
994 }
995
996 static void
997 j_term_save (void)
998 {
999 if (GET_TERMATTR (ttyfd, &savetmio) < 0)
1000 {
1001 set_default_termio (&savetmio);
1002 }
1003 #if defined(uniosu)
1004 if (ioctl (ttyfd, JTERMGET, &savejtmio) < 0)
1005 {
1006 fprintf (stderr, "uum: error in ioctl JTERMGET in open_ttyp.\n");
1007 exit (1);
1008 }
1009 #endif /* defined(uniosu) */
1010 }
1011
1012 static void
1013 j_term_restore (void)
1014 {
1015 if (SET_TERMATTR (ttyfd, &savetmio) < 0)
1016 {
1017 fprintf (stderr, SET_ATTR_ERROR);
1018 exit (1);
1019 }
1020
1021 #if defined(uniosu)
1022 if (ioctl (ttyfd, JTERMSET, &savejtmio) < 0)
1023 {
1024 fprintf (stderr, "error in ioctl JTERMSET.\n");
1025 exit (1);
1026 }
1027 #endif /* defined(uniosu) */
1028 }
1029
1030 static void
1031 j_term_p_init (int ttypfd)
1032 {
1033 struct TERMIO buf1;
1034 #if defined(uniosu)
1035 struct TERMIO buf2;
1036 #endif
1037 buf1 = savetmio;
1038 #ifdef DGUX /* copied from JLS5.4.2 */
1039 /* should clear on all platforms? */
1040 buf1.c_iflag &= ~ISTRIP;
1041 #endif /* DGUX */
1042 #ifdef nec_ews_svr2
1043 buf1.c_line = JAPANLD;
1044 #endif
1045 #ifdef USE_TERMIOS
1046 cfsetispeed(&buf1, cfgetispeed(&savetmio));
1047 cfsetospeed(&buf1, cfgetospeed(&savetmio));
1048 #endif
1049 if (SET_TERMATTR (ttypfd, &buf1) < 0)
1050 {
1051 fprintf (stderr, SET_ATTR_ERROR);
1052 exit (1);
1053 }
1054 #if defined(uniosu)
1055 buf2 = savejtmio;
1056 buf2.j_flg = CONVTOEXT | KANJIINPUT; /* kanji input & output ok */
1057 buf2.j_level = jterm;
1058 switch (jcode_set)
1059 {
1060 case 0:
1061 buf2.j_ecode = JIS;
1062 break;
1063 case 1:
1064 buf2.j_ecode = SJIS;
1065 break;
1066 case 2:
1067 buf2.j_ecode = UJIS;
1068 break;
1069 default:
1070 fprintf (stderr, "uum: kanji code set not supported in terminfo.\n");
1071 exit (1);
1072 }
1073
1074 if (jis_kanji_in)
1075 {
1076 strcpy (buf2.j_jst, jis_kanji_in);
1077 buf2.j_jstl = strlen (jis_kanji_in);
1078 }
1079 if (jis_kanji_out)
1080 {
1081 strcpy (buf2.j_jend, jis_kanji_out);
1082 buf2.j_jendl = strlen (jis_kanji_out);
1083 }
1084 if (jgaiji_start_address)
1085 {
1086 *(short *) buf2.j_gcsa = jgaiji_start_address;
1087 }
1088 if (jgaiji_disp)
1089 {
1090 strcpy (buf2.j_gdsp, jgaiji_disp);
1091 buf2.j_gdspl = strlen (jgaiji_disp);
1092 }
1093
1094 if (ioctl (ttypfd, JTERMSET, &buf2) < 0)
1095 {
1096 fprintf (stderr, "error in ioctl JTERMSET.\n");
1097 exit (1);
1098 }
1099
1100 if (ioctl (ttypfd, TIOCSETAUX, &auxterm) < 0)
1101 {
1102 fprintf (stderr, "error in ioctl TIOCSETAUX.\n");
1103 exit (1);
1104 }
1105
1106 #endif /* defined(uniosu) */
1107 }
1108 #endif /* USE_TERMIO || USE_TERMIOS */
1109
1110 /** signal SIGCHLD を受けた後の処理をする。*/
1111 RETSIGTYPE
1112 chld_handler (void)
1113 {
1114 #ifdef HAVE_WAIT3
1115 #ifdef HAVE_UNION_WAIT
1116 union wait status;
1117 #else /* POSIX */
1118 int status;
1119 #endif
1120 int pid;
1121
1122 if ((pid = wait3 (&status, WNOHANG | WUNTRACED, NULL)) == child_id)
1123 {
1124 if (WIFSTOPPED (status))
1125 {
1126 #ifdef SIGCONT
1127 kill (pid, SIGCONT);
1128 #ifdef GETPGID
1129 KILLPG (GETPGID (pid), SIGCONT);
1130 #endif
1131 #endif
1132 }
1133 else
1134 {
1135 signal (SIGCHLD, SIG_IGN);
1136 printf (MSG_GET (3));
1137 /*
1138 printf("\r\nuumを終わります。\r\n");
1139 */
1140 #ifdef HAVE_LIBSPT
1141 if (spth)
1142 spt_utmp_set_exit (spth, *(int *)&status);
1143 #endif
1144 epilogue ();
1145 do_end ();
1146 }
1147 }
1148 #else /* ! HAVE_WAIT3 */
1149 if (wait (0) == child_id)
1150 {
1151 signal (SIGCHLD, SIG_IGN);
1152 printf (MSG_GET (3));
1153 /*
1154 printf("\r\nuumを終わります。\r\n");
1155 */
1156 epilogue ();
1157 do_end ();
1158 }
1159 #endif /* HAVE_WAIT3 */
1160
1161 re_signal (SIGCHLD, chld_handler);
1162
1163 /* not reached */
1164 #ifndef RETSIGTYPE_VOID
1165 return 0;
1166 #endif
1167 }
1168
1169 /** signal SIGTERM を受けた時の処理をする。*/
1170 static RETSIGTYPE
1171 terminate_handler (void)
1172 {
1173 signal (SIGCHLD, SIG_IGN);
1174 epilogue_no_close ();
1175 do_end ();
1176
1177 /* not reached */
1178 #ifndef RETSIGTYPE_VOID
1179 return 0;
1180 #endif
1181 }
1182
1183 #ifdef SIGWINCH
1184 RETSIGTYPE
1185 resize_handler (void)
1186 {
1187 re_signal (SIGWINCH, resize_handler);
1188 change_size ();
1189
1190 /* not reached */
1191 #ifndef RETSIGTYPE_VOID
1192 return 0;
1193 #endif
1194 }
1195 #endif /* SIGWINCH */
1196
1197 /** メインループ */
1198
1199 /* Assume fd_set, FD_ZERO() family.
1200 though we may use glue in jserver/de.c */
1201 fd_set sel_ptn;
1202 int ptyfd;
1203
1204 static void
1205 do_main (void)
1206 {
1207 #ifndef CANNA
1208 unsigned char *buf;
1209 int ml;
1210
1211 if ((buf = (unsigned char *) malloc (maxchg * 4)) == NULL)
1212 {
1213 printf (MSG_GET (2));
1214 printf (MSG_GET (3));
1215 /*
1216 printf("malloc に失敗しました。uumを終わります。\r\n");
1217 */
1218 epilogue ();
1219 do_end ();
1220 }
1221 #else /* CANNA */
1222 extern void canna_mainloop();
1223 #endif /* CANNA */
1224
1225 FD_ZERO (&sel_ptn);
1226 FD_SET (ptyfd, &sel_ptn);
1227 FD_SET (ttyfd, &sel_ptn);
1228
1229 if (henkan_off_flag == 0)
1230 {
1231 disp_mode ();
1232 }
1233
1234 #ifndef CANNA
1235 for (;;)
1236 {
1237 ml = kk ();
1238 make_history (return_buf, ml);
1239 ml = (*code_trans[(internal_code << 2) | pty_c_flag]) (buf, return_buf, sizeof (w_char) * ml);
1240 if (ml > 0)
1241 write (ptyfd, buf, ml);
1242 }
1243 #else /* CANNA */
1244 canna_mainloop();
1245 #endif /* CANNA */
1246 }
1247
1248 int
1249 keyin2 (void)
1250 {
1251 int total, ret;
1252 unsigned char in;
1253
1254 in = keyin0 ();
1255 if (in == 0xff)
1256 return (-1);
1257 total = (int) (in & 0xff);
1258 if (henkan_off_flag == 0 || pty_c_flag != tty_c_flag)
1259 {
1260 ret = get_cswidth_by_char (in);
1261 for (; ret > 1; ret--)
1262 {
1263 total = ((total & 0xff) << 8) + (int) (keyin0 () & 0xff);
1264 }
1265 }
1266 return (total);
1267 }
1268
1269 /** convert_key nomi okonau key-in function */
1270 int
1271 conv_keyin (char *inkey)
1272 {
1273 return keyin1 (keyin2, inkey);
1274 }
1275
1276 /** キー入力関数 1 */
1277 int
1278 keyin (void)
1279 {
1280 char inkey[16];
1281 return (conv_keyin (inkey));
1282 }
1283
1284 /** キー入力関数 2 */
1285 static unsigned char
1286 keyin0 (void)
1287 {
1288 static unsigned char buf[BUFSIZ];
1289 static unsigned char outbuf[BUFSIZ];
1290 static unsigned char *bufend = outbuf;
1291 static unsigned char *bufstart = outbuf;
1292 int n;
1293 fd_set rfds, mask;
1294 int i, j;
1295 unsigned char *p;
1296 extern int henkan_off_flag;
1297 struct timeval time_out; /* If your OS's select was implemented as
1298 a pointer for int, you must modify the
1299 time_out variable to integer */
1300 int sel_ret;
1301
1302 if (bufstart < bufend)
1303 {
1304 return (*bufstart++);
1305 }
1306 for (;;)
1307 {
1308 if ((n = read (ttyfd, buf, BUFSIZ)) > 0)
1309 {
1310 if (henkan_off_flag == 1)
1311 {
1312 if (tty_c_flag == pty_c_flag)
1313 {
1314 i = through (outbuf, buf, n);
1315 }
1316 else
1317 {
1318 i = (*code_trans[(tty_c_flag << 2) | file_code]) (outbuf, buf, n);
1319 }
1320 }
1321 else
1322 {
1323 i = (*code_trans[(tty_c_flag << 2) | file_code]) (outbuf, buf, n);
1324 }
1325 if (i <= 0)
1326 continue;
1327 bufstart = outbuf;
1328 bufend = outbuf + i;
1329 return (*bufstart++);
1330 }
1331
1332 time_out.tv_sec = 0;
1333 time_out.tv_usec = 200 * 1000; /* 200 msec 間待つのだゾ! */
1334 for (rfds = sel_ptn;
1335 #ifdef linux
1336 (sel_ret = select (FD_SETSIZE, &rfds, 0, 0, NULL)) < 0 && errno == EINTR;
1337 #else
1338 /* FD_SETSIZE should be 20 in classical env. */
1339 (sel_ret = select (FD_SETSIZE, &rfds, 0, 0, &time_out)) < 0 && errno == EINTR;
1340 #endif
1341 rfds = sel_ptn)
1342 ;
1343 if (sel_ret == 0)
1344 {
1345 if ((tty_c_flag == J_JIS) && ((i = flush_designate ((w_char *) outbuf)) > 0))
1346 {
1347 /* 溜まっているESCを吐き出す */
1348 bufstart = outbuf;
1349 bufend = outbuf + i;
1350 return (*bufstart++);
1351 }
1352 return (0xff);
1353 }
1354
1355 if (FD_ISSET(ptyfd, &rfds))
1356 {
1357 if ((n = read (ptyfd, buf, BUFSIZ)) <= 0)
1358 {
1359 epilogue ();
1360 do_end ();
1361 }
1362 #if defined(uniosu)
1363 if (*buf == PIOCPKT_IOCTL)
1364 {
1365 arrange_ioctl (1);
1366 }
1367 else if (*buf == 0)
1368 #endif /* defined(uniosu) */
1369 { /* sequence of data */
1370 #if defined(uniosu)
1371 i = (*code_trans[(pty_c_flag << 2) | tty_c_flag]) (outbuf, buf + 1, n - 1);
1372 #else /* defined(uniosu) */
1373 i = (*code_trans[(pty_c_flag << 2) | tty_c_flag]) (outbuf, buf, n);
1374 #endif /* defined(uniosu) */
1375 if (i <= 0)
1376 continue;
1377 p = outbuf;
1378 push_cursor ();
1379 kk_restore_cursor ();
1380 while ((j = write (ttyfd, p, i)) < i)
1381 {
1382 if (j >= 0)
1383 {
1384 p += j;
1385 i -= j;
1386 }
1387 FD_ZERO (&mask);
1388 FD_SET (ttyfd, &mask);
1389 select (32, 0, &mask, 0, 0);
1390 }
1391 pop_cursor ();
1392 }
1393 }
1394 if (FD_ISSET(ttyfd, &rfds))
1395 {
1396 if ((n = read (ttyfd, buf, BUFSIZ)) > 0)
1397 {
1398 if (henkan_off_flag == 1)
1399 {
1400 if (tty_c_flag == pty_c_flag)
1401 {
1402 i = through (outbuf, buf, n);
1403 }
1404 else
1405 {
1406 i = (*code_trans[(tty_c_flag << 2) | file_code]) (outbuf, buf, n);
1407 }
1408 }
1409 else
1410 {
1411 i = (*code_trans[(tty_c_flag << 2) | file_code]) (outbuf, buf, n);
1412 }
1413 if (i <= 0)
1414 continue;
1415 bufstart = outbuf;
1416 bufend = outbuf + i;
1417 return (*bufstart++);
1418 #ifdef nodef
1419 }
1420 else
1421 { /* Consider it as EOF */
1422 epilogue ();
1423 do_end ();
1424 #endif /* It seems that select does not return EOF when Non-brock
1425 What should I do? */
1426 }
1427 }
1428 }
1429 }
1430
1431
1432 #if defined(uniosu)
1433 /** pty から ioctl がかかった時の処理 */
1434 int
1435 arrange_ioctl (int jflg)
1436 /* jflg: jtermio の j_flg の変換フラグがオフの時 0 オンの時 1 */
1437 {
1438 struct jtermio jbuf1;
1439 struct TERMIO frombuf;
1440 struct TERMIO tobuf;
1441 int i;
1442
1443 GET_TERMATTR (ptyfd, &frombuf);
1444 GET_TERMATTR (ttyfd, &frombuf);
1445
1446 if ((i = (frombuf.c_iflag & IXON)) != (tobuf.c_iflag & IXON))
1447 {
1448 if (i == 0)
1449 {
1450 tobuf.c_iflag &= ~IXON;
1451 }
1452 else
1453 {
1454 tobuf.c_iflag |= IXON;
1455 }
1456 }
1457 if ((i = (frombuf.c_iflag & IXOFF)) != (tobuf.c_iflag & IXOFF))
1458 {
1459 if (i == 0)
1460 {
1461 tobuf.c_iflag &= ~IXOFF;
1462 }
1463 else
1464 {
1465 tobuf.c_iflag |= IXOFF;
1466 }
1467 }
1468 if ((i = (frombuf.c_oflag & OPOST)) != (tobuf.c_oflag & OPOST))
1469 {
1470 if (i == 0)
1471 {
1472 tobuf.c_oflag &= ~OPOST;
1473 }
1474 else
1475 {
1476 tobuf.c_oflag |= OPOST;
1477 }
1478 }
1479 tobuf.c_cflag = (tobuf.c_cflag & ~CBAUD) | (frombuf.c_cflag & CBAUD);
1480
1481 SET_TERMATTR (ttyfd, &tobuf); /* set again */
1482
1483 ioctl (ptyfd, JTERMGET, &jbuf1); /* about Japanease */
1484
1485 if ((jflg) && ((jbuf1.j_flg & KANJIINPUT) == 0))
1486 {
1487 jbuf1.j_flg &= ~(KANJIINPUT | CONVTOINT); /* kanji henkan flg off */
1488 ioctl (ttyfd, JTERMSET, &jbuf1);
1489 kk_restore_cursor ();
1490 reset_cursor ();
1491 longjmp (kk_env, 1);
1492 }
1493 if ((!jflg) && ((jbuf1.j_flg & KANJIINPUT) != 0))
1494 {
1495 jbuf1.j_flg &= ~(KANJIINPUT | CONVTOINT); /* kanji henkan flg off */
1496 ioctl (ttyfd, JTERMSET, &jbuf1);
1497 return (1);
1498 }
1499 jbuf1.j_flg &= ~(KANJIINPUT | CONVTOINT); /* kanji henkan flg off */
1500 ioctl (ttyfd, JTERMSET, &jbuf1);
1501 return (0);
1502 }
1503 #endif /* defined(uniosu) */
1504
1505 /** 子プロセスを起こす。*/
1506
1507 int ttypfd = -1; /* slave tty */
1508
1509 static void
1510 exec_cmd (char **argv)
1511 {
1512 int i;
1513 #if defined(HAVE_LIBSPT) && !defined(USE_LINUX_TERM)
1514 int r;
1515 const char *ttynm;
1516 #elif !defined(HAVE_SETSID) || defined(USE_LINUX_TERM)
1517 #ifdef BSD42
1518 int pid;
1519 #endif
1520 #endif /* (!HAVE_LIBSPT && !HAVE_SETSID) || USE_LINUX_TERM */
1521 #if defined(SIGWINCH) && defined(TIOCSWINSZ) /* || defined(linux) */
1522 struct winsize win;
1523 extern int Term_RowWidth;
1524 #endif
1525
1526 child_id = fork ();
1527 if (child_id < 0)
1528 uum_err ("cannot fork.");
1529 if (!child_id)
1530 {
1531 /* --- start changing controlling tty --- */
1532 #if defined(HAVE_LIBSPT) && !defined(USE_LINUX_TERM)
1533 #if defined(SIGWINCH) && defined(TIOCSWINSZ)
1534 if (ioctl (ttyfd, TIOCGWINSZ, &win) == 0)
1535 ioctl (ttypfd, TIOCSWINSZ, &win);
1536 #endif /* SIGWINCH && TIOCSWINSZ */
1537 spt_detach_handle (spth);
1538 spth = NULL;
1539 if (spt_detach_ctty () || spt_set_ctty2 (ttypfd))
1540 {
1541 uum_err ("cannot change controlling tty.");
1542 }
1543
1544 #elif defined(HAVE_SETSID) && !defined(USE_LINUX_TERM) /* !HAVE_LIBSPT */
1545
1546 int fd;
1547 # if defined(SIGWINCH) && defined(TIOCSWINSZ)
1548 if (ioctl (ttyfd, TIOCGWINSZ, &win) == 0)
1549 ioctl (ttypfd, TIOCSWINSZ, &win);
1550 # endif /* SIGWINCH && TIOCSWINSZ */
1551 setsid ();
1552 # ifdef TIOCSCTTY
1553 ioctl (ttypfd, TIOCSCTTY, 0);
1554 # else
1555 close (open (ttyname (ttypfd), O_WRONLY, 0));
1556 # endif
1557 if ((fd = open("/dev/tty", O_WRONLY)) < 0)
1558 {
1559 uum_err ("cannot change controlling tty.");
1560 }
1561 close (fd);
1562 /* disable utmp logging for now */
1563
1564 #else /* (!HAVE_LIBSPT && !HAVE_SETSID) || USE_LINUX_TERM */
1565
1566 #ifdef BSD42
1567 #ifdef TIOCNOTTY
1568 /* set notty */
1569 {
1570 int fd;
1571 if ((fd = open ("/dev/tty", O_WRONLY)) >= 0)
1572 {
1573 (void) ioctl (fd, TIOCNOTTY, 0);
1574 close (fd);
1575 }
1576 }
1577 #endif /* TIOCNOTTY */
1578 #ifdef TIOCSCTTY
1579 setsid ();
1580 ioctl (ttypfd, TIOCSCTTY, 0);
1581 #endif /* TIOCSCTTY */
1582 /* set tty process group */
1583 pid = getpid ();
1584 ioctl (ttypfd, TIOCSPGRP, &pid);
1585 setpgrp (0, 0);
1586 close (open (ttyname (ttypfd), O_WRONLY, 0));
1587 setpgrp (0, pid);
1588 #endif /* BSD42 */
1589 #if defined(SYSVR2) && !defined(linux)
1590 setpgrp (); /* should setpgrp() AFTER fork() */
1591 close (open (ttyname (ttypfd), O_WRONLY, 0));
1592 #endif /* SYSVR2 */
1593
1594 #if 0
1595 /* unneccessary? */
1596 /* setutmp() does utmp handling if USE_UTMP is set to 1 */
1597 if (setutmp (ttypfd) == ERROR)
1598 {
1599 puts ("Can't set utmp.");
1600 }
1601 else
1602 {
1603 need_utmp_clear = 1;
1604 }
1605 #endif
1606
1607 /* It is bizarre to open tty after fork().
1608 So, try to do same as other os.
1609 If it does work, we can remove this. */
1610 # ifdef linux
1611 setsid ();
1612 open_ttyp ();
1613 close (ptyfd);
1614 ioctl (ttypfd, TCSETA, &savetmio);
1615 # endif
1616 # if defined(SIGWINCH) && defined(TIOCSWINSZ) /* || defined(linux) */
1617 ioctl (ttyfd, TIOCGWINSZ, &win);
1618 # endif
1619
1620 #endif /* (!HAVE_LIBSPT && !HAVE_SETSID) || USE_LINUX_TERM */
1621 /* --- finish changing controlling tty --- */
1622
1623 #ifndef linux
1624 setgid (getgid ());
1625 setuid (getuid ());
1626 #endif
1627 #ifdef HAVE_DUP2
1628 dup2 (ttypfd, 0);
1629 dup2 (ttypfd, 1);
1630 dup2 (ttypfd, 2);
1631 #else /* !HAVE_DUP2 */
1632 close (0);
1633 close (1);
1634 close (2);
1635 if (dup (ttypfd) != 0 || dup (ttypfd) != 1 || dup (ttypfd) != 2)
1636 {
1637 uum_err ("redirection fault.");
1638 }
1639 #endif /* !HAVE_DUP2 */
1640 for (i = WNN_NFD - 1; i > 2; i--)
1641 {
1642 close (i);
1643 }
1644
1645 restore_signals ();
1646
1647 #ifdef SIGTSTP
1648 signal (SIGTSTP, SIG_IGN);
1649 #endif
1650 #ifdef SIGTTIN
1651 signal (SIGTTIN, SIG_IGN);
1652 #endif
1653 #ifdef SIGTTOU
1654 signal (SIGTTOU, SIG_IGN);
1655 #endif
1656
1657 #if defined(SIGWINCH) && defined(TIOCSWINSZ) /* || defined(linux) */
1658 crow = win.ws_row = Term_RowWidth = win.ws_row - conv_lines;
1659 ioctl (ttyfd, TIOCSWINSZ, &win);
1660 #endif
1661 #ifdef linux
1662 setgid (getgid ());
1663 setuid (getuid ());
1664 #endif
1665 execvp (cmdnm, argv);
1666 uum_err ("exec fault.");
1667 }
1668
1669 /* parent */
1670 #ifdef HAVE_LIBSPT
1671 ttynm = ttyname (0);
1672 if (ttynm)
1673 {
1674 ttynm = strchr (ttynm + 1, '/');
1675 if (ttynm && ttynm[1])
1676 {
1677 spt_utmp_set_host (spth, ttynm + 1);
1678 }
1679 }
1680 spt_utmp_set_pid (spth, child_id);
1681 r = spt_login_utmp (spth);
1682 if (!r)
1683 {
1684 need_utmp_clear = 1;
1685 }
1686 else
1687 {
1688 spt_perror ("exec_cmd (login_utmp)", r);
1689 }
1690 #else /* !HAVE_LIBSPT */
1691 /* setutmp() does utmp handling if USE_UTMP is set to 1 */
1692 if (setutmp (ttypfd) == ERROR)
1693 {
1694 puts ("Can't set utmp.");
1695 }
1696 else
1697 {
1698 need_utmp_clear = 1;
1699 }
1700 #endif /* HAVE_LIBSPT */
1701 }
1702
1703 #if !(HAVE_SETENV)
1704 /** 環境変数のセット */
1705 /*
1706 * This function causes memory leak, but I leave it as it is. Anyway,
1707 * this function is called only a few times at the startup of uum.
1708 * The 3rd parameter is ignored. It is added for compatibility only.
1709 */
1710 int
1711 setenv (char *var, char *value, int overwrite)
1712 {
1713 extern char **environ;
1714 char **newenv;
1715 int i, j;
1716
1717 j = strlen (var);
1718 for (i = 0; environ[i] != NULL; i++)
1719 {
1720 if (strncmp (var, environ[i], j) == 0 && environ[i][j] == '=')
1721 {
1722 break;
1723 }
1724 }
1725 if (environ[i] == NULL)
1726 {
1727 if ((newenv = (char **) malloc ((sizeof (char *)) * (i + 2))) == NULL)
1728 {
1729 return (-1);
1730 }
1731 for (j = 0; j < i + 1; j++)
1732 {
1733 newenv[j] = environ[j];
1734 }
1735 newenv[i + 1] = NULL;
1736 environ = newenv;
1737 }
1738 if ((environ[i] = malloc (strlen (var) + strlen (value) + 2)) == NULL)
1739 {
1740 return (-1);
1741 }
1742 strcpy (environ[i], var);
1743 strcat (environ[i], "=");
1744 strcat (environ[i], value);
1745 return (0);
1746 }
1747 #endif /* !HAVE_SETENV */
1748
1749 #ifdef SVR4
1750 static int
1751 euc_set (eucioc_t *eucioc, int ttyfd)
1752 {
1753 struct strioctl sb;
1754
1755 sb.ic_cmd = EUC_WSET;
1756 sb.ic_timout = 0;
1757 sb.ic_len = sizeof (struct eucioc);
1758 sb.ic_dp = (char *) eucioc;
1759 if (ioctl (ttyfd, I_STR, &sb) < 0)
1760 {
1761 return (1);
1762 }
1763 return (0);
1764 }
1765
1766 static int
1767 set_euc_term (int ttyfd)
1768 {
1769 eucioc_t eucioc;
1770
1771 /* for Japanese EUC */
1772 eucioc.eucw[0] = 1;
1773 eucioc.eucw[1] = 2;
1774 eucioc.eucw[2] = 2;
1775 eucioc.eucw[3] = 3;
1776 eucioc.scrw[0] = 1;
1777 eucioc.scrw[1] = 2;
1778 eucioc.scrw[2] = 1;
1779 eucioc.scrw[3] = 2;
1780 if (euc_set (&eucioc, ttyfd) != 0)
1781 {
1782 fprintf (stderr, "eucwidth set failed\n");
1783 return (1);
1784 }
1785 return (0);
1786 }
1787
1788 #endif /* SVR4 */
1789
1790 #ifdef nec_ews_svr2
1791 static void
1792 set_jterm (int ttyfd, int ttypfd)
1793 {
1794 struct jtermio buf;
1795
1796 if (ioctl (ttyfd, TCJGETA, &buf) == -1)
1797 {
1798 fprintf (stderr, "error in ioctl TCJGETA.\n");
1799 exit (1);
1800 }
1801 buf.c_iflag = 0;
1802 buf.c_oflag = 0;
1803 if (ioctl (ttypfd, TCJSETA, &buf) < 0)
1804 {
1805 fprintf (stderr, "error in ioctl TCSETA.\n");
1806 exit (1);
1807 }
1808 }
1809 #endif /* nec_ews_svr2 */
1810
1811 #ifdef sony
1812 static void
1813 set_sony_jterm (int ttyfd, int ttypfd)
1814 {
1815 #ifdef TIOCKGET
1816 int tmode, jmode = 0;
1817 struct jtchars jtc;
1818
1819 if (ioctl(ttyfd, TIOCKGET, &tmode) < 0)
1820 {
1821 fprintf(stderr, "error in ioctl TIOCKGET.\n");
1822 exit (1);
1823 }
1824 jmode = tmode;
1825 tmode &= ~(KM_SYSCODE | KM_TTYPE);
1826 switch (pty_c_flag)
1827 {
1828 case J_EUJIS:
1829 tmode |= KM_EUC | KM_SYSEUC;
1830 break;
1831 case J_JIS:
1832 tmode |= KM_ASCII;
1833 break;
1834 case J_SJIS:
1835 tmode |= KM_SJIS | KM_SYSSJIS;
1836 break;
1837 }
1838 if (ioctl(ttypfd, TIOCKSET, &tmode) < 0)
1839 {
1840 fprintf(stderr, "error in ioctl TIOCKSET.\n");
1841 exit (1);
1842 }
1843 #endif /* TIOCKGET */
1844
1845 #ifdef TIOCKGETC
1846 if ((jmode & KM_TTYPE) == KM_JIS)
1847 {
1848 ioctl(ttyfd, TIOCKGETC, &jtc);
1849 jtc.t_ascii = 'B';
1850 jtc.t_kanji = 'B';
1851 if (ioctl(ttypfd, TIOCKSETC, &jtc) < 0)
1852 {
1853 fprintf(stderr, "error in ioctl TIOCKSETC.\n");
1854 exit(1);
1855 }
1856 }
1857 #endif
1858 }
1859 #endif /* sony */
1860
1861 /** ttyp のオープン */
1862
1863 #ifndef HAVE_LIBSPT
1864 /* ways to get a pty'
1865 == Traditional
1866 Try opening each /dev/ptyXX and use the succeeded one
1867 == SGI IRIX
1868 use _getpty()
1869 == BSD? (HAVE_OPENPTY)
1870 use openpty()
1871 == STREAMS (Solaris) (HAVE_PTSNAME)
1872 use posix_openpt() (or open /dev/ptmx directly) and ptsname()
1873 (see pts(7D) for EXAMPLE)
1874 */
1875
1876 #if !defined(sgi) && !defined(HAVE_PTSNAME)
1877 char tty_master[32]; /*VVVV overflow?*/
1878 #endif
1879 char tty_slave [32]; /*VVVV overflow?*/
1880
1881 #if defined(BSD43) || defined(DGUX) /* FOR PASS8 */
1882 static int local_mode_sv;
1883 #endif
1884 #endif /* !HAVE_LIBSPT */
1885
1886 /* open slave side of pty to ttypfd */
1887 static void
1888 open_ttyp (void)
1889 {
1890 #ifdef HAVE_LIBSPT
1891 if ((ttypfd = spt_open_slave(spth)) == ERROR)
1892 #else /* HAVE_LIBSPT */
1893 # if defined(sgi)
1894 if ((ttypfd = open (tty_slave, O_RDWR)) == ERROR)
1895 # elif defined(HAVE_PTSNAME)
1896 if ((ttypfd = open(tty_slave, O_RDWR)) == ERROR /* open slave */
1897 # if defined(I_PUSH)
1898 /* for systems that have STREAMS */
1899 || ioctl (ttypfd, I_PUSH, "ptem") == ERROR /* push ptem */
1900 || ioctl (ttypfd, I_PUSH, "ldterm") == ERROR /* push ldterm */
1901 # endif
1902 )
1903 # elif defined (HAVE_OPENPTY)
1904 if (ttypfd < 0) /* already open */
1905 # else
1906 if ((ttypfd = open (tty_slave, O_RDWR, 0)) == ERROR) /* old method */
1907 # endif /* sgi */
1908 #endif /* HAVE_LIBSPT */
1909 {
1910 perror(tty_slave); /* debug */
1911 uum_err ("Can't open ttyp.");
1912 }
1913 #if defined(HAVE_LIBSPT)
1914 spt_init_slavefd(spth, ttypfd);
1915 #else
1916 /* #if !defined(linux) */
1917 chown (tty_slave, getuid (), getgid ());
1918 chmod (tty_slave, 0622);
1919 /* #endif */ /* linux */
1920 #endif /* HAVE_LIBSPT */
1921
1922 /*
1923 * We save terminal settings in main() instead of here.
1924 * When defined(linux) open_ttyp() is invoked from child!
1925 */
1926 #ifndef USE_LINUX_TERM
1927 j_term_p_init (ttypfd);
1928 #endif
1929
1930 #ifdef TIOCSSIZE
1931 pty_rowcol.ts_lines = crow; /* instead of lines */
1932 pty_rowcol.ts_cols = maxlength; /* instead of columns */
1933 ioctl (ttypfd, TIOCSSIZE, &pty_rowcol);
1934 #endif /* TIOCSSIZE */
1935
1936 #ifdef SVR4
1937 set_euc_term(ttypfd);
1938 #endif
1939 #if defined(nec_ews_svr2)
1940 set_jterm (ttyfd, ttypfd);
1941 #endif
1942 #ifdef sony
1943 set_sony_jterm(ttyfd, ttypfd);
1944 #endif
1945 }
1946
1947 #if defined(HAVE_PTSNAME) && ! defined(HAVE_POSIX_OPENPT)
1948 /* Maybe harmless on defined(HAVE_LIBSPT) */
1949 #if !defined(HAVE__DEV_PTMX)
1950 #warning "If not cross compile, you must check pts master device (other than /dev/ptmx)."
1951 /* but continue anyway. */
1952 #endif
1953
1954 /* fallback function to posix_openpt */
1955 static int
1956 posix_openpt (int flags)
1957 {
1958 return open("/dev/ptmx", flags);
1959 }
1960 #endif /* HAVE_PTSNAME && !HAVE_POSIX_OPENPT */
1961
1962 /** pty のオープン */
1963 /* allocate a new pty master into int ptyfd */
1964 static void
1965 open_pty (void)
1966 {
1967 #if defined(HAVE_LIBSPT)
1968 int r;
1969 r = spt_open_pty(&spth, &ptyfd, NULL, NULL);
1970 if (r != SPT_E_NONE && r != SPT_E_CHOWN_FAIL)
1971 uum_err ("Can't get pty.");
1972
1973 #elif defined(sgi)
1974 char *tty_name_buff;
1975 extern char *_getpty (int *, int, mode_t, int);
1976 tty_name_buff = _getpty (&ptyfd, O_RDWR | O_NDELAY, 0600, 0);
1977 if (tty_name_buff == 0)
1978 uum_err ("Can't get pty.");
1979 strcpy (tty_slave, tty_name_buff);
1980
1981 #elif defined(HAVE_PTSNAME)
1982 char *p;
1983 ptyfd = posix_openpt(O_RDWR); /* open master */
1984 if (ptyfd < 0)
1985 uum_err ("Could not get a pty.");
1986 grantpt (ptyfd); /* change permission of slave */
1987 unlockpt (ptyfd); /* unlock slave */
1988
1989 p = ptsname (ptyfd); /* get name of slave */
1990 strcpy(tty_slave, p);
1991 /* you can't get path of the "master" by ttyname;
1992 * only the open filedes ptyfd is available.
1993 */
1994 /* strcpy (tty_master, "/dev/ptm/x"); */
1995
1996 #elif HAVE_OPENPTY
1997 if (openpty(&ptyfd, &ttypfd, tty_slave, NULL, NULL) == ERROR)
1998 uum_err ("Could not get a pty.");
1999 /* Note: slave tty is ALREADY OPEN as ttypfd */
2000 strcpy(tty_master, ttyname(ptyfd));
2001
2002 #else
2003 /* Traditional method that search in /dev/ttyXX */
2004 open_pty_traditional ();
2005 #endif /* HAVE_LIBSPT */
2006
2007 return;
2008 }
2009
2010 #if !(HAVE_LIBSPT) && !(sgi) && !(HAVE_PTSNAME) && !(HAVE_OPENPTY)
2011 static void
2012 open_pty_traditional (void)
2013 {
2014 int ptyno;
2015
2016 #ifdef hpux
2017 # define MAXPTYS (11*16)
2018 # define PTYDEV ";/dev/ptym/pty"
2019 # define TTYDEV "/dev/pty/tty"
2020 #else
2021 # define MAXPTYS 32
2022 # define PTYDEV "/dev/pty"
2023 # define TTYDEV "/dev/tty"
2024 #endif
2025
2026 for (ptyno = 0; ptyno < MAXPTYS; ptyno++) /* sysconf? */
2027 {
2028 /*
2029 * Change pseudo-devices.
2030 * Because FreeBSD's master pseudo-devices are pty[p-sP-S][0-9a-v].
2031 * Patched by Hidekazu Kuroki(hidekazu@cs.titech.ac.jp) 1996/8/20
2032 */
2033 #if (defined(BSD) && (BSD >= 199306)) /* 4.4BSD-Lite by Taoka */
2034 # define PTXNAME(b, PFX, no) \
2035 sprintf ((b), PFX "%1c%1c", "pqrsPQRS"[((no) >> 5)], "0123456789abcdefghijklmnopqrstuv"[(no) & 0x1f])
2036 #elif defined(hpux)
2037 # define PTXNAME(b, PFX, no) \
2038 sprintf ((b), PFX "%1c%1c", "zyxwvutsrqp"[(no)>>4], "fedcba9876543210"[(no)&0x0f])
2039 #else /* !4.4BSD-Lite, !hpux */
2040 # define PTXNAME(b, PFX, no) \
2041 sprintf ((b), PFX "%1c%1c", 'p' + ((no) >> 4), "0123456789abcdef"[(no) & 0x0f]);
2042 #endif /* !4.4BSD-Lite */
2043 #define PTMNAME(b, no) PTXNAME(b, PTYDEV, no)
2044 #define PTSNAME(b, no) PTXNAME(b, TTYDEV, no)
2045
2046 PTMNAME(tty_master, ptyno);
2047 fprintf(stderr, "trying master <%s>\n", tty_master); /* debug */
2048 if ((ptyfd = open (tty_master, O_RDWR, 0)) != ERROR)
2049 {
2050 # if defined(uniosu)
2051 if (ioctl (ptyfd, PIOCPKT, 1) < 0)
2052 { /* packet mode on */
2053 fprintf (stderr, "error in ioctl PIOCPKT.\n");
2054 exit (1);
2055 }
2056 # endif /* uniosu */
2057 return;
2058 }
2059 }
2060 uum_err ("Can't get pty.");
2061 }
2062 #endif /* !(HAVE_LIBSPT) && !(sgi) && !(HAVE_PTSNAME) && !(HAVE_OPENPTY) */
2063
2064 /** エラーだよ。さようなら。 */
2065 void
2066 uum_err (char *s)
2067 {
2068 puts (s);
2069 fclose (stdout);
2070 fclose (stderr);
2071 fclose (stdin);
2072 do_end ();
2073 }
2074
2075 /** 立つ鳥後を濁さず 終わりの処理 */
2076 static void
2077 do_end (void)
2078 {
2079 #ifdef USE_LIBSPT
2080 int r;
2081 #endif
2082
2083 static int do_end_flg = 0;
2084 if (do_end_flg == 1)
2085 return;
2086 do_end_flg = 1;
2087
2088 signal (SIGCHLD, SIG_DFL);
2089 fcntl (ttyfd, F_SETFL, 0);
2090 j_term_restore ();
2091
2092 #if !defined(HAVE_LIBSPT) && !defined(sgi)
2093 # ifndef HAVE_PTSNAME
2094 if (chown (tty_master, 0, 0) == ERROR)
2095 {
2096 perror (prog);
2097 }
2098 if (chmod (tty_master, 0666) == ERROR)
2099 {
2100 perror (prog);
2101 }
2102
2103 if (chown (tty_slave, 0, 0) == ERROR)
2104 {
2105 perror (prog);
2106 }
2107 if (chmod (tty_slave, 0666) == ERROR)
2108 {
2109 perror (prog);
2110 }
2111 # endif /* HAVE_PTSNAME */
2112
2113 #endif /* !HAVE_LIBSPT && !sgi */
2114 close (ttyfd);
2115 #ifdef HAVE_LIBSPT
2116 if (spth && need_utmp_clear && (r = spt_logout_utmp(spth)))
2117 spt_perror(NULL, r);
2118 if (spth && (r = spt_close_pty(spth)))
2119 spt_perror(NULL, r);
2120 #else
2121 /* needless? */
2122 /* resetutmp() does utmp handling if USE_UTMP is set to 1 */
2123 if (need_utmp_clear)
2124 {
2125 if (resetutmp (ttypfd) == ERROR)
2126 {
2127 printf ("Can't reset utmp.");
2128 }
2129 need_utmp_clear = 0; /* for safety */
2130 }
2131 close (ptyfd);
2132 #endif /* HAVE_LIBSPT */
2133
2134 chdir ("/tmp"); /* to avoid making too many mon.out files */
2135
2136 KILLPG (child_id, SIGHUP);
2137 exit (0);
2138 }
2139
2140 #if defined(uniosu)
2141 /** 仮名漢字変換を ioctl でオフした時の keyin に代わる関数 */
2142 int
2143 ioctl_off (void)
2144 {
2145 static unsigned char buf[BUFSIZ];
2146 int n;
2147 fd_set rfds;
2148
2149 kk_restore_cursor ();
2150 clr_line_all ();
2151 display_henkan_off_mode ();
2152
2153 for (;;)
2154 {
2155 if ((n = read (ttyfd, buf, BUFSIZ)) > 0)
2156 {
2157 write (ptyfd, buf, n);
2158 }
2159 rfds = sel_ptn;
2160 select (FD_SETSIZE, &rfds, 0, 0, NULL);
2161 if (FD_ISSET(ptyfd, &rfds))
2162 {
2163 if ((n = read (ptyfd, buf, BUFSIZ)) <= 0)
2164 {
2165 epilogue ();
2166 do_end ();
2167 }
2168 if (*buf == 0)
2169 { /* sequence of data */
2170 write (ttyfd, buf + 1, n - 1);
2171 }
2172 else if (*buf == PIOCPKT_IOCTL)
2173 {
2174 if (arrange_ioctl (0) > 0)
2175 {
2176 return;
2177 }
2178 }
2179 }
2180 if (FD_ISSET(ttyfd, &rfds))
2181 {
2182 if ((n = read (ttyfd, buf, BUFSIZ)) > 0)
2183 {
2184 write (ptyfd, buf, n);
2185 }
2186 }
2187 }
2188 }
2189 #endif /* defined(uniosu) */
2190
2191 static void
2192 default_usage (void)
2193 {
2194 fprintf (stderr, "%s: Bad -L option\n", prog);
2195 exit (0);
2196 }
2197
2198 static void
2199 usage (char *optstr)
2200 {
2201 printf ("usage: prog %s by lang \"%s\"\n", optstr, lang_dir);
2202 exit (0);
2203 }
2204
2205 /*
2206 save/restore signal settings
2207 */
2208
2209 intfnptr sigpipe, sighup, sigint, sigquit, sigterm, sigtstp, sigttin, sigttou, sigchld;
2210 #ifdef SIGWINCH
2211 intfnptr sigwinch;
2212 #endif /* SIGWINCH */
2213
2214 static void
2215 save_signals (void)
2216 {
2217 sigpipe = signal (SIGPIPE, SIG_IGN);
2218 #ifdef linux /* XXX */
2219 sighup = signal (SIGHUP, SIG_IGN);
2220 #endif
2221 sighup = signal (SIGHUP, terminate_handler);
2222 sigint = signal (SIGINT, SIG_IGN);
2223 sigquit = signal (SIGQUIT, SIG_IGN);
2224 sigterm = signal (SIGTERM, terminate_handler);
2225 sigchld = signal (SIGCHLD, chld_handler);
2226 #ifdef SIGWINCH
2227 sigwinch = signal (SIGWINCH, resize_handler);
2228 #endif /* SIGWINCH */
2229 #ifdef SIGTSTP
2230 sigtstp = signal (SIGTSTP, SIG_IGN);
2231 sigttin = signal (SIGTTIN, SIG_IGN);
2232 sigttou = signal (SIGTTOU, SIG_IGN);
2233 #endif /* SIGTSTP */
2234 }
2235
2236 static void
2237 restore_signals (void)
2238 {
2239 signal (SIGPIPE, sigpipe);
2240 signal (SIGHUP, sighup);
2241 signal (SIGINT, sigint);
2242 signal (SIGQUIT, sigquit);
2243 signal (SIGTERM, sigterm);
2244 signal (SIGCHLD, sigchld);
2245 #ifdef SIGWINCH
2246 signal (SIGWINCH, sigwinch);
2247 #endif /* SIGWINCH */
2248 #ifdef SIGTSTP
2249 signal (SIGTSTP, sigtstp);
2250 signal (SIGTTIN, sigttin);
2251 signal (SIGTTOU, sigttou);
2252 #endif /* SIGTSTP */
2253 }
2254
2255 #if defined(BSD43) || defined(DGUX)
2256 static void
2257 setsize (void)
2258 {
2259 int i;
2260 struct winsize win;
2261 extern int Term_LineWidth, Term_RowWidth, maxlength;
2262
2263 if (ioctl (ttyfd, TIOCGWINSZ, &win) < 0)
2264 {
2265 /* Default set at getTermData() */
2266 return;
2267 }
2268 else
2269 {
2270 if ((i = win.ws_row) != 0)
2271 {
2272 crow = Term_RowWidth = i - conv_lines;
2273 }
2274 if ((i = win.ws_col) != 0)
2275 {
2276 maxlength = Term_LineWidth = i;
2277 }
2278 }
2279 }
2280 #endif /* BSD43 */
2281
2282 #ifdef SIGWINCH
2283 static void
2284 change_size (void)
2285 {
2286 register int i;
2287 struct winsize win;
2288 extern int Term_LineWidth, Term_RowWidth, maxlength;
2289
2290 if (ioctl (ttyfd, TIOCGWINSZ, &win) < 0)
2291 {
2292 /* Default set at getTermData() */
2293 return;
2294 }
2295 else
2296 {
2297 throw_cur_raw (0, crow);
2298 clr_line ();
2299
2300 if ((i = win.ws_row) != 0)
2301 {
2302 crow = Term_RowWidth = i - conv_lines;
2303 #ifdef TIOCSWINSZ
2304 win.ws_row = crow;
2305 #endif
2306 }
2307 if ((i = win.ws_col) != 0)
2308 {
2309 maxlength = Term_LineWidth = i;
2310 }
2311 #ifdef TIOCSWINSZ
2312 ioctl (ttypfd, TIOCSWINSZ, &win);
2313 #else /* !TIOCSWINSZ */
2314 #ifdef TIOCSSIZE
2315 pty_rowcol.ts_lines = crow; /* instead of lines */
2316 pty_rowcol.ts_cols = maxlength; /* instead of columns */
2317 ioctl (ttypfd, TIOCSSIZE, &pty_rowcol);
2318 #endif /* TIOCSSIZE */
2319 #ifdef sun /* When your machine needs SIGWINCH, add your machine */
2320 {
2321 int grp;
2322 ioctl (ptyfd, TIOCGPGRP, &grp);
2323 KILLPG (grp, SIGWINCH);
2324 }
2325 #endif /* sun */
2326 #endif /* !TIOCSWINSZ */
2327
2328 #ifndef CANNA
2329 set_scroll_region (0, crow - 1);
2330 if (henkan_off_flag)
2331 {
2332 kk_restore_cursor ();
2333 throw_cur_raw (0, 0);
2334 kk_save_cursor ();
2335 display_henkan_off_mode ();
2336 set_screen_vars_default ();
2337 t_print_l ();
2338 kk_restore_cursor ();
2339 }
2340 else
2341 {
2342 kk_restore_cursor ();
2343 throw_cur_raw (0, 0);
2344 kk_save_cursor ();
2345 disp_mode ();
2346 set_screen_vars_default ();
2347 t_print_l ();
2348 }
2349 #else /* CANNA */
2350 set_scroll_region(0, crow - 1);
2351 set_screen_vars_default();
2352 t_print_l();
2353 #endif /* CANNA */
2354 }
2355 }
2356 #endif /* SIGWINCH */