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
		Add a link
		
	
		Reference in a new issue
	
	 Thulinma
						Thulinma