Method: Net::Server#start
- Defined in:
- lib/net/server.rb
#start ⇒ Object
This is the main setup and loop.
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 |
# File 'lib/net/server.rb', line 164 def start # generate the first log messages LOG.info("%06d"%Process::pid) {"Starting RubyMTA at #{Time.now.strftime("%Y-%m-%d %H:%M:%S %Z")}, pid=#{Process::pid}"} if LOG LOG.info("%06d"%Process::pid) {"Options specified: #{ARGV.join(", ")}"} if LOG && ARGV.size>0 # get the certificates, if any; they're needed for STARTTLS # we do this before daemonizing because the working folder might change $prv = if @options[:private_key] then OpenSSL::PKey::RSA.new File.read(@options[:private_key]) else nil end $crt = if @options[:certificate] then OpenSSL::X509::Certificate.new File.read(@options[:certificate]) else nil end # daemonize it if the option was set--it doesn't have to be root to daemonize it Process::daemon if @options[:daemon] # get the process ID and the user id AFTER demonizing, if that was requested pid = Process::pid uid = Process::Sys.getuid gid = Process::Sys.getgid LOG.info("%06d"%Process::pid) {"Daemonized at #{Time.now.strftime("%Y-%m-%d %H:%M:%S %Z")}, pid=#{pid}, uid=#{uid}, gid=#{gid}"} if LOG && @options[:daemon] # store the pid of the server session begin puts "RubyMTA running as PID=>#{pid}, UID=>#{uid}, GID=>#{gid}" File.open(@options[:pid_file],"w") { |f| f.write(pid.to_s) } rescue Errno::EACCES => e LOG.warn("%06d"%Process::pid) {"The pid couldn't be written. To save the pid, create a directory for '#{@options[:pid_file]}' with r/w permissions for this user."} if LOG LOG.warn("%06d"%Process::pid) {"Proceeding without writing the pid."} if LOG end # if ssltransportagent was started as root, make sure UserName and # GroupName have values because we have to drop root privileges # after we fork a process for the receiver if uid==0 # it's root if @options[:user_name].nil? || @options[:group_name].nil? LOG.error("%06d"%Process::pid) {"ssltransportagent can't be started as root unless UserName and GroupName are set."} if LOG exit(1) end end # this is the main loop which runs until admin enters ^C Signal.trap("INT") { raise ServerTerminate.new } Signal.trap("HUP") { restart if defined?(restart) } Signal.trap("CHLD") do begin Process.wait(-1, Process::WNOHANG) rescue Errno::ECHILD => e # ignore the error end end # trap-chld threads = [] # start the server on multiple ports (the usual case) begin @options[:listening_ports].each do |port| threads << Thread.start(port) do |port| listening_thread(port) end end # the joins are done ONLY after all threads are started threads.each { |thread| thread.join } rescue ServerTerminate LOG.info("%06d"%Process::pid) {"#{@options[:server_name]} terminated by admin ^C"} if LOG end # attempt to remove the pid file begin File.delete(@options[:pid_file]) rescue Errno::ENOENT => e LOG.warn("%06d"%Process::pid) {"No such file: #{e.inspect}"} if LOG rescue Errno::EACCES, Errno::EPERM LOG.warn("%06d"%Process::pid) {"Permission denied: #{e.inspect}"} if LOG end end |