* Refactoring.

This commit is contained in:
Eelco Dolstra 2004-06-15 13:49:42 +00:00
parent 1bc6afefac
commit 0b70231b9d
3 changed files with 57 additions and 83 deletions

View File

@ -17,61 +17,6 @@
static string pathNullDevice = "/dev/null"; static string pathNullDevice = "/dev/null";
struct Pipe
{
int readSide, writeSide;
Pipe();
~Pipe();
void create();
void closeReadSide();
void closeWriteSide();
};
Pipe::Pipe()
: readSide(0), writeSide(0)
{
}
Pipe::~Pipe()
{
closeReadSide();
closeWriteSide();
}
void Pipe::create()
{
int fds[2];
if (pipe(fds) != 0) throw SysError("creating pipe");
readSide = fds[0];
writeSide = fds[1];
}
void Pipe::closeReadSide()
{
if (readSide != 0) {
if (close(readSide) == -1)
printMsg(lvlError, format("cannot close read side of pipe"));
readSide = 0;
}
}
void Pipe::closeWriteSide()
{
if (writeSide != 0) {
if (close(writeSide) == -1)
printMsg(lvlError, format("cannot close write side of pipe"));
writeSide = 0;
}
}
/* A goal is a store expression that still has to be normalised. */ /* A goal is a store expression that still has to be normalised. */
struct Goal struct Goal
{ {
@ -116,7 +61,7 @@ struct Goal
Path tmpDir; Path tmpDir;
/* File descriptor for the log file. */ /* File descriptor for the log file. */
int fdLogFile; AutoCloseFD fdLogFile;
/* Pipe for the builder's standard output/error. */ /* Pipe for the builder's standard output/error. */
Pipe logPipe; Pipe logPipe;
@ -135,7 +80,6 @@ struct Goal
Goal::Goal() Goal::Goal()
: pid(0) : pid(0)
, tmpDir("") , tmpDir("")
, fdLogFile(0)
{ {
} }
@ -164,9 +108,6 @@ Goal::~Goal()
} }
} }
if (fdLogFile && (close(fdLogFile) != 0))
printMsg(lvlError, format("cannot close fd"));
try { try {
deleteTmpDir(false); deleteTmpDir(false);
} catch (Error & e) { } catch (Error & e) {
@ -725,8 +666,8 @@ Normaliser::HookReply Normaliser::tryBuildHook(Goal & goal)
childStarted(goal, pid); childStarted(goal, pid);
goal.fromHook.closeWriteSide(); goal.fromHook.writeSide.close();
goal.toHook.closeReadSide(); goal.toHook.readSide.close();
/* Read the first line of input, which should be a word indicating /* Read the first line of input, which should be a word indicating
whether the hook wishes to perform the build. !!! potential whether the hook wishes to perform the build. !!! potential
@ -807,11 +748,10 @@ void Normaliser::terminateBuildHook(Goal & goal)
if (waitpid(goal.pid, &status, 0) != goal.pid) if (waitpid(goal.pid, &status, 0) != goal.pid)
printMsg(lvlError, format("process `%1%' missing") % goal.pid); printMsg(lvlError, format("process `%1%' missing") % goal.pid);
goal.pid = 0; goal.pid = 0;
goal.fromHook.closeReadSide(); goal.fromHook.readSide.close();
goal.toHook.closeWriteSide(); goal.toHook.writeSide.close();
close(goal.fdLogFile); goal.fdLogFile.close();
goal.fdLogFile = 0; goal.logPipe.readSide.close();
goal.logPipe.closeReadSide();
building.erase(pid); building.erase(pid);
} }
@ -820,11 +760,10 @@ void Normaliser::openLogFile(Goal & goal)
{ {
/* Create a log file. */ /* Create a log file. */
Path logFileName = nixLogDir + "/" + baseNameOf(goal.nePath); Path logFileName = nixLogDir + "/" + baseNameOf(goal.nePath);
int fdLogFile = open(logFileName.c_str(), goal.fdLogFile = open(logFileName.c_str(),
O_CREAT | O_WRONLY | O_TRUNC, 0666); O_CREAT | O_WRONLY | O_TRUNC, 0666);
if (fdLogFile == -1) if (goal.fdLogFile == -1)
throw SysError(format("creating log file `%1%'") % logFileName); throw SysError(format("creating log file `%1%'") % logFileName);
goal.fdLogFile = fdLogFile;
/* Create a pipe to get the output of the child. */ /* Create a pipe to get the output of the child. */
goal.logPipe.create(); goal.logPipe.create();
@ -844,8 +783,7 @@ void Normaliser::initChild(Goal & goal)
/* Dup the write side of the logger pipe into stderr. */ /* Dup the write side of the logger pipe into stderr. */
if (dup2(goal.logPipe.writeSide, STDERR_FILENO) == -1) if (dup2(goal.logPipe.writeSide, STDERR_FILENO) == -1)
throw SysError("cannot pipe standard error into log file"); throw SysError("cannot pipe standard error into log file");
if (close(goal.logPipe.readSide) != 0) /* close read side */ goal.logPipe.readSide.close();
throw SysError("closing fd");
/* Dup stderr to stdin. */ /* Dup stderr to stdin. */
if (dup2(STDERR_FILENO, STDOUT_FILENO) == -1) if (dup2(STDERR_FILENO, STDOUT_FILENO) == -1)
@ -859,15 +797,15 @@ void Normaliser::initChild(Goal & goal)
throw SysError("cannot dup null device into stdin"); throw SysError("cannot dup null device into stdin");
/* When running a hook, dup the communication pipes. */ /* When running a hook, dup the communication pipes. */
bool inHook = goal.fromHook.writeSide != 0; bool inHook = goal.fromHook.writeSide.isOpen();
if (inHook) { if (inHook) {
goal.fromHook.closeReadSide(); goal.fromHook.readSide.close();
if (dup2(goal.fromHook.writeSide, 3) == -1) if (dup2(goal.fromHook.writeSide, 3) == -1)
throw SysError("dup"); throw SysError("dup1");
goal.toHook.closeWriteSide(); goal.toHook.writeSide.close();
if (dup2(goal.toHook.readSide, 4) == -1) if (dup2(goal.toHook.readSide, 4) == -1)
throw SysError("dup"); throw SysError("dup2");
} }
/* Close all other file descriptors. */ /* Close all other file descriptors. */
@ -887,7 +825,7 @@ void Normaliser::childStarted(Goal & goal, pid_t pid)
building[goal.pid] = goal.nePath; building[goal.pid] = goal.nePath;
/* Close the write side of the logger pipe. */ /* Close the write side of the logger pipe. */
goal.logPipe.closeWriteSide(); goal.logPipe.writeSide.close();
} }
@ -971,12 +909,10 @@ void Normaliser::reapChild(Goal & goal)
goal.pid = 0; goal.pid = 0;
/* Close the read side of the logger pipe. */ /* Close the read side of the logger pipe. */
goal.logPipe.closeReadSide(); goal.logPipe.readSide.close();
/* Close the log file. */ /* Close the log file. */
if (close(goal.fdLogFile) != 0) goal.fdLogFile.close();
throw SysError("closing fd");
goal.fdLogFile = 0;
debug(format("builder process %1% finished") % pid); debug(format("builder process %1% finished") % pid);

View File

@ -365,11 +365,16 @@ AutoCloseFD::AutoCloseFD(int fd)
AutoCloseFD::~AutoCloseFD() AutoCloseFD::~AutoCloseFD()
{ {
if (fd != -1) close(fd); try {
close();
} catch (Error & e) {
printMsg(lvlError, format("error (ignored): %1%") % e.msg());
}
} }
void AutoCloseFD::operator =(int fd) void AutoCloseFD::operator =(int fd)
{ {
if (this->fd != fd) close();
this->fd = fd; this->fd = fd;
} }
@ -378,6 +383,30 @@ AutoCloseFD::operator int()
return fd; return fd;
} }
void AutoCloseFD::close()
{
if (fd != -1) {
if (::close(fd) == -1)
/* This should never happen. */
throw SysError("closing file descriptor");
fd = -1;
}
}
bool AutoCloseFD::isOpen()
{
return fd != -1;
}
void Pipe::create()
{
int fds[2];
if (pipe(fds) != 0) throw SysError("creating pipe");
readSide = fds[0];
writeSide = fds[1];
}
AutoCloseDir::AutoCloseDir() AutoCloseDir::AutoCloseDir()
{ {

View File

@ -181,6 +181,15 @@ public:
~AutoCloseFD(); ~AutoCloseFD();
void operator =(int fd); void operator =(int fd);
operator int(); operator int();
void close();
bool isOpen();
};
class Pipe
{
public:
AutoCloseFD readSide, writeSide;
void create();
}; };
class AutoCloseDir class AutoCloseDir