how to deal with Python BaseHTTPServer killed,but

2019-09-12 15:06发布

问题:

I use python BaseHTTPServer,it can handle do_GET,do_POST methods,in do_POST method,i execute linux shell using os.system,when i kill the python script,but the listening port still occupied,so i can't run the script again, the netstat -antp|grep 80 show that the bash/tail is occupied the port 80

import sys
import os
import traceback
import time
import logging.handlers
import logging
from threading import *
from datetime import datetime
import urllib2
reload(sys)
sys.setdefaultencoding('utf-8')

class WebRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
    server_version = 'python httpserver'
    sys_version = 'b'
    backup_dir = None
    def do_HEAD(s):
        s.send_response(200)
        s.send_header("Content-type", "text/html")
        s.end_headers()
    def do_GET(self):
        if self.path == '/foo':
            self.send_response(200)               
            os.system('nohup tail -f a.log &')

        else:
            self.send_error(404)
if __name__ == "__main__":
    try:
        server = BaseHTTPServer.HTTPServer(('',80), WebRequestHandler)    
        server.serve_forever()
    except KeyboardInterrupt:
        server.socket.close()

回答1:

File descriptors are inherited by default by child processes, so the socket listening on port 80 is inherited by the command you have launched using your system() call.

To avoid that, you should set the FD_CLOEXEC flag on the listening socket. This can be done by adding (and using) a specific HTTPServer class.

class WebServer(BaseHTTPServer.HTTPServer):
    def __init__(self, *args, **kwargs):
        BaseHTTPServer.HTTPServer.__init__(self, *args, **kwargs)
        # Set FD_CLOEXEC flag
        flags = fcntl.fcntl(self.socket.fileno(), fcntl.F_GETFD)
        flags |= fcntl.FD_CLOEXEC
        fcntl.fcntl(self.socket.fileno(), fcntl.F_SETFD, flags)

Related :

  • Process started from system command in C inherits parent fd's