def spawn(cls, channel): pid = pid_t() file_actions = ctypes.pointer(posix_spawn_file_actions_t()) res = posix_spawn_file_actions_init(file_actions) check_errno(res) exe = ctypes.c_char_p(util.str2b(sys.executable)) # Bind remap = ( (channel.fd, kStartFd), ) for fromfd, tofd in remap: res = posix_spawn_file_actions_adddup2(file_actions, fromfd, tofd) check_errno(res) envp = (ctypes.c_char_p * (len(os.environ) + 1))() for index, key in enumerate(os.environ.keys()): export = key + '=' + os.environ[key] envp[index] = ctypes.c_char_p(util.str2b(export)) envp[len(os.environ)] = None # Create argv. argv = [ sys.executable, '-c', 'import sys; from ambuild2.ipc.posix_proc import child_main; child_main("{0}")'.format(channel.name) ] c_argv = (ctypes.c_char_p * (len(argv) + 1))() for index, arg in enumerate(argv): c_argv[index] = ctypes.c_char_p(util.str2b(arg)) c_argv[len(argv)] = None res = posix_spawnp( ctypes.pointer(pid), exe, file_actions, None, ctypes.cast(c_argv, ctypes.c_void_p), ctypes.cast(envp, ctypes.c_void_p) ) check_errno(res) posix_spawn_file_actions_destroy(file_actions) return cls(pid.value)
def spawn(cls, channel): eval = 'from ambuild2.ipc.windows import child_main; child_main()' argv = [sys.executable, '-c', eval] argv += ['--name', '{0}'.format(channel.name)] # This is pretty hacky. Maybe we should just pass in the pipe name instead. argv += ['--pipe', '{0}'.format(channel.path)] cmdline = ' '.join(['"{0}"'.format(arg) for arg in argv]) cmdline = util.str2b(cmdline) cmdline_buffer = ctypes.create_string_buffer(cmdline) startup_info = StartupInfo() startup_info.dwFlags |= STARTF_USESTDHANDLES startup_info.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE) startup_info.hStdError = GetStdHandle(STD_ERROR_HANDLE) startup_info.hStdInput = GetStdHandle(STD_INPUT_HANDLE) proc_info = ProcessInformation() executable = sys_executable() rval = fnCreateProcessA( util.str2b(executable), cmdline_buffer, None, None, 1, # bInheritHandles 0, # dwCreationFlags None, # lpEnvironment None, # lpCurrentDirectory ctypes.pointer(startup_info), ctypes.pointer(proc_info) ) if not rval: raise WinError() CloseHandle(proc_info.hThread) return cls(proc_info.hProcess, proc_info.dwProcessId)
def OpenPipe(path): rval = fnCreateFileA( util.str2b(path), GENERIC_READ | GENERIC_WRITE, 0, None, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, None ) if rval == INVALID_HANDLE_VALUE: raise WinError() return handle_t(rval)
def spawn(cls, channel): eval = 'from ambuild2.ipc.windows import child_main; child_main()' argv = [sys.executable, '-c', eval] argv += ['--name', '{0}'.format(channel.name)] # This is pretty hacky. Maybe we should just pass in the pipe name instead. argv += ['--pipe', '{0}'.format(channel.path)] cmdline = ' '.join(['"{0}"'.format(arg) for arg in argv]) cmdline = util.str2b(cmdline) cmdline_buffer = ctypes.create_string_buffer(cmdline) startup_info = StartupInfo() startup_info.dwFlags |= STARTF_USESTDHANDLES startup_info.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE) startup_info.hStdError = GetStdHandle(STD_ERROR_HANDLE) startup_info.hStdInput = GetStdHandle(STD_INPUT_HANDLE) proc_info = ProcessInformation() executable = sys_executable() rval = fnCreateProcessA( util.str2b(executable), cmdline_buffer, None, None, 1, # bInheritHandles 0, # dwCreationFlags None, # lpEnvironment None, # lpCurrentDirectory ctypes.pointer(startup_info), ctypes.pointer(proc_info)) if not rval: raise WinError() CloseHandle(proc_info.hThread) return cls(proc_info.hProcess, proc_info.dwProcessId)
def CreateNamedPipe(): global pipe_counter_ pipe_name = r'\\.\pipe\ambuild-{0}-{1}'.format(os.getpid(), pipe_counter_) pipe_counter_ += 1 flags = PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED | FILE_FLAG_FIRST_PIPE_INSTANCE rval = fnCreateNamedPipeA(util.str2b(pipe_name), flags, PIPE_TYPE_BYTE | PIPE_TYPE_READMODE_BYTE, 1, 4096, 4096, 5000, None) if rval == INVALID_HANDLE_VALUE: raise WinError() return handle_t(rval), pipe_name
def CreateNamedPipe(): global pipe_counter_ pipe_name = r'\\.\pipe\ambuild-{0}-{1}'.format(os.getpid(), pipe_counter_) pipe_counter_ += 1 flags = PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED | FILE_FLAG_FIRST_PIPE_INSTANCE rval = fnCreateNamedPipeA( util.str2b(pipe_name), flags, PIPE_TYPE_BYTE | PIPE_TYPE_READMODE_BYTE, 1, 4096, 4096, 5000, None ) if rval == INVALID_HANDLE_VALUE: raise WinError() return handle_t(rval), pipe_name
def OpenPipe(path): rval = fnCreateFileA(util.str2b(path), GENERIC_READ | GENERIC_WRITE, 0, None, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, None) if rval == INVALID_HANDLE_VALUE: raise WinError() return handle_t(rval)