Add sparclite support.
[deliverable/binutils-gdb.git] / gdb / cadillac.c
CommitLineData
1744d4eb
SG
1/* Cadillac interface routines.
2 Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
3
4This file is part of GDB.
5
6This program is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2 of the License, or
9(at your option) any later version.
10
11This program is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with this program; if not, write to the Free Software
18Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
bf226124
SG
20#include "defs.h"
21#include "symtab.h"
22#include "inferior.h"
23#include "command.h"
1744d4eb
SG
24#include <sys/types.h>
25#include <sys/time.h>
26#include <sys/param.h>
27#include <connection.h>
28#include <genericreq.h>
29#include <debuggerreq.h>
30#include <debuggerconn.h>
31#include <ttyconn.h>
bf226124
SG
32#include <varargs.h>
33#include <sys/stat.h>
34#include <fcntl.h>
35#include <sys/filio.h>
36#include <setjmp.h>
37#include <signal.h>
38#include <sys/errno.h>
39#include <termios.h>
40#include <strings.h>
1744d4eb
SG
41
42/* Connection block for debugger<=>kernel communications. */
43static Connection *conn = 0;
44
45/* fd for our socket to the kernel. */
46static int kerfd;
47
48/* The kernel's ID for this instance of the program. */
49static int program_id;
bf226124
SG
50
51static int instance_id;
52
53/* The fd for the pty associated with the inferior. */
54static int inferior_pty = -1;
55static int inferior_tty = -1;
56
57static int has_run = 0;
58
59extern int cadillac;
60
61char **pprompt; /* Pointer to pointer to prompt */
1744d4eb 62\f
bf226124
SG
63static void
64prompt()
65{
66 fputs_filtered(*pprompt, stdout);
67}
1744d4eb
SG
68
69/* This routine redirects the output of fputs_filtered to the kernel so that
70 the user can see what's going on in his debugger window. */
71
72void
73cadillac_fputs(ptr)
74 char *ptr;
bf226124
SG
75{
76 if (conn)
77 CVWriteTranscriptInfo (conn, instance_id, ptr);
78 else
79 fputs (ptr, stdout);
80}
81
82/* Copy all data from the pty to the kernel. */
83
84static void
85pty_to_kernel()
1744d4eb
SG
86{
87 CTtyRequest *req;
bf226124
SG
88 char buf[1024];
89 int cc;
1744d4eb 90
bf226124 91 while (1)
1744d4eb 92 {
bf226124
SG
93 cc = read(inferior_pty, buf, sizeof(buf));
94
95 if (cc == 0
96 || (cc < 0
97 && errno == EWOULDBLOCK))
98 break;
99
100 if (cc < 0)
101 {
102 close(inferior_pty);
103 inferior_pty = -1;
104 perror("pty read error");
105 break;
106 }
107
108 req = CWriteTtyRequest(conn, TextIORType);
109 CWriteVstringLen(conn, buf, cc);
110 CWriteLength(conn);
111 }
112 CWriteRequestBuffer(conn);
113}
114
115/* Copy data from the kernel to the pty. */
116
117static void
118kernel_to_pty(data, len)
119 char *data;
120 int len;
121{
122 int cc;
123
124 cc = write(inferior_pty, data, len);
125
126 if (cc != len)
127 {
128 if (cc < 0)
129 {
130 close(inferior_pty);
131 inferior_pty = -1;
132 perror("pty write error");
133 return;
134 }
135 printf("Couldn't write all the data to the pty, wanted %d, got %d\n",
136 len, cc);
1744d4eb 137 }
bf226124
SG
138}
139
140/* Tell the kernel where we are in the program, and what the stack looks like.
141 */
142
143static void
144send_status()
145{
146 static int linecount = 48;
147 struct symtab_and_line sal;
148 struct symbol *symbol;
149 char *funcname, *filename;
150 static int foo = 0;
151 static int sent_prog_inst = 0;
152
153 if (!has_run)
154 return;
155
156 if (inferior_pid == 0) /* target has died */
157 {
158 CVWriteProgramTerminatedInfo(conn,
159 instance_id,
160 ""
161 );
162 return;
163 }
164
165 sal = find_pc_line(stop_pc, 0);
166 symbol = find_pc_function(stop_pc);
167
168 funcname = symbol ? symbol->name : "";
169 filename = sal.symtab ? sal.symtab->filename : "";
170
171 if (!sent_prog_inst)
172 {
173 sent_prog_inst = 1;
174 CVWriteProgramInstanceInfo(conn,
175 program_id,
176 instance_id,
177 "", /* hostname */
178 "", /* arglist */
179 ""
180 );
181 }
182
183 CVWriteStackSizeInfo(conn,
184 instance_id,
185 1, /* XXX - frame depth */
186 CInnerFrameIs0,
187 foo++ ? 1 : 0, /* XXX - frame diff */
188 ""
189 );
190
191 CVWriteStackFrameInfo(conn,
192 instance_id,
193 sal.line,
194 CFileLinePos,
195 0, /* XXX - frame # */
196 funcname,
197 filename,
198 "" /* XXX ? transcript */
199 );
200
201 CVWriteProgramStoppedInfo(conn,
202 instance_id,
203 0, /* XXX - breakpoint # or signal # */
204 CDebuggerCommand,
205 funcname,
206 "" /* XXX ? transcript */
207 );
208}
209
210/* Tell the kernel that the target is now running. */
211
212static void
213go_busy()
214{
215 CVWriteProgramBusyInfo(conn,
216 instance_id,
217 ""); /* XXX ? transcript */
218 CWriteRequestBuffer(conn); /* Must take place synchronusly! */
1744d4eb
SG
219}
220
221/* This wrapper routine is needed because execute_command modifies the command
222 string that it's given. It also echos the commands. */
223
224static void
bf226124
SG
225execute_command_1(va_alist)
226 va_dcl
1744d4eb 227{
bf226124
SG
228 char buf[100]; /* XXX - make buf dynamic! */
229 char *cmd;
230 va_list args;
231
232 va_start(args);
1744d4eb 233
bf226124
SG
234 cmd = va_arg(args, char *);
235
236 vsprintf(buf, cmd, args);
237
238 printf_filtered("%s\n", buf);
239 execute_command(buf, 1);
240
241 va_end(args);
1744d4eb
SG
242}
243
bf226124
SG
244#ifdef KERNEL_RECORD
245FILE *kerout;
246
247static int
248kernel_record(fd, ptr, num)
249 int fd, num;
250 char *ptr;
251
252{
253 fwrite(ptr, num, 1, kerout);
254 fflush(kerout);
255 return write(fd, ptr, num);
256}
257#endif
258
259void
260cadillac_condition_breakpoint(b)
261 struct breakpoint *b;
262{
263 CVWriteBreakConditionInfo(conn,
264 instance_id,
265 b->number,
266 b->cond_string ? b->cond_string : "",
267 "" /* transcript */
268 );
269}
270
271void
272cadillac_commands_breakpoint(b)
273 struct breakpoint *b;
274{
275 struct command_line *l;
276
277 CVWriteBreakCommandBegInfo(conn,
278 instance_id,
279 b->number,
280 ""); /* transcript */
281
282 for (l = b->commands; l; l = l->next)
283 CVWriteBreakCommandEntryInfo(conn,
284 instance_id,
285 l->line,
286 ""); /* transcript */
287
288 CVWriteBreakCommandEndInfo(conn,
289 instance_id,
290 ""); /* transcript */
291}
292
293static void
294breakpoint_notify(b, action)
295 struct breakpoint *b;
296 int action;
297{
298 struct symtab *s;
299 struct symbol *s1;
300 char *funcname = "", *filename = "", *included_in_filename = "";
301
302 if (b->type != bp_breakpoint)
303 return;
304
305 s = b->symtab;
306
307 if (s)
308 {
309 filename = s->filename;
310 s1 = find_pc_function(b->address);
311 if (s1)
312 funcname = SYMBOL_NAME(s1);
313 }
314
315 CVWriteBreakpointInfo (conn,
316 instance_id,
317 b->number,
318 b->line_number,
319 CFileLinePos,
320 CBreakOnInstrAccess,
321 action,
322 b->ignore_count,
323 funcname,
324 filename,
325 "", /* included_in_filename */
326 "" /* transcript */
327 );
328
329 if (b->commands)
330 cadillac_commands_breakpoint(b);
331}
332
333void
334cadillac_create_breakpoint(b)
335 struct breakpoint *b;
336{
337 breakpoint_notify(b, CEnableBreakpoint);
338}
339
340void
341cadillac_delete_breakpoint(b)
342 struct breakpoint *b;
343{
344 breakpoint_notify(b, CDeleteBreakpoint);
345}
346
347void
348cadillac_enable_breakpoint(b)
349 struct breakpoint *b;
350{
351 breakpoint_notify(b, CEnableBreakpoint);
352}
353
354void
355cadillac_disable_breakpoint(b)
356 struct breakpoint *b;
357{
358 breakpoint_notify(b, CDisableBreakpoint);
359}
360
361void
362cadillac_ignore_breakpoint(b)
363 struct breakpoint *b;
364{
365 breakpoint_notify(b, CBreakAttrUnchanged);
366}
367
368static int command_line_length = 0;
369static char *command_line_text = 0;
370
371int
372cadillac_reading()
373{
374 if (command_line_text)
375 return 1;
376 else
377 return 0;
378}
379
380char *
381cadillac_command_line_input()
382{
383 char *p;
384
385 if (command_line_length <= 0)
386 return (char *)NULL;
387
388 p = command_line_text;
389
390 while (command_line_length-- > 0)
391 {
392 if (*command_line_text == '\n')
393 {
394 *command_line_text = '\000';
395 command_line_text++;
396 break;
397 }
398 command_line_text++;
399 }
400
401 return p;
402}
403
404/* Open up a pty and its associated tty. Return the fd of the tty. */
405
406char *
407cadillac_getpty()
408{
409 int n, ptyfd, ttyfd;
410 static char dev[30];
411 struct stat statbuf;
412 struct termios termios;
413
414#define HIGHPTY (('z' - 'p') * 16 - 1)
415
416 if (inferior_pty >= 0) /* Only do this once */
417 return dev;
418
419 for (n = 0; n <= HIGHPTY; n++)
420 {
421 sprintf(dev, "/dev/pty%c%x", n/16 + 'p', n%16);
422 if (stat(dev, &statbuf))
423 break;
424 ptyfd = open(dev, O_RDWR);
425 if (ptyfd < 0)
426 continue;
427 sprintf(dev, "/dev/tty%c%x", n/16 + 'p', n%16);
428 ttyfd = open(dev, O_RDWR);
429 if (ttyfd < 0) {close(ptyfd); continue;}
430
431 /* Setup pty for non-blocking I/O. Also make it give us a SIGIO when
432 there's data available. */
433
434 n = fcntl(ptyfd, F_GETFL, 0);
435 fcntl(ptyfd, F_SETFL, n|FNDELAY|FASYNC);
436 fcntl(ptyfd, F_SETOWN, getpid());
437
438 tcgetattr(ttyfd, &termios);
439 termios.c_oflag &= ~OPOST; /* No post-processing */
440 tcsetattr(ttyfd, TCSANOW, &termios);
441
442 inferior_pty = ptyfd;
443 inferior_tty = ttyfd;
444 return dev;
445 }
446
447 error ("getpty: can't get a pty\n");
448}
449\f
450/* Examine a protocol packet from the driver. */
451
452static int
453kernel_dispatch(interrupt)
454 int interrupt; /* Non-zero means we are at interrupt level
455 and can only do a few commands. */
456{
457 register CHeader *head;
458
459 head = (CHeader *)CPeekNextRequest (conn);
460 if (head == NULL)
461 {
462 fprintf (stderr, "EOF on kernel read!\n");
463 exit (1);
464 }
465
466 if (interrupt)
467 switch (head->reqType)
468 {
469 case KillProgramRType:
470 case TextIORType:
471 case StopRType:
472 break;
473 default:
474 return;
475 }
476
477 if (head->reqType < LastTtyRequestRType)
478 {
479 CTtyRequest* req = CReadTtyRequest (conn);
480 switch (req->head.reqType)
481 {
482 case AcceptConnectionRType:
483 /* Tell the rest of the world that cadillac is now set up */
484 CSkipRequest (conn);
485 break;
486
487 case RefuseConnectionRType:
488 fprintf (stderr, "Debugger connection refused\n");
489 exit (1);
490
491 case KillProgramRType:
492 exit (0);
493
494 case TextIORType:
495 {
496 char *p;
497 ReqLen len;
498
499 p = CGetVstring(conn, &len);
500 kernel_to_pty(p, len);
501 }
502 break;
503 default:
504 fprintf(stderr, "Unknown request type = %d\n",
505 req->head.reqType);
506 break;
507 }
508 }
509 else
510 {
511 CVDebuggerRequest *req = CVReadDebuggerRequest (conn);
512 if (!req)
513 {
514 fprintf (stderr, "CVReadDebuggerRequest returned NULL, type = %d\n",
515 head->reqType);
516 exit(1);
517 }
518
519 switch (req->head.request->reqType)
520 {
521 case OpenProgramInstanceRType:
522 {
523 char *arglist, buf[100]; /* XXX - Make buf dynamic! */
524 int arglen;
525 /* XXX - should notice when program_id changes */
526 arglist = req->openProgramInstance.progArglist.text;
527 arglen = req->openProgramInstance.progArglist.byteLen;
528
529 execute_command_1("break main");
530 execute_command_1("enable delete $bpnum");
531 if (arglist)
532 {
533 execute_command_1("set args %.*s", arglen, arglist);
534 }
535 execute_command_1("run");
536 }
537 break;
538 case QuitDebuggerRType:
539 exit (0);
540 case RunRType:
541 if (req->run.request->useArglist == CNewArglist)
542 {
543 execute_command_1("set args %.*s",
544 req->run.progArglist.byteLen,
545 req->run.progArglist.text);
546 }
547 execute_command_1("run");
548 break;
549 case ContinueRType:
550 execute_command_1("continue");
551 break;
552 case StepRType:
553 execute_command_1("step %d", req->step.request->stepCount);
554 break;
555 case NextRType:
556 execute_command_1("next %d", req->next.request->nextCount);
557 break;
558 case ChangeStackFrameRType:
559 switch (req->changeStackFrame.request->frameMovement)
560 {
561 case CToCurrentStackFrame:
562 execute_command_1("frame %d",
563 req->changeStackFrame.request->frameNo);
564 break;
565 case CToInnerStackFrame:
566 execute_command_1("down %d",
567 req->changeStackFrame.request->frameNo);
568 break;
569 case CToOuterStackFrame:
570 execute_command_1("up %d",
571 req->changeStackFrame.request->frameNo);
572 break;
573 case CToAbsoluteStackFrame:
574 printf_filtered("ChangeStackFrame ToAbsolute\n");
575 break;
576 }
577 break;
578 case BackTraceRType:
579 /* XXX - deal with limit??? */
580 execute_command_1("backtrace");
581 break;
582 case FinishRType:
583 execute_command_1("finish");
584 break;
585 case TerminateProgramRType:
586 execute_command_1("kill");
587 break;
588 case NewBreakpointRType:
589 {
590 char *tail;
591 int skipped;
592
593 tail = rindex(req->newBreakpoint.fileName.text, '/');
594 if (!tail)
595 tail = req->newBreakpoint.fileName.text;
596 else
597 tail++;
598 skipped = tail - req->newBreakpoint.fileName.text;
599 execute_command_1("break %.*s:%d",
600 req->newBreakpoint.fileName.byteLen - skipped,
601 tail,
602 req->newBreakpoint.request->fileLinePos);
603 }
604 break;
605 case StopRType:
606 {
607 extern int pgrp_inferior;
608 killpg(pgrp_inferior, SIGINT);
609 }
610 break;
611 case UserInputRType:
612 {
613 char *text;
614 long len;
615
616 /* XXX - should really break command up into seperate lines
617 and spoon-feed it to execute_command */
618
619 text = req->userInput.userInput.text;
620 len = req->userInput.userInput.byteLen;
621
622 if (text[len-1] == '\n') text[len-1] = '\000';
623 execute_command (text);
624 break;
625 }
626 case ChangeBreakpointRType:
627 switch (req->changeBreakpoint.request->breakpointAttr)
628 {
629 case CEnableBreakpoint:
630 execute_command_1("enable %d",
631 req->changeBreakpoint.request->breakpointId);
632 break;
633 case CDisableBreakpoint:
634 execute_command_1("disable %d",
635 req->changeBreakpoint.request->breakpointId);
636 break;
637 case CDeleteBreakpoint:
638 execute_command_1("delete %d",
639 req->changeBreakpoint.request->breakpointId);
640 break;
641 case CBreakAttrUnchanged:
642 execute_command_1("ignore %d %d",
643 req->changeBreakpoint.request->breakpointId,
644 req->changeBreakpoint.request->ignoreCount);
645 break;
646 default:
647 printf_filtered("Got to ChangeBreakpoint\n");
648 printf_filtered(" breakpointId = %d\n",
649 req->changeBreakpoint.request->breakpointId);
650 printf_filtered(" breakpointType = %d\n",
651 req->changeBreakpoint.request->breakpointType);
652 printf_filtered(" breakpointAttr = %d\n",
653 req->changeBreakpoint.request->breakpointAttr);
654 printf_filtered(" ignoreCount = %d\n",
655 req->changeBreakpoint.request->ignoreCount);
656 break;
657 }
658 break;
659 case BreakConditionRType:
660 execute_command_1("condition %d %.*s",
661 req->breakCondition.request->breakpointId,
662 req->breakCondition.condition.byteLen,
663 req->breakCondition.condition.text);
664 break;
665 case BreakCommandsRType:
666 /* Put pointers to where cadillac_command_line_input() can find
667 them. */
668 command_line_length = req->breakCommands.commands.byteLen;
669 command_line_text = req->breakCommands.commands.text;
670 execute_command_1("commands %d",
671 req->breakCommands.request->breakpointId);
672 command_line_text = (char *)NULL;
673 command_line_length = 0;
674 break;
675 default:
676 fprintf(stderr, "Unknown request type = %d\n",
677 req->head.request->reqType);
678 break;
679 }
680 free (req); /* Should probably call CVFreeDebuggerRequest() here, but
681 can't do so if interrupt level has mucked with req->
682 request. CVFreeDebuggerRequest() only ends up calling
683 free() anyway! */
684 }
685}
686\f
687#define KERNEL_EVENT 1
688#define PTY_EVENT 2
689
690/* Return a bitmask indicating if the kernel or the pty did something
691 interesting. Set poll to non-zero if you don't want to wait. */
692
693static int
694wait_for_events(poll)
695 int poll;
696{
697 fd_set readfds;
698 int numfds;
699 int eventmask = 0;
700 static struct timeval tv = {0};
701
702 /* Output all pending requests. */
703 CWriteRequestBuffer(conn);
704
705 /* Wait till there's some activity from the kernel or the pty. */
706 do
707 {
708 FD_ZERO(&readfds);
709 FD_SET(kerfd, &readfds);
710 if (inferior_pty > 0)
711 FD_SET(inferior_pty, &readfds);
712 if (poll)
713 numfds = select(sizeof(readfds)*8, &readfds, 0, 0, &tv);
714 else
715 numfds = select(sizeof(readfds)*8, &readfds, 0, 0, 0);
716 }
717 while (numfds <= 0 && !poll);
718
719 if (FD_ISSET(inferior_pty, &readfds))
720 eventmask |= PTY_EVENT;
721
722 if (FD_ISSET(kerfd, &readfds))
723 eventmask |= KERNEL_EVENT;
724
725 return eventmask;
726}
727\f
1744d4eb
SG
728/* Establish contact with the kernel. */
729
730void
731cadillac_initialize(cadillac_id, execarg)
732 char *cadillac_id;
733 char *execarg;
734{
735 CTtyRequest *req;
736 char *ctmp;
737 extern long strtol(char *str, char **ptr, int base);
738 char pathname[MAXPATHLEN];
bf226124 739 int n;
1744d4eb
SG
740
741 if (!execarg) execarg = "";
742
743 printf("gdb-debugger pid=%d\n", getpid()); /* XXX - debugging only */
744
745 /* First establish the connection with the kernel. */
746
747 kerfd = COpenClientSocket(NULL);
748 if (kerfd < 0) {
749 printf("COpenClientSocket() failed\n");
750 exit(1);
751 }
752
bf226124
SG
753 /* Setup for I/O interrupts when appropriate. */
754
755 n = fcntl(kerfd, F_GETFL, 0);
756 fcntl(kerfd, F_SETFL, n|FASYNC);
757 fcntl(kerfd, F_SETOWN, getpid());
758
1744d4eb
SG
759 /* Setup connection buffering. */
760
761 CSetSocketBufferSize (kerfd, 12000);
762
763 /* Generate a new connection control block. */
764
765 conn = NewConnection (0, kerfd, kerfd);
766 if (!conn) {
767 printf("NewConnection() failed\n");
768 exit(1);
769 }
770
bf226124
SG
771#ifdef KERNEL_RECORD
772 kerout = fopen("kernel.output", "+w");
773
774 CReadWriteHooks(conn, conn->previewMethod, conn->readMethod, kernel_record);
775#endif
776
1744d4eb
SG
777 /* Tell the kernel that we are the "debugger". */
778
779 req = CWriteTtyRequest (conn, QueryConnectionRType);
780 req->generic.queryconnection.major = 0;
781 req->generic.queryconnection.minor = 0;
782 req->generic.queryconnection.cadillacId1=strtol(cadillac_id, &ctmp, 16);
783 req->generic.queryconnection.cadillacId2 = strtol(++ctmp, NULL, 16);
784 req->generic.queryconnection.nProtocols = 1;
785 CWriteProtocol (conn, 0, 0, "debugger");
786 CWriteLength (conn);
787
788 /* Tell the kernel that we are actually running. */
789
790 /* KROCK ALERT!!! The kernel doesn't really care about the arguments to
791 the program at all! It only cares that argument 7 be the name of the
792 target program. So, we just fill in the rest of the slots with
793 padding. I hope the kernel never cares about this! */
794
795 req = CWriteTtyRequest (conn, RunningProgramRType);
796 req->runningprogram.argc = 8;
797 getwd (pathname);
798 CWriteVstring0 (conn, pathname);
799
800 CWriteVstring0 (conn, "0");
801 CWriteVstring0 (conn, "1");
802 CWriteVstring0 (conn, "2");
803 CWriteVstring0 (conn, "3");
804 CWriteVstring0 (conn, "4");
805 CWriteVstring0 (conn, "5");
806 CWriteVstring0 (conn, "6");
807 CWriteVstring0 (conn, execarg);
808 CWriteLength (conn);
bf226124
SG
809
810 /* Tell the kernel our PID and all that */
811
812 program_id = 1;
813 CVWriteDebugProgramInfo(conn,
814 getpid(),
815 program_id,
816 execarg,
817 "");
818
819 /* Tell the rest of the world that Cadillac is now set up. */
820 cadillac = 1;
1744d4eb
SG
821}
822
bf226124
SG
823/* This is called from execute_command, and provides a wrapper around
824 various command routines in a place where both protocol messages and
825 user input both flow through.
826*/
1744d4eb
SG
827
828void
bf226124
SG
829cadillac_call_command(cmdblk, arg, from_tty)
830 struct cmd_list_element *cmdblk;
831 char *arg;
832 int from_tty;
1744d4eb 833{
bf226124
SG
834 if (cmdblk->class == class_run)
835 {
836 go_busy();
837 has_run = 1;
838 (*cmdblk->function.cfunc)(arg, from_tty);
839 send_status();
840 }
841 else
842 (*cmdblk->function.cfunc)(arg, from_tty);
1744d4eb 843
bf226124
SG
844 prompt();
845}
1744d4eb 846
bf226124
SG
847void
848cadillac_new_process()
849{
850 instance_id = inferior_pid;
851}
852
853static void
854iosig()
855{
1744d4eb
SG
856 while (1)
857 {
bf226124 858 int eventmask;
1744d4eb 859
bf226124 860 eventmask = wait_for_events(1);
1744d4eb 861
bf226124
SG
862 if (eventmask == 0)
863 return;
1744d4eb 864
bf226124
SG
865 if (eventmask & PTY_EVENT)
866 pty_to_kernel();
1744d4eb 867
bf226124
SG
868 if (eventmask & KERNEL_EVENT)
869 kernel_dispatch(1);
870 }
871}
1744d4eb 872
bf226124
SG
873int
874cadillac_wait(status)
875 int *status;
876{
877 int pid;
1744d4eb 878
bf226124 879 signal(SIGIO, iosig);
1744d4eb 880
bf226124 881 pid = wait(status);
1744d4eb 882
bf226124
SG
883 signal(SIGIO, SIG_DFL);
884 return pid;
885}
1744d4eb 886
bf226124
SG
887static void
888null_routine(arg)
889 int arg;
890{
891}
1744d4eb 892
bf226124 893/* All requests from the Cadillac kernel eventually end up here. */
1744d4eb 894
bf226124
SG
895void
896cadillac_main_loop(pp)
897 char **pp;
898{
899 CTtyRequest *req;
900 struct cleanup *old_chain;
901
902 pprompt = pp;
903
904/* We will come thru here any time there is an error, so send status if
905 necessary. */
906
907 send_status();
908
909 prompt();
910
911 /* The actual event loop! */
912
913 while (1)
914 {
915 int eventmask;
916
917 eventmask = wait_for_events(0);
918
919 if (eventmask & PTY_EVENT)
920 pty_to_kernel();
921
922 if (eventmask & KERNEL_EVENT)
923 {
924 old_chain = make_cleanup(null_routine, 0);
925 kernel_dispatch(0);
926 bpstat_do_actions(&stop_bpstat);
927 do_cleanups(old_chain);
1744d4eb
SG
928 }
929 }
930}
This page took 0.063977 seconds and 4 git commands to generate.