1 // 2 // system.cpp 3 // 4 // Copyright (c) Microsoft Corporation. All rights reserved. 5 // 6 // Defines the system() family of functions, which execute a command via the 7 // shell. 8 // 9 #include <corecrt_internal.h> 10 #include <corecrt_internal_traits.h> 11 #include <process.h> 12 #include <io.h> 13 #include <stdlib.h> 14 #include <errno.h> 15 16 17 18 // Executes a command via the shell. If the command is null, attempts to execute 19 // the command processor specified by the %COMSPEC% environment variable. If 20 // that fails, attempts to execute cmd.exe. 21 template <typename Character> 22 static int __cdecl common_system(Character const* const command) throw() 23 { 24 typedef __crt_char_traits<Character> traits; 25 26 static Character const comspec_name[] = { 'C', 'O', 'M', 'S', 'P', 'E', 'C', '\0' }; 27 static Character const cmd_exe[] = { 'c', 'm', 'd', '.', 'e', 'x', 'e', '\0' }; 28 static Character const slash_c[] = { '/', 'c', '\0' }; 29 30 __crt_unique_heap_ptr<Character> comspec_value; 31 _ERRCHECK_EINVAL(traits::tdupenv_s_crt(comspec_value.get_address_of(), nullptr, comspec_name)); 32 33 // If the command is null, return TRUE only if %COMSPEC% is set and the file 34 // to which it points exists. 35 if (!command) 36 { 37 if (!comspec_value) 38 return 0; 39 40 return traits::taccess_s(comspec_value.get(), 0) == 0; 41 } 42 43 _ASSERTE(command[0] != '\0'); 44 45 Character const* arguments[4] = 46 { 47 comspec_value.get(), 48 slash_c, 49 command, 50 nullptr 51 }; 52 53 if (comspec_value) 54 { 55 errno_t const saved_errno = errno; 56 errno = 0; 57 58 int const result = static_cast<int>(traits::tspawnve(_P_WAIT, arguments[0], arguments, nullptr)); 59 if (result != -1) 60 { 61 errno = saved_errno; 62 return result; 63 } 64 65 if (errno != ENOENT && errno != EACCES) 66 { 67 return result; 68 } 69 70 // If the error wasn't one of those two errors, try again with cmd.exe... 71 errno = saved_errno; 72 } 73 74 arguments[0] = cmd_exe; 75 return static_cast<int>(traits::tspawnvpe(_P_WAIT, arguments[0], arguments, nullptr)); 76 } 77 78 extern "C" int __cdecl system(char const* const command) 79 { 80 return common_system(command); 81 } 82 83 extern "C" int __cdecl _wsystem(wchar_t const* const command) 84 { 85 return common_system(command); 86 } 87