@@ -70,7 +70,7 @@ wstring GetLastErrorString(DWORD error_code) {
7070 return result;
7171}
7272
73- bool AutoAttributeList::Create (HANDLE* handles, size_t count ,
73+ bool AutoAttributeList::Create (HANDLE stdin_h, HANDLE stdout_h, HANDLE stderr_h ,
7474 std::unique_ptr<AutoAttributeList>* result,
7575 wstring* error_msg) {
7676 static constexpr DWORD kAttributeCount = 1 ;
@@ -79,7 +79,7 @@ bool AutoAttributeList::Create(HANDLE* handles, size_t count,
7979 // According to MSDN, the first call to InitializeProcThreadAttributeList is
8080 // expected to fail.
8181 InitializeProcThreadAttributeList (NULL , kAttributeCount , 0 , &size);
82- std::unique_ptr<uint8_t > data (new uint8_t [size]);
82+ std::unique_ptr<uint8_t [] > data (new uint8_t [size]);
8383 LPPROC_THREAD_ATTRIBUTE_LIST attrs =
8484 reinterpret_cast <LPPROC_THREAD_ATTRIBUTE_LIST>(data.get ());
8585 if (!InitializeProcThreadAttributeList (attrs, kAttributeCount , 0 , &size)) {
@@ -92,20 +92,31 @@ bool AutoAttributeList::Create(HANDLE* handles, size_t count,
9292 return false ;
9393 }
9494
95+ std::unique_ptr<AutoAttributeList> attr_list (
96+ new AutoAttributeList (std::move (data), stdin_h, stdout_h, stderr_h));
9597 if (!UpdateProcThreadAttribute (attrs, 0 , PROC_THREAD_ATTRIBUTE_HANDLE_LIST,
96- handles, count * sizeof (HANDLE), NULL , NULL )) {
98+ attr_list->handles_ .handle_array ,
99+ StdHandles::kHandleCount * sizeof (HANDLE),
100+ NULL , NULL )) {
97101 if (error_msg) {
98102 DWORD err = GetLastError ();
99103 *error_msg = MakeErrorMessage (WSTR (__FILE__), __LINE__,
100104 L" UpdateProcThreadAttribute" , L" " , err);
101105 }
102106 return false ;
103107 }
104- result-> reset ( new AutoAttributeList (data. release ()) );
108+ * result = std::move (attr_list );
105109 return true ;
106110}
107111
108- AutoAttributeList::AutoAttributeList (uint8_t * data) : data_(data) {}
112+ AutoAttributeList::AutoAttributeList (std::unique_ptr<uint8_t []>&& data,
113+ HANDLE stdin_h, HANDLE stdout_h,
114+ HANDLE stderr_h)
115+ : data_(std::move(data)) {
116+ handles_.stdin_h = stdin_h;
117+ handles_.stdout_h = stdout_h;
118+ handles_.stderr_h = stderr_h;
119+ }
109120
110121AutoAttributeList::~AutoAttributeList () {
111122 DeleteProcThreadAttributeList (*this );
@@ -115,6 +126,26 @@ AutoAttributeList::operator LPPROC_THREAD_ATTRIBUTE_LIST() const {
115126 return reinterpret_cast <LPPROC_THREAD_ATTRIBUTE_LIST>(data_.get ());
116127}
117128
129+ void AutoAttributeList::InitStartupInfoExA (STARTUPINFOEXA* startup_info) const {
130+ ZeroMemory (startup_info, sizeof (STARTUPINFOEXA));
131+ startup_info->StartupInfo .cb = sizeof (STARTUPINFOEXA);
132+ startup_info->StartupInfo .dwFlags = STARTF_USESTDHANDLES;
133+ startup_info->StartupInfo .hStdInput = handles_.stdin_h ;
134+ startup_info->StartupInfo .hStdOutput = handles_.stdout_h ;
135+ startup_info->StartupInfo .hStdError = handles_.stderr_h ;
136+ startup_info->lpAttributeList = *this ;
137+ }
138+
139+ void AutoAttributeList::InitStartupInfoExW (STARTUPINFOEXW* startup_info) const {
140+ ZeroMemory (startup_info, sizeof (STARTUPINFOEXW));
141+ startup_info->StartupInfo .cb = sizeof (STARTUPINFOEXW);
142+ startup_info->StartupInfo .dwFlags = STARTF_USESTDHANDLES;
143+ startup_info->StartupInfo .hStdInput = handles_.stdin_h ;
144+ startup_info->StartupInfo .hStdOutput = handles_.stdout_h ;
145+ startup_info->StartupInfo .hStdError = handles_.stderr_h ;
146+ startup_info->lpAttributeList = *this ;
147+ }
148+
118149static void QuotePath (const wstring& path, wstring* result) {
119150 *result = wstring (L" \" " ) + path + L" \" " ;
120151}
0 commit comments