// ===========================================================
// Author: Yee Hsu #1-8748
// Instru: Dr. J. Wong
// Date: May 2, 2001
//
// File: SMVS.cpp
//
// The Server driver. The server first forks a process and
// executes com pd1. Then it continueously listens to
// Com (pd1) and Clients (pd2) and service them if there is
// a request. Clients are created when Com issues a command
// to execute a process. The Server loops indefinitely to
// service the two in such algorithm:
//
// infinite loop ()
// read from pipe1, service Com
// read from pipe2, service Client
// loop back
// ===========================================================
#include <iostream.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
#include "Pcib.h"
#include "List.h"
#include "Semaphore.h"
#include "Message.h"
#include "Server.h"
#include "Host.h"
/* ************************************************ */
/* */
/* Server Main Driver */
/* */
/* ************************************************ */
void main()
{
// declaration of all pipes
int pipe1[2], pipe2[2], pipen[2];
// create pipe channels for communications
pipe(pipe1), pipe(pipe2);
// set channels to be non-blocked
fcntl(pipe1[0], F_SETFL, O_NONBLOCK);
fcntl(pipe2[0], F_SETFL, O_NONBLOCK);
if (fork() == 0)
{
// child executes Com pd1
char pd1[10] = {"\0"};
sprintf(pd1, "%d", pipe1[1]);
execl("./Com", "Com", pd1, 0);
exit(0);
}
else
{
Server s; // create Server [ActiveList and Semaphore(s)]
ComMsg m1; // m1 - com -> server
RequestMsg m2; // m2 - client -> server
ReplyMsg m3; // m3 - server -> client
while (1)
{
// listen to com query from pipe1 and service if needed
if (read(pipe1[0], &m1, sizeof(m1)) > 0)
{
if (!strcmp(m1.command, RUN))
{
// create new pipe for process communication
pipe(pipen);
// fork and insert process to active list
int retv = fork();
if (retv == 0)
{
// child executes program
SetChannel(pipen[0], pipe2[1]);
RunCommand(m1);
exit(0);
}
else
s.Insert(retv, pipen[1], m1);
}
else if (!strcmp(m1.command, LS))
{
// list information on server queues
s.LsCommand(m1);
}
else if (!strcmp(m1.command, EXIT))
{
// finalize and terminate server
s.ExitCommand();
ClosePipes(pipe1, pipe2, pipen);
exit(0);
}
}
// listen to client query from pipe2 and service if needed
if (read(pipe2[0], &m2, sizeof(m2)) > 0)
{
m3 = s.SemAction(m2);
UpdateLogFile(m1, m2);
if (!(m2.purpose == WAIT_SEM && m3.returnValue == -1))
{
if (m2.purpose != VS_EXIT)
write(pipen[1], &m3, sizeof(m3));
}
}
}
}
}