2015-11-05 18:33:21 -06:00
|
|
|
/*
|
|
|
|
File: requestchannel.C
|
|
|
|
|
|
|
|
Author: R. Bettati
|
|
|
|
Department of Computer Science
|
|
|
|
Texas A&M University
|
|
|
|
Date : 2012/07/11
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
/* DEFINES */
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
/* -- (none) -- */
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
/* INCLUDES */
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
#include <cassert>
|
|
|
|
#include <cstring>
|
|
|
|
#include <iostream>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
|
|
#include <errno.h>
|
|
|
|
|
|
|
|
#include "reqchannel.h"
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
/* DATA STRUCTURES */
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
/* -- (none) -- */
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
/* CONSTANTS */
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
/* -- (none) -- */
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
/* FORWARDS */
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
/* -- (none) -- */
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
/* PRIVATE METHODS FOR CLASS R e q u e s t C h a n n e l */
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
char * RequestChannel::pipe_name(Mode _mode) {
|
|
|
|
string pname = "fifo_" + my_name;
|
|
|
|
|
|
|
|
if (my_side == CLIENT_SIDE) {
|
|
|
|
if (_mode == READ_MODE)
|
|
|
|
pname += "1";
|
|
|
|
else
|
|
|
|
pname += "2";
|
|
|
|
} else {
|
|
|
|
/* SERVER_SIDE */
|
|
|
|
if (_mode == READ_MODE)
|
|
|
|
pname += "2";
|
|
|
|
else
|
|
|
|
pname += "1";
|
|
|
|
}
|
|
|
|
char * result = new char[pname.size()+1];
|
|
|
|
strncpy(result, pname.c_str(), pname.size()+1);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
void RequestChannel::open_write_pipe(char * _pipe_name) {
|
|
|
|
|
|
|
|
// cout << "mkfifo write pipe\n" << flush;
|
|
|
|
|
|
|
|
if (mkfifo(_pipe_name, 0600) < 0) {
|
|
|
|
if (errno != EEXIST) {
|
|
|
|
perror("Error creating pipe for writing; exit program");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// cout << "open write pipe\n" << flush;
|
|
|
|
|
|
|
|
wfd = open(_pipe_name, O_WRONLY);
|
|
|
|
if (wfd < 0) {
|
|
|
|
perror("Error opening pipe for writing; exit program");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
// cout << "done opening write pipe\n" << flush;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void RequestChannel::open_read_pipe(char * _pipe_name) {
|
|
|
|
|
|
|
|
// cout << "mkfifo read pipe\n" << flush;
|
|
|
|
|
|
|
|
if (mkfifo(_pipe_name, 0600) < 0) {
|
|
|
|
if (errno != EEXIST) {
|
|
|
|
perror("Error creating pipe for writing; exit program");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// cout << "open read pipe\n" << flush;
|
|
|
|
|
|
|
|
rfd = open(_pipe_name, O_RDONLY);
|
|
|
|
if (rfd < 0) {
|
|
|
|
perror("Error opening pipe for reading; exit program");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
// cout << "done opening read pipe\n" << flush;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
/* CONSTRUCTOR/DESTRUCTOR FOR CLASS R e q u e s t C h a n n e l */
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
RequestChannel::RequestChannel(const string _name, const Side _side) : my_name(_name), my_side(_side) {
|
|
|
|
|
|
|
|
if (_side == SERVER_SIDE) {
|
|
|
|
open_write_pipe(pipe_name(WRITE_MODE));
|
|
|
|
open_read_pipe(pipe_name(READ_MODE));
|
|
|
|
} else {
|
|
|
|
open_read_pipe(pipe_name(READ_MODE));
|
|
|
|
open_write_pipe(pipe_name(WRITE_MODE));
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
RequestChannel::~RequestChannel() {
|
2015-11-13 10:02:10 -06:00
|
|
|
//cout << "close requests channel " << my_name << endl;
|
2015-11-05 18:33:21 -06:00
|
|
|
close(wfd);
|
|
|
|
close(rfd);
|
|
|
|
if (my_side == SERVER_SIDE) {
|
2015-11-13 10:02:10 -06:00
|
|
|
//cout << "close IPC mechanisms on server side for channel " << my_name << endl;
|
2015-11-05 18:33:21 -06:00
|
|
|
/* Destruct the underlying IPC mechanisms. */
|
|
|
|
if (remove(pipe_name(READ_MODE)) != 0) {
|
|
|
|
perror(string("Request Channel (" + my_name + ") : Error deleting pipe for reading").c_str());
|
|
|
|
}
|
|
|
|
|
|
|
|
if (remove(pipe_name(WRITE_MODE)) != 0) {
|
|
|
|
perror(string("Request Channel (" + my_name + ") : Error deleting pipe for writing").c_str());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
/* READ/WRITE FROM/TO REQUEST CHANNELS */
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
const int MAX_MESSAGE = 255;
|
|
|
|
|
|
|
|
string RequestChannel::send_request(string _request) {
|
|
|
|
cwrite(_request);
|
|
|
|
string s = cread();
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
string RequestChannel::cread() {
|
|
|
|
|
|
|
|
char buf[MAX_MESSAGE];
|
|
|
|
|
|
|
|
if (read(rfd, buf, MAX_MESSAGE) < 0) {
|
|
|
|
perror(string("Request Channel (" + my_name + "): Error reading from pipe!").c_str());
|
|
|
|
}
|
|
|
|
|
|
|
|
string s = buf;
|
|
|
|
|
|
|
|
// cout << "Request Channel (" << my_name << ") reads [" << buf << "]\n";
|
|
|
|
|
|
|
|
return s;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
int RequestChannel::cwrite(string _msg) {
|
|
|
|
|
|
|
|
if (_msg.length() >= MAX_MESSAGE) {
|
|
|
|
cerr << "Message too long for Channel!\n";
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// cout << "Request Channel (" << my_name << ") writing [" << _msg << "]";
|
|
|
|
|
|
|
|
const char * s = _msg.c_str();
|
|
|
|
|
|
|
|
if (write(wfd, s, strlen(s)+1) < 0) {
|
|
|
|
perror(string("Request Channel (" + my_name + ") : Error writing to pipe!").c_str());
|
|
|
|
}
|
|
|
|
|
|
|
|
// cout << "(" << my_name << ") done writing." << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
/* ACCESS THE NAME OF REQUEST CHANNEL */
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
string RequestChannel::name() {
|
|
|
|
return my_name;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
/* ACCESS FILE DESCRIPTORS OF REQUEST CHANNEL */
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
int RequestChannel::read_fd() {
|
|
|
|
return rfd;
|
|
|
|
}
|
|
|
|
|
|
|
|
int RequestChannel::write_fd() {
|
|
|
|
return wfd;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|