winetest: Use Win32 APIs exclusively for file I/O and output redirection.

This commit is contained in:
Alexandre Julliard 2008-07-10 17:45:22 +02:00
parent e98933a279
commit 23296f0c4a
4 changed files with 97 additions and 99 deletions

View file

@ -29,12 +29,7 @@
#include "wine/port.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <errno.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <windows.h>
#include "winetest.h"
@ -266,27 +261,17 @@ extract_test (struct wine_test *test, const char *dir, LPTSTR res_name)
value of WaitForSingleObject.
*/
static int
run_ex (char *cmd, const char *out, const char *tempdir, DWORD ms)
run_ex (char *cmd, HANDLE out_file, const char *tempdir, DWORD ms)
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
int fd, oldstdout = -1;
DWORD wait, status;
GetStartupInfo (&si);
si.dwFlags = 0;
if (out) {
fd = open (out, O_WRONLY | O_CREAT, 0666);
if (-1 == fd)
report (R_FATAL, "Can't open '%s': %d", out, errno);
oldstdout = dup (1);
if (-1 == oldstdout)
report (R_FATAL, "Can't save stdout: %d", errno);
if (-1 == dup2 (fd, 1))
report (R_FATAL, "Can't redirect stdout: %d", errno);
close (fd);
}
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdInput = GetStdHandle( STD_INPUT_HANDLE );
si.hStdOutput = out_file ? out_file : GetStdHandle( STD_OUTPUT_HANDLE );
si.hStdError = GetStdHandle( STD_ERROR_HANDLE );
if (!CreateProcessA (NULL, cmd, NULL, NULL, TRUE, CREATE_DEFAULT_ERROR_MODE,
NULL, tempdir, &si, &pi)) {
@ -332,43 +317,49 @@ run_ex (char *cmd, const char *out, const char *tempdir, DWORD ms)
CloseHandle (pi.hProcess);
}
if (out) {
close (1);
if (-1 == dup2 (oldstdout, 1))
report (R_FATAL, "Can't recover stdout: %d", errno);
close (oldstdout);
}
return status;
}
static void
get_subtests (const char *tempdir, struct wine_test *test, LPTSTR res_name)
{
char *subname, *cmd;
FILE *subfile;
size_t total;
char *cmd;
HANDLE subfile;
DWORD total;
char buffer[8192], *index;
static const char header[] = "Valid test names:";
int allocated;
char tmpdir[MAX_PATH], subname[MAX_PATH];
SECURITY_ATTRIBUTES sa;
test->subtest_count = 0;
subname = tempnam (0, "sub");
if (!subname) report (R_FATAL, "Can't name subtests file.");
if (!GetTempPathA( MAX_PATH, tmpdir ) ||
!GetTempFileNameA( tmpdir, "sub", 0, subname ))
report (R_FATAL, "Can't name subtests file.");
/* make handle inheritable */
sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
subfile = CreateFileA( subname, GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
&sa, CREATE_ALWAYS, 0, NULL );
if (subfile == INVALID_HANDLE_VALUE) {
report (R_ERROR, "Can't open subtests output of %s: %u",
test->name, GetLastError());
goto quit;
}
extract_test (test, tempdir, res_name);
cmd = strmake (NULL, "%s --list", test->exename);
run_ex (cmd, subname, tempdir, 5000);
run_ex (cmd, subfile, tempdir, 5000);
free (cmd);
subfile = fopen (subname, "r");
if (!subfile) {
report (R_ERROR, "Can't open subtests output of %s: %d",
test->name, errno);
goto quit;
}
total = fread (buffer, 1, sizeof buffer, subfile);
fclose (subfile);
SetFilePointer( subfile, 0, NULL, FILE_BEGIN );
ReadFile( subfile, buffer, sizeof(buffer), &total, NULL );
CloseHandle( subfile );
if (sizeof buffer == total) {
report (R_ERROR, "Subtest list of %s too big.",
test->name, sizeof buffer);
@ -400,21 +391,19 @@ get_subtests (const char *tempdir, struct wine_test *test, LPTSTR res_name)
test->subtest_count * sizeof(char*));
quit:
if (remove (subname))
report (R_WARNING, "Can't delete file '%s': %d",
subname, errno);
free (subname);
if (!DeleteFileA (subname))
report (R_WARNING, "Can't delete file '%s': %u", subname, GetLastError());
}
static void
run_test (struct wine_test* test, const char* subtest, const char *tempdir)
run_test (struct wine_test* test, const char* subtest, HANDLE out_file, const char *tempdir)
{
int status;
const char* file = get_test_source_file(test->name, subtest);
char *cmd = strmake (NULL, "%s %s", test->exename, subtest);
xprintf ("%s:%s start %s -\n", test->name, subtest, file);
status = run_ex (cmd, NULL, tempdir, 120000);
status = run_ex (cmd, out_file, tempdir, 120000);
free (cmd);
xprintf ("%s:%s done (%d)\n", test->name, subtest, status);
}
@ -459,43 +448,49 @@ static char *
run_tests (char *logname)
{
int i;
char *tempdir, *shorttempdir;
int logfile;
char *strres, *eol, *nextline;
DWORD strsize;
SECURITY_ATTRIBUTES sa;
char tmppath[MAX_PATH], tempdir[MAX_PATH+4];
SetErrorMode (SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
if (!GetTempPathA( MAX_PATH, tmppath ))
report (R_FATAL, "Can't name temporary dir (check %%TEMP%%).");
if (!logname) {
logname = tempnam (0, "res");
if (!logname) report (R_FATAL, "Can't name logfile.");
static char tmpname[MAX_PATH];
if (!GetTempFileNameA( tmppath, "res", 0, tmpname ))
report (R_FATAL, "Can't name logfile.");
logname = tmpname;
}
report (R_OUT, logname);
logfile = open (logname, O_WRONLY | O_CREAT | O_EXCL | O_APPEND,
0666);
if (-1 == logfile) {
if (EEXIST == errno)
report (R_FATAL, "File %s already exists.", logname);
else report (R_FATAL, "Could not open logfile: %d", errno);
}
if (-1 == dup2 (logfile, 1))
report (R_FATAL, "Can't redirect stdout: %d", errno);
close (logfile);
/* make handle inheritable */
sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
tempdir = tempnam (0, "wct");
if (!tempdir)
logfile = CreateFileA( logname, GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
&sa, CREATE_ALWAYS, 0, NULL );
if (logfile == INVALID_HANDLE_VALUE)
report (R_FATAL, "Could not open logfile: %u", GetLastError());
if (!GetTempPathA( MAX_PATH, tmppath ))
report (R_FATAL, "Can't name temporary dir (check %%TEMP%%).");
shorttempdir = strdup (tempdir);
if (shorttempdir) { /* try stable path for ZoneAlarm */
strstr (shorttempdir, "wct")[3] = 0;
if (CreateDirectoryA (shorttempdir, NULL)) {
free (tempdir);
tempdir = shorttempdir;
} else free (shorttempdir);
/* try stable path for ZoneAlarm */
strcpy( tempdir, tmppath );
strcat( tempdir, "wct" );
if (!CreateDirectoryA( tempdir, NULL ))
{
if (!GetTempFileNameA( tmppath, "wct", 0, tempdir ))
report (R_FATAL, "Can't name temporary dir (check %%TEMP%%).");
DeleteFileA( tempdir );
if (!CreateDirectoryA( tempdir, NULL ))
report (R_FATAL, "Could not create directory: %s", tempdir);
}
if (tempdir != shorttempdir && !CreateDirectoryA (tempdir, NULL))
report (R_FATAL, "Could not create directory: %s", tempdir);
report (R_DIR, tempdir);
xprintf ("Version 4\n");
@ -553,15 +548,15 @@ run_tests (char *logname)
for (j = 0; j < test->subtest_count; j++) {
report (R_STEP, "Running: %s:%s", test->name,
test->subtests[j]);
run_test (test, test->subtests[j], tempdir);
run_test (test, test->subtests[j], logfile, tempdir);
}
}
report (R_DELTA, 0, "Running: Done");
report (R_STATUS, "Cleaning up");
close (1);
CloseHandle( logfile );
logfile = 0;
remove_dir (tempdir);
free (tempdir);
free (wine_tests);
return logname;
@ -666,7 +661,7 @@ int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrevInst,
putenv (debug_yes) ||
putenv (interactive_no) ||
putenv (report_success_no)))
report (R_FATAL, "Could not reset environment: %d", errno);
report (R_FATAL, "Could not reset environment");
if (!tag) {
if (!interactive)
@ -684,9 +679,8 @@ int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrevInst,
logname = run_tests (NULL);
if (build_id[0] &&
report (R_ASK, MB_YESNO, "Do you want to submit the test results?") == IDYES)
if (!send_file (logname) && remove (logname))
report (R_WARNING, "Can't remove logfile: %d.", errno);
free (logname);
if (!send_file (logname) && !DeleteFileA(logname))
report (R_WARNING, "Can't remove logfile: %u", GetLastError());
} else run_tests (logname);
report (R_STATUS, "Finished");
}

