0

From a parent process, I am trying to control a child process through standard input/output. I used the following MSDN example to create the child process and redirect its standard input & output : http://msdn.microsoft.com/en-us/library/windows/desktop/ms682499%28v=vs.100%29.aspx

On the parent side I send the same "command" twice using the following code:

const char cmd[] = "test\n";
DWORD written, read;
BOOL success;
success = WriteFile(g_hChildStd_IN_Wr, cmd, sizeof(cmd), &written, NULL);
success = WriteFile(g_hChildStd_IN_Wr, cmd, sizeof(cmd), &written, NULL);

On the child side, I read those commands through a fgets call. The first command is read as expected. But when the second command is sent, the fgets call returns with an empty string and the next fgets call does not return. Here is the child process code:

char *retStrP;
char str[256];
size_t strLen;

retStrP = fgets(str, 256, stdin);
strLen = strlen(str);
if (retStrP != str)
{
    char errorStr[256];
    int a = feof(stdin);
    int b = ferror(stdin);
    sprintf(errorStr, "Fgets error, %d %d\n", a, b);
    OutputDebugString(errorStr);
}
else if (strLen == 0)
{
    char errorStr[256];
    int a = feof(stdin);
    int b = ferror(stdin);
    sprintf(errorStr, "Strlen is 0, %d %d\n", a, b);
    OutputDebugString(errorStr);
}

From the previous code, the second call to fgets behaves as follow: the returned pointer is equal to the str buffer but the strlen is 0.

When reading the MSDN fgets documentation ( http://msdn.microsoft.com/en-us/library/c37dh6kf%28v=vs.100%29.aspx ), I don't see any way it could return the pointer to the buffer passed as the first argument with the first buffer's byte being set to 0 (as far as the buffer size is greater than 1). If an error occurs or the end of file is reached, the fgets should return NULL and either feof or ferror should return something not 0.

I suspect something is going wrong with the pipes handling but I can't figure out what... From the parent side, I don't do anything more with the stdin write pipe than sending the same buffer twice. Any idea what could cause such a behaviour?

4

2 に答える 2

0

あなたの質問はあなたがリンクした例にかなり漠然と関連しています。それでもここにいくつかの提案があります。

これを試して:

while(!success)
   success = WriteFile(g_hChildStd_IN_Wr, cmd, sizeof(cmd), &written, NULL);
while(!success)
   success = WriteFile(g_hChildStd_IN_Wr, cmd, sizeof(cmd), &written, NULL);

理由:WriteFile()関数が成功した場合、戻り値はゼロ以外(TRUE)です。関数が失敗した場合、または非同期で完了している場合、戻り値はゼロ(FALSE)です。エラー情報を取得するには、GetLastError()関数を使用します。

ReadFile()の代わりに、子プロセスのforループ内でfgetsによって書き込まれたデータを読み取るために使用します。WriteFile()

それでも問題が発生する場合は、コード内のおよびGetLastError()の後に関数を使用して、エラーコード情報を投稿してください。私たちはあなたをより良く助けることができるかもしれません。WriteFile()ReadFile()

于 2012-11-06T18:21:41.213 に答える
0

I found out the problem!

From the parent process, the WriteFile calls send the NULL terminating character to the pipe.

So after the first WriteFile call, the fgets reads the string upto the newline character. Then on the second WriteFile call, the fgets reads the string starting from the previous NULL terminating character upto the second newline character. It results in a returned string with the first character being the NULL terminating character. This is why the fgets return without error but the string length is 0.

The solution is then to not send the NULL terminating character by substracting 1 from the cmd buffer size.

于 2012-11-07T17:49:29.867 に答える