10 #include <netinet/in.h>
11 #include <arpa/inet.h>
14 // #include <qthread.h>
17 static void load(char *);
18 static void initiate(int,char **);
19 int main(int,char **);
22 static void initiate();
28 * @brief Compiler and interpreter code
31 int internal_sock, graph_sock, net_sock, connected = 0;
32 struct sockaddr_un svr;
34 char ProgName[255], mygname[80], gname[80], mykname[80], nname[80], mynname[80];
39 ctx_struct parent_ctx;
42 * IDs of remote instances
47 * Direct connection channels
54 int fcol, bcol, curx=0, cury=0;
58 * Macro to decode addressing modes:
60 #define getargument(a, argnr) \
61 switch (eop->args[ argnr ]) \
63 case GLOBAL : a = M[ ic++ ]; break; \
64 case LOCAL : a = c1+M[ ic++ ]; break; \
65 case TEMPLOCAL : a = c2+M[ ic++ ]; break; \
66 case REMOTE : a = M[ M[ ic+1 ] ]+M[ ic ]; ic+=2; break;\
67 case INDIRECT : a = M[ M[ ic++ ] ]; break;\
68 case IMMEDIATE : a = ic++; break;\
69 case CONSTANT : a = M[ ic++ ]; break;\
70 case DOTACCESS : a = M[ display+M[ ic+1 ] ]+M[ ic ]; ic += 2; break;\
71 case NOARGUMENT : return; \
75 * Loads code and prototypes from files
76 * Files have following extensions:
77 * .ccd - compiler code
80 * @param _filename Filename of file to read.
82 static void load(char *_filename)
87 /* should suffice on all systems */
90 strcpy(filename, _filename);
91 /* allocate main memory array */
92 M = mallocate(memorysize + 1);
94 abend("Memory size too large (use /m option)\n");
96 addext(filename, ".ccd");
97 if ((fp = fopen(filename, BINARYREAD)) == NULL) {
98 fprintf(stderr, "Cannot open .ccd file\n");
102 /* read static data and code from .ccd file */
104 left = memorysize + 1;
107 abend("Memory size too small (use /m option)\n");
108 n = min(IOBLOCK / sizeof(word), left);
109 n = fread((char *) &M[ ic ], sizeof(word), (int) n, fp);
113 /* now ic = number of words read */
117 /* Get various addresses passed by GENERATOR */
119 /* primitive type desctriptions */
121 /* global temporary variables */
122 temporary = M[ic - 4];
123 /* string constants */
125 /* last prototype number */
126 lastprot = M[ic - 2];
127 /* first free word in memory */
130 /* Read prototypes from .pcd file */
131 addext(filename, ".pcd");
132 if ((fp = fopen(filename, BINARYREAD)) == NULL) {
133 fprintf(stderr,"Cannot open .pcd file\n");
136 for (n = MAINBLOCK; n <= lastprot; n++) {
137 cp = ballocate(sizeof(protdescr));
139 abend("Memory size too large (use /m option)\n");
140 prototype[n] = (protdescr *) cp;
142 if (fread(cp, sizeof(protdescr), 1, fp) != 1)
143 abend("Cannot read .pcd file\n");
147 /* Open trace file */
149 addext(filename, ".trd");
150 if ((tracefile = fopen(filename, "w")) == NULL)
151 abend("Cannot open .trd file\n");
156 * Establishes configuration parameters
157 * Creates two sockets for program run
159 * @param argc number of passed values in argv array
162 * @param argv[3] if value is equal to: "r", sets global #remote variable to
163 * TRUE, FALSE otherwise
165 static void initiate(int argc, char **argv)
175 if ((argc == 4) && (strcmp(argv[3], "r") == 0))
180 for(i = 0; i < 255; i++) {
188 strcpy(filename, argv[2]);
189 strcpy(ProgName, argv[2]);
191 strcpy(mynname, argv[1]);
192 strcat(mynname, ".net");
194 sock = socket(AF_UNIX, SOCK_STREAM, 0);
195 bzero(&svr, sizeof(svr));
196 svr.sun_family = AF_UNIX;
197 strcpy(svr.sun_path, mynname);
198 len = strlen(svr.sun_path) + sizeof(svr.sun_family);
199 fprintf(stderr, "logint: Binding to socket: %s\n", svr.sun_path);
200 bind(sock, (struct sockaddr*)&svr, len);
204 /* socket for graphic requests */
205 strcpy(mygname, argv[1]);
206 strcat(mygname, ".gr");
209 /* socket for KERNEL communication */
210 internal_sock = socket(AF_UNIX, SOCK_STREAM, 0);
211 bzero(&svr, sizeof(svr));
212 svr.sun_family = AF_UNIX;
213 strcpy(svr.sun_path, argv[1]);
214 strcpy(mykname, argv[1]);
215 len = strlen(svr.sun_path) + sizeof(svr.sun_family);
216 fprintf(stderr, "logint: Connecting to socket: %s\n", svr.sun_path);
217 i = connect(internal_sock, (struct sockaddr*)&svr, len);
220 fcntl(internal_sock,F_SETFL, O_NONBLOCK |
221 fcntl(internal_sock,F_GETFL,0));
225 close(internal_sock);
226 internal_sock = socket(AF_UNIX, SOCK_STREAM, 0);
227 fcntl(internal_sock, F_SETFL, O_NONBLOCK |
228 fcntl(internal_sock, F_GETFL, 0));
229 i = connect(internal_sock, (struct sockaddr*)&svr, len);
233 setsockopt(internal_sock, IPPROTO_TCP, TCP_NODELAY, (char*)&on,
236 /* socket for network requests */
240 if (select(sock + 1, &rset, &wset, 0, 0))
241 net_sock = accept(sock, (struct sockaddr*)0, (int *)0);
244 fcntl(net_sock, F_SETFL, O_NONBLOCK |
245 fcntl(net_sock, F_GETFL, 0));
246 setsockopt(net_sock, IPPROTO_TCP, TCP_NODELAY, (char*)&on,
252 /* load code and prototypes */
253 if (filename != NULL) {
254 fprintf(stderr, "logint: loading code: %s\n", filename);
268 /* pointer to extended opcode in M */
269 eop = (extopcode *)(M + ic);
270 /* save ic for possible redecoding */
273 opcode = ((int) eop->opcode ) & 0xFF ;
280 * Sends message to graph module.
281 * @param msg Message to send.
283 void send_to_graph(G_MESSAGE *msg)
285 write(graph_sock, msg, sizeof(G_MESSAGE));
289 * Reads message from graph module.
290 * @param msg Message to read.
292 int read_from_graph(G_MESSAGE *msg)
295 struct timeval tout = {0, 0};
299 FD_SET(graph_sock, &rset);
302 if (select(graph_sock + 1, &rset, &wset, 0, (struct timeval *)&tout) > 0) {
303 if (FD_ISSET(graph_sock, &rset))
304 return(read(graph_sock,msg,sizeof(G_MESSAGE)));
310 * Reads message from net module.
312 * @param msg Message to read.
314 int read_from_net(MESSAGE *msg)
317 struct timeval tout = {0, 0};
321 FD_SET(net_sock, &rset);
324 if (select(net_sock + 1, &rset, &wset, 0, (struct timeval *)&tout) > 0) {
325 if (FD_ISSET(net_sock, &rset))
326 return(read(net_sock, msg, sizeof(MESSAGE)));
333 * Gets graphic resource number
339 struct sockaddr_un svr;
344 sock = socket(AF_UNIX, SOCK_STREAM, 0);
345 bzero(&svr, sizeof(svr));
346 svr.sun_family = AF_UNIX;
347 strcpy(svr.sun_path, mygname);
348 len = strlen(svr.sun_path) + sizeof(svr.sun_family);
349 bind(sock, (struct sockaddr*)&svr, len);
353 msg.msg_type = MSG_GRAPH;
354 msg.param.pword[0] = GRAPH_ALLOCATE;
355 strcpy(msg.param.pstr, mygname);
356 write(internal_sock, &msg, sizeof(MESSAGE));
357 bzero(&msg, sizeof(MESSAGE));
361 if (select(sock+1, &rset, &wset, 0, 0))
362 graph_sock = accept(sock, (struct sockaddr*)0, (int*)0);
364 if (graph_sock == -1) {
370 fcntl(graph_sock, F_SETFL, O_NONBLOCK|fcntl(graph_sock, F_GETFL, 0));
371 setsockopt(graph_sock, IPPROTO_TCP, TCP_NODELAY, (char*)&on, sizeof(on));
378 * Writes string line (ended with new line character)
380 void writeln_str(char *s)
383 msg.msg_type = MSG_GRAPH;
384 msg.param.pword[1] = GraphRes;
385 msg.param.pword[2] = GRAPH_WRITE;
386 strcpy(msg.param.pstr, s);
389 strcpy(msg.param.pstr, "\n");
396 * Passed string is send to graph module by G_MESSAGE packet using send_to_graph
398 * @param s String to write
400 void write_str(char *s)
403 msg.msg_type = MSG_GRAPH;
404 msg.param.pword[1] = GraphRes;
405 msg.param.pword[0] = GRAPH_WRITE;
406 strcpy(msg.param.pstr, s);
413 * Passed char is send to graph module by G_MESSAGE packet using send_to_graph
415 * @param a Character to write
417 void write_char(char a)
421 msg.msg_type = MSG_GRAPH;
422 msg.param.pword[1] = GraphRes;
423 msg.param.pword[0] = GRAPH_PUTCHAR;
431 * @return Read character
439 msg.msg_type = MSG_GRAPH;
440 msg.param.pword[1] = GraphRes;
441 msg.param.pword[0] = GRAPH_READCHAR;
444 st = read_from_graph(&msg);
446 if ((msg.msg_type == MSG_GRAPH) &&
447 (msg.param.pword[0] == GRAPH_READCHAR_RESPONSE))
449 ch = msg.param.pchar;
466 msg.msg_type = MSG_GRAPH;
467 msg.param.pword[1] = GraphRes;
468 msg.param.pword[0] = GRAPH_READLN;
471 st = read_from_graph(&msg);
473 if ((msg.msg_type == MSG_GRAPH) &&
474 (msg.param.pword[0] == GRAPH_READLN_RESPONSE))
481 * @param s Buffer to store string.
483 void read_str(char *s)
489 msg.msg_type = MSG_GRAPH;
490 msg.param.pword[1] = GraphRes;
491 msg.param.pword[0] = GRAPH_READSTR;
494 st = read_from_graph(&msg);
496 if ((msg.msg_type == MSG_GRAPH) &&
497 (msg.param.pword[0] == GRAPH_READSTR_RESPONSE)) {
498 strcpy(ss, msg.param.pstr);
507 * Sends message to kernel
508 * @param msg Message to send to kernel
510 void send_to_kernel(MESSAGE *msg)
512 write(internal_sock, msg, sizeof(MESSAGE));
516 * Sends message to net
517 * @return Returns 1 if ok and 0 if node desn't exists (since 2010)
519 int send_to_net(MESSAGE *msg)
523 struct sockaddr_in svr;
527 k = msg->int_msg.control.receiver.node;
529 /* 2010 check if node exists */
530 m.msg_type = MSG_NET;
531 m.param.pword[0] = NET_NODE_EXIST;
532 m.param.pword[1] = k;
533 m.param.pword[2] = my_ctx.program_id;
534 write(net_sock, &m, sizeof(MESSAGE));
535 bzero(&m, sizeof(MESSAGE));
536 while((m.msg_type != MSG_NET) && (m.param.pword[0] != NET_NODE_EXIST))
537 read(net_sock, &m, sizeof(MESSAGE));
539 if (m.param.pword[1] != 1)
542 strcpy(addr, m.param.pstr);
544 if (RInstance[k] == -1) {
545 bzero(&m,sizeof(MESSAGE));
546 m.msg_type = MSG_VLP;
547 m.param.pword[0] = VLP_REMOTE_INSTANCE_PLEASE;
548 m.param.pword[1] = my_ctx.program_id;
549 m.param.pword[2] = k;
551 bzero(&m, sizeof(MESSAGE));
554 read(internal_sock, &m, sizeof(MESSAGE));
555 if ((m.msg_type == MSG_VLP) &&
556 (m.param.pword[0] == VLP_REMOTE_INSTANCE_HERE))
560 /*printf("DEBUG: remote instance made with id: "
561 "%d addr %s port %d\n", m.param.pword[1], addr,
562 htons(m.param.pword[8]));*/
563 RInstance[k] = m.param.pword[1];
564 /* Make direct connection */
565 DirConn[k] = socket(AF_INET, SOCK_STREAM, 0);
566 svr.sin_family = AF_INET;
567 svr.sin_addr.s_addr = inet_addr(addr);
568 svr.sin_port = htons(m.param.pword[8]);
569 len = connect(DirConn[k], (struct sockaddr*)&svr, sizeof(svr));
573 writeln_str("Cannot connect remote instance!");
575 fcntl(DirConn[k], F_SETFL, O_NONBLOCK |
576 fcntl(DirConn[k], F_GETFL, 0));
579 if (RInstance[k] != -1) {
580 write(DirConn[k], &(msg->int_msg), sizeof(message));
585 /* -------------------- Check for message on internal socket -------------*/
595 struct timeval tout = {0, 0};
598 /* ----------- Direct connection messages -----
601 for(i = 0; i < 255; i++)
602 if (DirConn[i]!=-1) {
603 FD_SET(DirConn[i], &DirSet);
604 if (maxDirSet<DirConn[i])
605 maxDirSet=DirConn[i];
608 if (select(maxDirSet + 1, &DirSet, 0, 0, (struct timeval *)&tout) > 0) {
609 for(i = 0; i < 255; i++) {
610 if ((DirConn[i] != -1) &&
611 (FD_ISSET(DirConn[i], &DirSet))) {
612 r = read(DirConn[i], &mx, sizeof(mx));
614 memcpy(globmsgqueue + msgtail,&mx,
616 msgtail = (msgtail + 1) % MAXMSGQUEUE;
622 -----------------------------------------*/
625 FD_SET(net_sock, &rset);
626 FD_SET(internal_sock, &rset);
627 if (net_sock > internal_sock)
632 for(i = 0; i < 255; i++) {
633 if (DirConn[i] != -1) {
634 FD_SET(DirConn[i], &rset);
635 if (max < DirConn[i])
640 if (select(max + 1, &rset, 0, 0, (struct timeval *)&tout) > 0) {
642 for(i = 0; i < 255; i++) {
643 if ((DirConn[i] != -1) && (FD_ISSET(DirConn[i], &rset))) {
645 printf("DEBUG: Interp has message on "
646 "direct connection: type %d par %d\n",
647 mx.control.type,mx.control.par);
649 r = read(DirConn[i], &mx, sizeof(mx));
650 if (r > 0 && r == sizeof(mx)) {
651 memcpy(globmsgqueue + msgtail, &mx,
653 msgtail = (msgtail+1) % MAXMSGQUEUE;
659 if (FD_ISSET(net_sock,&rset)) {
660 r = read(net_sock, &m, sizeof(MESSAGE));
665 switch(m.param.pword[0]) {
668 printf("DEBUG: cint net_sock MSG_NET "
669 "NET_PROPAGATE cmd %d\n",
671 memcpy(globmsgqueue + msgtail,
674 msgtail = (msgtail + 1) %
684 if (FD_ISSET(internal_sock, &rset)) {
685 r = read(internal_sock, &m, sizeof(MESSAGE));
690 switch(m.param.pword[0]) {
691 case INT_CLOSE_INSTANCE:
699 if (m.param.pword[0] == NET_PROPAGATE) {
701 printf("DEBUG: cint internal_sock MSG_NET NET_PROPAGATE cmd %d\n",m.param.pword[6]);*/
702 memcpy(globmsgqueue + msgtail,
705 msgtail = (msgtail+1) %
722 m.msg_type = MSG_INT;
723 m.param.pword[0] = INT_CTX_REQ;
725 while ((m.msg_type != MSG_INT) || (m.param.pword[0] != INT_CTX))
726 read(internal_sock, &m, sizeof(MESSAGE));
728 my_ctx.node = m.param.pword[1];
729 my_ctx.program_id = m.param.pword[2];
731 parent_ctx.node = m.param.pword[3];
732 parent_ctx.program_id = m.param.pword[4];
733 RInstance[parent_ctx.node] = parent_ctx.program_id;
735 parent_ctx.node = my_ctx.node;
736 parent_ctx.program_id = my_ctx.program_id;
738 ournode = my_ctx.node;
739 /* strcpy(nname,m.param.pstr);*/
740 /* net_sock = open(nname,O_WRONLY);*/
741 m1.msg_type = MSG_GRAPH;
742 m1.param.pword[0] = GRAPH_SET_TITLE;
743 m1.param.pword[1] = GraphRes;
744 sprintf(m1.param.pstr, "%s ID: %d", ProgName, my_ctx.program_id);
747 strcat(m1.param.pstr, " REMOTE instance");
757 struct sockaddr_in svr;
759 struct hostent *info;
762 msg.msg_type = MSG_NET;
763 msg.param.pword[0] = NET_PROPAGATE;
764 msg.param.pword[1] = MSG_VLP;
765 msg.param.pword[2] = my_ctx.node;
766 msg.param.pword[4] = parent_ctx.node;
767 msg.param.pword[6] = VLP_REMOTE_INSTANCE_OK;
768 msg.param.pword[7] = my_ctx.program_id;
770 sock = socket(AF_INET, SOCK_STREAM, 0);
771 bzero(&svr, sizeof(svr));
772 svr.sin_family = AF_INET;
773 svr.sin_addr.s_addr = INADDR_ANY;
775 bind(sock, (struct sockaddr*)&svr, sizeof(svr));
778 getsockname(sock,(struct sockaddr*)&svr, &len);
779 msg.param.pword[8] = ntohs(svr.sin_port);
780 gethostname(name, &len);
781 info = (struct hostent*)gethostbyname(name);
782 bcopy((char*)info->h_addr, (char*)&svr.sin_addr, info->h_length);
783 sprintf(msg.param.pstr, "%s", inet_ntoa(svr.sin_addr));
784 send_to_kernel(&msg);
786 bzero(&svr, sizeof(svr));
787 DirConn[parent_ctx.node] = accept(sock, (struct sockaddr*)&svr, &len);
788 fcntl(DirConn[parent_ctx.node], F_SETFL, O_NONBLOCK |
789 fcntl(DirConn[parent_ctx.node], F_GETFL, 0));
793 * strcpy(filename, argv[2]);
794 * strcpy(ProgName, argv[2]);
796 * @param argv[1] = base name of this interpreter instance.
797 * For network there is created argv[1].net socket
798 * For graphics there is created argv[1].gr socket
799 * @param argv[2] = up to 80 characters string (with terminating \0). It is used to
800 * load selected program
801 * @param argv[3] = if exists and is equal to 'r', this is a remote call
803 int main(int argc, char **argv)
805 fprintf(stderr, "logint: initializing\n");
806 /* initialize executor */
807 initiate(argc, argv);
808 /* initialize running system */
809 fprintf(stderr, "logint: runsys\n");
811 fprintf(stderr, "logint: initializing scheduler\n");
813 fprintf(stderr, "logint: acquiring GRAPH resource\n");
814 GraphRes = get_graph_res();
816 fprintf(stderr, "logint: > acquiring GRAPH resource failed\n");
824 /* set label for continue long jump */
826 /* repeat until exit() is called */
829 /* reschedule current process */
832 /* fetch instruction */