View file

@ -105,10 +105,11 @@ int
send_file (const char *name)
{
SOCKET s;
FILE *f;
HANDLE file;
#define BUFLEN 8192
char buffer[BUFLEN+1];
size_t bytes_read, total, filesize;
DWORD bytes_read, filesize;
size_t total;
char *str;
int ret;
@ -130,20 +131,21 @@ send_file (const char *name)
s = open_http ("test.winehq.org");
if (s == INVALID_SOCKET) return 1;
f = fopen (name, "rb");
if (!f) {
report (R_WARNING, "Can't open file '%s': %d", name, errno);
file = CreateFileA( name, GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL, OPEN_EXISTING, 0, NULL );
if (file == INVALID_HANDLE_VALUE)
{
report (R_WARNING, "Can't open file '%s': %u", name, GetLastError());
goto abort1;
}
fseek (f, 0, SEEK_END);
filesize = ftell (f);
filesize = GetFileSize( file, NULL );
if (filesize > 1.5*1024*1024) {
report (R_WARNING,
"File too big (%.1f MB > 1.5 MB); submitting partial report.",
filesize/1024.0/1024);
filesize = 1.5*1024*1024;
}
fseek (f, 0, SEEK_SET);
report (R_STATUS, "Sending header");
str = strmake (&total, body1, name);
@ -159,11 +161,8 @@ send_file (const char *name)
report (R_STATUS, "Sending %u bytes of data", filesize);
report (R_PROGRESS, 2, filesize);
total = 0;
while (total < filesize && (bytes_read = fread (buffer, 1, BUFLEN/2, f))) {
if ((signed)bytes_read == -1) {
report (R_WARNING, "Error reading log file: %d", errno);
goto abort2;
}
while (total < filesize && ReadFile( file, buffer, BUFLEN/2, &bytes_read, NULL )) {
if (!bytes_read) break;
total += bytes_read;
if (total > filesize) bytes_read -= total - filesize;
if (send_buf (s, buffer, bytes_read)) {
@ -173,7 +172,7 @@ send_file (const char *name)
}
report (R_DELTA, bytes_read, "Network transfer: In progress");
}
fclose (f);
CloseHandle( file );
if (send_buf (s, body2, sizeof body2 - 1)) {
report (R_WARNING, "Error sending trailer: %d, %d",
@ -216,7 +215,7 @@ send_file (const char *name)
return ret;
abort2:
fclose (f);
CloseHandle( file );
abort1:
close_http (s);
return 1;

View file

@ -19,11 +19,14 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <unistd.h>
#include <errno.h>
#include <stdarg.h>
#include <windef.h>
#include <winbase.h>
#include "winetest.h"
HANDLE logfile = 0;
void *xmalloc (size_t len)
{
void *p = malloc (len);
@ -95,16 +98,16 @@ void xprintf (const char *fmt, ...)
{
va_list ap;
size_t size;
ssize_t written;
DWORD written;
char *buffer, *head;
va_start (ap, fmt);
buffer = vstrfmtmake (&size, fmt, ap);
head = buffer;
va_end (ap);
while ((written = write (1, head, size)) != size) {
if (written == -1)
report (R_FATAL, "Can't write logs: %d", errno);
while (size) {
if (!WriteFile( logfile, head, size, &written, NULL ))
report (R_FATAL, "Can't write logs: %u", GetLastError());
head += written;
size -= written;
}

View file

@ -39,6 +39,8 @@ const char *findbadtagchar (const char *tag);
int send_file (const char *name);
extern HANDLE logfile;
/* GUI definitions */
#include <windows.h>