]>
diplodocus.org Git - nmh/blob - uip/wmh.c
3 * wmh.c -- window front-end to nmh
7 * This code is Copyright (c) 2002, by the authors of nmh. See the
8 * COPYRIGHT file in the root directory of the nmh distribution for
9 * complete copyright information.
14 * Pass signals to client during execution
16 * Figure out a way for the user to say how big the Scan/Display
17 * windows should be, and where all the windows should be.
21 #include <h/signals.h>
32 #define ALARM ((unsigned int) 10)
33 #define PAUSE ((unsigned int) 2)
35 #define SZ(a) (sizeof a / sizeof a[0])
37 static struct swit switches
[] = {
39 { "prompt string", 6 },
41 { "vmhproc program", 7 },
51 static int PEERpid
= NOTOK
;
53 static jmp_buf PEERctx
;
57 static int dfd
= NOTOK
;
58 static int twd
= NOTOK
;
59 static char *myprompt
= "(%s) ";
88 struct line
*w_bottom
;
90 char w_buffer
[BUFSIZ
];
96 static WINDOW
*Status
;
97 static WINDOW
*Display
;
98 static WINDOW
*Command
;
102 WINDOW
*windows
[NWIN
+ 1];
107 #ifdef HAVE_TERMIOS_H
108 static struct termios tio
;
109 # define ERASE tio.c_cc[VERASE]
110 # define KILL tio.c_cc[VKILL]
111 # define INTR tio.c_cc[VINTR]
113 # ifdef HAVE_TERMIO_H
114 static struct termio tio
;
115 # define ERASE tio.c_cc[VERASE]
116 # define KILL tio.c_cc[VKILL]
117 # define INTR tio.c_cc[VINTR]
119 static struct sgttyb tio
;
120 static struct tchars tc
;
121 # define ERASE tio.sg_erase
122 # define KILL tio.sg_kill
123 # define INTR tc.t_intrc
124 # define EOFC tc.t_eofc
128 #define WERASC ltc.t_werasc
129 static struct ltchars ltc
;
133 int ALRMser (), PIPEser (), SIGser ();
134 int ADJser (), REFser ();
139 static void adorn(char *, char *, ...);
143 main (int argc
, char **argv
)
145 int vecp
= 1, nprog
= 0;
146 char *cp
, buffer
[BUFSIZ
], **argp
;
147 char **arguments
, *vec
[MAXARGS
];
150 setlocale(LC_ALL
, "");
152 invo_name
= r1bindex (argv
[0], '/');
154 /* read user profile/context */
157 arguments
= getarguments (invo_name
, argc
,argv
, 1);
160 while ((cp
= *argp
++))
162 switch (smatch (++cp
, switches
)) {
164 ambigsw (cp
, switches
);
171 snprintf (buffer
, sizeof(buffer
), "%s [switches for vmhproc]",
173 print_help (buffer
, switches
, 1);
176 print_version(invo_name
);
180 if (!(myprompt
= *argp
++) || *myprompt
== '-')
181 adios (NULL
, "missing argument to %s", argp
[-2]);
185 if (!(vmhproc
= *argp
++) || *vmhproc
== '-')
186 adios (NULL
, "missing argument to %s", argp
[-2]);
196 if (WINinit (nprog
) == NOTOK
) {
199 vec
[0] = r1bindex (vmhproc
, '/');
200 execvp (vmhproc
, vec
);
201 adios (vmhproc
, "unable to exec");
203 PEERinit (vecp
, vec
);
214 char buffer
[BUFSIZ
], prompt
[BUFSIZ
];
217 pLOOP (RC_QRY
, NULL
);
219 snprintf (prompt
, sizeof(prompt
), myprompt
, invo_name
);
221 switch (WINgetstr (Command
, prompt
, buffer
)) {
226 done (0); /* NOTREACHED */
230 pLOOP (RC_CMD
, buffer
);
239 PEERinit (int vecp
, char *vec
[])
241 int pfd0
[2], pfd1
[2];
242 char buf1
[BUFSIZ
], buf2
[BUFSIZ
];
245 SIGNAL (SIGPIPE
, PIPEser
);
247 if (pipe (pfd0
) == NOTOK
|| pipe (pfd1
) == NOTOK
)
248 adios ("pipe", "unable to");
249 switch (PEERpid
= vfork ()) {
251 adios ("vfork", "unable to");/* NOTREACHED */
254 for (w
= windows
; *w
; w
++)
255 if ((*w
)->w_fd
!= NOTOK
)
260 vec
[vecp
++] = "-vmhread";
261 snprintf (buf1
, sizeof(buf1
), "%d", pfd1
[0]);
263 vec
[vecp
++] = "-vmhwrite";
264 snprintf (buf2
, sizeof(buf2
), "%d", pfd0
[1]);
268 SIGNAL (SIGINT
, SIG_DFL
);
269 SIGNAL (SIGQUIT
, SIG_DFL
);
270 SIGNAL (SIGTERM
, SIG_DFL
);
272 vec
[0] = r1bindex (vmhproc
, '/');
273 execvp (vmhproc
, vec
);
275 _exit (-1); /* NOTREACHED */
281 rcinit (pfd0
[0], pfd1
[1]);
291 char *bp
, buffer
[BUFSIZ
];
292 struct record rcs
, *rc
;
298 /* Get buffer ready to go */
300 buflen
= sizeof(buffer
);
302 snprintf (bp
, buflen
, "%d %d", RC_VRSN
, numwins
);
307 for (w
= windows
; *w
; w
++) {
308 snprintf (bp
, buflen
, " %d", (*w
)->w_height
);
314 switch (str2rc (RC_INI
, buffer
, rc
)) {
320 adios (NULL
, "%s", rc
->rc_data
);
322 adios (NULL
, "pINI peer error");
325 adios (NULL
, "%s", rc
->rc_data
);
328 adios (NULL
, "pINI protocol screw-up");
335 pLOOP (char code
, char *str
)
338 struct record rcs
, *rc
;
344 str2peer (code
, str
);
346 switch (peer2rc (rc
)) {
348 if (pTTY () == NOTOK
)
353 if (sscanf (rc
->rc_data
, "%d", &i
) != 1
356 fmt2peer (RC_ERR
, "no such window \"%s\"", rc
->rc_data
);
359 if ((w
= windows
[i
- 1])->w_flags
& W_CMND
) {
360 fmt2peer (RC_ERR
, "not a display window \"%s\"", rc
->rc_data
);
363 if (pWIN (w
) == NOTOK
)
372 adorn (NULL
, "%s", rc
->rc_data
);
374 adorn (NULL
, "pLOOP(%s) peer error",
375 code
== RC_QRY
? "QRY" : "CMD");
380 adorn (NULL
, "%s", rc
->rc_data
);
382 i
= pidwait (PEERpid
, OK
);
387 adios (NULL
, "%s", rc
->rc_data
);
390 adios (NULL
, "pLOOP(%s) protocol screw-up",
391 code
== RC_QRY
? "QRY" : "CMD");
399 SIGNAL_HANDLER hstat
, istat
, qstat
, tstat
;
400 struct record rcs
, *rc
;
405 if (ChangeWindowDepth (dfd
, twd
, 0) == NOTOK
)
406 adios ("failed", "ChangeWindowDepth");
408 /* should block here instead of ignore */
409 hstat
= SIGNAL (SIGHUP
, SIG_IGN
);
410 istat
= SIGNAL (SIGINT
, SIG_IGN
);
411 qstat
= SIGNAL (SIGQUIT
, SIG_IGN
);
412 tstat
= SIGNAL (SIGTERM
, SIG_IGN
);
414 rc2rc (RC_ACK
, 0, NULL
, rc
);
416 SIGNAL (SIGHUP
, hstat
);
417 SIGNAL (SIGINT
, istat
);
418 SIGNAL (SIGQUIT
, qstat
);
419 SIGNAL (SIGTERM
, tstat
);
421 switch (rc
->rc_type
) {
423 rc2peer (RC_ACK
, 0, NULL
);
428 adorn (NULL
, "%s", rc
->rc_data
);
430 adorn (NULL
, "pTTY peer error");
434 adios (NULL
, "%s", rc
->rc_data
);
437 adios (NULL
, "pTTY protocol screw-up");
448 if ((i
= pWINaux (w
)) == OK
)
460 register struct line
*lp
, *mp
;
461 struct record rcs
, *rc
;
466 for (lp
= w
->w_head
; lp
; lp
= mp
) {
471 w
->w_head
= w
->w_top
= w
->w_bottom
= w
->w_tail
= NULL
;
475 switch (rc2rc (RC_ACK
, 0, NULL
, rc
)) {
477 for (bp
= rc
->rc_data
, n
= rc
->rc_len
; n
-- > 0; )
482 rc2peer (RC_ACK
, 0, NULL
);
489 adorn (NULL
, "%s", rc
->rc_data
);
491 adorn (NULL
, "pWIN peer error");
495 adios (NULL
, "%s", rc
->rc_data
);
498 adios (NULL
, "pWIN protocol screw-up");
512 rc2peer (RC_FIN
, 0, NULL
);
515 switch (setjmp (PEERctx
)) {
517 SIGNAL (SIGALRM
, ALRMser
);
520 status
= pidwait (PEERpid
, OK
);
526 kill (PEERpid
, SIGKILL
);
537 /* should dynamically determine all this stuff from gconfig... */
539 #define MyX 20 /* anchored hpos */
540 #define MyY 40 /* .. vpos */
541 #define MyW 800 /* .. width */
542 #define MyH 500 /* .. height */
543 #define MyS 30 /* .. height for Status, about one line */
546 #define MySlop 45 /* slop */
548 #define EWIDTH 25 /* Width of vertical EBAR */
549 #define ESLOP 5 /* .. slop */
552 static intWINinit (nprog
) {
553 short wx
, wy
, wh
, sy
;
556 if (GetGraphicsConfig (fileno (stderr
), &gc
) == NOTOK
)
560 adios (NULL
, "not a window");
562 if ((dfd
= open ("/dev/ttyw0", O_RDWR
)) == NOTOK
)
563 adios ("/dev/ttyw0", "unable to open");
565 if ((twd
= GetTopWindow (dfd
)) == NOTOK
)
566 adios ("failed", "GetTopWindow");
568 BlockRefreshAdjust (1);
572 wx
= gc
.w
- (MyX
+ MyW
+ EWIDTH
+ ESLOP
);
573 Scan
= WINnew (wx
, wy
= MyY
, MyW
, wh
= MyH
* 2 / 3, "Scan", W_EBAR
);
576 Status
= WINnew (wx
, sy
= wy
, MyW
, wh
= MyS
, "Status", W_FAKE
);
579 Display
= WINnew (wx
, wy
, MyW
, MyH
, "Display", W_EBAR
);
581 Command
= WINnew (wx
, sy
, MyW
, MyS
, invo_name
, W_CMND
);
583 windows
[numwins
] = NULL
;
590 WINnew (short wx
, short wy
, short ww
, short wh
, char *name
, int flags
)
594 if ((w
= (WINDOW
*) calloc (1, sizeof *w
)) == NULL
)
595 adios (NULL
, "unable to allocate window");
597 if ((w
->w_flags
= flags
) & W_FAKE
) {
604 if (w
->w_flags
& W_EBAR
)
605 ww
+= EWIDTH
+ ESLOP
;
607 wx
+= EWIDTH
+ ESLOP
;
609 if ((w
->w_fd
= OpenWindow (wx
, wy
, ww
, wh
, name
)) == NOTOK
)
610 adios ("failed", "OpenWindow");
611 if ((w
->w_wd
= GetTopWindow (dfd
)) == NOTOK
)
612 adios ("failed", "GetTopWindow");
613 if (GetWindowState (w
->w_fd
, &w
->w_ws
) == NOTOK
)
614 adios ("failed", "GetWindowState");
615 if (SetLineDisc (w
->w_fd
, TWSDISC
) == NOTOK
)
616 adios ("failed", "SetLineDisc");
618 SetBuf (w
->w_fd
, 1024);
619 SetAdjust (w
->w_fd
, numwins
, ADJser
);
620 SetRefresh (w
->w_fd
, numwins
, REFser
);
622 SetAddressing (w
->w_fd
, VT_ABSOLUTE
);
624 if (w
->w_flags
& W_EBAR
) {
625 w
->w_eb
= CreateElevatorBar (w
->w_fd
, 0, 0, EWIDTH
,
626 w
->w_ws
.height
, VT_Gray50
, 1, EB_VERTICAL
,
627 EB_ARROWS
, w
->w_ebloc
= 0, w
->w_ebsize
= EB_MAX
,
630 adios (NULL
, "CreateElevatorBar failed");
631 RefreshElevatorBar (w
->w_eb
);
634 if ((w
->w_cbase
= CharacterBaseline (w
->w_ws
.font
)) <= 0)
637 if ((w
->w_cheight
= CharacterHeight (w
->w_ws
.font
)) <= 0)
639 w
->w_height
= w
->w_ws
.height
/ w
->w_cheight
;
644 if ((w
->w_cwidth
= CharacterWidth (w
->w_ws
.font
, 'm')) <= 0)
646 w
->w_width
= (w
->w_ws
.width
- (w
->w_eb
? (EWIDTH
+ ESLOP
) : 0))
652 windows
[numwins
++] = w
;
659 WINgetstr (WINDOW
*w
, char *prompt
, char *buffer
)
662 register char *bp
, *ip
;
665 register struct vtseq
*vt
= &vts
;
668 adios (NULL
, "internal error--elevator bar found");
670 if (w
->w_head
== NULL
671 && (w
->w_head
= (struct line
*) calloc (1, sizeof *w
->w_head
))
673 adios (NULL
, "unable to allocate line storage");
674 w
->w_head
->l_buf
= image
;
675 w
->w_top
= w
->w_bottom
= w
->w_tail
= w
->w_head
;
677 if (ChangeWindowDepth (dfd
, w
->w_wd
, 0) == NOTOK
)
678 adios ("failed", "ChangeWindowDepth");
680 strncpy (image
, prompt
, sizeof(image
));
681 bp
= ip
= image
+ strlen (image
);
686 switch (getvtseq (w
->w_fd
, vt
)) {
688 DisplayStatus (w
->w_fd
, "no hardkeys, please");
692 switch (c
= toascii (vt
->u
.ascii
)) {
693 case '\f': /* refresh? */
703 adorn (NULL
, "Interrupt");
732 } while (isspace (*bp
) && bp
> ip
);
736 } while (!isspace (*bp
) && bp
> buffer
);
743 if (c
< ' ' || c
>= '\177')
753 switch (vt
->u
.mouse
.buttons
754 & (VT_MOUSE_LEFT
| VT_MOUSE_MIDDLE
| VT_MOUSE_RIGHT
)) {
756 DisplayStatus (w
->w_fd
, "use middle or right button");
759 #define WPOP "WMH\0Advance\0Burst\0Exit\0EOF\0"
760 case VT_MOUSE_MIDDLE
:
761 SetPosition (w
->w_fd
, vt
->u
.mouse
.x
,
763 switch (DisplayPopUp (w
->w_fd
, WPOP
)) {
764 case 1: /* Advance */
766 strcpy (buffer
, "advance");
770 strcpy (buffer
, "burst");
774 strcpy (buffer
, "exit");
780 default: /* failed or none taken */
792 adios (NULL
, "end-of-file on window");/* NOTREACHED */
795 DisplayStatus (w
->w_fd
, "unknown VT sequence");
802 WINputc (WINDOW
*w
, char c
)
806 register struct line
*lp
;
811 if (WINputc (w
, 'M') == NOTOK
|| WINputc (w
, '-') == NOTOK
)
816 if (c
< ' ' || c
== '\177') {
817 if (WINputc (w
, '^') == NOTOK
)
824 for (i
= 8 - (w
->w_bufpos
& 0x07); i
> 0; i
--)
825 if (WINputc (w
, ' ') == NOTOK
)
839 w
->w_buffer
[w
->w_bufpos
++] = c
;
843 w
->w_buffer
[w
->w_bufpos
] = NULL
;
846 if ((lp
= (struct line
*) calloc (1, sizeof *lp
)) == NULL
)
847 adios (NULL
, "unable to allocate line storage");
849 lp
->l_no
= (w
->w_tail
? w
->w_tail
->l_no
: 0) + 1;
850 lp
->l_buf
= getcpy (w
->w_buffer
);
851 for (cp
= lp
->l_buf
+ strlen (lp
->l_buf
) - 1; cp
>= lp
->l_buf
; cp
--)
857 if (w
->w_head
== NULL
)
859 if (w
->w_top
== NULL
)
861 if (w
->w_bottom
== NULL
)
864 w
->w_tail
->l_next
= lp
;
865 lp
->l_prev
= w
->w_tail
;
874 static char mylineno
[5];
876 static bool cancel
[] = { 1 };
877 static struct choice mychoices
[] = { LABEL
, "cancel", VT_White
};
879 static struct question myquestions
[] = {
880 STRING
, "Line", SZ (mylineno
), (struct choice
*) 0,
882 TOGGLE
, "", SZ (mychoices
), mychoices
885 static struct menu mymenu
= { "Goto", SZ (myquestions
), myquestions
};
887 static int *myanswers
[] = { (int *) mylineno
, (int *) cancel
};
893 int clear
, pos
, forw
, refresh
;
895 register struct vtseq
*vt
= &vts
;
897 if (w
->w_fd
== NOTOK
) {
899 DisplayStatus (dfd
, w
->w_top
->l_buf
);
906 if (ChangeWindowDepth (dfd
, w
->w_wd
, 0) == NOTOK
)
907 adios ("failed", "ChangeWindowDepth");
911 if (w
->w_bottom
== w
->w_tail
)
915 adios (NULL
, "internal error--no elevator bar");
917 for (clear
= refresh
= 0, forw
= 1;;) {
919 RemoveStatus (w
->w_fd
);
927 switch (getvtseq (w
->w_fd
, vt
)) {
930 DisplayStatus (w
->w_fd
, "use the mouse");
935 switch (vt
->u
.mouse
.buttons
936 & (VT_MOUSE_LEFT
| VT_MOUSE_MIDDLE
| VT_MOUSE_RIGHT
)) {
938 if ((pos
= vt
->u
.mouse
.x
) < EWIDTH
) {
939 pos
= w
->w_ebloc
= DoElevatorBar (w
->w_eb
, pos
,
941 refresh
= WINgoto (w
, ((pos
* (w
->w_tail
->l_no
943 / EB_MAX
) + w
->w_head
->l_no
);
947 #define WPOP "Paging\0Next\0Prev\0Left\0Right\0First\0Last\0Goto ...\0Exit\0"
948 case VT_MOUSE_MIDDLE
:
949 SetPosition (w
->w_fd
, vt
->u
.mouse
.x
,
951 switch (DisplayPopUp (w
->w_fd
, WPOP
)) {
954 if (w
->w_bottom
== w
->w_tail
)
956 refresh
= WINgoto (w
, w
->w_bottom
->l_no
+ 1 - PSLOP
);
961 if (w
->w_top
== w
->w_head
)
963 refresh
= WINgoto (w
, w
->w_top
->l_no
964 - w
->w_height
+ PSLOP
);
969 DisplayStatus (w
->w_fd
, "not yet");
975 refresh
= WINgoto (w
, w
->w_head
->l_no
);
980 refresh
= WINgoto (w
, w
->w_tail
->l_no
984 case 7: /* Goto ... */
985 snprintf (mylineno
, sizeof(mylineno
),
986 "%d", w
->w_top
->l_no
);
988 if (PresentMenu (&mymenu
, myanswers
)
991 if (sscanf (mylineno
, "%d", &pos
) != 1) {
992 DisplayStatus (w
->w_fd
, "bad format");
996 if (pos
< w
->w_head
->l_no
997 || pos
> w
->w_tail
->l_no
) {
998 DisplayStatus (w
->w_fd
, "no such line");
1002 refresh
= WINgoto (w
, pos
);
1008 default: /* failed or none taken */
1014 case VT_MOUSE_RIGHT
:
1016 if (w
->w_bottom
== w
->w_tail
)
1027 adios (NULL
, "end-of-file on window");/* NOTREACHED */
1030 DisplayStatus (w
->w_fd
, "unknown VT sequence");
1039 WINgoto (WINDOW
*w
, int n
)
1042 register struct line
*lp
;
1044 if (n
> (i
= w
->w_tail
->l_no
- w
->w_height
+ 1))
1046 if (n
< w
->w_head
->l_no
)
1047 n
= w
->w_head
->l_no
;
1049 if ((i
= n
- (lp
= w
->w_head
)->l_no
)
1050 > (j
= abs (n
- w
->w_top
->l_no
)))
1051 i
= j
, lp
= w
->w_top
;
1053 if (i
> (j
= abs (w
->w_tail
->l_no
- n
)))
1054 i
= j
, lp
= w
->w_tail
;
1056 if (n
>= lp
->l_no
) {
1057 for (; lp
; lp
= lp
->l_next
)
1062 for (; lp
; lp
= lp
->l_prev
)
1079 ADJser (int id
, short ww
, short wh
)
1083 if (id
< 0 || id
>= numwins
)
1084 adios (NULL
, "ADJser on bogus window (%d)", id
);
1086 if (w
->w_fd
== NOTOK
)
1087 adios (NULL
, "ADJser on closed window (%d)", id
);
1089 w
->w_ws
.width
= w
->w_ws
.tw
= ww
;
1090 w
->w_ws
.height
= w
->w_ws
.th
= wh
;
1093 DeleteElevatorBar (w
->w_eb
);
1094 w
->w_eb
= CreateElevatorBar (w
->w_fd
, 0, 0, EWIDTH
,
1095 w
->w_ws
.height
, VT_Gray50
, 1, EB_VERTICAL
,
1096 EB_ARROWS
, w
->w_ebloc
= 0, w
->w_ebsize
= EB_MAX
,
1098 if (w
->w_eb
== NULL
)
1099 adios (NULL
, "CreateElevatorBar failed");
1107 REFser (int id
, short wx
, short wy
, short ww
, short wh
)
1109 short cx
, cy
, cw
, ch
;
1112 if (id
< 0 || id
>= numwins
)
1113 adios (NULL
, "REFser on bogus window (%d)", id
);
1115 if (w
->w_fd
== NOTOK
)
1116 adios (NULL
, "REFser on closed window (%d)", id
);
1119 if (GetWindowState (w
->w_fd
, &w
->w_ws
) == NOTOK
)
1120 adios ("failed", "GetWindowState");
1122 GetPermanentClipping (w
->w_fd
, &cx
, &cy
, &cw
, &ch
);
1123 SetPermanentClipping (w
->w_fd
, wx
, wy
, ww
, wh
);
1125 SetPermanentClipping (w
->w_fd
, cx
, cy
, cw
, ch
);
1130 Redisplay (WINDOW
*w
, int doeb
)
1134 register struct line
*lp
;
1136 if (w
->w_fd
== NOTOK
)
1139 sx
= w
->w_eb
? (EWIDTH
+ ESLOP
) : 0;
1140 w
->w_height
= w
->w_ws
.height
/ w
->w_cheight
;
1141 if (w
->w_height
< 1)
1144 w
->w_width
= (w
->w_ws
.width
- (w
->w_eb
? (EWIDTH
+ ESLOP
) : 0))
1149 SetPosition (w
->w_fd
, sx
, 0);
1150 SetColor (w
->w_fd
, VT_White
);
1151 PaintRectangleInterior (w
->w_fd
, w
->w_ws
.width
, w
->w_ws
.height
);
1154 SetColor (w
->w_fd
, VT_Black
);
1155 for (lp
= w
->w_top
, y
= 0;
1156 lp
&& y
< w
->w_height
;
1157 w
->w_bottom
= lp
, lp
= lp
->l_next
, y
++) {
1158 SetPosition (w
->w_fd
, sx
, y
* w
->w_cheight
+ w
->w_cbase
);
1159 PaintString (w
->w_fd
, VT_STREND
, lp
->l_buf
);
1164 if ((y
= EB_LOC (w
)) != w
->w_ebloc
)
1165 MoveElevator (w
->w_eb
, w
->w_ebloc
= y
);
1166 if ((y
= EB_SIZE (w
)) != w
->w_ebsize
)
1167 SizeElevator (w
->w_eb
, w
->w_ebsize
= y
);
1169 RefreshElevatorBar (w
->w_eb
);
1181 if (w
->w_head
== NULL
)
1184 if ((i
= w
->w_tail
->l_no
- w
->w_head
->l_no
) <= 0)
1187 return (((w
->w_bottom
->l_no
- w
->w_top
->l_no
) * EB_MAX
) / i
);
1196 if (w
->w_head
== NULL
)
1199 if ((i
= w
->w_tail
->l_no
- w
->w_head
->l_no
) <= 0)
1202 return (((w
->w_top
->l_no
- w
->w_head
->l_no
) * EB_MAX
) / i
);
1211 if (ioctl (fileno (stdin
), TIOCGETP
, (char *) &tio
) == NOTOK
)
1212 adios ("failed", "ioctl TIOCGETP");
1213 if (ioctl (fileno (stdin
), TIOCGETC
, (char *) &tc
) == NOTOK
)
1214 adios ("failed", "ioctl TIOCGETC");
1215 if (ioctl (fileno (stdin
), TIOCGLTC
, (char *) <c
) == NOTOK
)
1216 adios ("failed", "ioctl TIOCGLTC");
1219 SIGNAL (SIGHUP
, SIGser
);
1220 SIGNAL (SIGINT
, SIGser
);
1221 SIGNAL (SIGQUIT
, SIGser
);
1230 SIGNAL_HANDLER tstat
;
1232 if ((pgrp
= getpgrp (0)) == NOTOK
)
1233 adios ("process group", "unable to determine");
1235 if (ioctl (fileno (stdin
), TIOCGPGRP
, (char *) &tpgrp
) == NOTOK
)
1236 adios ("tty's process group", "unable to determine");
1240 tstat
= SIGNAL (SIGTTIN
, SIG_DFL
);
1242 SIGNAL (SIGTTIN
, tstat
);
1245 SIGNAL (SIGTTIN
, SIG_IGN
);
1246 SIGNAL (SIGTTOU
, SIG_IGN
);
1247 SIGNAL (SIGTSTP
, SIG_IGN
);
1256 SIGNAL (SIGTTIN
, SIG_DFL
);
1257 SIGNAL (SIGTTOU
, SIG_DFL
);
1258 SIGNAL (SIGTSTP
, SIG_DFL
);
1266 longjmp (PEERctx
, DONE
);
1273 #ifndef RELIABLE_SIGNALS
1274 SIGNAL (sig
, SIG_IGN
);
1277 adios (NULL
, "lost peer");
1284 #ifndef RELIABLE_SIGNALS
1285 SIGNAL (sig
, SIG_IGN
);
1301 return 1; /* dead code to satisfy the compiler */
1306 adorn (char *what
, char *fmt
, ...)
1315 advertise (what
, NULL
, fmt
, ap
);
1323 advertise (char *what
, char *tail
, va_list ap
)
1326 char buffer
[BUFSIZ
], err
[BUFSIZ
];
1327 struct iovec iob
[20];
1328 register struct iovec
*iov
= iob
;
1334 iov
->iov_len
= strlen (iov
->iov_base
= invo_name
);
1336 iov
->iov_len
= strlen (iov
->iov_base
= ": ");
1340 vsnprintf (buffer
, sizeof(buffer
), fmt
, ap
);
1341 iov
->iov_len
= strlen (iov
->iov_base
= buffer
);
1345 iov
->iov_len
= strlen (iov
->iov_base
= " ");
1347 iov
->iov_len
= strlen (iov
->iov_base
= what
);
1349 iov
->iov_len
= strlen (iov
->iov_base
= ": ");
1352 if (!(iov
->iov_base
= strerror (eindex
))) {
1353 snprintf (err
, sizeof(err
), "unknown error %d", eindex
);
1354 iov
->iov_base
= err
;
1356 iov
->iov_len
= strlen (iov
->iov_base
);
1359 if (tail
&& *tail
) {
1360 iov
->iov_len
= strlen (iov
->iov_base
= ", ");
1362 iov
->iov_len
= strlen (iov
->iov_base
= tail
);
1365 iov
->iov_len
= strlen (iov
->iov_base
= "\n");
1369 DisplayVector (iob
, iov
- iob
);
1371 writev (fileno (stderr
), iob
, iov
- iob
);
1376 DisplayVector (struct iovec
*iov
, int n
)
1380 char buffer
[BUFSIZ
];
1382 for (i
= 0, cp
= NULL
; i
< n
; i
++, iov
++) {
1383 snprintf (buffer
, sizeof(buffer
), "%*.*s", iov
->iov_len
,
1384 iov
->iov_len
, iov
->iov_base
);
1385 cp
= add (buffer
, cp
);
1388 DisplayStatus (dfd
, cp
);