astyled
This commit is contained in:
parent
90afc535a4
commit
ae2962a41c
6 changed files with 785 additions and 703 deletions
|
@ -113,7 +113,7 @@ public:
|
||||||
sigemptyset(&m_blkcld);
|
sigemptyset(&m_blkcld);
|
||||||
}
|
}
|
||||||
// Child process code
|
// Child process code
|
||||||
inline void dochild(const std::string &cmd, const char **argv,
|
inline void dochild(const std::string& cmd, const char **argv,
|
||||||
const char **envv, bool has_input, bool has_output);
|
const char **envv, bool has_input, bool has_output);
|
||||||
};
|
};
|
||||||
bool ExecCmd::Internal::o_useVfork = false;
|
bool ExecCmd::Internal::o_useVfork = false;
|
||||||
|
@ -121,8 +121,9 @@ bool ExecCmd::Internal::o_useVfork = false;
|
||||||
ExecCmd::ExecCmd(int)
|
ExecCmd::ExecCmd(int)
|
||||||
{
|
{
|
||||||
m = new Internal();
|
m = new Internal();
|
||||||
if (m)
|
if (m) {
|
||||||
m->reset();
|
m->reset();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
void ExecCmd::setAdvise(ExecCmdAdvise *adv)
|
void ExecCmd::setAdvise(ExecCmdAdvise *adv)
|
||||||
{
|
{
|
||||||
|
@ -134,10 +135,11 @@ void ExecCmd::setProvide(ExecCmdProvide *p)
|
||||||
}
|
}
|
||||||
void ExecCmd::setTimeout(int mS)
|
void ExecCmd::setTimeout(int mS)
|
||||||
{
|
{
|
||||||
if (mS > 30)
|
if (mS > 30) {
|
||||||
m->m_timeoutMs = mS;
|
m->m_timeoutMs = mS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
void ExecCmd::setStderr(const std::string &stderrFile)
|
void ExecCmd::setStderr(const std::string& stderrFile)
|
||||||
{
|
{
|
||||||
m->m_stderrFile = stderrFile;
|
m->m_stderrFile = stderrFile;
|
||||||
}
|
}
|
||||||
|
@ -158,9 +160,10 @@ void ExecCmd::zapChild()
|
||||||
bool ExecCmd::requestChildExit()
|
bool ExecCmd::requestChildExit()
|
||||||
{
|
{
|
||||||
if (m->m_pid > 0) {
|
if (m->m_pid > 0) {
|
||||||
if (kill(m->m_pid, SIGTERM) == 0)
|
if (kill(m->m_pid, SIGTERM) == 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,8 +185,9 @@ static bool exec_is_there(const char *candidate)
|
||||||
|
|
||||||
bool ExecCmd::which(const string& cmd, string& exepath, const char* path)
|
bool ExecCmd::which(const string& cmd, string& exepath, const char* path)
|
||||||
{
|
{
|
||||||
if (cmd.empty())
|
if (cmd.empty()) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
if (cmd[0] == '/') {
|
if (cmd[0] == '/') {
|
||||||
if (exec_is_there(cmd.c_str())) {
|
if (exec_is_there(cmd.c_str())) {
|
||||||
exepath = cmd;
|
exepath = cmd;
|
||||||
|
@ -199,14 +203,16 @@ bool ExecCmd::which(const string& cmd, string& exepath, const char* path)
|
||||||
} else {
|
} else {
|
||||||
pp = getenv("PATH");
|
pp = getenv("PATH");
|
||||||
}
|
}
|
||||||
if (pp == 0)
|
if (pp == 0) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
vector<string> pels;
|
vector<string> pels;
|
||||||
stringToTokens(pp, pels, ":");
|
stringToTokens(pp, pels, ":");
|
||||||
for (vector<string>::iterator it = pels.begin(); it != pels.end(); it++) {
|
for (vector<string>::iterator it = pels.begin(); it != pels.end(); it++) {
|
||||||
if (it->empty())
|
if (it->empty()) {
|
||||||
*it = ".";
|
*it = ".";
|
||||||
|
}
|
||||||
string candidate = (it->empty() ? string(".") : *it) + "/" + cmd;
|
string candidate = (it->empty() ? string(".") : *it) + "/" + cmd;
|
||||||
if (exec_is_there(candidate.c_str())) {
|
if (exec_is_there(candidate.c_str())) {
|
||||||
exepath = candidate;
|
exepath = candidate;
|
||||||
|
@ -227,12 +233,12 @@ void ExecCmd::useVfork(bool on)
|
||||||
Internal::o_useVfork = on;
|
Internal::o_useVfork = on;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExecCmd::putenv(const string &ea)
|
void ExecCmd::putenv(const string& ea)
|
||||||
{
|
{
|
||||||
m->m_env.push_back(ea);
|
m->m_env.push_back(ea);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExecCmd::putenv(const string &name, const string& value)
|
void ExecCmd::putenv(const string& name, const string& value)
|
||||||
{
|
{
|
||||||
string ea = name + "=" + value;
|
string ea = name + "=" + value;
|
||||||
putenv(ea);
|
putenv(ea);
|
||||||
|
@ -258,19 +264,24 @@ public:
|
||||||
m_active = false;
|
m_active = false;
|
||||||
}
|
}
|
||||||
~ExecCmdRsrc() {
|
~ExecCmdRsrc() {
|
||||||
if (!m_active || !m_parent)
|
if (!m_active || !m_parent) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
LOGDEB1(("~ExecCmdRsrc: working. mypid: %d\n", (int)getpid()));
|
LOGDEB1(("~ExecCmdRsrc: working. mypid: %d\n", (int)getpid()));
|
||||||
|
|
||||||
// Better to close the descs first in case the child is waiting in read
|
// Better to close the descs first in case the child is waiting in read
|
||||||
if (m_parent->m_pipein[0] >= 0)
|
if (m_parent->m_pipein[0] >= 0) {
|
||||||
close(m_parent->m_pipein[0]);
|
close(m_parent->m_pipein[0]);
|
||||||
if (m_parent->m_pipein[1] >= 0)
|
}
|
||||||
|
if (m_parent->m_pipein[1] >= 0) {
|
||||||
close(m_parent->m_pipein[1]);
|
close(m_parent->m_pipein[1]);
|
||||||
if (m_parent->m_pipeout[0] >= 0)
|
}
|
||||||
|
if (m_parent->m_pipeout[0] >= 0) {
|
||||||
close(m_parent->m_pipeout[0]);
|
close(m_parent->m_pipeout[0]);
|
||||||
if (m_parent->m_pipeout[1] >= 0)
|
}
|
||||||
|
if (m_parent->m_pipeout[1] >= 0) {
|
||||||
close(m_parent->m_pipeout[1]);
|
close(m_parent->m_pipeout[1]);
|
||||||
|
}
|
||||||
|
|
||||||
// It's apparently possible for m_pid to be > 0 and getpgid to fail. In
|
// It's apparently possible for m_pid to be > 0 and getpgid to fail. In
|
||||||
// this case, we have to conclude that the child process does
|
// this case, we have to conclude that the child process does
|
||||||
|
@ -285,8 +296,9 @@ public:
|
||||||
msleep(i == 0 ? 5 : (i == 1 ? 100 : 2000));
|
msleep(i == 0 ? 5 : (i == 1 ? 100 : 2000));
|
||||||
int status;
|
int status;
|
||||||
(void)waitpid(m_parent->m_pid, &status, WNOHANG);
|
(void)waitpid(m_parent->m_pid, &status, WNOHANG);
|
||||||
if (kill(m_parent->m_pid, 0) != 0)
|
if (kill(m_parent->m_pid, 0) != 0) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
if (i == 2) {
|
if (i == 2) {
|
||||||
LOGDEB(("ExecCmd: killpg(%d, SIGKILL)\n", grp));
|
LOGDEB(("ExecCmd: killpg(%d, SIGKILL)\n", grp));
|
||||||
killpg(grp, SIGKILL);
|
killpg(grp, SIGKILL);
|
||||||
|
@ -311,8 +323,9 @@ private:
|
||||||
ExecCmd::~ExecCmd()
|
ExecCmd::~ExecCmd()
|
||||||
{
|
{
|
||||||
ExecCmdRsrc(this->m);
|
ExecCmdRsrc(this->m);
|
||||||
if (m)
|
if (m) {
|
||||||
delete m;
|
delete m;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// In child process. Set up pipes and exec command.
|
// In child process. Set up pipes and exec command.
|
||||||
|
@ -328,7 +341,7 @@ ExecCmd::~ExecCmd()
|
||||||
// If one of the calls block, the problem manifests itself by 20mn
|
// If one of the calls block, the problem manifests itself by 20mn
|
||||||
// (filter timeout) of looping on "ExecCmd::doexec: selectloop
|
// (filter timeout) of looping on "ExecCmd::doexec: selectloop
|
||||||
// returned 1', because the father is waiting on the read descriptor
|
// returned 1', because the father is waiting on the read descriptor
|
||||||
inline void ExecCmd::Internal::dochild(const string &cmd, const char **argv,
|
inline void ExecCmd::Internal::dochild(const string& cmd, const char **argv,
|
||||||
const char **envv,
|
const char **envv,
|
||||||
bool has_input, bool has_output)
|
bool has_input, bool has_output)
|
||||||
{
|
{
|
||||||
|
@ -411,9 +424,9 @@ inline void ExecCmd::Internal::dochild(const string &cmd, const char **argv,
|
||||||
}
|
}
|
||||||
// Do we need to redirect stderr ?
|
// Do we need to redirect stderr ?
|
||||||
if (!m_stderrFile.empty()) {
|
if (!m_stderrFile.empty()) {
|
||||||
int fd = open(m_stderrFile.c_str(), O_WRONLY|O_CREAT
|
int fd = open(m_stderrFile.c_str(), O_WRONLY | O_CREAT
|
||||||
#ifdef O_APPEND
|
#ifdef O_APPEND
|
||||||
|O_APPEND
|
| O_APPEND
|
||||||
#endif
|
#endif
|
||||||
, 0600);
|
, 0600);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
|
@ -443,10 +456,11 @@ void ExecCmd::setrlimit_as(int mbytes)
|
||||||
m->m_rlimit_as_mbytes = mbytes;
|
m->m_rlimit_as_mbytes = mbytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ExecCmd::startExec(const string &cmd, const vector<string>& args,
|
int ExecCmd::startExec(const string& cmd, const vector<string>& args,
|
||||||
bool has_input, bool has_output)
|
bool has_input, bool has_output)
|
||||||
{
|
{
|
||||||
{ // Debug and logging
|
{
|
||||||
|
// Debug and logging
|
||||||
string command = cmd + " ";
|
string command = cmd + " ";
|
||||||
for (vector<string>::const_iterator it = args.begin();
|
for (vector<string>::const_iterator it = args.begin();
|
||||||
it != args.end(); it++) {
|
it != args.end(); it++) {
|
||||||
|
@ -478,7 +492,7 @@ int ExecCmd::startExec(const string &cmd, const vector<string>& args,
|
||||||
// Allocate arg vector (2 more for arg0 + final 0)
|
// Allocate arg vector (2 more for arg0 + final 0)
|
||||||
typedef const char *Ccharp;
|
typedef const char *Ccharp;
|
||||||
Ccharp *argv;
|
Ccharp *argv;
|
||||||
argv = (Ccharp *)malloc((args.size()+2) * sizeof(char *));
|
argv = (Ccharp *)malloc((args.size() + 2) * sizeof(char *));
|
||||||
if (argv == 0) {
|
if (argv == 0) {
|
||||||
LOGERR(("ExecCmd::doexec: malloc() failed. errno %d\n", errno));
|
LOGERR(("ExecCmd::doexec: malloc() failed. errno %d\n", errno));
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -495,8 +509,9 @@ int ExecCmd::startExec(const string &cmd, const vector<string>& args,
|
||||||
Ccharp *envv;
|
Ccharp *envv;
|
||||||
int envsize;
|
int envsize;
|
||||||
for (envsize = 0; ; envsize++)
|
for (envsize = 0; ; envsize++)
|
||||||
if (environ[envsize] == 0)
|
if (environ[envsize] == 0) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
envv = (Ccharp *)malloc((envsize + m->m_env.size() + 2) * sizeof(char *));
|
envv = (Ccharp *)malloc((envsize + m->m_env.size() + 2) * sizeof(char *));
|
||||||
if (envv == 0) {
|
if (envv == 0) {
|
||||||
LOGERR(("ExecCmd::doexec: malloc() failed. errno %d\n", errno));
|
LOGERR(("ExecCmd::doexec: malloc() failed. errno %d\n", errno));
|
||||||
|
@ -504,8 +519,9 @@ int ExecCmd::startExec(const string &cmd, const vector<string>& args,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
int eidx;
|
int eidx;
|
||||||
for (eidx = 0; eidx < envsize; eidx++)
|
for (eidx = 0; eidx < envsize; eidx++) {
|
||||||
envv[eidx] = environ[eidx];
|
envv[eidx] = environ[eidx];
|
||||||
|
}
|
||||||
for (vector<string>::const_iterator it = m->m_env.begin();
|
for (vector<string>::const_iterator it = m->m_env.begin();
|
||||||
it != m->m_env.end(); it++) {
|
it != m->m_env.end(); it++) {
|
||||||
envv[eidx++] = it->c_str();
|
envv[eidx++] = it->c_str();
|
||||||
|
@ -526,7 +542,7 @@ int ExecCmd::startExec(const string &cmd, const vector<string>& args,
|
||||||
// Note that posix_spawn provides no way to setrlimit() the child.
|
// Note that posix_spawn provides no way to setrlimit() the child.
|
||||||
{
|
{
|
||||||
posix_spawnattr_t attrs;
|
posix_spawnattr_t attrs;
|
||||||
posix_spawnattr_init (&attrs);
|
posix_spawnattr_init(&attrs);
|
||||||
short flags;
|
short flags;
|
||||||
posix_spawnattr_getflags(&attrs, &flags);
|
posix_spawnattr_getflags(&attrs, &flags);
|
||||||
|
|
||||||
|
@ -537,7 +553,7 @@ int ExecCmd::startExec(const string &cmd, const vector<string>& args,
|
||||||
|
|
||||||
sigset_t sset;
|
sigset_t sset;
|
||||||
sigemptyset(&sset);
|
sigemptyset(&sset);
|
||||||
posix_spawnattr_setsigmask (&attrs, &sset);
|
posix_spawnattr_setsigmask(&attrs, &sset);
|
||||||
flags |= POSIX_SPAWN_SETSIGMASK;
|
flags |= POSIX_SPAWN_SETSIGMASK;
|
||||||
|
|
||||||
sigemptyset(&sset);
|
sigemptyset(&sset);
|
||||||
|
@ -567,7 +583,7 @@ int ExecCmd::startExec(const string &cmd, const vector<string>& args,
|
||||||
|
|
||||||
// Do we need to redirect stderr ?
|
// Do we need to redirect stderr ?
|
||||||
if (!m->m_stderrFile.empty()) {
|
if (!m->m_stderrFile.empty()) {
|
||||||
int oflags = O_WRONLY|O_CREAT;
|
int oflags = O_WRONLY | O_CREAT;
|
||||||
#ifdef O_APPEND
|
#ifdef O_APPEND
|
||||||
oflags |= O_APPEND;
|
oflags |= O_APPEND;
|
||||||
#endif
|
#endif
|
||||||
|
@ -670,10 +686,10 @@ public:
|
||||||
m_cmd->m_pipein[1] = -1;
|
m_cmd->m_pipein[1] = -1;
|
||||||
m_cmd->m_tocmd.reset();
|
m_cmd->m_tocmd.reset();
|
||||||
}
|
}
|
||||||
virtual int data(NetconData *con, Netcon::Event reason)
|
virtual int data(NetconData *con, Netcon::Event reason) {
|
||||||
{
|
if (!m_input) {
|
||||||
if (!m_input)
|
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
LOGDEB1(("ExecWriter: input m_cnt %d input length %d\n", m_cnt,
|
LOGDEB1(("ExecWriter: input m_cnt %d input length %d\n", m_cnt,
|
||||||
m_input->length()));
|
m_input->length()));
|
||||||
if (m_cnt >= m_input->length()) {
|
if (m_cnt >= m_input->length()) {
|
||||||
|
@ -715,10 +731,9 @@ private:
|
||||||
class ExecReader : public NetconWorker {
|
class ExecReader : public NetconWorker {
|
||||||
public:
|
public:
|
||||||
ExecReader(string *output, ExecCmdAdvise *advise)
|
ExecReader(string *output, ExecCmdAdvise *advise)
|
||||||
: m_output(output), m_advise(advise)
|
: m_output(output), m_advise(advise) {
|
||||||
{}
|
}
|
||||||
virtual int data(NetconData *con, Netcon::Event reason)
|
virtual int data(NetconData *con, Netcon::Event reason) {
|
||||||
{
|
|
||||||
char buf[8192];
|
char buf[8192];
|
||||||
int n = con->receive(buf, 8192);
|
int n = con->receive(buf, 8192);
|
||||||
LOGDEB1(("ExecReader: got %d from command\n", n));
|
LOGDEB1(("ExecReader: got %d from command\n", n));
|
||||||
|
@ -726,8 +741,9 @@ public:
|
||||||
LOGERR(("ExecCmd::doexec: receive failed. errno %d\n", errno));
|
LOGERR(("ExecCmd::doexec: receive failed. errno %d\n", errno));
|
||||||
} else if (n > 0) {
|
} else if (n > 0) {
|
||||||
m_output->append(buf, n);
|
m_output->append(buf, n);
|
||||||
if (m_advise)
|
if (m_advise) {
|
||||||
m_advise->newData(n);
|
m_advise->newData(n);
|
||||||
|
}
|
||||||
} // else n == 0, just return
|
} // else n == 0, just return
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
@ -737,7 +753,7 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
int ExecCmd::doexec(const string &cmd, const vector<string>& args,
|
int ExecCmd::doexec(const string& cmd, const vector<string>& args,
|
||||||
const string *input, string *output)
|
const string *input, string *output)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -781,8 +797,9 @@ int ExecCmd::doexec(const string &cmd, const vector<string>& args,
|
||||||
myloop.setperiodichandler(0, 0, m->m_timeoutMs);
|
myloop.setperiodichandler(0, 0, m->m_timeoutMs);
|
||||||
while ((ret = myloop.doLoop()) > 0) {
|
while ((ret = myloop.doLoop()) > 0) {
|
||||||
LOGDEB(("ExecCmd::doexec: selectloop returned %d\n", ret));
|
LOGDEB(("ExecCmd::doexec: selectloop returned %d\n", ret));
|
||||||
if (m->m_advise)
|
if (m->m_advise) {
|
||||||
m->m_advise->newData(0);
|
m->m_advise->newData(0);
|
||||||
|
}
|
||||||
if (m->m_killRequest) {
|
if (m->m_killRequest) {
|
||||||
LOGINFO(("ExecCmd::doexec: cancel request\n"));
|
LOGINFO(("ExecCmd::doexec: cancel request\n"));
|
||||||
break;
|
break;
|
||||||
|
@ -790,8 +807,9 @@ int ExecCmd::doexec(const string &cmd, const vector<string>& args,
|
||||||
}
|
}
|
||||||
LOGDEB0(("ExecCmd::doexec: selectloop returned %d\n", ret));
|
LOGDEB0(("ExecCmd::doexec: selectloop returned %d\n", ret));
|
||||||
// Check for interrupt request: we won't want to waitpid()
|
// Check for interrupt request: we won't want to waitpid()
|
||||||
if (m->m_advise)
|
if (m->m_advise) {
|
||||||
m->m_advise->newData(0);
|
m->m_advise->newData(0);
|
||||||
|
}
|
||||||
|
|
||||||
// The netcons don't take ownership of the fds: we have to close them
|
// The netcons don't take ownership of the fds: we have to close them
|
||||||
// (have to do it before wait, this may be the signal the child is
|
// (have to do it before wait, this may be the signal the child is
|
||||||
|
@ -810,8 +828,9 @@ int ExecCmd::doexec(const string &cmd, const vector<string>& args,
|
||||||
e.inactivate();
|
e.inactivate();
|
||||||
|
|
||||||
int ret1 = ExecCmd::wait();
|
int ret1 = ExecCmd::wait();
|
||||||
if (ret)
|
if (ret) {
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
return ret1;
|
return ret1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -824,8 +843,9 @@ int ExecCmd::send(const string& data)
|
||||||
}
|
}
|
||||||
unsigned int nwritten = 0;
|
unsigned int nwritten = 0;
|
||||||
while (nwritten < data.length()) {
|
while (nwritten < data.length()) {
|
||||||
if (m->m_killRequest)
|
if (m->m_killRequest) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
int n = con->send(data.c_str() + nwritten, data.length() - nwritten);
|
int n = con->send(data.c_str() + nwritten, data.length() - nwritten);
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
LOGERR(("ExecCmd::send: send failed\n"));
|
LOGERR(("ExecCmd::send: send failed\n"));
|
||||||
|
@ -873,8 +893,9 @@ int ExecCmd::getline(string& data)
|
||||||
const int BS = 1024;
|
const int BS = 1024;
|
||||||
char buf[BS];
|
char buf[BS];
|
||||||
int timeosecs = m->m_timeoutMs / 1000;
|
int timeosecs = m->m_timeoutMs / 1000;
|
||||||
if (timeosecs == 0)
|
if (timeosecs == 0) {
|
||||||
timeosecs = 1;
|
timeosecs = 1;
|
||||||
|
}
|
||||||
|
|
||||||
// Note that we only go once through here, except in case of
|
// Note that we only go once through here, except in case of
|
||||||
// timeout, which is why I think that the goto is more expressive
|
// timeout, which is why I think that the goto is more expressive
|
||||||
|
@ -884,8 +905,9 @@ again:
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
if (con->timedout()) {
|
if (con->timedout()) {
|
||||||
LOGDEB(("ExecCmd::getline: timeout\n"));
|
LOGDEB(("ExecCmd::getline: timeout\n"));
|
||||||
if (m->m_advise)
|
if (m->m_advise) {
|
||||||
m->m_advise->newData(0);
|
m->m_advise->newData(0);
|
||||||
|
}
|
||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
LOGERR(("ExecCmd::getline: error\n"));
|
LOGERR(("ExecCmd::getline: error\n"));
|
||||||
|
@ -1006,15 +1028,16 @@ void ReExec::init(int argc, char *args[])
|
||||||
}
|
}
|
||||||
m_cfd = open(".", 0);
|
m_cfd = open(".", 0);
|
||||||
char *cd = getcwd(0, 0);
|
char *cd = getcwd(0, 0);
|
||||||
if (cd)
|
if (cd) {
|
||||||
m_curdir = cd;
|
m_curdir = cd;
|
||||||
|
}
|
||||||
free(cd);
|
free(cd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReExec::insertArgs(const vector<string>& args, int idx)
|
void ReExec::insertArgs(const vector<string>& args, int idx)
|
||||||
{
|
{
|
||||||
vector<string>::iterator it, cit;
|
vector<string>::iterator it, cit;
|
||||||
unsigned int cmpoffset = (unsigned int)-1;
|
unsigned int cmpoffset = (unsigned int) - 1;
|
||||||
|
|
||||||
if (idx == -1 || string::size_type(idx) >= m_argv.size()) {
|
if (idx == -1 || string::size_type(idx) >= m_argv.size()) {
|
||||||
it = m_argv.end();
|
it = m_argv.end();
|
||||||
|
@ -1029,7 +1052,7 @@ void ReExec::insertArgs(const vector<string>& args, int idx)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that the option is not already there
|
// Check that the option is not already there
|
||||||
if (cmpoffset != (unsigned int)-1) {
|
if (cmpoffset != (unsigned int) - 1) {
|
||||||
bool allsame = true;
|
bool allsame = true;
|
||||||
for (unsigned int i = 0; i < args.size(); i++) {
|
for (unsigned int i = 0; i < args.size(); i++) {
|
||||||
if (m_argv[cmpoffset + i] != args[i]) {
|
if (m_argv[cmpoffset + i] != args[i]) {
|
||||||
|
@ -1037,9 +1060,10 @@ void ReExec::insertArgs(const vector<string>& args, int idx)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (allsame)
|
if (allsame) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
m_argv.insert(it, args.begin(), args.end());
|
m_argv.insert(it, args.begin(), args.end());
|
||||||
}
|
}
|
||||||
|
@ -1048,9 +1072,10 @@ void ReExec::removeArg(const string& arg)
|
||||||
{
|
{
|
||||||
for (vector<string>::iterator it = m_argv.begin();
|
for (vector<string>::iterator it = m_argv.begin();
|
||||||
it != m_argv.end(); it++) {
|
it != m_argv.end(); it++) {
|
||||||
if (*it == arg)
|
if (*it == arg) {
|
||||||
it = m_argv.erase(it);
|
it = m_argv.erase(it);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reexecute myself, as close as possible to the initial exec
|
// Reexecute myself, as close as possible to the initial exec
|
||||||
|
@ -1059,10 +1084,10 @@ void ReExec::reexec()
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
char *cwd;
|
char *cwd;
|
||||||
cwd = getcwd(0,0);
|
cwd = getcwd(0, 0);
|
||||||
FILE *fp = stdout; //fopen("/tmp/exectrace", "w");
|
FILE *fp = stdout; //fopen("/tmp/exectrace", "w");
|
||||||
if (fp) {
|
if (fp) {
|
||||||
fprintf(fp, "reexec: pwd: [%s] args: ", cwd?cwd:"getcwd failed");
|
fprintf(fp, "reexec: pwd: [%s] args: ", cwd ? cwd : "getcwd failed");
|
||||||
for (vector<string>::const_iterator it = m_argv.begin();
|
for (vector<string>::const_iterator it = m_argv.begin();
|
||||||
it != m_argv.end(); it++) {
|
it != m_argv.end(); it++) {
|
||||||
fprintf(fp, "[%s] ", it->c_str());
|
fprintf(fp, "[%s] ", it->c_str());
|
||||||
|
@ -1091,7 +1116,7 @@ void ReExec::reexec()
|
||||||
// Allocate arg vector (1 more for final 0)
|
// Allocate arg vector (1 more for final 0)
|
||||||
typedef const char *Ccharp;
|
typedef const char *Ccharp;
|
||||||
Ccharp *argv;
|
Ccharp *argv;
|
||||||
argv = (Ccharp *)malloc((m_argv.size()+1) * sizeof(char *));
|
argv = (Ccharp *)malloc((m_argv.size() + 1) * sizeof(char *));
|
||||||
if (argv == 0) {
|
if (argv == 0) {
|
||||||
LOGERR(("ExecCmd::doexec: malloc() failed. errno %d\n", errno));
|
LOGERR(("ExecCmd::doexec: malloc() failed. errno %d\n", errno));
|
||||||
return;
|
return;
|
||||||
|
@ -1167,7 +1192,7 @@ bool exercise_mhexecm(const string& cmdstr, const string& mimetype,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read answer
|
// Read answer
|
||||||
for (int loop=0;;loop++) {
|
for (int loop = 0;; loop++) {
|
||||||
string name, data;
|
string name, data;
|
||||||
|
|
||||||
// Code from mh_execm.cpp: readDataElement
|
// Code from mh_execm.cpp: readDataElement
|
||||||
|
@ -1217,8 +1242,9 @@ bool exercise_mhexecm(const string& cmdstr, const string& mimetype,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Empty element: end of message
|
// Empty element: end of message
|
||||||
if (name.empty())
|
if (name.empty()) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
cerr << "Got name: [" << name << "] data [" << data << "]\n";
|
cerr << "Got name: [" << name << "] data [" << data << "]\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1228,19 +1254,19 @@ bool exercise_mhexecm(const string& cmdstr, const string& mimetype,
|
||||||
|
|
||||||
static char *thisprog;
|
static char *thisprog;
|
||||||
static char usage [] =
|
static char usage [] =
|
||||||
"trexecmd [-c -r -i -o] cmd [arg1 arg2 ...]\n"
|
"trexecmd [-c -r -i -o] cmd [arg1 arg2 ...]\n"
|
||||||
" -c : test cancellation (ie: trexecmd -c sleep 1000)\n"
|
" -c : test cancellation (ie: trexecmd -c sleep 1000)\n"
|
||||||
" -r : run reexec. Must be separate option.\n"
|
" -r : run reexec. Must be separate option.\n"
|
||||||
" -i : command takes input\n"
|
" -i : command takes input\n"
|
||||||
" -o : command produces output\n"
|
" -o : command produces output\n"
|
||||||
" If -i is set, we send /etc/group contents to whatever command is run\n"
|
" If -i is set, we send /etc/group contents to whatever command is run\n"
|
||||||
" If -o is set, we print whatever comes out\n"
|
" If -o is set, we print whatever comes out\n"
|
||||||
"trexecmd -m <filter> <mimetype> <file> [file ...]: test execm:\n"
|
"trexecmd -m <filter> <mimetype> <file> [file ...]: test execm:\n"
|
||||||
" <filter> should be the path to an execm filter\n"
|
" <filter> should be the path to an execm filter\n"
|
||||||
" <mimetype> the type of the file parameters\n"
|
" <mimetype> the type of the file parameters\n"
|
||||||
"trexecmd -w cmd : do the 'which' thing\n"
|
"trexecmd -w cmd : do the 'which' thing\n"
|
||||||
"trexecmd -l cmd test getline\n"
|
"trexecmd -l cmd test getline\n"
|
||||||
;
|
;
|
||||||
|
|
||||||
static void Usage(void)
|
static void Usage(void)
|
||||||
{
|
{
|
||||||
|
@ -1285,14 +1311,14 @@ public:
|
||||||
FILE *m_fp;
|
FILE *m_fp;
|
||||||
string *m_input;
|
string *m_input;
|
||||||
MEPv(string *i)
|
MEPv(string *i)
|
||||||
: m_input(i)
|
: m_input(i) {
|
||||||
{
|
|
||||||
m_fp = fopen("/etc/group", "r");
|
m_fp = fopen("/etc/group", "r");
|
||||||
}
|
}
|
||||||
~MEPv() {
|
~MEPv() {
|
||||||
if (m_fp)
|
if (m_fp) {
|
||||||
fclose(m_fp);
|
fclose(m_fp);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
void newData() {
|
void newData() {
|
||||||
char line[1024];
|
char line[1024];
|
||||||
if (m_fp && fgets(line, 1024, m_fp)) {
|
if (m_fp && fgets(line, 1024, m_fp)) {
|
||||||
|
@ -1322,36 +1348,59 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
thisprog = argv[0];
|
thisprog = argv[0];
|
||||||
argc--; argv++;
|
argc--;
|
||||||
|
argv++;
|
||||||
|
|
||||||
while (argc > 0 && **argv == '-') {
|
while (argc > 0 && **argv == '-') {
|
||||||
(*argv)++;
|
(*argv)++;
|
||||||
if (!(**argv))
|
if (!(**argv))
|
||||||
/* Cas du "adb - core" */
|
/* Cas du "adb - core" */
|
||||||
|
{
|
||||||
Usage();
|
Usage();
|
||||||
|
}
|
||||||
while (**argv)
|
while (**argv)
|
||||||
switch (*(*argv)++) {
|
switch (*(*argv)++) {
|
||||||
case 'c': op_flags |= OPT_c; break;
|
case 'c':
|
||||||
case 'r': op_flags |= OPT_r; break;
|
op_flags |= OPT_c;
|
||||||
case 'w': op_flags |= OPT_w; break;
|
break;
|
||||||
|
case 'r':
|
||||||
|
op_flags |= OPT_r;
|
||||||
|
break;
|
||||||
|
case 'w':
|
||||||
|
op_flags |= OPT_w;
|
||||||
|
break;
|
||||||
#ifdef BUILDING_RECOLL
|
#ifdef BUILDING_RECOLL
|
||||||
case 'm': op_flags |= OPT_m; break;
|
case 'm':
|
||||||
|
op_flags |= OPT_m;
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
case 'i': op_flags |= OPT_i; break;
|
case 'i':
|
||||||
case 'l': op_flags |= OPT_l; break;
|
op_flags |= OPT_i;
|
||||||
case 'o': op_flags |= OPT_o; break;
|
break;
|
||||||
default: Usage(); break;
|
case 'l':
|
||||||
}
|
op_flags |= OPT_l;
|
||||||
argc--; argv++;
|
break;
|
||||||
}
|
case 'o':
|
||||||
|
op_flags |= OPT_o;
|
||||||
if (argc < 1)
|
break;
|
||||||
|
default:
|
||||||
Usage();
|
Usage();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
argc--;
|
||||||
|
argv++;
|
||||||
|
}
|
||||||
|
|
||||||
string arg1 = *argv++; argc--;
|
if (argc < 1) {
|
||||||
|
Usage();
|
||||||
|
}
|
||||||
|
|
||||||
|
string arg1 = *argv++;
|
||||||
|
argc--;
|
||||||
vector<string> l;
|
vector<string> l;
|
||||||
while (argc > 0) {
|
while (argc > 0) {
|
||||||
l.push_back(*argv++); argc--;
|
l.push_back(*argv++);
|
||||||
|
argc--;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef BUILDING_RECOLL
|
#ifdef BUILDING_RECOLL
|
||||||
|
@ -1384,8 +1433,9 @@ int main(int argc, char *argv[])
|
||||||
return 1;
|
return 1;
|
||||||
#ifdef BUILDING_RECOLL
|
#ifdef BUILDING_RECOLL
|
||||||
} else if (op_flags & OPT_m) {
|
} else if (op_flags & OPT_m) {
|
||||||
if (l.size() < 2)
|
if (l.size() < 2) {
|
||||||
Usage();
|
Usage();
|
||||||
|
}
|
||||||
string mimetype = l[0];
|
string mimetype = l[0];
|
||||||
l.erase(l.begin());
|
l.erase(l.begin());
|
||||||
return exercise_mhexecm(arg1, mimetype, l) ? 0 : 1;
|
return exercise_mhexecm(arg1, mimetype, l) ? 0 : 1;
|
||||||
|
@ -1403,7 +1453,7 @@ int main(int argc, char *argv[])
|
||||||
cerr << "Waiting\n";
|
cerr << "Waiting\n";
|
||||||
int status = mexec.wait();
|
int status = mexec.wait();
|
||||||
cerr << "Got status " << status << endl;
|
cerr << "Got status " << status << endl;
|
||||||
exit (status);
|
exit(status);
|
||||||
} else {
|
} else {
|
||||||
// Default: execute command line arguments
|
// Default: execute command line arguments
|
||||||
ExecCmd mexec;
|
ExecCmd mexec;
|
||||||
|
@ -1447,7 +1497,7 @@ int main(int argc, char *argv[])
|
||||||
if (op_flags & OPT_o) {
|
if (op_flags & OPT_o) {
|
||||||
cout << output;
|
cout << output;
|
||||||
}
|
}
|
||||||
exit (status >> 8);
|
exit(status >> 8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // TEST
|
#endif // TEST
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class ExecCmdAdvise {
|
class ExecCmdAdvise {
|
||||||
public:
|
public:
|
||||||
virtual ~ExecCmdAdvise() {}
|
virtual ~ExecCmdAdvise() {}
|
||||||
virtual void newData(int cnt) = 0;
|
virtual void newData(int cnt) = 0;
|
||||||
};
|
};
|
||||||
|
@ -41,7 +41,7 @@ class ExecCmdAdvise {
|
||||||
* into the initial input string, set it to empty to signify eof.
|
* into the initial input string, set it to empty to signify eof.
|
||||||
*/
|
*/
|
||||||
class ExecCmdProvide {
|
class ExecCmdProvide {
|
||||||
public:
|
public:
|
||||||
virtual ~ExecCmdProvide() {}
|
virtual ~ExecCmdProvide() {}
|
||||||
virtual void newData() = 0;
|
virtual void newData() = 0;
|
||||||
};
|
};
|
||||||
|
@ -65,7 +65,7 @@ class ExecCmdProvide {
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class ExecCmd {
|
class ExecCmd {
|
||||||
public:
|
public:
|
||||||
// Use vfork instead of fork. Our vfork usage is multithread-compatible as
|
// Use vfork instead of fork. Our vfork usage is multithread-compatible as
|
||||||
// far as I can see, but just in case...
|
// far as I can see, but just in case...
|
||||||
static void useVfork(bool on);
|
static void useVfork(bool on);
|
||||||
|
@ -76,8 +76,8 @@ class ExecCmd {
|
||||||
* times for several variables).
|
* times for several variables).
|
||||||
* @param envassign an environment assignment string ("name=value")
|
* @param envassign an environment assignment string ("name=value")
|
||||||
*/
|
*/
|
||||||
void putenv(const std::string &envassign);
|
void putenv(const std::string& envassign);
|
||||||
void putenv(const std::string &name, const std::string& value);
|
void putenv(const std::string& name, const std::string& value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Try to set a limit on child process vm size. This will use
|
* Try to set a limit on child process vm size. This will use
|
||||||
|
@ -114,7 +114,7 @@ class ExecCmd {
|
||||||
* If the parameter can't be opened for writing, the command's
|
* If the parameter can't be opened for writing, the command's
|
||||||
* stderr will be closed.
|
* stderr will be closed.
|
||||||
*/
|
*/
|
||||||
void setStderr(const std::string &stderrFile);
|
void setStderr(const std::string& stderrFile);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute command.
|
* Execute command.
|
||||||
|
@ -133,7 +133,7 @@ class ExecCmd {
|
||||||
* @param output Output FROM the command.
|
* @param output Output FROM the command.
|
||||||
* @return the exec output status (0 if ok), or -1
|
* @return the exec output status (0 if ok), or -1
|
||||||
*/
|
*/
|
||||||
int doexec(const std::string &cmd, const std::vector<std::string>& args,
|
int doexec(const std::string& cmd, const std::vector<std::string>& args,
|
||||||
const std::string *input = 0,
|
const std::string *input = 0,
|
||||||
std::string *output = 0);
|
std::string *output = 0);
|
||||||
|
|
||||||
|
@ -141,8 +141,9 @@ class ExecCmd {
|
||||||
int doexec1(const std::vector<std::string>& args,
|
int doexec1(const std::vector<std::string>& args,
|
||||||
const std::string *input = 0,
|
const std::string *input = 0,
|
||||||
std::string *output = 0) {
|
std::string *output = 0) {
|
||||||
if (args.empty())
|
if (args.empty()) {
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
return doexec(args[0],
|
return doexec(args[0],
|
||||||
std::vector<std::string>(args.begin() + 1, args.end()),
|
std::vector<std::string>(args.begin() + 1, args.end()),
|
||||||
input, output);
|
input, output);
|
||||||
|
@ -152,7 +153,7 @@ class ExecCmd {
|
||||||
* The next four methods can be used when a Q/A dialog needs to be
|
* The next four methods can be used when a Q/A dialog needs to be
|
||||||
* performed with the command
|
* performed with the command
|
||||||
*/
|
*/
|
||||||
int startExec(const std::string &cmd, const std::vector<std::string>& args,
|
int startExec(const std::string& cmd, const std::vector<std::string>& args,
|
||||||
bool has_input, bool has_output);
|
bool has_input, bool has_output);
|
||||||
int send(const std::string& data);
|
int send(const std::string& data);
|
||||||
int receive(std::string& data, int cnt = -1);
|
int receive(std::string& data, int cnt = -1);
|
||||||
|
@ -221,11 +222,13 @@ class ExecCmd {
|
||||||
static bool backtick(const std::vector<std::string> cmd, std::string& out);
|
static bool backtick(const std::vector<std::string> cmd, std::string& out);
|
||||||
|
|
||||||
class Internal;
|
class Internal;
|
||||||
private:
|
private:
|
||||||
Internal *m;
|
Internal *m;
|
||||||
/* Copyconst and assignment are private and forbidden */
|
/* Copyconst and assignment are private and forbidden */
|
||||||
ExecCmd(const ExecCmd &) {}
|
ExecCmd(const ExecCmd&) {}
|
||||||
ExecCmd& operator=(const ExecCmd &) {return *this;};
|
ExecCmd& operator=(const ExecCmd&) {
|
||||||
|
return *this;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -259,13 +262,14 @@ public:
|
||||||
ReExec() {}
|
ReExec() {}
|
||||||
ReExec(int argc, char *argv[]);
|
ReExec(int argc, char *argv[]);
|
||||||
void init(int argc, char *argv[]);
|
void init(int argc, char *argv[]);
|
||||||
int atexit(void (*function)(void))
|
int atexit(void (*function)(void)) {
|
||||||
{
|
|
||||||
m_atexitfuncs.push(function);
|
m_atexitfuncs.push(function);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
void reexec();
|
void reexec();
|
||||||
const std::string& getreason() {return m_reason;}
|
const std::string& getreason() {
|
||||||
|
return m_reason;
|
||||||
|
}
|
||||||
// Insert new args into the initial argv. idx designates the place
|
// Insert new args into the initial argv. idx designates the place
|
||||||
// before which the new args are inserted (the default of 1
|
// before which the new args are inserted (the default of 1
|
||||||
// inserts after argv[0] which would probably be an appropriate
|
// inserts after argv[0] which would probably be an appropriate
|
||||||
|
|
|
@ -116,12 +116,12 @@ int Netcon::select1(int fd, int timeo, int write)
|
||||||
FD_ZERO(&rd);
|
FD_ZERO(&rd);
|
||||||
FD_SET(fd, &rd);
|
FD_SET(fd, &rd);
|
||||||
if (write) {
|
if (write) {
|
||||||
ret = select(fd+1, 0, &rd, 0, &tv);
|
ret = select(fd + 1, 0, &rd, 0, &tv);
|
||||||
} else {
|
} else {
|
||||||
ret = select(fd+1, &rd, 0, 0, &tv);
|
ret = select(fd + 1, &rd, 0, 0, &tv);
|
||||||
}
|
}
|
||||||
if (!FD_ISSET(fd, &rd)) {
|
if (!FD_ISSET(fd, &rd)) {
|
||||||
LOGDEB2(("Netcon::select1: fd %d timeout\n",fd));
|
LOGDEB2(("Netcon::select1: fd %d timeout\n", fd));
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -199,11 +199,11 @@ int SelectLoop::doLoop()
|
||||||
// Walk the netcon map and set up the read and write fd_sets
|
// Walk the netcon map and set up the read and write fd_sets
|
||||||
// for select()
|
// for select()
|
||||||
nfds = 0;
|
nfds = 0;
|
||||||
for (map<int,NetconP>::iterator it = m_polldata.begin();
|
for (map<int, NetconP>::iterator it = m_polldata.begin();
|
||||||
it != m_polldata.end(); it++) {
|
it != m_polldata.end(); it++) {
|
||||||
NetconP &pll = it->second;
|
NetconP& pll = it->second;
|
||||||
int fd = it->first;
|
int fd = it->first;
|
||||||
LOGDEB2(("Selectloop: fd %d flags 0x%x\n",fd, pll->m_wantedEvents));
|
LOGDEB2(("Selectloop: fd %d flags 0x%x\n", fd, pll->m_wantedEvents));
|
||||||
if (pll->m_wantedEvents & Netcon::NETCONPOLL_READ) {
|
if (pll->m_wantedEvents & Netcon::NETCONPOLL_READ) {
|
||||||
FD_SET(fd, &rd);
|
FD_SET(fd, &rd);
|
||||||
nfds = MAX(nfds, fd + 1);
|
nfds = MAX(nfds, fd + 1);
|
||||||
|
@ -275,7 +275,7 @@ int SelectLoop::doLoop()
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
map<int,NetconP>::iterator it = m_polldata.find(fd);
|
map<int, NetconP>::iterator it = m_polldata.find(fd);
|
||||||
if (it == m_polldata.end()) {
|
if (it == m_polldata.end()) {
|
||||||
/// This should not happen actually
|
/// This should not happen actually
|
||||||
LOGDEB2(("Netcon::selectloop: fd %d not found\n", fd));
|
LOGDEB2(("Netcon::selectloop: fd %d not found\n", fd));
|
||||||
|
@ -284,14 +284,14 @@ int SelectLoop::doLoop()
|
||||||
|
|
||||||
// Next start will be one beyond last serviced (modulo nfds)
|
// Next start will be one beyond last serviced (modulo nfds)
|
||||||
m_placetostart = fd + 1;
|
m_placetostart = fd + 1;
|
||||||
NetconP &pll = it->second;
|
NetconP& pll = it->second;
|
||||||
if (canread && pll->cando(Netcon::NETCONPOLL_READ) <= 0) {
|
if (canread && pll->cando(Netcon::NETCONPOLL_READ) <= 0) {
|
||||||
pll->m_wantedEvents &= ~Netcon::NETCONPOLL_READ;
|
pll->m_wantedEvents &= ~Netcon::NETCONPOLL_READ;
|
||||||
}
|
}
|
||||||
if (canwrite && pll->cando(Netcon::NETCONPOLL_WRITE) <= 0) {
|
if (canwrite && pll->cando(Netcon::NETCONPOLL_WRITE) <= 0) {
|
||||||
pll->m_wantedEvents &= ~Netcon::NETCONPOLL_WRITE;
|
pll->m_wantedEvents &= ~Netcon::NETCONPOLL_WRITE;
|
||||||
}
|
}
|
||||||
if (!(pll->m_wantedEvents & (Netcon::NETCONPOLL_WRITE|Netcon::NETCONPOLL_READ))) {
|
if (!(pll->m_wantedEvents & (Netcon::NETCONPOLL_WRITE | Netcon::NETCONPOLL_READ))) {
|
||||||
LOGDEB0(("Netcon::selectloop: fd %d has 0x%x mask, erasing\n",
|
LOGDEB0(("Netcon::selectloop: fd %d has 0x%x mask, erasing\n",
|
||||||
it->first, it->second->m_wantedEvents));
|
it->first, it->second->m_wantedEvents));
|
||||||
m_polldata.erase(it);
|
m_polldata.erase(it);
|
||||||
|
@ -324,7 +324,7 @@ int SelectLoop::remselcon(NetconP con)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
LOGDEB1(("Netcon::remselcon: fd %d\n", con->m_fd));
|
LOGDEB1(("Netcon::remselcon: fd %d\n", con->m_fd));
|
||||||
map<int,NetconP>::iterator it = m_polldata.find(con->m_fd);
|
map<int, NetconP>::iterator it = m_polldata.find(con->m_fd);
|
||||||
if (it == m_polldata.end()) {
|
if (it == m_polldata.end()) {
|
||||||
LOGDEB1(("Netcon::remselcon: con not found for fd %d\n", con->m_fd));
|
LOGDEB1(("Netcon::remselcon: con not found for fd %d\n", con->m_fd));
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -369,7 +369,7 @@ void Netcon::setpeer(const char *hostname)
|
||||||
|
|
||||||
int Netcon::settcpnodelay(int on)
|
int Netcon::settcpnodelay(int on)
|
||||||
{
|
{
|
||||||
LOGDEB2(( "Netcon::settcpnodelay\n" ));
|
LOGDEB2(("Netcon::settcpnodelay\n"));
|
||||||
if (m_fd < 0) {
|
if (m_fd < 0) {
|
||||||
LOGERR(("Netcon::settcpnodelay: connection not opened\n"));
|
LOGERR(("Netcon::settcpnodelay: connection not opened\n"));
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -386,7 +386,7 @@ int Netcon::settcpnodelay(int on)
|
||||||
int Netcon::set_nonblock(int onoff)
|
int Netcon::set_nonblock(int onoff)
|
||||||
{
|
{
|
||||||
int flags = fcntl(m_fd, F_GETFL, 0);
|
int flags = fcntl(m_fd, F_GETFL, 0);
|
||||||
if (flags != -1 ) {
|
if (flags != -1) {
|
||||||
int newflags = onoff ? flags | O_NONBLOCK : flags & ~O_NONBLOCK;
|
int newflags = onoff ? flags | O_NONBLOCK : flags & ~O_NONBLOCK;
|
||||||
if (newflags != flags)
|
if (newflags != flags)
|
||||||
if (fcntl(m_fd, F_SETFL, newflags) < 0) {
|
if (fcntl(m_fd, F_SETFL, newflags) < 0) {
|
||||||
|
@ -511,7 +511,7 @@ int NetconData::doreceive(char *buf, int cnt, int timeo)
|
||||||
LOGDEB2(("Netcon::doreceive: cnt %d, timeo %d\n", cnt, timeo));
|
LOGDEB2(("Netcon::doreceive: cnt %d, timeo %d\n", cnt, timeo));
|
||||||
cur = 0;
|
cur = 0;
|
||||||
while (cnt > cur) {
|
while (cnt > cur) {
|
||||||
got = receive(buf, cnt-cur, timeo);
|
got = receive(buf, cnt - cur, timeo);
|
||||||
LOGDEB2(("Netcon::doreceive: got %d\n", got));
|
LOGDEB2(("Netcon::doreceive: got %d\n", got));
|
||||||
if (got < 0) {
|
if (got < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -551,7 +551,7 @@ int NetconData::getline(char *buf, int cnt, int timeo)
|
||||||
for (;;) {
|
for (;;) {
|
||||||
// Transfer from buffer. Have to take a lot of care to keep counts and
|
// Transfer from buffer. Have to take a lot of care to keep counts and
|
||||||
// pointers consistant in all end cases
|
// pointers consistant in all end cases
|
||||||
int maxtransf = MIN(m_bufbytes, cnt-1);
|
int maxtransf = MIN(m_bufbytes, cnt - 1);
|
||||||
int nn = maxtransf;
|
int nn = maxtransf;
|
||||||
LOGDEB2(("Before loop, bufbytes %d, maxtransf %d, nn: %d\n",
|
LOGDEB2(("Before loop, bufbytes %d, maxtransf %d, nn: %d\n",
|
||||||
m_bufbytes, maxtransf, nn));
|
m_bufbytes, maxtransf, nn));
|
||||||
|
@ -723,7 +723,7 @@ int NetconCli::openconn(const char *host, const char *serv, int timeo)
|
||||||
if (host[0] != '/') {
|
if (host[0] != '/') {
|
||||||
struct servent *sp;
|
struct servent *sp;
|
||||||
if ((sp = getservbyname(serv, "tcp")) == 0) {
|
if ((sp = getservbyname(serv, "tcp")) == 0) {
|
||||||
LOGERR(("NetconCli::openconn: getservbyname failed for %s\n",serv));
|
LOGERR(("NetconCli::openconn: getservbyname failed for %s\n", serv));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
// Callee expects the port number in host byte order
|
// Callee expects the port number in host byte order
|
||||||
|
@ -822,7 +822,7 @@ int NetconServLis::openservice(const char *serv, int backlog)
|
||||||
|
|
||||||
LOGDEB1(("NetconServLis::openservice: service opened ok\n"));
|
LOGDEB1(("NetconServLis::openservice: service opened ok\n"));
|
||||||
ret = 0;
|
ret = 0;
|
||||||
out:
|
out:
|
||||||
if (ret < 0 && m_fd >= 0) {
|
if (ret < 0 && m_fd >= 0) {
|
||||||
close(m_fd);
|
close(m_fd);
|
||||||
m_fd = -1;
|
m_fd = -1;
|
||||||
|
@ -846,9 +846,9 @@ int NetconServLis::openservice(int port, int backlog)
|
||||||
LOGSYSERR("NetconServLis", "socket", "");
|
LOGSYSERR("NetconServLis", "socket", "");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
(void) setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR,(char *)&one, sizeof(one));
|
(void) setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one));
|
||||||
#ifdef SO_REUSEPORT
|
#ifdef SO_REUSEPORT
|
||||||
(void) setsockopt(m_fd, SOL_SOCKET, SO_REUSEPORT,(char *)&one, sizeof(one));
|
(void) setsockopt(m_fd, SOL_SOCKET, SO_REUSEPORT, (char *)&one, sizeof(one));
|
||||||
#endif /*SO_REUSEPORT*/
|
#endif /*SO_REUSEPORT*/
|
||||||
memset(&ipaddr, 0, sizeof(ipaddr));
|
memset(&ipaddr, 0, sizeof(ipaddr));
|
||||||
ipaddr.sin_family = AF_INET;
|
ipaddr.sin_family = AF_INET;
|
||||||
|
@ -1033,7 +1033,7 @@ NetconServLis::checkperms(void *cl, int)
|
||||||
if (i < okmasks.len) {
|
if (i < okmasks.len) {
|
||||||
mask = okmasks.intarray[i];
|
mask = okmasks.intarray[i];
|
||||||
} else {
|
} else {
|
||||||
mask = okmasks.intarray[okmasks.len-1];
|
mask = okmasks.intarray[okmasks.len - 1];
|
||||||
}
|
}
|
||||||
LOGDEB2(("checkperms: trying okaddr 0x%x, mask 0x%x\n",
|
LOGDEB2(("checkperms: trying okaddr 0x%x, mask 0x%x\n",
|
||||||
okaddrs.intarray[i], mask));
|
okaddrs.intarray[i], mask));
|
||||||
|
@ -1271,7 +1271,7 @@ public:
|
||||||
}
|
}
|
||||||
if (reason & Netcon::NETCONPOLL_READ) {
|
if (reason & Netcon::NETCONPOLL_READ) {
|
||||||
#define LL 200
|
#define LL 200
|
||||||
char buf[LL+1];
|
char buf[LL + 1];
|
||||||
int n;
|
int n;
|
||||||
if ((n = con->receive(buf, LL)) < 0) {
|
if ((n = con->receive(buf, LL)) < 0) {
|
||||||
fprintf(stderr, "receive failed\n");
|
fprintf(stderr, "receive failed\n");
|
||||||
|
@ -1282,7 +1282,7 @@ public:
|
||||||
}
|
}
|
||||||
buf[n] = 0;
|
buf[n] = 0;
|
||||||
fprintf(stderr, "%d received \"%s\"\n", getpid(), buf);
|
fprintf(stderr, "%d received \"%s\"\n", getpid(), buf);
|
||||||
con->setselevents(Netcon::NETCONPOLL_READ|Netcon::NETCONPOLL_WRITE);
|
con->setselevents(Netcon::NETCONPOLL_READ | Netcon::NETCONPOLL_WRITE);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1292,7 +1292,7 @@ private:
|
||||||
|
|
||||||
class MyNetconServLis : public NetconServLis {
|
class MyNetconServLis : public NetconServLis {
|
||||||
public:
|
public:
|
||||||
MyNetconServLis(SelectLoop &loop)
|
MyNetconServLis(SelectLoop& loop)
|
||||||
: NetconServLis(), m_loop(loop) {
|
: NetconServLis(), m_loop(loop) {
|
||||||
}
|
}
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -48,7 +48,7 @@ class SelectLoop;
|
||||||
|
|
||||||
class Netcon {
|
class Netcon {
|
||||||
public:
|
public:
|
||||||
enum Event {NETCONPOLL_READ = 0x1, NETCONPOLL_WRITE=0x2};
|
enum Event {NETCONPOLL_READ = 0x1, NETCONPOLL_WRITE = 0x2};
|
||||||
Netcon()
|
Netcon()
|
||||||
: m_peer(0), m_fd(-1), m_ownfd(true), m_didtimo(0), m_wantedEvents(0),
|
: m_peer(0), m_fd(-1), m_ownfd(true), m_didtimo(0), m_wantedEvents(0),
|
||||||
m_loop(0) {
|
m_loop(0) {
|
||||||
|
|
|
@ -22,12 +22,16 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "safefcntl.h"
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include "safefcntl.h"
|
||||||
#include "safesysstat.h"
|
#include "safesysstat.h"
|
||||||
#include "safeunistd.h"
|
#include "safeunistd.h"
|
||||||
#ifndef _WIN32
|
#else
|
||||||
#define O_BINARY 0
|
#define O_BINARY 0
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
@ -41,8 +45,9 @@ public:
|
||||||
FileToString(string& data) : m_data(data) {}
|
FileToString(string& data) : m_data(data) {}
|
||||||
string& m_data;
|
string& m_data;
|
||||||
bool init(size_t size, string *reason) {
|
bool init(size_t size, string *reason) {
|
||||||
if (size > 0)
|
if (size > 0) {
|
||||||
m_data.reserve(size);
|
m_data.reserve(size);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool data(const char *buf, int cnt, string *reason) {
|
bool data(const char *buf, int cnt, string *reason) {
|
||||||
|
@ -56,18 +61,18 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
bool file_to_string(const string &fn, string &data, string *reason)
|
bool file_to_string(const string& fn, string& data, string *reason)
|
||||||
{
|
{
|
||||||
return file_to_string(fn, data, 0, size_t(-1), reason);
|
return file_to_string(fn, data, 0, size_t(-1), reason);
|
||||||
}
|
}
|
||||||
bool file_to_string(const string &fn, string &data, off_t offs, size_t cnt,
|
bool file_to_string(const string& fn, string& data, off_t offs, size_t cnt,
|
||||||
string *reason)
|
string *reason)
|
||||||
{
|
{
|
||||||
FileToString accum(data);
|
FileToString accum(data);
|
||||||
return file_scan(fn, &accum, offs, cnt, reason);
|
return file_scan(fn, &accum, offs, cnt, reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool file_scan(const string &fn, FileScanDo* doer, string *reason)
|
bool file_scan(const string& fn, FileScanDo* doer, string *reason)
|
||||||
{
|
{
|
||||||
return file_scan(fn, doer, 0, size_t(-1), reason);
|
return file_scan(fn, doer, 0, size_t(-1), reason);
|
||||||
}
|
}
|
||||||
|
@ -77,7 +82,7 @@ const int RDBUFSZ = 8192;
|
||||||
// on both linux i586 and macosx (compared to just append())
|
// on both linux i586 and macosx (compared to just append())
|
||||||
// Also tried a version with mmap, but it's actually slower on the mac and not
|
// Also tried a version with mmap, but it's actually slower on the mac and not
|
||||||
// faster on linux.
|
// faster on linux.
|
||||||
bool file_scan(const string &fn, FileScanDo* doer, off_t startoffs,
|
bool file_scan(const string& fn, FileScanDo* doer, off_t startoffs,
|
||||||
size_t cnttoread, string *reason)
|
size_t cnttoread, string *reason)
|
||||||
{
|
{
|
||||||
if (startoffs < 0) {
|
if (startoffs < 0) {
|
||||||
|
@ -94,7 +99,7 @@ bool file_scan(const string &fn, FileScanDo* doer, off_t startoffs,
|
||||||
|
|
||||||
// If we have a file name, open it, else use stdin.
|
// If we have a file name, open it, else use stdin.
|
||||||
if (!fn.empty()) {
|
if (!fn.empty()) {
|
||||||
fd = open(fn.c_str(), O_RDONLY|O_BINARY);
|
fd = open(fn.c_str(), O_RDONLY | O_BINARY);
|
||||||
if (fd < 0 || fstat(fd, &st) < 0) {
|
if (fd < 0 || fstat(fd, &st) < 0) {
|
||||||
catstrerror(reason, "open/stat", errno);
|
catstrerror(reason, "open/stat", errno);
|
||||||
return false;
|
return false;
|
||||||
|
@ -108,10 +113,10 @@ bool file_scan(const string &fn, FileScanDo* doer, off_t startoffs,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (cnttoread != (size_t)-1 && cnttoread) {
|
if (cnttoread != (size_t) - 1 && cnttoread) {
|
||||||
doer->init(cnttoread+1, reason);
|
doer->init(cnttoread + 1, reason);
|
||||||
} else if (st.st_size > 0) {
|
} else if (st.st_size > 0) {
|
||||||
doer->init(size_t(st.st_size+1), reason);
|
doer->init(size_t(st.st_size + 1), reason);
|
||||||
} else {
|
} else {
|
||||||
doer->init(0, reason);
|
doer->init(0, reason);
|
||||||
}
|
}
|
||||||
|
@ -141,25 +146,29 @@ bool file_scan(const string &fn, FileScanDo* doer, off_t startoffs,
|
||||||
catstrerror(reason, "read", errno);
|
catstrerror(reason, "read", errno);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (n == 0)
|
if (n == 0) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
curoffs += n;
|
curoffs += n;
|
||||||
if (curoffs - n < startoffs)
|
if (curoffs - n < startoffs) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (!doer->data(buf, n, reason)) {
|
if (!doer->data(buf, n, reason)) {
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
totread += n;
|
totread += n;
|
||||||
if (cnttoread > 0 && totread >= cnttoread)
|
if (cnttoread > 0 && totread >= cnttoread) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ret = true;
|
ret = true;
|
||||||
out:
|
out:
|
||||||
if (fd >= 0 && !noclosing)
|
if (fd >= 0 && !noclosing) {
|
||||||
close(fd);
|
close(fd);
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,11 +190,10 @@ using namespace std;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
class myCB : public FsTreeWalkerCB {
|
class myCB : public FsTreeWalkerCB {
|
||||||
public:
|
public:
|
||||||
FsTreeWalker::Status processone(const string &path,
|
FsTreeWalker::Status processone(const string& path,
|
||||||
const struct stat *st,
|
const struct stat *st,
|
||||||
FsTreeWalker::CbFlag flg)
|
FsTreeWalker::CbFlag flg) {
|
||||||
{
|
|
||||||
if (flg == FsTreeWalker::FtwDirEnter) {
|
if (flg == FsTreeWalker::FtwDirEnter) {
|
||||||
//cout << "[Entering " << path << "]" << endl;
|
//cout << "[Entering " << path << "]" << endl;
|
||||||
} else if (flg == FsTreeWalker::FtwDirReturn) {
|
} else if (flg == FsTreeWalker::FtwDirReturn) {
|
||||||
|
@ -214,8 +222,8 @@ static int op_flags;
|
||||||
|
|
||||||
static const char *thisprog;
|
static const char *thisprog;
|
||||||
static char usage [] =
|
static char usage [] =
|
||||||
"trreadfile [-o offs] [-c cnt] topdirorfile\n\n"
|
"trreadfile [-o offs] [-c cnt] topdirorfile\n\n"
|
||||||
;
|
;
|
||||||
static void
|
static void
|
||||||
Usage(void)
|
Usage(void)
|
||||||
{
|
{
|
||||||
|
@ -228,29 +236,48 @@ int main(int argc, const char **argv)
|
||||||
off_t offs = 0;
|
off_t offs = 0;
|
||||||
size_t cnt = size_t(-1);
|
size_t cnt = size_t(-1);
|
||||||
thisprog = argv[0];
|
thisprog = argv[0];
|
||||||
argc--; argv++;
|
argc--;
|
||||||
|
argv++;
|
||||||
|
|
||||||
while (argc > 0 && **argv == '-') {
|
while (argc > 0 && **argv == '-') {
|
||||||
(*argv)++;
|
(*argv)++;
|
||||||
if (!(**argv))
|
if (!(**argv))
|
||||||
/* Cas du "adb - core" */
|
/* Cas du "adb - core" */
|
||||||
|
{
|
||||||
Usage();
|
Usage();
|
||||||
|
}
|
||||||
while (**argv)
|
while (**argv)
|
||||||
switch (*(*argv)++) {
|
switch (*(*argv)++) {
|
||||||
case 'c': op_flags |= OPT_c; if (argc < 2) Usage();
|
case 'c':
|
||||||
cnt = atoll(*(++argv)); argc--;
|
op_flags |= OPT_c;
|
||||||
goto b1;
|
if (argc < 2) {
|
||||||
case 'o': op_flags |= OPT_o; if (argc < 2) Usage();
|
Usage();
|
||||||
offs = strtoull(*(++argv), 0, 0); argc--;
|
|
||||||
goto b1;
|
|
||||||
default: Usage(); break;
|
|
||||||
}
|
}
|
||||||
b1: argc--; argv++;
|
cnt = atoll(*(++argv));
|
||||||
|
argc--;
|
||||||
|
goto b1;
|
||||||
|
case 'o':
|
||||||
|
op_flags |= OPT_o;
|
||||||
|
if (argc < 2) {
|
||||||
|
Usage();
|
||||||
|
}
|
||||||
|
offs = strtoull(*(++argv), 0, 0);
|
||||||
|
argc--;
|
||||||
|
goto b1;
|
||||||
|
default:
|
||||||
|
Usage();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
b1:
|
||||||
|
argc--;
|
||||||
|
argv++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argc != 1)
|
if (argc != 1) {
|
||||||
Usage();
|
Usage();
|
||||||
string top = *argv++;argc--;
|
}
|
||||||
|
string top = *argv++;
|
||||||
|
argc--;
|
||||||
cerr << "filename " << top << " offs " << offs << " cnt " << cnt << endl;
|
cerr << "filename " << top << " offs " << offs << " cnt " << cnt << endl;
|
||||||
|
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
@ -262,8 +289,9 @@ int main(int argc, const char **argv)
|
||||||
FsTreeWalker walker;
|
FsTreeWalker walker;
|
||||||
myCB cb;
|
myCB cb;
|
||||||
walker.walk(top, cb);
|
walker.walk(top, cb);
|
||||||
if (walker.getErrCnt() > 0)
|
if (walker.getErrCnt() > 0) {
|
||||||
cout << walker.getReason();
|
cout << walker.getReason();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
string s, reason;
|
string s, reason;
|
||||||
if (!file_to_string(top, s, offs, cnt, &reason)) {
|
if (!file_to_string(top, s, offs, cnt, &reason)) {
|
||||||
|
|
|
@ -31,20 +31,20 @@ public:
|
||||||
virtual bool init(size_t size, std::string *reason) = 0;
|
virtual bool init(size_t size, std::string *reason) = 0;
|
||||||
virtual bool data(const char *buf, int cnt, std::string* reason) = 0;
|
virtual bool data(const char *buf, int cnt, std::string* reason) = 0;
|
||||||
};
|
};
|
||||||
bool file_scan(const std::string &filename, FileScanDo* doer, std::string *reason = 0);
|
bool file_scan(const std::string& filename, FileScanDo* doer, std::string *reason = 0);
|
||||||
/* Same but only process count cnt from offset offs. Set cnt to size_t(-1)
|
/* Same but only process count cnt from offset offs. Set cnt to size_t(-1)
|
||||||
* for no limit */
|
* for no limit */
|
||||||
bool file_scan(const std::string &fn, FileScanDo* doer, off_t offs, size_t cnt,
|
bool file_scan(const std::string& fn, FileScanDo* doer, off_t offs, size_t cnt,
|
||||||
std::string *reason = 0);
|
std::string *reason = 0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read file into string.
|
* Read file into string.
|
||||||
* @return true for ok, false else
|
* @return true for ok, false else
|
||||||
*/
|
*/
|
||||||
bool file_to_string(const std::string &filename, std::string &data, std::string *reason = 0);
|
bool file_to_string(const std::string& filename, std::string& data, std::string *reason = 0);
|
||||||
|
|
||||||
/** Read file chunk into string. Set cnt to size_t(-1) for whole file */
|
/** Read file chunk into string. Set cnt to size_t(-1) for whole file */
|
||||||
bool file_to_string(const std::string &filename, std::string &data,
|
bool file_to_string(const std::string& filename, std::string& data,
|
||||||
off_t offs, size_t cnt, std::string *reason = 0);
|
off_t offs, size_t cnt, std::string *reason = 0);
|
||||||
|
|
||||||
#endif /* _READFILE_H_INCLUDED_ */
|
#endif /* _READFILE_H_INCLUDED_ */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue