Unicode port: Adapted MakensisW & zip2exe for UTF-8 (avoid cutting sequence). Also fix a bug where they would get stuck if output log was multiple of 1023 bytes. Simplification of reading loop.

git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@6085 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
wizou 2010-05-07 13:54:03 +00:00
parent 27977fd335
commit 428ae80ab1
2 changed files with 58 additions and 60 deletions

View file

@ -706,6 +706,8 @@ BOOL CALLBACK DialogProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) {
} }
DWORD WINAPI MakeNSISProc(LPVOID p) { DWORD WINAPI MakeNSISProc(LPVOID p) {
TCHAR buf[1024];
char iobuf[1024]; //i/o buffer
STARTUPINFO si={sizeof(si),}; STARTUPINFO si={sizeof(si),};
SECURITY_ATTRIBUTES sa={sizeof(sa),}; SECURITY_ATTRIBUTES sa={sizeof(sa),};
SECURITY_DESCRIPTOR sd={0,}; SECURITY_DESCRIPTOR sd={0,};
@ -746,34 +748,40 @@ DWORD WINAPI MakeNSISProc(LPVOID p) {
PostMessage(g_sdata.hwnd,WM_MAKENSIS_PROCESSCOMPLETE,0,0); PostMessage(g_sdata.hwnd,WM_MAKENSIS_PROCESSCOMPLETE,0,0);
return 1; return 1;
} }
char szBuf[1024]; CloseHandle(newstdout); // close this handle (duplicated in subprocess) now so we get ERROR_BROKEN_PIPE
DWORD dwRead = 1; DWORD dwLeft = 0, dwRead = 0;
DWORD dwExit = !STILL_ACTIVE; while (ReadFile(read_stdout, iobuf+dwLeft, sizeof(iobuf)-dwLeft-1, &dwRead, NULL)) //wait for buffer, or fails with ERROR_BROKEN_PIPE when subprocess exits
while (dwExit == STILL_ACTIVE || dwRead) { {
PeekNamedPipe(read_stdout, 0, 0, 0, &dwRead, NULL); dwRead += dwLeft;
if (dwRead) { iobuf[dwRead] = '\0';
ReadFile(read_stdout, szBuf, sizeof(szBuf)-sizeof(TCHAR), &dwRead, NULL);
szBuf[dwRead] = 0;
#ifdef _UNICODE #ifdef _UNICODE
TCHAR wideBuf[1024]; // this tweak is to prevent LogMessage from cutting in the middle of an UTF-8 sequence
MultiByteToWideChar(CP_UTF8,0,szBuf,-1,wideBuf,COUNTOF(wideBuf)); // we print only up to the latest \n of the buffer, and keep the remaining for the next loop
LogMessage(g_sdata.hwnd, wideBuf); char* lastLF = strrchr(iobuf,'\n');
if (lastLF == NULL) lastLF = iobuf+dwRead-1;
char ch = *++lastLF;
*lastLF = '\0';
MultiByteToWideChar(CP_UTF8,0,iobuf,lastLF+1-iobuf,buf,COUNTOF(buf));
LogMessage(g_sdata.hwnd, buf);
*lastLF = ch;
dwLeft = iobuf+dwRead-lastLF;
memmove(iobuf, lastLF, dwLeft);
#else #else
LogMessage(g_sdata.hwnd, szBuf); LogMessage(g_sdata.hwnd, iobuf);
#endif #endif
}
else Sleep(TIMEOUT);
GetExitCodeProcess(pi.hProcess, &dwExit);
// Make sure we have no data before killing getting out of the loop
if (dwExit != STILL_ACTIVE) {
PeekNamedPipe(read_stdout, 0, 0, 0, &dwRead, NULL);
}
} }
#ifdef _UNICODE
// because of UTF-8 tweak, in rare case there can be some data remaining
dwRead += dwLeft;
iobuf[dwRead] = 0;
MultiByteToWideChar(CP_UTF8,0,iobuf,dwRead+1,buf,COUNTOF(buf));
LogMessage(g_sdata.hwnd, buf);
#endif
DWORD dwExit;
GetExitCodeProcess(pi.hProcess, &dwExit);
g_sdata.retcode = dwExit; g_sdata.retcode = dwExit;
CloseHandle(pi.hThread); CloseHandle(pi.hThread);
CloseHandle(pi.hProcess); CloseHandle(pi.hProcess);
CloseHandle(newstdout);
CloseHandle(read_stdout); CloseHandle(read_stdout);
CloseHandle(newstdin); CloseHandle(newstdin);
CloseHandle(read_stdin); CloseHandle(read_stdin);

View file

@ -386,7 +386,8 @@ void ErrorMessage(TCHAR *str) //display detailed error info
DWORD WINAPI ThreadProc(LPVOID p) // thread that will start & monitor makensis DWORD WINAPI ThreadProc(LPVOID p) // thread that will start & monitor makensis
{ {
TCHAR buf[1024]; //i/o buffer TCHAR buf[1024];
char iobuf[1024]; //i/o buffer
STARTUPINFO si={sizeof(si),}; STARTUPINFO si={sizeof(si),};
SECURITY_ATTRIBUTES sa={sizeof(sa),}; SECURITY_ATTRIBUTES sa={sizeof(sa),};
SECURITY_DESCRIPTOR sd={0,}; //security information for pipes SECURITY_DESCRIPTOR sd={0,}; //security information for pipes
@ -436,48 +437,37 @@ DWORD WINAPI ThreadProc(LPVOID p) // thread that will start & monitor makensis
PostMessage(g_hwnd,WM_USER+1203,0,1); PostMessage(g_hwnd,WM_USER+1203,0,1);
return 1; return 1;
} }
CloseHandle(newstdout); // close this handle (duplicated in subprocess) now so we get ERROR_BROKEN_PIPE
DWORD exit=0; //process exit code DWORD dwLeft = 0, dwRead = 0;
DWORD bread; //bytes read while (ReadFile(read_stdout, iobuf+dwLeft, sizeof(iobuf)-dwLeft-1, &dwRead, NULL)) //wait for buffer, or fails with ERROR_BROKEN_PIPE when subprocess exits
DWORD avail; //bytes available
// Number of bytes available in the buffer.
const int bufBytesAvail = sizeof(buf)-sizeof(TCHAR);
memset(buf,0,sizeof(buf));
while (1) //main program loop
{ {
PeekNamedPipe(read_stdout,buf,bufBytesAvail,&bread,&avail,NULL); dwRead += dwLeft;
iobuf[dwRead] = '\0';
//check to see if there is any data to read from stdout #ifdef _UNICODE
if (bread != 0) // this tweak is to prevent LogMessage from cutting in the middle of an UTF-8 sequence
{ // we print only up to the latest \n of the buffer, and keep the remaining for the next loop
memset(buf,0,sizeof(buf)); char* lastLF = strrchr(iobuf,'\n');
if (avail > bufBytesAvail) if (lastLF == NULL) lastLF = iobuf+dwRead-1;
{ char ch = *++lastLF;
while (bread >= bufBytesAvail) *lastLF = '\0';
{ MultiByteToWideChar(CP_UTF8,0,iobuf,lastLF+1-iobuf,buf,COUNTOF(buf));
ReadFile(read_stdout,buf,bufBytesAvail,&bread,NULL); //read the stdout pipe wnd_printf(buf);
wnd_printf(buf); *lastLF = ch;
memset(buf,0,sizeof(buf)); dwLeft = iobuf+dwRead-lastLF;
} memmove(iobuf, lastLF, dwLeft);
} #else
else wnd_printf(iobuf);
{ #endif
ReadFile(read_stdout,buf,bufBytesAvail,&bread,NULL);
wnd_printf(buf);
}
}
GetExitCodeProcess(pi.hProcess,&exit); //while the process is running
if (exit != STILL_ACTIVE)
break;
Sleep(100);
} }
#ifdef _UNICODE
// because of UTF-8 tweak, in rare case there can be some data remaining
dwRead += dwLeft;
iobuf[dwRead] = 0;
MultiByteToWideChar(CP_UTF8,0,iobuf,dwRead+1,buf,COUNTOF(buf));
wnd_printf(buf);
#endif
CloseHandle(pi.hThread); CloseHandle(pi.hThread);
CloseHandle(pi.hProcess); CloseHandle(pi.hProcess);
CloseHandle(newstdout);
CloseHandle(read_stdout); CloseHandle(read_stdout);