1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
|
#include "wvsendmail.h"
int WvSendmailProc::num_sendmails = 0;
WvSendmailProc::WvSendmailProc(const char **argv, int _count,
const WvSendmailCallback &_cb)
: WvPipe(argv[0], argv, true, false, false), count(_count), cb(_cb)
{
is_done = exited = false;
num_sendmails++;
}
WvSendmailProc::~WvSendmailProc()
{
close();
int ret = finish();
// be certain the callback gets called
if (!exited && cb)
cb(count, (ret == 0));
num_sendmails--;
}
bool WvSendmailProc::pre_select(SelectInfo &si)
{
bool must = false;
if (is_done && !exited && si.msec_timeout > 20)
si.msec_timeout = 20;
if (child_exited() && !exited && is_done)
{
exited = true;
// call the callback
if (cb)
cb(count, !exit_status());
si.msec_timeout = 0;
must = true;
}
// another hack because isok() returns true when it shouldn't really
if ((exited || is_done) && si.wants.writable)
must = true;
return must || WvPipe::pre_select(si);
}
bool WvSendmailProc::isok() const
{
// note: this means people will try to write to us even if the pipe
// says it's invalid!
return WvPipe::isok() || !exited;
}
size_t WvSendmailProc::uwrite(const void *buf, size_t count)
{
if (child_exited())
return count; // fake it, because isok() is also faking it
return WvPipe::uwrite(buf, count);
}
void WvSendmailProc::execute()
{
WvPipe::execute();
if (is_done && select(0, false, true, false))
close();
}
void WvSendmailProc::done()
{
is_done = true;
force_select(false, true);
}
|