1 /**************************************************************
3 Copyright (C) 1997 Oskar Swida
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 NOTE: This software is using the free software license of
23 the QT library v.1.30 from Troll Tech AS.
24 See the file LICENSE.QT.
27 To contact the author, write:
28 e-mail: swida@aragorn.pb.bialystok.pl
30 ************************************************************/
32 #include <QtGui/QApplication>
33 #include <QtGui/QMainWindow>
34 #include <QtGui/QTextEdit>
35 #include <QtGui/QMenuBar>
36 #include <QtGui/QMessageBox>
37 #include <QtGui/QFileDialog>
38 #include <QtGui/QDialog>
39 #include <QtCore/QString>
40 #include <QtGui/QLabel>
41 #include <QtGui/QLineEdit>
42 #include <QtGui/QPushButton>
43 #include <QtGui/QRadioButton>
44 #include <QtGui/QGroupBox>
45 #include <QtGui/QVBoxLayout>
46 #include <QtCore/QList>
47 #include <QtGui/QListWidget>
50 #include <QtCore/QSocketNotifier>
51 #include <QtGui/QCloseEvent>
52 #include <QtCore/QDir>
53 #include <QtCore/QProcess>
62 #include <netinet/in.h>
64 #include <libconfig.h>
68 #include "ui/kernelwindow.h"
71 #include "kill_interpreter_dialog.h"
72 #include "connect_dialog.h"
74 #include "vlp/config.h"
76 /* File resides in top directory (where are Makefiles)*/
77 #include "../../config.h"
80 char CharLine[25] = "________________________";
83 * Event invoked on program close.
84 * Closes application. Displays additional window to confirm exit.
86 void QKernel::closeEvent(QCloseEvent * e)
91 on_actionQuit_triggered();
95 void QKernel::setLocked(bool locked)
99 actionQuit->setDisabled(locked);
101 actionExecute->setDisabled(locked);
102 actionKill->setDisabled(locked);
103 actionMessage->setDisabled(locked);
104 actionConnect->setDisabled(locked);
105 actionDisconnect->setDisabled(locked);
106 actionInfo->setDisabled(locked);
109 /* Enable only menu entry for unlocking */
110 actionEditor->setDisabled(locked);
111 actionOptions->setDisabled(locked);
112 actionLock_console->setDisabled(locked);
113 actionUnlock_console->setDisabled(!locked);
117 * Kernel program constructor.
118 * Prepares everything to work.
120 QKernel::QKernel(int argc, char **argv)
124 QString arg0(argv[0]);
126 homeDir = QDir(arg0);
131 for(i = 0; (i < 5) && (i < argc-1); i++) {
132 strcpy(myargs[i], "");
134 strcpy(myargs[i], argv[i+1]);
138 QDir q(getRemoteDir());
141 q.mkpath(getRemoteDir());
144 info_messages = actionInfo_messages->isChecked();
145 wait_for_info = FALSE;
147 setWindowTitle(PACKAGE_NAME);
153 ActiveConnections = 0;
154 strcpy(LockPasswd, "");
156 loadConfig(getConfigFilePath());
160 Net_Notify = new QSocketNotifier(net_sock, QSocketNotifier::Read, this);
161 connect(Net_Notify, SIGNAL(activated(int)), this, SLOT(NetMessage()));
163 WriteMessage("\n " PACKAGE_STRING ": READY \n");
166 QString QKernel::getConfigFilePath()
168 return homeDir.absoluteFilePath("vlp.cfg");
171 const char * QKernel::getHomeDir()
173 return homeDir.absolutePath().toStdString().c_str();
176 const char * QKernel::getRemoteDir()
178 return homeDir.absoluteFilePath(REMOTE_PATH).toStdString().c_str();
181 const char * QKernel::getNetModuleSocket()
183 return homeDir.absoluteFilePath(NPATH).toStdString().c_str();
186 const char * QKernel::getGraphModuleSocket()
188 return homeDir.absoluteFilePath(GPATH).toStdString().c_str();
191 void QKernel::loadConfig(const QString & fname)
193 loadConfig(fname.toStdString().c_str());
196 * Loads configuration from the given file.
197 * @param fname Filename of the configuration file.
199 void QKernel::loadConfig(const char * fname)
201 loglan::vlp::Config config;
202 if(config.load(fname)) {
203 NodeNumber = config.getNodeNumber();
204 ConType = config.getConnectionType();
207 std::vector<std::string> hosts = config.getHosts();
208 for (unsigned int i = 0; i < hosts.size(); i++) {
209 ConnectList.append(new ConnectEntry(hosts[i].c_str()));
212 strncpy(progdir, config.getProgramDir(), 256);
218 * Additional window id displayed to set which code to execute.
220 void QKernel::on_actionExecute_triggered()
223 QString s = QFileDialog::getOpenFileName(this, "Execute", progdir, "*.log");
226 i = s.indexOf(".log");
231 // @TODO: if no interpreter is running will result in killing app
232 RunIntModule((char*)s.toAscii().data(), 0);
237 * Invokes editor program
239 void QKernel::on_actionEditor_triggered()
241 QString program = getHomeDir();
242 program += "/modules/logedit";
246 if (execl(program.toStdString().c_str(),
255 WriteMessage("Executing logedit failed!");
259 WriteMessage("fork(logedit) failed!");
260 WriteMessage("Exiting...");
262 on_actionQuit_triggered();
268 * Invokes help program
270 void QKernel::on_actionHelp_triggered()
272 QString program = getHomeDir();
273 program += "/modules/loghelp";
275 QString docDir = getHomeDir();
280 if (execl(program.toStdString().c_str(),
281 docDir.toStdString().c_str(),
290 WriteMessage("Executing loghelp failed!");
294 WriteMessage("fork(loghelp) failed!");
295 WriteMessage("Exiting...");
297 on_actionQuit_triggered();
303 * Invokes graphics module
305 void QKernel::RunGraphModule(char *sk)
307 QString program = getHomeDir();
308 program += "/modules/loggraph";
312 if (execl(program.toStdString().c_str(),
313 program.toStdString().c_str(),
323 WriteMessage("Executing loggraph failed!");
324 WriteMessage("Exiting...");
326 on_actionQuit_triggered();
330 WriteMessage("fork(loggraph) failed!");
331 WriteMessage("Exiting...");
333 on_actionQuit_triggered();
341 void QKernel::RunNetModule()
343 struct sockaddr_un svr;
348 QString program = getHomeDir();
349 program += "/modules/lognet";
353 if (execl(program.toStdString().c_str(),
354 program.toStdString().c_str(),
355 getNetModuleSocket(),
356 getConfigFilePath().toStdString().c_str(),
365 WriteMessage("Executing lognet failed!");
366 WriteMessage("Exiting...");
368 on_actionQuit_triggered();
372 WriteMessage("fork(lognet) failed!");
373 WriteMessage("Exiting...");
375 on_actionQuit_triggered();
379 /* -------- socket for NET module -------- */
380 unlink(getNetModuleSocket());
381 sock = socket(AF_UNIX, SOCK_STREAM, 0);
382 bzero(&svr, sizeof(svr));
383 svr.sun_family = AF_UNIX;
384 strcpy(svr.sun_path, getNetModuleSocket());
385 len = strlen(svr.sun_path) + sizeof(svr.sun_family);
386 bind(sock, (struct sockaddr*)&svr, len);
389 net_sock = accept(sock, (struct sockaddr*)0, (unsigned int*)0);
392 WriteMessage("NETWORK successfully connected");
393 fcntl(net_sock, F_SETFL, O_NONBLOCK|fcntl(net_sock, F_GETFL, 0));
395 setsockopt(net_sock, IPPROTO_TCP, TCP_NODELAY, (char*)&on, sizeof(on));
397 WriteMessage("Cannot connect NETWORK resources");
398 WriteMessage("Exiting...");
400 on_actionQuit_triggered();
405 * Connects to the specified address
406 * Additional window is displayed to connect to the specified address
408 void QKernel::on_actionConnect_triggered()
412 ConnectDialog dialog(this);
413 dialog.setWindowTitle("IP Address:");
416 m.msg_type = MSG_NET;
417 m.param.pword[0] = NET_CONNECT_TO;
418 strcpy(m.param.pstr, dialog.getAddress().toStdString().c_str());
419 write(net_sock, &m, sizeof(MESSAGE));
424 * Disconnects from virtual machine
426 void QKernel::on_actionDisconnect_triggered()
431 WriteMessage("Disconnecting from virtual machine");
433 msg.msg_type = MSG_NET;
434 msg.param.pword[0] = NET_DISCONNECT;
435 write(net_sock, &msg, sizeof(MESSAGE));
439 * Quits process. Closes VLP. Shows additional window to confirm exit.
441 void QKernel::on_actionQuit_triggered()
445 QMessageBox::StandardButton response = QMessageBox::question(this,
448 QMessageBox::Ok | QMessageBox::Cancel
452 if (response == QMessageBox::Cancel) {
456 msg.msg_type = MSG_NET;
457 msg.param.pword[0] = NET_DISCONNECT;
458 write(net_sock, &msg, sizeof(MESSAGE));*/
461 msg.msg_type = MSG_NET;
462 msg.param.pword[0] = NET_EXIT;
463 write(net_sock, &msg, sizeof(MESSAGE));
464 /* ::close(net_sock);*/
465 QApplication::instance()->quit();
469 * Sends message to node.
470 * Additional window is displayed to set Node Number of node where send message,
471 * and textfield to enter message.
473 void QKernel::on_actionMessage_triggered()
479 dlg = new QDialog(this, Qt::Dialog);
480 dlg->setWindowTitle("Send message to node");
482 nodenr = new QLineEdit("number", dlg);
483 nodenr->setGeometry(90, 10, 50, 30);
487 tmpQLabel = new QLabel("Node number:", dlg);
488 tmpQLabel->setGeometry(10, 10, 77, 30);
490 tmpQLabel = new QLabel("Message:", dlg);
491 tmpQLabel->setGeometry(10, 50, 70, 30);
494 msg = new QLineEdit("", dlg);
495 msg->setGeometry(80, 60, 330, 30);
498 ob = new QPushButton("Send", dlg);
499 ob->setGeometry(230, 10, 80, 30);
500 ob->setDefault(TRUE);
503 cb = new QPushButton("Cancel", dlg);
504 cb->setGeometry(330, 10, 80, 30);
505 dlg->resize(430, 110);
506 connect(ob, SIGNAL(clicked()), dlg, SLOT(accept()));
507 connect(cb, SIGNAL(clicked()), dlg, SLOT(reject()));
510 m.msg_type = MSG_NET;
511 m.param.pword[0] = NET_PROPAGATE;
512 m.param.pword[1] = MSG_VLP;
513 m.param.pword[2] = NodeNumber;
514 m.param.pword[4] = atoi(nodenr->text().toAscii().data());
515 m.param.pword[6] = VLP_WRITE;
516 strcpy(m.param.pstr, msg->text().toAscii().data());
517 write(net_sock, &m, sizeof(MESSAGE));
523 * Additional window is displayed to get ID of interpreter which should be
526 void QKernel::on_actionKill_triggered()
528 KillInterpreterDialog dialog(this);
529 dialog.setWindowTitle("Kill interpreter");
532 InterpEntry *interpreter;
535 m.msg_type = MSG_INT;
536 m.param.pword[0] = INT_KILL;
537 interpreter = findINTbyID(dialog.getInterpreterId());
538 if (interpreter != NULL) {
539 if (!(interpreter->remote))
540 write(interpreter->sock, &m, sizeof(MESSAGE));
542 WriteMessage("This is a remote instance of a program!");
545 WriteMessage("Interpreter not found");
551 * Sends message to the net module.
553 void QKernel::NetMessage()
556 /* TODO: It has to be rewritten */
562 cnt = read(net_sock, &msg, sizeof(MESSAGE));
563 if ((cnt > 0) && (msg.msg_type == MSG_NET)) {
564 switch(msg.param.pword[0]) {
566 WriteMessage(msg.param.pstr);
569 switch(msg.param.pword[1]) {
571 /* pom = find_link_by_ID(msg.param.pword[5]);
572 msg.msg_type = MSG_NET;
573 msg.param.pword[0] = NET_PROPAGATE;
574 send_int(pom, &msg);*/
577 switch(msg.param.pword[6]) {
579 QApplication::beep();
580 WriteMessage(CharLine);
582 "### Incoming Messsage ###");
583 sprintf(ss, "Mesg from Node %d: %s",
587 WriteMessage(CharLine);
589 case VLP_REMOTE_INSTANCE:
590 sprintf(ss, "%s/%s", getRemoteDir(),
594 WriteMessage("Running program:");
597 pom = RunIntModule(ss, 1);
599 pom->p_ctx.node = msg.param.pword[2];
600 pom->p_ctx.program_id =
602 pom->RInstances[msg.param.pword[2]] = msg.param.pword[7];
605 case VLP_CLOSE_INSTANCE:
606 msg.msg_type = MSG_INT;
607 msg.param.pword[0] = INT_CLOSE_INSTANCE;
608 pom = findINTbyID(msg.param.pword[7]);
610 write(pom->sock, &msg,
613 m1.msg_type = MSG_VLP;
614 m1.param.pword[0] = VLP_INTERPRETER_DOWN;
615 m1.param.pword[1] = pom->ID;
619 WriteMessage("Instance not found");
625 case NET_CONNECTIONS:
626 ActiveConnections = msg.param.pword[1];
627 WriteMessage(msg.param.pstr);
632 /* TODO: It has to be rewritten */
634 QString poms, poms1, poms2;
635 poms.sprintf("%s", msg.param.pstr);
636 while (poms.length() > 0) {
637 cnt = poms.indexOf(';');
639 poms1 = poms.left(cnt);
640 poms = poms.right(poms.length() - cnt - 1);
641 cnt = poms1.indexOf('=');
643 poms2 = poms1.left(cnt);
644 poms1 = poms1.right(poms1.length() - cnt - 1);
645 sprintf(ss, "Node: %s Addr: %s", poms2.toStdString().c_str(), poms1.toStdString().c_str());
653 wait_for_info = FALSE;
654 WriteMessage(CharLine);
661 * Sends message to the interpreter program.
662 * @param sock Interpreter socket to whom the message will be send.
664 void QKernel::IntMessage(int sock)
670 cnt = read(sock, &msg, sizeof(MESSAGE));
671 e = findINTbySocket(sock);
672 if ((cnt > 0) && (e != NULL)) {
673 switch (msg.msg_type) {
675 if (msg.param.pword[0] == GRAPH_ALLOCATE) {
676 RunGraphModule(msg.param.pstr);
680 write(net_sock, &msg, sizeof(MESSAGE));
683 switch(msg.param.pword[0]) {
684 case VLP_REMOTE_INSTANCE_PLEASE:
685 RemoteInstance(e, msg.param.pword[2]);
690 switch(msg.param.pword[0]) {
695 m.msg_type = MSG_VLP;
696 m.param.pword[0] = VLP_INTERPRETER_DOWN;
697 m.param.pword[1] = e->ID;
698 write(net_sock, &m, sizeof(MESSAGE));
703 /* TODO: Check this */
704 Interpreters.removeOne(e);
708 sprintf(ss, "%s : End of program "
709 "execution", msg.param.pstr);
714 msg.msg_type = MSG_INT;
715 msg.param.pword[0] = INT_CTX;
716 msg.param.pword[1] = NodeNumber;
717 msg.param.pword[2] = e->ID;
719 msg.param.pword[3] = e->p_ctx.node;
723 write(sock, &msg, sizeof(MESSAGE));
732 * Writes message to kernel logger.
733 * @parame msg String with message to log
735 void QKernel::WriteMessage(const char *msg)
739 x = desktop->textCursor().blockNumber();
740 // y = desktop->textCursor().columnNumber();
746 desktop->setReadOnly(FALSE);
747 desktop->append(msg);
748 desktop->setReadOnly(TRUE);
750 QTextCursor tmpCursor = desktop->textCursor();
751 tmpCursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor);
752 desktop->setTextCursor(tmpCursor);
756 if (desktop->document()->blockCount() > 100) {
762 * Adds checkbox to menu item. If it is checked additional info messages are
765 void QKernel::on_actionInfo_messages_triggered()
767 if (toolsMenu != NULL) {
768 info_messages = actionInfo_messages->isChecked();
769 actionInfo_messages->setChecked(info_messages);
774 * Allows to set options in GUI window.
775 * Additional window is displayed to set kernel options which are saved in
776 * vlp.cfg file in kernel executable directory.
778 void QKernel::on_actionOptions_triggered()
780 OptionsDialog optionsDialog(getConfigFilePath(), this);
781 if (optionsDialog.exec()) {
782 optionsDialog.saveConfig(getConfigFilePath());
784 loadConfig(getConfigFilePath());
789 * Locks kernel program.
790 * Additional window is displayed to enter password and retype it. If both are
791 * same kernel window is locked.
793 void QKernel::on_actionLock_console_triggered()
795 LockDialog lockDialog(this);
797 if (lockDialog.exec()) {
798 QString password = lockDialog.getPassword();
799 if (lockDialog.getPassword().size() > 0) {
800 strcpy(LockPasswd, password.toStdString().c_str());
803 if (lockDialog.exec()) {
804 password = lockDialog.getPassword();
805 if (password == LockPasswd) {
807 WriteMessage("CONSOLE LOCKED");
809 QMessageBox msg(this);
810 msg.setText("Not matching!");
811 msg.setButtonText(0, "Close");
813 strcpy(LockPasswd, "");
816 strcpy(LockPasswd, "");
823 * Unlocks kernel program.
824 * Additional window is displayed to enter password. If it is correct, kernel
827 void QKernel::on_actionUnlock_console_triggered()
829 LockDialog lockDialog(this);
831 if (lockDialog.exec()) {
832 QString password = lockDialog.getPassword();
833 if (strcmp(password.toStdString().c_str(), LockPasswd) == 0) {
835 WriteMessage("CONSOLE UNLOCKED");
837 QMessageBox msg(this);
838 msg.setText("Wrong password!");
839 msg.setButtonText(0, "Close");
846 * Finds Interpreter by its socket
847 * @param _id ID of the socket
848 * @return returns pointer to the found interpreter slot. NULL otherwise
850 InterpEntry *QKernel::findINTbySocket(int _id)
852 InterpEntry *pom = NULL;
854 for (int i = 0; i < Interpreters.size(); i++) {
855 if (Interpreters.at(i)->sock == _id) {
856 pom = Interpreters.at(i);
865 * Finds Interpreter by its ID.
866 * @param _id ID of the interpreter
867 * @return returns pointer to the found interpreter slot. NULL otherwise
869 InterpEntry *QKernel::findINTbyID(int _id)
871 InterpEntry *pom = NULL;
873 for (int i = 0; i < Interpreters.size(); i++) {
874 if (Interpreters.at(i)->ID == _id) {
875 pom = Interpreters.at(i);
885 * Connects interpreter
886 * @param ss full filepath with filename but without extension of the loglan
888 * @param r Interpreter execution mode. 0 if it will be local instance, 1 if
890 * @return Returns pointer to newly created interpreter slot, or NULL on error.
892 InterpEntry *QKernel::RunIntModule(char *ss, int r)
895 struct sockaddr_un svr;
902 InterpEntry *newINT = NULL;
908 WriteMessage("File not found: no .ccd file");
917 WriteMessage("File not found: no .pcd file");
922 newINT = new InterpEntry;
923 for(i = 0; i < MAXINSTANCES; i++)
924 newINT->RInstances[i] =- 1;
926 strcpy(b, rindex(ss, '/'));
927 for(i = 0; i < strlen(b); i++)
930 sprintf(a, "%s : Start execution", b);
937 strcpy(newINT->shortname, b);
938 strcpy(newINT->fullname, ss);
940 sprintf(a, "%s%d", IPATH, newint);
941 sprintf(cmd, "%s/modules/logint %s %s",
948 sprintf(b, " %s %s %s %s %s",
949 myargs[0], myargs[1], myargs[2], myargs[3], myargs[4]);
953 sock = socket(AF_UNIX, SOCK_STREAM, 0);
955 bzero(&svr, sizeof(svr));
956 svr.sun_family = AF_UNIX;
957 strcpy(svr.sun_path, a);
958 len = strlen(svr.sun_path)+sizeof(svr.sun_family);
959 bind(sock, (struct sockaddr*)&svr, len);
962 newINT->sock = accept(sock, (struct sockaddr*)0, (unsigned int *)0);
965 if (newINT->sock > 0) {
966 fcntl(newINT->sock, F_SETFL,
967 O_NONBLOCK|fcntl(newINT->sock, F_GETFL, 0));
969 setsockopt(newINT->sock, IPPROTO_TCP, TCP_NODELAY, (char*)&on,
976 bzero(&msg, sizeof(MESSAGE));
977 msg.msg_type = MSG_VLP;
978 msg.param.pword[0] = VLP_REGINT;
979 msg.param.pword[1] = newINT->ID;
980 sprintf(msg.param.pstr, "logi%d.net", newint);
981 write(net_sock, &msg, sizeof(MESSAGE));
983 Interpreters.append(newINT);
984 newINT->notify = new QSocketNotifier(newINT->sock,
985 QSocketNotifier::Read);
986 connect(newINT->notify, SIGNAL(activated(int)), this,
987 SLOT(IntMessage(int)));
989 WriteMessage("INTERPRETER successfully connected");
991 WriteMessage("Cannot connect interpreter");
998 * Allocates remote instance of interpreter
999 * @param interp Interpreter slot
1000 * @param on Node Number
1002 void QKernel::RemoteInstance(InterpEntry *interp, int on)
1007 m.msg_type = MSG_NET;
1008 m.param.pword[0] = NET_NODE_EXIST;
1009 m.param.pword[1] = on;
1010 m.param.pword[2] = interp->ID;
1011 write(net_sock, &m, sizeof(MESSAGE));
1012 bzero(&m, sizeof(MESSAGE));
1013 while((m.msg_type!=MSG_NET) && (m.param.pword[0]!=NET_NODE_EXIST))
1014 read(net_sock, &m, sizeof(MESSAGE));
1016 /* means node exists */
1017 if (m.param.pword[1] == 1) {
1018 m.msg_type = MSG_NET;
1019 m.param.pword[0] = NET_TRANSMIT_CODE;
1020 m.param.pword[1] = interp->ID;
1021 m.param.pword[2] = on;
1022 strcpy(m.param.pstr, interp->fullname);
1023 write(net_sock, &m, sizeof(MESSAGE));
1025 Net_Notify->setEnabled(FALSE);
1026 while ((m.msg_type != MSG_NET) ||
1027 (m.param.pword[0] != NET_TRANSMITTED))
1028 read(net_sock, &m, sizeof(MESSAGE));
1030 m.msg_type = MSG_NET;
1031 m.param.pword[0] = NET_PROPAGATE;
1032 m.param.pword[1] = MSG_VLP;
1033 m.param.pword[2] = NodeNumber;
1034 m.param.pword[3] = 0;
1035 m.param.pword[4] = on;
1036 m.param.pword[5] = 0;
1037 m.param.pword[6] = VLP_REMOTE_INSTANCE;
1038 m.param.pword[7] = interp->ID;
1039 strcpy(m.param.pstr, interp->shortname);
1040 write(net_sock, &m, sizeof(MESSAGE));
1042 read(net_sock, &m, sizeof(MESSAGE));
1044 if ((m.param.pword[0] == NET_PROPAGATE) &&
1045 (m.param.pword[6] == VLP_REMOTE_INSTANCE_OK)) {
1046 interp->RInstances[on] = m.param.pword[7];
1049 read(net_sock, &m, sizeof(MESSAGE));
1052 Net_Notify->setEnabled(TRUE);
1054 /*bzero(&m, sizeof(MESSAGE));*/
1055 m.msg_type = MSG_VLP;
1056 m.param.pword[0] = VLP_REMOTE_INSTANCE_HERE;
1057 m.param.pword[1] = interp->RInstances[on];
1058 write(interp->sock, &m, sizeof(MESSAGE));
1059 } else { /* There is no such a node! */
1060 sprintf(s, "Warning: Node number %d not found!", on);
1062 WriteMessage("Allocating O-process on the local node");
1063 bzero(&m, sizeof(MESSAGE));
1064 m.msg_type = MSG_VLP;
1065 m.param.pword[0] = VLP_REMOTE_INSTANCE_HERE;
1066 m.param.pword[1] = interp->ID;
1067 write(interp->sock, &m, sizeof(MESSAGE));
1072 * Closes all remote instances
1074 void QKernel::CloseInstances(InterpEntry *e)
1080 WriteMessage("Closing remote instances");
1082 for(i=0; i < MAXINSTANCES; i++)
1083 if (e->RInstances[i]>=0) {
1084 msg.msg_type = MSG_NET;
1085 msg.param.pword[0] = NET_PROPAGATE;
1086 msg.param.pword[1] = MSG_VLP;
1087 msg.param.pword[2] = NodeNumber;
1088 msg.param.pword[4] = i;
1089 msg.param.pword[6] = VLP_CLOSE_INSTANCE;
1090 msg.param.pword[7] = e->RInstances[i];
1091 write(net_sock, &msg, sizeof(MESSAGE));
1096 * Displays information about virtual machine
1098 void QKernel::on_actionInfo_triggered()
1102 WriteMessage(CharLine);
1103 WriteMessage("### Virtual Machine Information ###");
1104 m.msg_type = MSG_NET;
1105 m.param.pword[0] = NET_GET_INFO;
1106 write(net_sock, &m, sizeof(MESSAGE));
1107 wait_for_info = TRUE;
1111 * Program main function
1112 * All program arguments but the first one (argv[0]: program name) are saved and
1113 * passed to all dependent programs on their invocation.
1114 * @param argc Number of program arguments
1115 * @param argv Program arguments
1117 int main(int argc, char **argv)
1121 QApplication * app = new QApplication(argc, argv);
1122 QKernel kernel(argc, argv);