Commit 1431a89f authored by Jonathon Duerig's avatar Jonathon Duerig

Added the first version of the prepass (or at least the first one that works)....

Added the first version of the prepass (or at least the first one that works). This is a prepass stage for ipassign which partitions the graph based on biconnectivity and dispatches each component to be assigned by an appropriate assigner.
parent bae4b6cc
g++ -o trivial-ipassign trivial-ipassign.cc
g++ -o prepass prepass.cc coprocess.cc
// coprocess.cc
/*
* EMULAB-COPYRIGHT
* Copyright (c) 2003 University of Utah and the Flux Group.
* All rights reserved.
*/
#include <unistd.h>
//#include "lib.h"
#include "coprocess.h"
// TODO: Make sure that the pipes are properly closed in the case of
// error.
auto_ptr<FileT> coprocess(char const * path, char * const argv[],
char * const envp[])
{
auto_ptr<FileT> file;
// child_stdin[0] = stdin for child
// child_stdin[1] = write end for parent
int child_stdin[2] = {-1, -1};
// child_stdout[0] = read end for parent
// child_stdout[1] = stdout for child
int child_stdout[2] = {-1, -1};
// child_stderr[0] = read end for parent
// child_stderr[1] = stderr for child
int child_stderr[2] = {-1, -1};
int error = 0;
error = pipe(child_stdin);
if (error == -1)
{
cerr << "Failed to open pipe child_stdin: " << strerror(errno)
<< endl;
throw;
}
error = pipe(child_stdout);
if (error == -1)
{
cerr << "Failed to open pipe for child_stdout: " << strerror(errno)
<< endl;
throw;
}
error = pipe(child_stderr);
if (error == -1)
{
cerr << "Failed to open pipe child_stderr: " << strerror(errno)
<< endl;
throw;
}
error = fork();
if (error == 0)
{
// child
error = dup2(child_stdin[0], fileno(stdin));
if (error == -1)
{
cerr << "Failed to dup stdin: " << strerror(errno) << endl;
_exit(1);
}
error = close(child_stdin[0]);
if (error == -1)
{
cerr << "Failed to close child_stdin[0]: " << strerror(errno)
<< endl;
_exit(1);
}
error = close(child_stdin[1]);
if (error == -1)
{
cerr << "Failed to close child_stdin[1]: " << strerror(errno)
<< endl;
_exit(1);
}
error = dup2(child_stdout[1], fileno(stdout));
if (error == -1)
{
cerr << "Failed to dup stdout: " << strerror(errno) << endl;
_exit(1);
}
error = close(child_stdout[0]);
if (error == -1)
{
cerr << "Failed to close child_stdout[0]: " << strerror(errno)
<< endl;
_exit(1);
}
error = close(child_stdout[1]);
if (error == -1)
{
cerr << "Failed to close child_stdout[1]: " << strerror(errno)
<< endl;
_exit(1);
}
error = dup2(child_stderr[1], fileno(stderr));
if (error == -1)
{
cerr << "Failed to dup stderr" << strerror(errno) << endl;
_exit(1);
}
error = close(child_stderr[0]);
if (error == -1)
{
cerr << "Failed to close child_stderr[0]: " << strerror(errno)
<< endl;
_exit(1);
}
error = close(child_stderr[1]);
if (error == -1)
{
cerr << "Failed to close child_stderr[1]: " << strerror(errno)
<< endl;
_exit(1);
}
error = execve(path, argv, envp);
cerr << "Failed to execve: " << strerror(errno) << endl;
_exit(1);
}
else if (error > 0)
{
// parent
file.reset(new FileT(child_stdin[1], child_stdout[0],
child_stderr[0]));
close(child_stdin[0]);
close(child_stdout[1]);
close(child_stderr[1]);
}
else
{
// error
cerr << "Failed to fork properly: " << strerror(errno) << endl;
throw;
}
return file;
}
// coprocess.h
/*
* EMULAB-COPYRIGHT
* Copyright (c) 2003 University of Utah and the Flux Group.
* All rights reserved.
*/
#ifndef COPROCESS_H_IP_ASSIGN_2
#define COPROCESS_H_IP_ASSIGN_2
#include <memory>
#include <string>
#include <errno.h>
#include "pistream.h"
#include "postream.h"
class FileT
{
public:
FileT(int newInput, int newOutput, int newError)
: inDes(newInput)
, in(newInput)
, outDes(newOutput)
, out(newOutput)
, errDes(newError)
, err(newError)
{
}
~FileT()
{
if (inDes != -1)
{
close(inDes);
}
if (outDes != -1)
{
close(outDes);
}
if (errDes != -1)
{
close(errDes);
}
}
void closeIn(void)
{
if (inDes != -1)
{
close(inDes);
inDes = -1;
}
}
void closeOut(void)
{
if (outDes != -1)
{
close(outDes);
outDes = -1;
}
}
void closeErr(void)
{
if (errDes != -1)
{
close(errDes);
errDes = -1;
}
}
std::ostream & input(void) const
{
if (inDes == -1)
{
cerr << "Error: input used after closing" << endl;
throw;
}
return in;
}
std::istream & output(void) const
{
if (outDes == -1)
{
cerr << "Error: output used after closing" << endl;
throw;
}
return out;
}
std::istream & error(void) const
{
if (errDes == -1)
{
cerr << "Error: error used after closing" << endl;
}
return err;
}
private:
FileT();
FileT(FileT const &);
FileT & operator=(FileT const &) { return *this; }
private:
int inDes;
int outDes;
int errDes;
mutable postream in;
mutable pistream out;
mutable pistream err;
};
std::auto_ptr<FileT> coprocess(char const * path, char * const argv[],
char * const envp[]);
#endif
// This was taken from the below book for speed-of-implementation purposes.
/* The following code example is taken from the book
* "The C++ Standard Library - A Tutorial and Reference"
* by Nicolai M. Josuttis, Addison-Wesley, 1999
*
* (C) Copyright Nicolai M. Josuttis 1999.
* Permission to copy, use, modify, sell and distribute this software
* is granted provided this copyright notice appears in all copies.
* This software is provided "as is" without express or implied
* warranty, and with no claim as to its suitability for any purpose.
*/
#include <cstdio>
#include <cstring>
#include <streambuf.h>
#include <unistd.h>
class pinbuf : public std::streambuf {
private:
pinbuf();
protected:
/* data buffer:
* - at most, four characters in putback area plus
* - at most, six characters in ordinary read buffer
*/
static const int bufferSize = 10; // size of the data buffer
char buffer[bufferSize]; // data buffer
public:
/* constructor
* - initialize empty data buffer
* - no putback area
* => force underflow()
*/
pinbuf(int newfile) : file(newfile) {
setg (buffer+4, // beginning of putback area
buffer+4, // read position
buffer+4); // end position
}
protected:
// insert new characters into the buffer
virtual int underflow () {
// is read position before end of buffer?
if (gptr() < egptr()) {
return static_cast<int>(*gptr());
}
/* process size of putback area
* - use number of characters read
* - but at most four
*/
int numPutback;
numPutback = gptr() - eback();
if (numPutback > 4) {
numPutback = 4;
}
/* copy up to four characters previously read into
* the putback buffer (area of first four characters)
*/
std::memmove (buffer+(4-numPutback), gptr()-numPutback,
numPutback);
// read new characters
int num;
num = read (file, buffer+4, bufferSize-4);
if (num <= 0) {
// ERROR or EOF
return EOF;
}
// reset buffer pointers
setg (buffer+(4-numPutback), // beginning of putback area
buffer+4, // read position
buffer+4+num); // end of buffer
// return next character
return static_cast<int>(*gptr());
}
int file;
};
class pistream : public std::istream {
protected:
pinbuf buf;
public:
pistream (int file) : std::istream(0), buf(file)
{
rdbuf(&buf);
}
private:
pistream();
};
// This was taken from the below book for speed-of-implementation purposes.
/* The following code example is taken from the book
* "The C++ Standard Library - A Tutorial and Reference"
* by Nicolai M. Josuttis, Addison-Wesley, 1999
*
* (C) Copyright Nicolai M. Josuttis 1999.
* Permission to copy, use, modify, sell and distribute this software
* is granted provided this copyright notice appears in all copies.
* This software is provided "as is" without express or implied
* warranty, and with no claim as to its suitability for any purpose.
*/
#include <iostream>
#include <streambuf.h>
#include <cstdio>
#include <unistd.h>
class poutbuf : public std::streambuf {
private:
poutbuf();
protected:
int file; // file descriptor
public:
// constructor
poutbuf (int newfile) : file(newfile) {
}
protected:
// write one character
virtual int overflow (int c) {
if (c != EOF) {
char z = c;
if (write (file, &z, sizeof(char)) != 1) {
return EOF;
}
}
return c;
}
// write multiple characters
virtual
std::streamsize xsputn (const char* s,
std::streamsize num) {
return write(file, s, num);
}
};
class postream : public std::ostream {
protected:
poutbuf buf;
public:
postream (int file) : std::ostream(0), buf(file) {
rdbuf(&buf);
}
private:
postream();
};
This diff is collapsed.
// trivial-ipassign.cc
#include <iostream>
#include <string>
using namespace std;
int main()
{
string line;
getline(cin, line);
while (cin && line != "%%")
{
getline(cin, line);
}
int count = 0;
getline(cin, line);
while (cin)
{
cout << count << endl;
getline(cin, line);
++count;
}
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment