According to windows API docs we can use global variable to pass data from creating thread to the new thread and I am assuming the opposite is also possible
Data can also be passed from the creating thread to the new thread using global variables.
Here is a data structure and a callback function, ptr
is a pointer to heap allocated memory in main
typedef struct Output
{
char *ptr;
DWORD len;
}Output, *POutput;
Output out; // global variable
DWORD grab_output(LPVOID args)
{
DWORD dread;
BOOL success = FALSE;
while (1)
{
success = ReadFile(g_hChildStd_OUT_Rd,out.ptr, 1024, &dread, NULL);
if (!success || dread == 0 ) break;
out.ptr = realloc(out.ptr, out.len+1024);
out.len += dread;
}
}
int run()
{
BOOL res;
STARTUPINFO si;
PROCESS_INFORMATION pi;
SECURITY_ATTRIBUTES sa;
DWORD dwThreadIdArray[1];
DWORD n_size;
memset(&si, 0 ,sizeof(si));
memset(&pi, 0, sizeof(pi));
memset(&sa, 0, sizeof(sa));
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = NULL;
if (!CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &sa, 0))
return GetLastError();
if (!SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0))
return GetLastError();
si.cb = sizeof(STARTUPINFOA);
si.hStdError = g_hChildStd_OUT_Wr;
si.hStdOutput = g_hChildStd_OUT_Wr;
si.dwFlags |= STARTF_USESTDHANDLES;
if(!CreateProcess(NULL,
"C:\\Windows\\System32\\cmd.exe /c dir",
NULL,
NULL,
TRUE,
CREATE_NEW_CONSOLE,
NULL,
NULL,
&si,
&pi
))
{
}
else
{
handle = CreateThread(0, 0, grab_output, NULL, 0, NULL);
}
return 0;
}
int main()
{
out.ptr = malloc(1024);
out.len = 0;
run();
printf("%s\n", out.ptr);
}
when running the code out.ptr
returns garbage values
gcc example.c && ./a.exe
└e╔┐═☺
for the sake of this question assume that I will be running a single thread at any given time
The reason this prints garbage values is you assumed for no clear reason that the thread finishes before you accessed the global variable.
There's too many unchecked fault points. Right now, check every function that can error for an error return and produce output in that case, and also set a flag in another global variable. Really, you shouldn't have to, but better to much than not enough. Then close the process and thread handles you aren't using.
Now we should be able to discuss synchronization.
It looks like you want to grab all of the output at once. Thus WaitForSingleObject()
on your own thread handle. To produce output incrementally, you need to track input highwater and output highwater and output only the characters in between with putc()
.
Don't forget to null-terminate your string either, or printf()
won't be happy.