def set_socket_inherit(sock, inherit): ''' Mark a socket as inheritable or non-inheritable to child processes. This should be called right after socket creation if you want to prevent the socket from being inherited by child processes. Note that for sockets, a new socket returned from accept() will be inheritable even if the listener socket was not; so you should call set_socket_inherit for the new socket as well. ''' try: if iswindows: import win32api, win32con if inherit: flags = win32con.HANDLE_FLAG_INHERIT else: flags = 0 win32api.SetHandleInformation(sock.fileno(), win32con.HANDLE_FLAG_INHERIT, flags) else: import fcntl fd = sock.fileno() flags = fcntl.fcntl(fd, fcntl.F_GETFD) & ~fcntl.FD_CLOEXEC if not inherit: flags = flags | fcntl.FD_CLOEXEC fcntl.fcntl(fd, fcntl.F_SETFD, flags) except: import traceback traceback.print_exc()
def test_granting_to_subprocess(self): parent_socket, child_socket = naclimc.os_socketpair() if sys.platform == "win32": import win32api import win32con close = win32api.CloseHandle win32api.SetHandleInformation(child_socket, win32con.HANDLE_FLAG_INHERIT, win32con.HANDLE_FLAG_INHERIT) kwargs = {} else: close = os.close def pre_exec(): close(parent_socket) kwargs = {"preexec_fn": pre_exec} if 'PYTHON_ARCH' in os.environ: # This is a workaround for Mac OS 10.6 where we have to request # an architecture for the interpreter that matches the extension # we built. python_prefix = ['arch', '-arch', os.environ['PYTHON_ARCH']] else: python_prefix = [] proc = subprocess.Popen( python_prefix + [ sys.executable, os.path.join(os.path.dirname(__file__), "test_prog.py"), "%i" % child_socket ], **kwargs) close(child_socket) socket = naclimc.from_os_socket(parent_socket) received = socket.imc_recvmsg(100) self.assertEquals(received, ("message from test_prog", ()))
def __init__(self, filename, mode='r', encoding=None): if mode in ('r', 'r+'): creationDisposition = win32file.OPEN_EXISTING desiredAccess = win32con.GENERIC_READ elif mode == 'w': creationDisposition = win32con.CREATE_ALWAYS desiredAccess = win32con.GENERIC_WRITE elif mode in ('rw', 'wr', 'r+', 'w+', 'a+'): creationDisposition = win32con.OPEN_ALWAYS desiredAccess = win32con.GENERIC_READ | win32con.GENERIC_WRITE elif mode == 'a': creationDisposition = win32con.OPEN_ALWAYS desiredAccess = win32con.GENERIC_WRITE else: raise ValueError('Invalid access mode') self.filename = filename # shareMode = (win32con.FILE_SHARE_READ | win32con.FILE_SHARE_WRITE | # win32con.FILE_SHARE_DELETE) shareMode = win32con.shareMode = (win32con.FILE_SHARE_READ | win32con.FILE_SHARE_WRITE) attributes = win32security.SECURITY_ATTRIBUTES() # dwFlagsAndAttributes = win32con.FILE_ATTRIBUTE_NORMAL dwFlagsAndAttributes = win32con.FILE_FLAG_WRITE_THROUGH self.encoding = encoding or 'utf-8' self.handle = win32file.CreateFile(filename, desiredAccess, shareMode, attributes, creationDisposition, dwFlagsAndAttributes, 0) win32api.SetHandleInformation(self.handle, win32con.HANDLE_FLAG_INHERIT, 0) if mode in ('a', 'a+'): self.seek(0, 2) self.file_size = win32file.GetFileSize(self.handle) self.is_closed = False
def config_log(file_path, name): # err file handler fh_err = logging.handlers.TimedRotatingFileHandler(file_path + '_error.log', when='midnight', encoding='utf-8', backupCount=60) fh_err.setLevel(logging.WARNING) # file handler fh_dbg = logging.handlers.TimedRotatingFileHandler(file_path + '_debug.log', when='midnight', encoding='utf-8', backupCount=60) fh_dbg.setLevel(logging.DEBUG) # console handler sh = logging.StreamHandler() sh.setLevel(logging.INFO) # logging format setting ff = logging.Formatter('''[%(asctime)s] %(levelname)s : %(message)s''') sf = logging.Formatter('''[%(levelname)s] %(message)s''') fh_err.setFormatter(ff) fh_dbg.setFormatter(ff) sh.setFormatter(sf) if platform.system() == 'Windows': import msvcrt import win32api import win32con win32api.SetHandleInformation( msvcrt.get_osfhandle(fh_dbg.stream.fileno()), win32con.HANDLE_FLAG_INHERIT, 0) win32api.SetHandleInformation( msvcrt.get_osfhandle(fh_err.stream.fileno()), win32con.HANDLE_FLAG_INHERIT, 0) # create logger, assign handler logger = logging.getLogger(name) logger.setLevel(logging.DEBUG) logger.addHandler(fh_err) logger.addHandler(fh_dbg) logger.addHandler(sh) return logger
def DisableWindowsFileHandleInheritance(file_descriptor): """Flags a Windows file descriptor so that child processes don't inherit it. Args: file_descriptor (int): file handle descriptor, as returned by fileno() and similar methods. """ if msvcrt and win32api and win32con: os_handle = msvcrt.get_osfhandle(file_descriptor) win32api.SetHandleInformation(os_handle, win32con.HANDLE_FLAG_INHERIT, 0) return raise RuntimeError
def config_log(self, file_path, name): ''' it returns FileHandler and StreamHandler logger if you do not need to use multiprocess logging, just call this function and use returned logger. ''' # err file handler fh_err = logging.handlers.RotatingFileHandler(file_path + '_error.log', 'a', 300, 10) fh_err.setLevel(logging.WARNING) # file handler fh_dbg = logging.handlers.RotatingFileHandler(file_path + '_debug.log', 'a', 300, 10) fh_dbg.setLevel(logging.DEBUG) # console handler sh = logging.StreamHandler() sh.setLevel(logging.INFO) # logging format setting ff = logging.Formatter('''[%(asctime)s] %(levelname)s : %(message)s''') sf = logging.Formatter('''[%(levelname)s] %(message)s''') fh_err.setFormatter(ff) fh_dbg.setFormatter(ff) sh.setFormatter(sf) if platform.system() == 'Windows': import msvcrt import win32api import win32con win32api.SetHandleInformation( msvcrt.get_osfhandle(fh_dbg.stream.fileno()), win32con.HANDLE_FLAG_INHERIT, 0) win32api.SetHandleInformation( msvcrt.get_osfhandle(fh_err.stream.fileno()), win32con.HANDLE_FLAG_INHERIT, 0) # create logger, assign handler logger = logging.getLogger(name) logger.setLevel(logging.DEBUG) logger.addHandler(fh_err) logger.addHandler(fh_dbg) logger.addHandler(sh) return logger
def __init__(self, pipename): Thread.__init__(self, name='PipeServer') self.daemon = True import win32pipe, win32api, win32con FILE_FLAG_FIRST_PIPE_INSTANCE = 0x00080000 PIPE_REJECT_REMOTE_CLIENTS = 0x00000008 self.pipe_handle = win32pipe.CreateNamedPipe( pipename, win32pipe.PIPE_ACCESS_INBOUND | FILE_FLAG_FIRST_PIPE_INSTANCE, win32pipe.PIPE_TYPE_BYTE | win32pipe.PIPE_READMODE_BYTE | win32pipe.PIPE_WAIT | PIPE_REJECT_REMOTE_CLIENTS, 1, 8192, 8192, 0, None) win32api.SetHandleInformation(self.pipe_handle, win32con.HANDLE_FLAG_INHERIT, 0) self.err_msg = None self.data = b'' self.start()
def _disable_inheritance_filehandler(self): """Disable file handlers inheritance by child processes""" try: import win32api import win32con except ImportError: raise ImportWarning( "log rotation requires the installation of the \"pywin32\" library.\n" "Download and install from https://github.com/mhammond/pywin32/releases" ) import msvcrt win32api.SetHandleInformation( msvcrt.get_osfhandle(self.stream.fileno()), win32con.HANDLE_FLAG_INHERIT, 0)
def _create_pipes(self): sa = win32security.SECURITY_ATTRIBUTES() sa.bInheritHandle = 1 self._stdin_read, self._stdin_write = win32pipe.CreatePipe(sa, 0) win32api.SetHandleInformation(self._stdin_write, win32con.HANDLE_FLAG_INHERIT, 0) if self._stdout: if os.path.isfile(self._stdout): shell.remove(self._stdout) shell.touch(self._stdout) self.stdout_reader = io.open(self._stdout, 'rb+') else: self._stdout_reader = tempfile.TemporaryFile() self._stdout_handle = create_file(self._stdout_reader.name) if self._stderr: if os.path.isfile(self._stderr): shell.remove(self._stderr) shell.touch(self._stderr) self._stderr_reader = io.open(self._stderr, 'rb+') else: self._stderr_reader = tempfile.TemporaryFile() self._stderr_handle = create_file(self._stderr_reader.name)
def _scons_open(*args, **kw): fp = apply(_builtin_open, args, kw) win32api.SetHandleInformation(msvcrt.get_osfhandle(fp.fileno()), win32con.HANDLE_FLAG_INHERIT, 0) return fp
def __init__(self, *args, **kw): _builtin_file.__init__(self, *args, **kw) win32api.SetHandleInformation(msvcrt.get_osfhandle(self.fileno()), win32con.HANDLE_FLAG_INHERIT, 0)
def __call__(self): saAttr = win32security.SECURITY_ATTRIBUTES() saAttr.bInheritHandle = 1 self.hChildStdoutRd = win32pipe.CreateNamedPipe( self.stdoutPipeName, win32con.PIPE_ACCESS_INBOUND | win32con.FILE_FLAG_OVERLAPPED, # open mode win32con.PIPE_TYPE_BYTE, # pipe mode 1, # max instances WindowsShell.BUFFER_SIZE, # out buffer size WindowsShell.BUFFER_SIZE, # in buffer size 15, # timeout saAttr) hChildStdoutWr = win32file.CreateFile( self.stdoutPipeName, win32con.GENERIC_WRITE, win32con.FILE_SHARE_READ | win32con.FILE_SHARE_WRITE, saAttr, win32con.OPEN_EXISTING, win32con.FILE_FLAG_OVERLAPPED, 15) win32api.SetHandleInformation(self.hChildStdoutRd, win32con.HANDLE_FLAG_INHERIT, 0) self.hChildStderrRd = win32pipe.CreateNamedPipe( self.stderrPipeName, win32con.PIPE_ACCESS_INBOUND | win32con.FILE_FLAG_OVERLAPPED, # open mode win32con.PIPE_TYPE_BYTE, # pipe mode 1, # max instances WindowsShell.BUFFER_SIZE, # out buffer size WindowsShell.BUFFER_SIZE, # in buffer size 15, # timeout saAttr) hChildStderrWr = win32file.CreateFile( self.stderrPipeName, win32con.GENERIC_WRITE, win32con.FILE_SHARE_READ | win32con.FILE_SHARE_WRITE, saAttr, win32con.OPEN_EXISTING, win32con.FILE_FLAG_OVERLAPPED, 15) win32api.SetHandleInformation(self.hChildStderrRd, win32con.HANDLE_FLAG_INHERIT, 0) # Create a pipe for the child process's STDIN. This one is opened # in duplex mode so we can read from it too in order to detect when # the child closes their end of the pipe. self.hChildStdinWr = win32pipe.CreateNamedPipe( self.stdinPipeName, win32con.PIPE_ACCESS_DUPLEX | win32con.FILE_FLAG_OVERLAPPED, # open mode win32con.PIPE_TYPE_BYTE, # pipe mode 1, # max instances WindowsShell.BUFFER_SIZE, # out buffer size WindowsShell.BUFFER_SIZE, # in buffer size 15, # timeout... 0 gives a default 50 ms saAttr) hChildStdinRd = win32file.CreateFile( self.stdinPipeName, win32con.GENERIC_READ, win32con.FILE_SHARE_READ | win32con.FILE_SHARE_WRITE, saAttr, win32con.OPEN_EXISTING, win32con.FILE_FLAG_OVERLAPPED | win32con.FILE_FLAG_NO_BUFFERING, 15) win32api.SetHandleInformation(self.hChildStdinWr, win32con.HANDLE_FLAG_INHERIT, 0) # set the info structure for the new process. This is where # we tell the process to use the pipes for stdout/err/in. StartupInfo = win32process.STARTUPINFO() StartupInfo.hStdOutput = hChildStdoutWr StartupInfo.hStdError = hChildStderrWr StartupInfo.hStdInput = hChildStdinRd StartupInfo.dwFlags = win32process.STARTF_USESTDHANDLES flags = win32process.CREATE_UNICODE_ENVIRONMENT try: processHandle, threadHandle, dwPid, dwTid = win32process.CreateProcess( None, # name self.cmdline, # command line None, # process handle not inheritable None, # thread handle not inheritable True, # handles are inherited flags, # creation flags None, # NULL, use parent environment None, # current directory StartupInfo) # STARTUPINFO pointer except pywintypes.error as e: logger.exception('%s\n%s\n', self.cmdline, e.strerror) messageBox(f'{self.cmdline}\n{e.strerror}', mfError, (mfOKButton, )) return None win32file.CloseHandle(processHandle) win32file.CloseHandle(threadHandle) win32file.CloseHandle(hChildStderrWr) win32file.CloseHandle(hChildStdoutWr) win32file.CloseHandle(hChildStdinRd) self.stdin = os.fdopen(msvcrt.open_osfhandle(int(self.hChildStdinWr), 0), 'wb', buffering=0) self.stdout = os.fdopen(msvcrt.open_osfhandle(int(self.hChildStdoutRd), 0), 'rb', buffering=0) self.stderr = os.fdopen(msvcrt.open_osfhandle(int(self.hChildStderrRd), 0), 'rb', buffering=0) fds = WindowPipe(stdin=self.stdin, stdout=self.stdout, stderr=self.stderr) return fds
def create_logger(log_type): """ 지정된 로그 타입에 따라 config 파일 내 로그 설정에 따른 로깅 객체 반환 Parameters ---------- log_type : str 현재는 "RPA_LOG" 만 존재, 만일 다른 system 로그 파일 필요 시 system.ini 내 섹션 추가 필요 Returns ------- logging.Logger 생성한 로깅 객체 """ # *************CONFIG READ START************* # ini 파일 데이터를 적재할 config 객체 생성 logging_dict = '' try: # ini 파일 읽기 config = configparser.RawConfigParser() config.read(ConfigBean.CONFIG_FILE, encoding='utf-8-sig') # 섹션별 dict 처리 logging_dict = config[log_type] except IOError: print("Failed to load Config File! (", ConfigBean.CONFIG_FILE, ") ") # config 파일이 없으면 프로그램 그냥 종료해야 함 exit(-1) # *************CONFIG READ END************* # *************LOGGING CONFIG START************* # 로그 관련 설정값 가져오기 logger = logging_dict["logger_name"] file_name = LogBean.ABS_PATH + "\\" + logging_dict["file_name"] log_format = logging_dict["log_format"] start_time = logging_dict["start_time"] interval = int(logging_dict["interval"]) backup = int(logging_dict["backup"]) # 로그 객체 생성 my_logger = logging.getLogger(logger) # 이미 핸들러가 있다면 생성된 것이니까 그대로 돌려준다 if len(my_logger.handlers) > 0: return my_logger my_logger.setLevel(logging.INFO) # 로그 파일 핸들러를 작성하여 이 규칙에 맞게 파일 관리되도록 지정 file_handler = logging.handlers.TimedRotatingFileHandler( filename=file_name, when=start_time, interval=interval, backupCount=backup, encoding='utf-8') # 파일명 형식에 날짜 추가(백업 파일 간 구분용) file_handler.suffix = '_%Y%m%d.log' # 포맷 추가 = 로그 시간|레벨명|로그이름|파일명|라인번호 >> 메시지 file_handler.setFormatter(logging.Formatter(log_format)) # 콘솔 출력용 핸들러 작성 console_handler = logging.StreamHandler() console_handler.setFormatter(logging.Formatter(log_format)) console_handler.setLevel(logging.DEBUG) # 혹시 로그 사용 시 자식 프로세스가 핸들러를 물고 있지 않도록 설정 if platform.system() == 'Windows': import msvcrt import win32api import win32con win32api.SetHandleInformation( msvcrt.get_osfhandle(file_handler.stream.fileno()), win32con.HANDLE_FLAG_INHERIT, 0) # 핸들러를 로그 객체에 적용 my_logger.addHandler(file_handler) my_logger.addHandler(console_handler) # *************LOGGING CONFIG END************* my_logger.info("Created Logger") return my_logger