Fixes and new functionality by Wouter Spruit, mostly for the HTTP proxy rewrite.
This commit is contained in:
parent
d3bb5b13e4
commit
57bcd8f25c
5 changed files with 72 additions and 26 deletions
|
@ -428,6 +428,7 @@ void Util::Config::activate(){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
struct sigaction new_action;
|
struct sigaction new_action;
|
||||||
|
struct sigaction cur_action;
|
||||||
new_action.sa_handler = signal_handler;
|
new_action.sa_handler = signal_handler;
|
||||||
sigemptyset( &new_action.sa_mask);
|
sigemptyset( &new_action.sa_mask);
|
||||||
new_action.sa_flags = 0;
|
new_action.sa_flags = 0;
|
||||||
|
@ -435,7 +436,11 @@ void Util::Config::activate(){
|
||||||
sigaction(SIGHUP, &new_action, NULL);
|
sigaction(SIGHUP, &new_action, NULL);
|
||||||
sigaction(SIGTERM, &new_action, NULL);
|
sigaction(SIGTERM, &new_action, NULL);
|
||||||
sigaction(SIGPIPE, &new_action, NULL);
|
sigaction(SIGPIPE, &new_action, NULL);
|
||||||
|
//check if a child signal handler isn't set already, if so, set it.
|
||||||
|
sigaction(SIGCHLD, 0, &cur_action);
|
||||||
|
if (cur_action.sa_handler == SIG_DFL || cur_action.sa_handler == SIG_IGN){
|
||||||
sigaction(SIGCHLD, &new_action, NULL);
|
sigaction(SIGCHLD, &new_action, NULL);
|
||||||
|
}
|
||||||
is_active = true;
|
is_active = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -449,9 +454,17 @@ void Util::Config::signal_handler(int signum){
|
||||||
case SIGTERM:
|
case SIGTERM:
|
||||||
is_active = false;
|
is_active = false;
|
||||||
break;
|
break;
|
||||||
case SIGCHLD: //when a child dies, reap it.
|
case SIGCHLD:{ //when a child dies, reap it.
|
||||||
wait(0);
|
int status;
|
||||||
|
pid_t ret = -1;
|
||||||
|
while (ret != 0){
|
||||||
|
ret = waitpid( -1, &status, WNOHANG);
|
||||||
|
if (ret < 0 && errno != EINTR){
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
default: //other signals are ignored
|
default: //other signals are ignored
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,12 +126,16 @@ void Util::Procs::setHandler(){
|
||||||
sigaction(SIGCHLD, &new_action, NULL);
|
sigaction(SIGCHLD, &new_action, NULL);
|
||||||
atexit(exit_handler);
|
atexit(exit_handler);
|
||||||
handler_set = true;
|
handler_set = true;
|
||||||
}
|
}// else {
|
||||||
|
// DEBUG_MSG(DLVL_DEVEL, "not setting handler");
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Used internally to capture child signals and update plist.
|
/// Used internally to capture child signals and update plist.
|
||||||
void Util::Procs::childsig_handler(int signum){
|
void Util::Procs::childsig_handler(int signum){
|
||||||
if (signum != SIGCHLD){
|
if (signum != SIGCHLD){
|
||||||
|
DEBUG_MSG(DLVL_DEVEL, "signum != SIGCHLD");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int status;
|
int status;
|
||||||
|
@ -142,13 +146,14 @@ void Util::Procs::childsig_handler(int signum){
|
||||||
if (ret == 0 || errno != EINTR){
|
if (ret == 0 || errno != EINTR){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
int exitcode;
|
int exitcode;
|
||||||
if (WIFEXITED(status)){
|
if (WIFEXITED(status)){
|
||||||
exitcode = WEXITSTATUS(status);
|
exitcode = WEXITSTATUS(status);
|
||||||
}else if (WIFSIGNALED(status)){
|
}else if (WIFSIGNALED(status)){
|
||||||
exitcode = -WTERMSIG(status);
|
exitcode = -WTERMSIG(status);
|
||||||
}else{/* not possible */
|
}else{// not possible
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,6 +191,7 @@ std::string Util::Procs::getOutputOf(char* const* argv){
|
||||||
ret += fileBuf;
|
ret += fileBuf;
|
||||||
}
|
}
|
||||||
fclose(outFile);
|
fclose(outFile);
|
||||||
|
free(fileBuf);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,6 +207,7 @@ std::string Util::Procs::getOutputOf(std::string cmd){
|
||||||
while ( !(feof(outFile) || ferror(outFile)) && (getline(&fileBuf, &fileBufLen, outFile) != -1)){
|
while ( !(feof(outFile) || ferror(outFile)) && (getline(&fileBuf, &fileBufLen, outFile) != -1)){
|
||||||
ret += fileBuf;
|
ret += fileBuf;
|
||||||
}
|
}
|
||||||
|
free(fileBuf);
|
||||||
fclose(outFile);
|
fclose(outFile);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -431,15 +438,24 @@ pid_t Util::Procs::StartPiped(std::string name, char* const* argv, int * fdin, i
|
||||||
DEBUG_MSG(DLVL_WARN, "Process %s already active - skipping start", name.c_str());
|
DEBUG_MSG(DLVL_WARN, "Process %s already active - skipping start", name.c_str());
|
||||||
return getPid(name);
|
return getPid(name);
|
||||||
}
|
}
|
||||||
|
int pidtemp = StartPiped(argv, fdin, fdout, fderr);
|
||||||
|
if (pidtemp > 0 ) {
|
||||||
|
plist.insert(std::pair<pid_t, std::string>(pidtemp, name));
|
||||||
|
}
|
||||||
|
return pidtemp;
|
||||||
|
}
|
||||||
|
|
||||||
|
pid_t Util::Procs::StartPiped(char* const* argv, int * fdin, int * fdout, int * fderr){
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
int pipein[2], pipeout[2], pipeerr[2];
|
int pipein[2], pipeout[2], pipeerr[2];
|
||||||
|
//DEBUG_MSG(DLVL_DEVEL, "setHandler");
|
||||||
setHandler();
|
setHandler();
|
||||||
if (fdin && *fdin == -1 && pipe(pipein) < 0){
|
if (fdin && *fdin == -1 && pipe(pipein) < 0){
|
||||||
DEBUG_MSG(DLVL_ERROR, "Pipe in creation failed for process %s", name.c_str());
|
DEBUG_MSG(DLVL_ERROR, "Pipe in creation failed for process %s", argv[0]);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (fdout && *fdout == -1 && pipe(pipeout) < 0){
|
if (fdout && *fdout == -1 && pipe(pipeout) < 0){
|
||||||
DEBUG_MSG(DLVL_ERROR, "Pipe out creation failed for process %s", name.c_str());
|
DEBUG_MSG(DLVL_ERROR, "Pipe out creation failed for process %s", argv[0]);
|
||||||
if ( *fdin == -1){
|
if ( *fdin == -1){
|
||||||
close(pipein[0]);
|
close(pipein[0]);
|
||||||
close(pipein[1]);
|
close(pipein[1]);
|
||||||
|
@ -447,7 +463,7 @@ pid_t Util::Procs::StartPiped(std::string name, char* const* argv, int * fdin, i
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (fderr && *fderr == -1 && pipe(pipeerr) < 0){
|
if (fderr && *fderr == -1 && pipe(pipeerr) < 0){
|
||||||
DEBUG_MSG(DLVL_ERROR, "Pipe err creation failed for process %s", name.c_str());
|
DEBUG_MSG(DLVL_ERROR, "Pipe err creation failed for process %s", argv[0]);
|
||||||
if ( *fdin == -1){
|
if ( *fdin == -1){
|
||||||
close(pipein[0]);
|
close(pipein[0]);
|
||||||
close(pipein[1]);
|
close(pipein[1]);
|
||||||
|
@ -462,7 +478,7 @@ pid_t Util::Procs::StartPiped(std::string name, char* const* argv, int * fdin, i
|
||||||
if ( !fdin || !fdout || !fderr){
|
if ( !fdin || !fdout || !fderr){
|
||||||
devnull = open("/dev/null", O_RDWR);
|
devnull = open("/dev/null", O_RDWR);
|
||||||
if (devnull == -1){
|
if (devnull == -1){
|
||||||
DEBUG_MSG(DLVL_ERROR, "Could not open /dev/null for process %s: %s", name.c_str(), strerror(errno));
|
DEBUG_MSG(DLVL_ERROR, "Could not open /dev/null for process %s: %s", argv[0], strerror(errno));
|
||||||
if ( *fdin == -1){
|
if ( *fdin == -1){
|
||||||
close(pipein[0]);
|
close(pipein[0]);
|
||||||
close(pipein[1]);
|
close(pipein[1]);
|
||||||
|
@ -488,7 +504,6 @@ pid_t Util::Procs::StartPiped(std::string name, char* const* argv, int * fdin, i
|
||||||
close(pipein[0]);
|
close(pipein[0]);
|
||||||
}else if ( *fdin != STDIN_FILENO){
|
}else if ( *fdin != STDIN_FILENO){
|
||||||
dup2( *fdin, STDIN_FILENO);
|
dup2( *fdin, STDIN_FILENO);
|
||||||
close( *fdin);
|
|
||||||
}
|
}
|
||||||
if ( !fdout){
|
if ( !fdout){
|
||||||
dup2(devnull, STDOUT_FILENO);
|
dup2(devnull, STDOUT_FILENO);
|
||||||
|
@ -498,7 +513,6 @@ pid_t Util::Procs::StartPiped(std::string name, char* const* argv, int * fdin, i
|
||||||
close(pipeout[1]);
|
close(pipeout[1]);
|
||||||
}else if ( *fdout != STDOUT_FILENO){
|
}else if ( *fdout != STDOUT_FILENO){
|
||||||
dup2( *fdout, STDOUT_FILENO);
|
dup2( *fdout, STDOUT_FILENO);
|
||||||
close( *fdout);
|
|
||||||
}
|
}
|
||||||
if ( !fderr){
|
if ( !fderr){
|
||||||
dup2(devnull, STDERR_FILENO);
|
dup2(devnull, STDERR_FILENO);
|
||||||
|
@ -508,16 +522,24 @@ pid_t Util::Procs::StartPiped(std::string name, char* const* argv, int * fdin, i
|
||||||
close(pipeerr[1]);
|
close(pipeerr[1]);
|
||||||
}else if ( *fderr != STDERR_FILENO){
|
}else if ( *fderr != STDERR_FILENO){
|
||||||
dup2( *fderr, STDERR_FILENO);
|
dup2( *fderr, STDERR_FILENO);
|
||||||
|
}
|
||||||
|
if( fdin && *fdin !=-1 && *fdin != STDIN_FILENO){
|
||||||
|
close( *fdin);
|
||||||
|
}
|
||||||
|
if( fdout && *fdout !=-1 && *fdout != STDOUT_FILENO){
|
||||||
|
close( *fdout);
|
||||||
|
}
|
||||||
|
if( fderr && *fderr !=-1 && *fderr != STDERR_FILENO){
|
||||||
close( *fderr);
|
close( *fderr);
|
||||||
}
|
}
|
||||||
if (devnull != -1){
|
if (devnull != -1){
|
||||||
close(devnull);
|
close(devnull);
|
||||||
}
|
}
|
||||||
execvp(argv[0], argv);
|
execvp(argv[0], argv);
|
||||||
DEBUG_MSG(DLVL_ERROR, "execvp() failed for process %s", name.c_str());
|
DEBUG_MSG(DLVL_ERROR, "execvp() failed for process %s", argv[0]);
|
||||||
exit(42);
|
exit(42);
|
||||||
}else if (pid == -1){
|
}else if (pid == -1){
|
||||||
DEBUG_MSG(DLVL_ERROR, "fork() for pipe failed for process %s", name.c_str());
|
DEBUG_MSG(DLVL_ERROR, "fork() for pipe failed for process %s", argv[0]);
|
||||||
if (fdin && *fdin == -1){
|
if (fdin && *fdin == -1){
|
||||||
close(pipein[0]);
|
close(pipein[0]);
|
||||||
close(pipein[1]);
|
close(pipein[1]);
|
||||||
|
@ -535,7 +557,7 @@ pid_t Util::Procs::StartPiped(std::string name, char* const* argv, int * fdin, i
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}else{ //parent
|
}else{ //parent
|
||||||
DEBUG_MSG(DLVL_HIGH, "Piped process %s started, PID %d: %s", name.c_str(), pid, argv[0]);
|
DEBUG_MSG(DLVL_HIGH, "Piped process %s started, PID %d", argv[0], pid);
|
||||||
if (devnull != -1){
|
if (devnull != -1){
|
||||||
close(devnull);
|
close(devnull);
|
||||||
}
|
}
|
||||||
|
@ -551,7 +573,6 @@ pid_t Util::Procs::StartPiped(std::string name, char* const* argv, int * fdin, i
|
||||||
close(pipeerr[1]); // close unused write end
|
close(pipeerr[1]); // close unused write end
|
||||||
*fderr = pipeerr[0];
|
*fderr = pipeerr[0];
|
||||||
}
|
}
|
||||||
plist.insert(std::pair<pid_t, std::string>(pid, name));
|
|
||||||
}
|
}
|
||||||
return pid;
|
return pid;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,10 @@ namespace Util {
|
||||||
static pid_t Start(std::string name, std::string cmd);
|
static pid_t Start(std::string name, std::string cmd);
|
||||||
static pid_t Start(std::string name, std::string cmd, std::string cmd2);
|
static pid_t Start(std::string name, std::string cmd, std::string cmd2);
|
||||||
static pid_t Start(std::string name, std::string cmd, std::string cmd2, std::string cmd3);
|
static pid_t Start(std::string name, std::string cmd, std::string cmd2, std::string cmd3);
|
||||||
|
|
||||||
|
static pid_t StartPiped(char* const* argv, int * fdin, int * fdout, int * fderr);
|
||||||
static pid_t StartPiped(std::string name, char* const* argv, int * fdin, int * fdout, int * fderr);
|
static pid_t StartPiped(std::string name, char* const* argv, int * fdin, int * fdout, int * fderr);
|
||||||
|
|
||||||
static pid_t StartPiped(std::string name, std::string cmd, int * fdin, int * fdout, int * fderr);
|
static pid_t StartPiped(std::string name, std::string cmd, int * fdin, int * fdout, int * fderr);
|
||||||
static pid_t StartPiped2(std::string name, std::string cmd1, std::string cmd2, int * fdin, int * fdout, int * fderr1, int * fderr2);
|
static pid_t StartPiped2(std::string name, std::string cmd1, std::string cmd2, int * fdin, int * fdout, int * fderr1, int * fderr2);
|
||||||
static void Stop(std::string name);
|
static void Stop(std::string name);
|
||||||
|
|
|
@ -427,6 +427,13 @@ bool Socket::Connection::spool(){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
bool Socket::Connection::peek(){
|
||||||
|
/// clear buffer
|
||||||
|
downbuffer.clear();
|
||||||
|
return iread(downbuffer, MSG_PEEK);
|
||||||
|
}
|
||||||
|
|
||||||
/// Updates the downbuffer and upbuffer internal variables until upbuffer is empty.
|
/// Updates the downbuffer and upbuffer internal variables until upbuffer is empty.
|
||||||
/// Returns true if new data was received, false otherwise.
|
/// Returns true if new data was received, false otherwise.
|
||||||
bool Socket::Connection::flush(){
|
bool Socket::Connection::flush(){
|
||||||
|
@ -563,14 +570,15 @@ unsigned int Socket::Connection::iwrite(const void * buffer, int len){
|
||||||
/// \param buffer Location of the buffer to read to.
|
/// \param buffer Location of the buffer to read to.
|
||||||
/// \param len Amount of bytes to read.
|
/// \param len Amount of bytes to read.
|
||||||
/// \returns The amount of bytes actually read.
|
/// \returns The amount of bytes actually read.
|
||||||
int Socket::Connection::iread(void * buffer, int len){
|
int Socket::Connection::iread(void * buffer, int len, int flags){
|
||||||
if ( !connected() || len < 1){
|
if ( !connected() || len < 1){
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int r;
|
int r;
|
||||||
if (sock >= 0){
|
if (sock >=0 ){
|
||||||
r = recv(sock, buffer, len, 0);
|
r = recv(sock, buffer, len, flags);
|
||||||
}else{
|
} else {
|
||||||
|
//(pipes[1] >=0) {
|
||||||
r = read(pipes[1], buffer, len);
|
r = read(pipes[1], buffer, len);
|
||||||
}
|
}
|
||||||
if (r < 0){
|
if (r < 0){
|
||||||
|
@ -589,7 +597,7 @@ int Socket::Connection::iread(void * buffer, int len){
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (r == 0 && (sock >= 0)){
|
if (r == 0){
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
down += r;
|
down += r;
|
||||||
|
@ -601,9 +609,9 @@ int Socket::Connection::iread(void * buffer, int len){
|
||||||
/// then appended to end of buffer.
|
/// then appended to end of buffer.
|
||||||
/// \param buffer Socket::Buffer to append data to.
|
/// \param buffer Socket::Buffer to append data to.
|
||||||
/// \return True if new data arrived, false otherwise.
|
/// \return True if new data arrived, false otherwise.
|
||||||
bool Socket::Connection::iread(Buffer & buffer){
|
bool Socket::Connection::iread(Buffer & buffer, int flags){
|
||||||
char cbuffer[BUFFER_BLOCKSIZE];
|
char cbuffer[BUFFER_BLOCKSIZE];
|
||||||
int num = iread(cbuffer, BUFFER_BLOCKSIZE);
|
int num = iread(cbuffer, BUFFER_BLOCKSIZE, flags);
|
||||||
if (num < 1){
|
if (num < 1){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,9 +54,9 @@ namespace Socket {
|
||||||
long long int conntime;
|
long long int conntime;
|
||||||
Buffer downbuffer; ///< Stores temporary data coming in.
|
Buffer downbuffer; ///< Stores temporary data coming in.
|
||||||
Buffer upbuffer; ///< Stores temporary data going out.
|
Buffer upbuffer; ///< Stores temporary data going out.
|
||||||
int iread(void * buffer, int len); ///< Incremental read call.
|
int iread(void * buffer, int len, int flags = 0); ///< Incremental read call.
|
||||||
unsigned int iwrite(const void * buffer, int len); ///< Incremental write call.
|
unsigned int iwrite(const void * buffer, int len); ///< Incremental write call.
|
||||||
bool iread(Buffer & buffer); ///< Incremental write call that is compatible with Socket::Buffer.
|
bool iread(Buffer & buffer, int flags = 0); ///< Incremental write call that is compatible with Socket::Buffer.
|
||||||
bool iwrite(std::string & buffer); ///< Write call that is compatible with std::string.
|
bool iwrite(std::string & buffer); ///< Write call that is compatible with std::string.
|
||||||
public:
|
public:
|
||||||
//friends
|
//friends
|
||||||
|
@ -81,6 +81,7 @@ namespace Socket {
|
||||||
//buffered i/o methods
|
//buffered i/o methods
|
||||||
bool spool(); ///< Updates the downbuffer and upbuffer internal variables.
|
bool spool(); ///< Updates the downbuffer and upbuffer internal variables.
|
||||||
bool flush(); ///< Updates the downbuffer and upbuffer internal variables until upbuffer is empty.
|
bool flush(); ///< Updates the downbuffer and upbuffer internal variables until upbuffer is empty.
|
||||||
|
bool peek(); ///< Clears the downbuffer and fills it with peek
|
||||||
Buffer & Received(); ///< Returns a reference to the download buffer.
|
Buffer & Received(); ///< Returns a reference to the download buffer.
|
||||||
void Send(std::string & data); ///< Appends data to the upbuffer.
|
void Send(std::string & data); ///< Appends data to the upbuffer.
|
||||||
void Send(const char * data); ///< Appends data to the upbuffer.
|
void Send(const char * data); ///< Appends data to the upbuffer.
|
||||||
|
|
Loading…
Add table
Reference in a new issue