#include "blop_bookkeeper.h"
#include "warning.h"
#include <stdlib.h>
#include <cstdio>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <iostream>
namespace blop
{
using namespace std;
blop_initializer::blop_initializer()
{
call_INIT();
}
std::string blop_bookkeeper::tmpdir_;
int blop_bookkeeper::tmp_count_ = 1;
std::vector<int> blop_bookkeeper::wait_pid_;
blop_bookkeeper::~blop_bookkeeper()
{
if(!wait_pid_.empty())
{
cerr<<"[blop] Waiting for child processes to terminate...";
}
for(unsigned int i=0; i<wait_pid_.size(); ++i)
{
int status =0;
waitpid(wait_pid_[i],&status,0);
}
if(tmpdir_ != "")
{
char s[1000];
sprintf(s,"rm -rf %s",tmpdir_.c_str());
system(s);
}
}
void blop_bookkeeper::register_pid(int pid)
{
wait_pid_.push_back(pid);
}
void blop_bookkeeper::wait(int pid)
{
int status =0;
waitpid(pid,&status,0);
for(unsigned int i=0; i<wait_pid_.size(); ++i)
{
if(wait_pid_[i] == pid)
{
wait_pid_.erase(wait_pid_.begin()+1);
return;
}
}
}
std::string blop_bookkeeper::get_tmpdir_()
{
if(tmpdir_ == "")
{
char s[1000];
if(tmpdir_ == "")
{
sprintf(s,"/tmp/BLOP-%i-XXXXXX",getpid());
if(mkdtemp(s) == 0)
{
warning::print("Could not create temprary directory: " & var(s));
return "";
}
tmpdir_ = s;
}
}
return tmpdir_;
}
std::string blop_bookkeeper::tmpfile(var temp)
{
var::size_type slash = temp.rfind("/");
if(slash != var::npos) temp.replace(0,slash+1,"");
char s[1000];
if(temp.find("XXXXXX") == var::npos) temp = "XXXXXX-" & temp;
sprintf(s,"%06i",tmp_count_++);
temp.replace("XXXXXX",s);
string result = (get_tmpdir_() & "/" & temp).str();
struct stat buf;
if(stat(result.c_str(),&buf) == 0) warning::print("Oops, this temporary file already exists. Please report this problem!");
return result;
}
std::string blop_bookkeeper::tmpdir(var temp)
{
string result = tmpfile(temp);
if(mkdir(result.c_str(),S_IRWXU) != 0) warning::print("Failed to create temporary directory");
return result;
}
blop_bookkeeper BLOP;
}