Commit 23296f0c authored by Alexandre Julliard's avatar Alexandre Julliard

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

parent e98933a2
...@@ -29,12 +29,7 @@ ...@@ -29,12 +29,7 @@
#include "wine/port.h" #include "wine/port.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <assert.h> #include <assert.h>
#include <errno.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <windows.h> #include <windows.h>
#include "winetest.h" #include "winetest.h"
...@@ -266,27 +261,17 @@ extract_test (struct wine_test *test, const char *dir, LPTSTR res_name) ...@@ -266,27 +261,17 @@ extract_test (struct wine_test *test, const char *dir, LPTSTR res_name)
value of WaitForSingleObject. value of WaitForSingleObject.
*/ */
static int 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; STARTUPINFO si;
PROCESS_INFORMATION pi; PROCESS_INFORMATION pi;
int fd, oldstdout = -1;
DWORD wait, status; DWORD wait, status;
GetStartupInfo (&si); GetStartupInfo (&si);
si.dwFlags = 0; si.dwFlags = STARTF_USESTDHANDLES;
si.hStdInput = GetStdHandle( STD_INPUT_HANDLE );
if (out) { si.hStdOutput = out_file ? out_file : GetStdHandle( STD_OUTPUT_HANDLE );
fd = open (out, O_WRONLY | O_CREAT, 0666); si.hStdError = GetStdHandle( STD_ERROR_HANDLE );
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);
}
if (!CreateProcessA (NULL, cmd, NULL, NULL, TRUE, CREATE_DEFAULT_ERROR_MODE, if (!CreateProcessA (NULL, cmd, NULL, NULL, TRUE, CREATE_DEFAULT_ERROR_MODE,
NULL, tempdir, &si, &pi)) { NULL, tempdir, &si, &pi)) {
...@@ -332,43 +317,49 @@ run_ex (char *cmd, const char *out, const char *tempdir, DWORD ms) ...@@ -332,43 +317,49 @@ run_ex (char *cmd, const char *out, const char *tempdir, DWORD ms)
CloseHandle (pi.hProcess); 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; return status;
} }
static void static void
get_subtests (const char *tempdir, struct wine_test *test, LPTSTR res_name) get_subtests (const char *tempdir, struct wine_test *test, LPTSTR res_name)
{ {
char *subname, *cmd; char *cmd;
FILE *subfile; HANDLE subfile;
size_t total; DWORD total;
char buffer[8192], *index; char buffer[8192], *index;
static const char header[] = "Valid test names:"; static const char header[] = "Valid test names:";
int allocated; int allocated;
char tmpdir[MAX_PATH], subname[MAX_PATH];
SECURITY_ATTRIBUTES sa;
test->subtest_count = 0; test->subtest_count = 0;
subname = tempnam (0, "sub"); if (!GetTempPathA( MAX_PATH, tmpdir ) ||
if (!subname) report (R_FATAL, "Can't name subtests file."); !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); extract_test (test, tempdir, res_name);
cmd = strmake (NULL, "%s --list", test->exename); cmd = strmake (NULL, "%s --list", test->exename);
run_ex (cmd, subname, tempdir, 5000); run_ex (cmd, subfile, tempdir, 5000);
free (cmd); free (cmd);
subfile = fopen (subname, "r"); SetFilePointer( subfile, 0, NULL, FILE_BEGIN );
if (!subfile) { ReadFile( subfile, buffer, sizeof(buffer), &total, NULL );
report (R_ERROR, "Can't open subtests output of %s: %d", CloseHandle( subfile );
test->name, errno);
goto quit;
}
total = fread (buffer, 1, sizeof buffer, subfile);
fclose (subfile);
if (sizeof buffer == total) { if (sizeof buffer == total) {
report (R_ERROR, "Subtest list of %s too big.", report (R_ERROR, "Subtest list of %s too big.",
test->name, sizeof buffer); test->name, sizeof buffer);
...@@ -400,21 +391,19 @@ get_subtests (const char *tempdir, struct wine_test *test, LPTSTR res_name) ...@@ -400,21 +391,19 @@ get_subtests (const char *tempdir, struct wine_test *test, LPTSTR res_name)
test->subtest_count * sizeof(char*)); test->subtest_count * sizeof(char*));
quit: quit:
if (remove (subname)) if (!DeleteFileA (subname))
report (R_WARNING, "Can't delete file '%s': %d", report (R_WARNING, "Can't delete file '%s': %u", subname, GetLastError());
subname, errno);
free (subname);
} }
static void 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; int status;
const char* file = get_test_source_file(test->name, subtest); const char* file = get_test_source_file(test->name, subtest);
char *cmd = strmake (NULL, "%s %s", test->exename, subtest); char *cmd = strmake (NULL, "%s %s", test->exename, subtest);
xprintf ("%s:%s start %s -\n", test->name, subtest, file); 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); free (cmd);
xprintf ("%s:%s done (%d)\n", test->name, subtest, status); xprintf ("%s:%s done (%d)\n", test->name, subtest, status);
} }
...@@ -459,43 +448,49 @@ static char * ...@@ -459,43 +448,49 @@ static char *
run_tests (char *logname) run_tests (char *logname)
{ {
int i; int i;
char *tempdir, *shorttempdir;
int logfile;
char *strres, *eol, *nextline; char *strres, *eol, *nextline;
DWORD strsize; DWORD strsize;
SECURITY_ATTRIBUTES sa;
char tmppath[MAX_PATH], tempdir[MAX_PATH+4];
SetErrorMode (SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX); SetErrorMode (SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
if (!GetTempPathA( MAX_PATH, tmppath ))
report (R_FATAL, "Can't name temporary dir (check %%TEMP%%).");
if (!logname) { if (!logname) {
logname = tempnam (0, "res"); static char tmpname[MAX_PATH];
if (!logname) report (R_FATAL, "Can't name logfile."); if (!GetTempFileNameA( tmppath, "res", 0, tmpname ))
report (R_FATAL, "Can't name logfile.");
logname = tmpname;
} }
report (R_OUT, logname); report (R_OUT, logname);
logfile = open (logname, O_WRONLY | O_CREAT | O_EXCL | O_APPEND, /* make handle inheritable */
0666); sa.nLength = sizeof(sa);
if (-1 == logfile) { sa.lpSecurityDescriptor = NULL;
if (EEXIST == errno) sa.bInheritHandle = TRUE;
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);
tempdir = tempnam (0, "wct"); logfile = CreateFileA( logname, GENERIC_READ|GENERIC_WRITE,
if (!tempdir) 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%%)."); report (R_FATAL, "Can't name temporary dir (check %%TEMP%%).");
shorttempdir = strdup (tempdir);
if (shorttempdir) { /* try stable path for ZoneAlarm */ /* try stable path for ZoneAlarm */
strstr (shorttempdir, "wct")[3] = 0; strcpy( tempdir, tmppath );
if (CreateDirectoryA (shorttempdir, NULL)) { strcat( tempdir, "wct" );
free (tempdir); if (!CreateDirectoryA( tempdir, NULL ))
tempdir = shorttempdir; {
} else free (shorttempdir); 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); report (R_DIR, tempdir);
xprintf ("Version 4\n"); xprintf ("Version 4\n");
...@@ -553,15 +548,15 @@ run_tests (char *logname) ...@@ -553,15 +548,15 @@ run_tests (char *logname)
for (j = 0; j < test->subtest_count; j++) { for (j = 0; j < test->subtest_count; j++) {
report (R_STEP, "Running: %s:%s", test->name, report (R_STEP, "Running: %s:%s", test->name,
test->subtests[j]); 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_DELTA, 0, "Running: Done");
report (R_STATUS, "Cleaning up"); report (R_STATUS, "Cleaning up");
close (1); CloseHandle( logfile );
logfile = 0;
remove_dir (tempdir); remove_dir (tempdir);
free (tempdir);
free (wine_tests); free (wine_tests);
return logname; return logname;
...@@ -666,7 +661,7 @@ int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrevInst, ...@@ -666,7 +661,7 @@ int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrevInst,
putenv (debug_yes) || putenv (debug_yes) ||
putenv (interactive_no) || putenv (interactive_no) ||
putenv (report_success_no))) putenv (report_success_no)))
report (R_FATAL, "Could not reset environment: %d", errno); report (R_FATAL, "Could not reset environment");
if (!tag) { if (!tag) {
if (!interactive) if (!interactive)
...@@ -684,9 +679,8 @@ int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrevInst, ...@@ -684,9 +679,8 @@ int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrevInst,
logname = run_tests (NULL); logname = run_tests (NULL);
if (build_id[0] && if (build_id[0] &&
report (R_ASK, MB_YESNO, "Do you want to submit the test results?") == IDYES) report (R_ASK, MB_YESNO, "Do you want to submit the test results?") == IDYES)
if (!send_file (logname) && remove (logname)) if (!send_file (logname) && !DeleteFileA(logname))
report (R_WARNING, "Can't remove logfile: %d.", errno); report (R_WARNING, "Can't remove logfile: %u", GetLastError());
free (logname);
} else run_tests (logname); } else run_tests (logname);
report (R_STATUS, "Finished"); report (R_STATUS, "Finished");
} }
......
...@@ -105,10 +105,11 @@ int ...@@ -105,10 +105,11 @@ int
send_file (const char *name) send_file (const char *name)
{ {
SOCKET s; SOCKET s;
FILE *f; HANDLE file;
#define BUFLEN 8192 #define BUFLEN 8192
char buffer[BUFLEN+1]; char buffer[BUFLEN+1];
size_t bytes_read, total, filesize; DWORD bytes_read, filesize;
size_t total;
char *str; char *str;
int ret; int ret;
...@@ -130,20 +131,21 @@ send_file (const char *name) ...@@ -130,20 +131,21 @@ send_file (const char *name)
s = open_http ("test.winehq.org"); s = open_http ("test.winehq.org");
if (s == INVALID_SOCKET) return 1; if (s == INVALID_SOCKET) return 1;
f = fopen (name, "rb"); file = CreateFileA( name, GENERIC_READ,
if (!f) { FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
report (R_WARNING, "Can't open file '%s': %d", name, errno); NULL, OPEN_EXISTING, 0, NULL );
if (file == INVALID_HANDLE_VALUE)
{
report (R_WARNING, "Can't open file '%s': %u", name, GetLastError());
goto abort1; goto abort1;
} }
fseek (f, 0, SEEK_END); filesize = GetFileSize( file, NULL );
filesize = ftell (f);
if (filesize > 1.5*1024*1024) { if (filesize > 1.5*1024*1024) {
report (R_WARNING, report (R_WARNING,
"File too big (%.1f MB > 1.5 MB); submitting partial report.", "File too big (%.1f MB > 1.5 MB); submitting partial report.",
filesize/1024.0/1024); filesize/1024.0/1024);
filesize = 1.5*1024*1024; filesize = 1.5*1024*1024;
} }
fseek (f, 0, SEEK_SET);
report (R_STATUS, "Sending header"); report (R_STATUS, "Sending header");
str = strmake (&total, body1, name); str = strmake (&total, body1, name);
...@@ -159,11 +161,8 @@ send_file (const char *name) ...@@ -159,11 +161,8 @@ send_file (const char *name)
report (R_STATUS, "Sending %u bytes of data", filesize); report (R_STATUS, "Sending %u bytes of data", filesize);
report (R_PROGRESS, 2, filesize); report (R_PROGRESS, 2, filesize);
total = 0; total = 0;
while (total < filesize && (bytes_read = fread (buffer, 1, BUFLEN/2, f))) { while (total < filesize && ReadFile( file, buffer, BUFLEN/2, &bytes_read, NULL )) {
if ((signed)bytes_read == -1) { if (!bytes_read) break;
report (R_WARNING, "Error reading log file: %d", errno);
goto abort2;
}
total += bytes_read; total += bytes_read;
if (total > filesize) bytes_read -= total - filesize; if (total > filesize) bytes_read -= total - filesize;
if (send_buf (s, buffer, bytes_read)) { if (send_buf (s, buffer, bytes_read)) {
...@@ -173,7 +172,7 @@ send_file (const char *name) ...@@ -173,7 +172,7 @@ send_file (const char *name)
} }
report (R_DELTA, bytes_read, "Network transfer: In progress"); report (R_DELTA, bytes_read, "Network transfer: In progress");
} }
fclose (f); CloseHandle( file );
if (send_buf (s, body2, sizeof body2 - 1)) { if (send_buf (s, body2, sizeof body2 - 1)) {
report (R_WARNING, "Error sending trailer: %d, %d", report (R_WARNING, "Error sending trailer: %d, %d",
...@@ -216,7 +215,7 @@ send_file (const char *name) ...@@ -216,7 +215,7 @@ send_file (const char *name)
return ret; return ret;
abort2: abort2:
fclose (f); CloseHandle( file );
abort1: abort1:
close_http (s); close_http (s);
return 1; return 1;
......
...@@ -19,11 +19,14 @@ ...@@ -19,11 +19,14 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#include <unistd.h> #include <stdarg.h>
#include <errno.h> #include <windef.h>
#include <winbase.h>
#include "winetest.h" #include "winetest.h"
HANDLE logfile = 0;
void *xmalloc (size_t len) void *xmalloc (size_t len)
{ {
void *p = malloc (len); void *p = malloc (len);
...@@ -95,16 +98,16 @@ void xprintf (const char *fmt, ...) ...@@ -95,16 +98,16 @@ void xprintf (const char *fmt, ...)
{ {
va_list ap; va_list ap;
size_t size; size_t size;
ssize_t written; DWORD written;
char *buffer, *head; char *buffer, *head;
va_start (ap, fmt); va_start (ap, fmt);
buffer = vstrfmtmake (&size, fmt, ap); buffer = vstrfmtmake (&size, fmt, ap);
head = buffer; head = buffer;
va_end (ap); va_end (ap);
while ((written = write (1, head, size)) != size) { while (size) {
if (written == -1) if (!WriteFile( logfile, head, size, &written, NULL ))
report (R_FATAL, "Can't write logs: %d", errno); report (R_FATAL, "Can't write logs: %u", GetLastError());
head += written; head += written;
size -= written; size -= written;
} }
......
...@@ -39,6 +39,8 @@ const char *findbadtagchar (const char *tag); ...@@ -39,6 +39,8 @@ const char *findbadtagchar (const char *tag);
int send_file (const char *name); int send_file (const char *name);
extern HANDLE logfile;
/* GUI definitions */ /* GUI definitions */
#include <windows.h> #include <windows.h>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment