20 template <
typename Character>
56 h->process_handle = 0;
96 for (process_handle_pair* it =
first; it !=
last; ++it)
116 process_handle_pair*
const newptr = _recalloc_crt_t(process_handle_pair,
__idpairs,
__idtabsiz + 1).detach();
117 if (newptr ==
nullptr)
121 process_handle_pair*
const pairptr = newptr +
__idtabsiz;
129template <
typename Character>
131 Character
const*
const type
134 fdopen_mode<Character>
result = fdopen_mode<Character>();
136 Character
const* type_it =
type;
138 while (*type_it ==
' ')
142 result.mode[0] = *type_it++;
144 while (*type_it ==
' ')
148 result.mode[1] = *type_it;
155template <
typename Character>
160 static Character
const comspec_name[] = {
'C',
'O',
'M',
'S',
'P',
'E',
'C',
'\0' };
162 Character* comspec_value =
nullptr;
163 if (
_ERRCHECK_EINVAL(stdio_traits::tdupenv_s_crt(&comspec_value,
nullptr, comspec_name)) != 0)
166 return comspec_value;
171template <
typename Character>
176 static Character
const path_name[] = {
'P',
'A',
'T',
'H',
'\0' };
178 Character* path_value =
nullptr;
187template <
typename Character>
189 Character
const*
const executable
195 if (stdio_traits::taccess_s(executable, 0) == 0)
199 __crt_unique_heap_ptr<Character>
buffer(_calloc_crt_t(Character,
MAX_PATH));
200 if (
buffer.get() ==
nullptr)
203 __crt_unique_heap_ptr<Character const>
path(get_path<Character>());
210 static Character
const backslash[] = {
'\\',
'\0' };
214 if (stdio_traits::tcslen(
buffer.get()) + stdio_traits::tcslen(executable) >=
MAX_PATH)
219 if (stdio_traits::taccess_s(
buffer.get(), 0) == 0)
228template <
typename Character>
230 Character
const*
const command,
231 Character
const*
const fdopen_mode,
233 int (&pipe_handles)[2]
242 __crt_unique_handle new_pipe_handle;
247 new_pipe_handle.get_address_of(),
256 pipe_handles[0] = -1;
259 unique_stream pipe_stream(stdio_traits::tfdopen(pipe_handles[1], fdopen_mode));
269 static Character
const default_cmd_exe[] = {
'c',
'm',
'd',
'.',
'e',
'x',
'e',
'\0' };
271 __crt_unique_heap_ptr<Character const>
const comspec_variable(get_comspec<Character>());
272 Character
const*
const cmd_exe = comspec_variable.get() !=
nullptr
273 ? comspec_variable.get()
277 startup_info.
cb =
sizeof(startup_info);
285 static Character
const slash_c[] = {
' ',
'/',
'c',
' ',
'\0' };
287 size_t const command_line_count =
288 stdio_traits::tcslen(cmd_exe) +
289 stdio_traits::tcslen(slash_c) +
290 stdio_traits::tcslen(
command) +
293 __crt_unique_heap_ptr<Character>
const command_line(_calloc_crt_t(Character, command_line_count));
294 if (command_line.get() ==
nullptr)
297 _ERRCHECK(stdio_traits::tcscpy_s(command_line.get(), command_line_count, cmd_exe));
298 _ERRCHECK(stdio_traits::tcscat_s(command_line.get(), command_line_count, slash_c));
299 _ERRCHECK(stdio_traits::tcscat_s(command_line.get(), command_line_count,
command));
303 if (selected_cmd_exe ==
nullptr)
308 __crt_unique_heap_ptr<Character const>
const owned_final_exe_path(selected_cmd_exe != cmd_exe
313 BOOL const child_status = stdio_traits::create_process(
328 FILE*
const result_stream = pipe_stream.detach();
331 id_pair.get()->process_handle =
reinterpret_cast<intptr_t>(process_info.
hProcess);
332 id_pair.get()->stream = result_stream;
334 return result_stream;
339template <
typename Character>
341 Character
const*
const command,
342 Character
const*
const type
349 if (fdopen_mode.mode[0] ==
'\0')
354 if (fdopen_mode.mode[1] ==
't') { pipe_mode |=
_O_TEXT; }
355 if (fdopen_mode.mode[1] ==
'b') { pipe_mode |=
_O_BINARY; }
358 if (
_pipe(pipe_handles, 1024, pipe_mode) == -1)
361 int const std_fh = fdopen_mode.mode[0] ==
'w'
365 int ordered_pipe_handles[] =
367 std_fh ==
STDIN ? pipe_handles[0] : pipe_handles[1],
368 std_fh ==
STDIN ? pipe_handles[1] : pipe_handles[0]
371 FILE* return_value =
nullptr;
382 ordered_pipe_handles);
386 if (return_value !=
nullptr)
391 int*
const first = ordered_pipe_handles;
419 char const*
const type
429 wchar_t const*
const type
449 int return_value = -1;
454 process_handle_pair*
const id_pair =
idtab(
stream);
455 if (id_pair ==
nullptr)
463 intptr_t const process_handle = id_pair->process_handle;
466 id_pair->stream =
nullptr;
467 id_pair->process_handle = 0;
void __cdecl __acrt_unlock(_In_ __acrt_lock_id lock)
#define _ERRCHECK_EINVAL(e)
bool __cdecl __crt_stdio_path_requires_backslash(char const *const first)
#define _VALIDATE_RETURN(expr, errorcode, retexpr)
result_buffer_count char *const _In_ int const _In_ bool const _In_ unsigned const _In_ STRFLT const _In_ bool const _Inout_ __crt_cached_ptd_host &ptd throw()
__acrt_lock(__acrt_heap_lock)
#define GetCurrentProcess()
BOOL WINAPI DuplicateHandle(IN HANDLE hSourceProcessHandle, IN HANDLE hSourceHandle, IN HANDLE hTargetProcessHandle, OUT LPHANDLE lpTargetHandle, IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN DWORD dwOptions)
static char * path_name(DOS_FILE *file)
GLuint GLuint GLsizei GLenum type
GLfloat GLfloat GLfloat GLfloat h
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
struct task_struct * current
__crt_unique_handle_t< stream_traits > unique_stream
__crt_unique_handle_t< process_handle_pair_traits > unique_process_handle_pair
static Character const *__cdecl get_comspec()
static Character const *__cdecl get_path()
FILE *__cdecl _wpopen(wchar_t const *const command, wchar_t const *const type)
static Character const *__cdecl get_executable_path(Character const *const executable)
int __cdecl _pclose(FILE *const stream)
static FILE *__cdecl common_popen_nolock(Character const *const command, Character const *const fdopen_mode, int const std_fh, int(&pipe_handles)[2])
static process_handle_pair *__cdecl idtab(FILE *const stream)
static fdopen_mode< Character > __cdecl convert_popen_type_to_fdopen_mode(Character const *const type)
static process_handle_pair * __idpairs
static FILE *__cdecl common_popen(Character const *const command, Character const *const type)
FILE *__cdecl _popen(char const *const command, char const *const type)
static unsigned __idtabsiz
_Check_return_opt_ _CRTIMP int __cdecl _close(_In_ int _FileHandle)
_Check_return_ _CRTIMP int __cdecl _pipe(_Inout_updates_(2) int *_PtHandles, _In_ unsigned int _PipeSize, _In_ int _TextMode)
_CRTIMP intptr_t __cdecl _cwait(_Out_opt_ int *_TermStat, _In_ intptr_t _ProcHandle, _In_ int _Action)
static bool close(_In_ type h)
process_handle_pair * type
static type get_invalid_value()
static bool close(_In_ type h)
static type get_invalid_value()
struct _PROCESS_INFORMATION PROCESS_INFORMATION
#define STARTF_USESTDHANDLES
#define DUPLICATE_SAME_ACCESS