Author: cfinck
Date: Sun Jul 6 15:49:03 2008
New Revision: 34343
URL:
http://svn.reactos.org/svn/reactos?rev=34343&view=rev
Log:
Remixed our Win32 version of ccache:
- Mix in parts of a patch by Brant Young, which itself is based on an old patch by Filip
(see
http://code.google.com/p/ccache-win32/wiki/WhyNativeWin32Ccache)
- Change bInheritHandles for the CreateProcess call in failed() to TRUE, so that the
compilation of the RC files works (they are preprocessed with gcc and piped to a file)
- Add a safe version of mkstemp based on glibc sources, so that we don't run into race
condition problems
- Use CSIDL_LOCAL_APPDATA as the default base path for the ccache directory, not
CSIDL_PROFILE
Added:
trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/mkstemp.c (with props)
Modified:
trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/Makefile
trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/ccache-win32.vcproj
trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/ccache.c
trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/ccache.h
trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/execute.c
trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/unify.c
trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/util.c
Modified: trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/Makefile
URL:
http://svn.reactos.org/svn/reactos/trunk/tools/RosBE/RosBE-Windows/Tools/cc…
==============================================================================
--- trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/Makefile [iso-8859-1] (original)
+++ trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/Makefile [iso-8859-1] Sun Jul 6
15:49:03 2008
@@ -9,7 +9,7 @@
CC=gcc
CFLAGS := -Wall -pedantic -D_WIN32_WINNT=0x0500 -D_WIN32_IE=0x0400 -O2
LFLAGS := -s
-SRCS := args.c ccache.c cleanup.c execute.c getopt.c hash.c mdfour.c snprintf.c stats.c
unify.c util.c win32-dirent.c
+SRCS := args.c ccache.c cleanup.c execute.c getopt.c hash.c mdfour.c mkstemp.c snprintf.c
stats.c unify.c util.c win32-dirent.c
OBJS := $(SRCS:.c=.o)
$(TARGET): $(OBJS)
Modified: trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/ccache-win32.vcproj
URL:
http://svn.reactos.org/svn/reactos/trunk/tools/RosBE/RosBE-Windows/Tools/cc…
==============================================================================
--- trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/ccache-win32.vcproj [iso-8859-1]
(original)
+++ trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/ccache-win32.vcproj [iso-8859-1] Sun
Jul 6 15:49:03 2008
@@ -112,7 +112,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
WarningLevel="4"
@@ -197,6 +197,10 @@
</File>
<File
+ RelativePath=".\mkstemp.c"
+ >
+ </File>
+ <File
RelativePath=".\snprintf.c"
</File>
Modified: trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/ccache.c
URL:
http://svn.reactos.org/svn/reactos/trunk/tools/RosBE/RosBE-Windows/Tools/cc…
==============================================================================
--- trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/ccache.c [iso-8859-1] (original)
+++ trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/ccache.c [iso-8859-1] Sun Jul 6
15:49:03 2008
@@ -165,7 +165,7 @@
si.cb = sizeof(STARTUPINFOA);
- if(!CreateProcessA(orig_args->argv[0], merged, NULL, NULL, FALSE, 0, NULL, NULL,
&si, &pi))
+ if(!CreateProcessA(orig_args->argv[0], merged, NULL, NULL, TRUE, 0, NULL, NULL,
&si, &pi))
{
perror(orig_args->argv[0]);
exit(1);
Modified: trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/ccache.h
URL:
http://svn.reactos.org/svn/reactos/trunk/tools/RosBE/RosBE-Windows/Tools/cc…
==============================================================================
--- trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/ccache.h [iso-8859-1] (original)
+++ trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/ccache.h [iso-8859-1] Sun Jul 6
15:49:03 2008
@@ -42,8 +42,7 @@
#define mkdir(dirname, access) _mkdir(dirname)
#define x_realpath(a) strdup(a)
#define link(filename, linkname) CreateHardLinkA(linkname, filename, NULL)
- #define PROT_READ 0x0001
- #define MAP_PRIVATE 0x02
+ #define lstat(x, y) stat(x, y)
#ifdef _MSC_VER
typedef unsigned int mode_t;
@@ -55,7 +54,8 @@
#ifndef S_ISDIR
#define S_ISDIR(m) (((m) & _S_IFDIR) == _S_IFDIR)
#endif
- #define lstat(x, y) stat(x, y)
+
+ int mkstemp (char *template);
#else
#include <unistd.h>
#include <sys/wait.h>
Modified: trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/execute.c
URL:
http://svn.reactos.org/svn/reactos/trunk/tools/RosBE/RosBE-Windows/Tools/cc…
==============================================================================
--- trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/execute.c [iso-8859-1] (original)
+++ trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/execute.c [iso-8859-1] Sun Jul 6
15:49:03 2008
@@ -18,16 +18,90 @@
#include "ccache.h"
+#ifdef _WIN32
+static char *argvtos(char **argv)
+{
+ int i, len;
+ char *ptr, *str;
+
+ for (i = 0, len = 0; argv[i]; i++) {
+ len += strlen(argv[i]) + 3;
+ }
+
+ str = ptr = (char *)malloc(len + 1);
+ if (str == NULL)
+ return NULL;
+
+ for (i = 0; argv[i]; i++) {
+ len = strlen(argv[i]);
+ *ptr++ = '"';
+ memcpy(ptr, argv[i], len);
+ ptr += len;
+ *ptr++ = '"';
+ *ptr++ = ' ';
+ }
+ *ptr = 0;
+
+ return str;
+}
+#endif
/*
execute a compiler backend, capturing all output to the given paths
the full path to the compiler to run is in argv[0]
*/
-int execute(char **argv,
+int execute(char **argv,
const char *path_stdout,
const char *path_stderr)
{
-#ifndef _WIN32
+#ifdef _WIN32
+ PROCESS_INFORMATION pinfo;
+ STARTUPINFOA sinfo;
+ BOOL ret;
+ DWORD exitcode;
+ char *args;
+ HANDLE fd_out, fd_err;
+ SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE};
+
+ fd_out = CreateFileA(path_stdout, GENERIC_WRITE, 0, &sa, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);
+ if (fd_out == INVALID_HANDLE_VALUE) {
+ return STATUS_NOCACHE;
+ }
+
+ fd_err = CreateFileA(path_stderr, GENERIC_WRITE, 0, &sa, CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL, NULL);
+ if (fd_err == INVALID_HANDLE_VALUE) {
+ return STATUS_NOCACHE;
+ }
+
+ ZeroMemory(&pinfo, sizeof(PROCESS_INFORMATION));
+ ZeroMemory(&sinfo, sizeof(STARTUPINFOA));
+
+ sinfo.cb = sizeof(STARTUPINFOA);
+ sinfo.hStdError = fd_err;
+ sinfo.hStdOutput = fd_out;
+ sinfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
+ sinfo.dwFlags |= STARTF_USESTDHANDLES;
+
+ args = argvtos(argv);
+
+ ret = CreateProcessA(argv[0], args, NULL, NULL, TRUE, 0, NULL, NULL,
+ &sinfo, &pinfo);
+
+ free(args);
+ CloseHandle(fd_out);
+ CloseHandle(fd_err);
+
+ if (ret == 0)
+ return -1;
+
+ WaitForSingleObject(pinfo.hProcess, INFINITE);
+ GetExitCodeProcess(pinfo.hProcess, &exitcode);
+ CloseHandle(pinfo.hProcess);
+ CloseHandle(pinfo.hThread);
+
+ return exitcode;
+#else
pid_t pid;
int status;
@@ -65,46 +139,6 @@
}
return WEXITSTATUS(status);
-#else /* Should be portable */
- int status = -2;
- int fd, std_od = -1, std_ed = -1;
-
- unlink(path_stdout);
- std_od = _dup(1);
- fd = _open(path_stdout, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL|O_BINARY, 0666);
- if (fd == -1) {
- status = STATUS_NOCACHE;
- cc_log("stdout error: failed to open %s\n", path_stdout);
- goto out;
- }
- /*std_od = */ _dup2(fd, 1);
- _close(fd);
-
- unlink(path_stderr);
- fd = _open(path_stderr, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL|O_BINARY, 0666);
- std_ed = _dup(2);
- if (fd == -1) {
- status = STATUS_NOCACHE;
- cc_log("stderr error: failed to open %s\n", path_stderr);
- goto out;
- }
- /*std_ed =*/ _dup2(fd, 2);
- _close(fd);
-
- /* Spawn process (_exec* familly doesn't return) */
- status = _spawnv(_P_WAIT, argv[0], (const char* const*)argv);
-
- out:
- cc_log("%s:\n stdout -> %s\n stderr -> %s\n process status=%i\n",
- argv[0], path_stdout, path_stderr, status);
- if (status == -1) cc_log("Error %i: %s\n", errno, strerror(errno));
-
- /* Restore descriptors */
- if (std_od != -1) _dup2(std_od, 1);
- if (std_ed != -1) _dup2(std_ed, 2);
- _flushall();
-
- return (status>0);
#endif
}
@@ -158,11 +192,24 @@
*/
char *find_executable(const char *name, const char *exclude_name)
{
+#ifdef _WIN32
+ DWORD ret;
+ char namebuf[MAX_PATH];
+
+ UNREFERENCED_PARAMETER(exclude_name);
+
+ ret = SearchPathA(getenv("CCACHE_PATH"), name, ".exe",
sizeof(namebuf), namebuf, NULL);
+ if (ret != 0) {
+ return x_strdup(namebuf);
+ }
+
+ return NULL;
+#else
char *path;
char *tok;
- const char *sep = ":";
-
- if (*name == PATH_SEP_CHAR) {
+ struct stat st1, st2;
+
+ if (*name == '/') {
return x_strdup(name);
}
@@ -177,37 +224,40 @@
path = x_strdup(path);
- /* Determine path separator */
- if (strchr(path, ';')) sep = ";";
-
/* search the path looking for the first compiler of the right name
that isn't us */
- for (tok=strtok(path, sep); tok; tok = strtok(NULL, sep)) {
+ for (tok=strtok(path,":"); tok; tok = strtok(NULL, ":")) {
char *fname;
- x_asprintf(&fname, "%s"PATH_SEP"%s", tok, name);
+ x_asprintf(&fname, "%s/%s", tok, name);
/* look for a normal executable file */
-
-
- if (is_exec_file(fname, exclude_name) > 0)
- {
+ if (access(fname, X_OK) == 0 &&
+ lstat(fname, &st1) == 0 &&
+ stat(fname, &st2) == 0 &&
+ S_ISREG(st2.st_mode)) {
+ /* if its a symlink then ensure it doesn't
+ point at something called exclude_name */
+ if (S_ISLNK(st1.st_mode)) {
+ char *buf = x_realpath(fname);
+ if (buf) {
+ char *p = str_basename(buf);
+ if (strcmp(p, exclude_name) == 0) {
+ /* its a link to "ccache" ! */
+ free(p);
+ free(buf);
+ continue;
+ }
+ free(buf);
+ free(p);
+ }
+ }
+
+ /* found it! */
free(path);
return fname;
}
free(fname);
-
- /* found it! */
-#ifdef _WIN32 /* Add .exe under win32 */
- x_asprintf(&fname, "%s"PATH_SEP"%s.exe", tok, name);
-
- /* look for a normal executable file */
- if (is_exec_file(fname, exclude_name) > 0)
- {
- free(path);
- return fname;
- }
- free(fname);
-#endif
- }
-free(path);
+ }
+
return NULL;
-}
+#endif
+}
Added: trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/mkstemp.c
URL:
http://svn.reactos.org/svn/reactos/trunk/tools/RosBE/RosBE-Windows/Tools/cc…
==============================================================================
--- trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/mkstemp.c (added)
+++ trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/mkstemp.c [iso-8859-1] Sun Jul 6
15:49:03 2008
@@ -1,0 +1,84 @@
+#ifdef _WIN32
+/* Copyright (C) 1998, 1999, 2001, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Ported for ccache-win32 by Colin Finck <colin(a)reactos.org>
+ Source:
http://sources.redhat.com/cgi-bin/cvsweb.cgi/libc/sysdeps/posix/tempname.c?…
+*/
+
+#include "ccache.h"
+
+/* These are the characters used in temporary filenames. */
+static const char letters[] =
+"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+
+/* Generate a unique temporary file name from TEMPLATE.
+ The last six characters of TEMPLATE must be "XXXXXX";
+ they are replaced with a string that makes the filename unique.
+ Then open the file and return a fd. */
+int
+mkstemp (char *template)
+{
+ char *XXXXXX;
+ time_t value;
+ unsigned int count;
+ int fd;
+
+ /* A lower bound on the number of temporary files to attempt to
+ generate. The maximum total number of temporary file names that
+ can exist for a given template is 62**6. It should never be
+ necessary to try all these combinations. Instead if a reasonable
+ number of names is tried (we define reasonable as 62**3) fail to
+ give the system administrator the chance to remove the problems. */
+ unsigned int attempts = (62 * 62 * 62);
+
+ /* This is where the Xs start. */
+ XXXXXX = &template[ strlen(template) - 6 ];
+
+ /* Get some more or less random data. */
+ value = time(NULL) ^ _getpid();
+
+ for (count = 0; count < attempts; value += 7777, ++count)
+ {
+ time_t v = value;
+
+ /* Fill in the random bits. */
+ XXXXXX[0] = letters[v % 62];
+ v /= 62;
+ XXXXXX[1] = letters[v % 62];
+ v /= 62;
+ XXXXXX[2] = letters[v % 62];
+ v /= 62;
+ XXXXXX[3] = letters[v % 62];
+ v /= 62;
+ XXXXXX[4] = letters[v % 62];
+ v /= 62;
+ XXXXXX[5] = letters[v % 62];
+
+ fd = _open (template, O_RDWR | O_BINARY | O_CREAT | O_EXCL, 0600);
+
+ if (fd >= 0)
+ return fd;
+ else if (errno != EEXIST)
+ return -1;
+ }
+
+ /* We got out of the loop because we ran out of combinations to try. */
+ return -1;
+}
+#endif
Propchange: trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/mkstemp.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/unify.c
URL:
http://svn.reactos.org/svn/reactos/trunk/tools/RosBE/RosBE-Windows/Tools/cc…
==============================================================================
--- trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/unify.c [iso-8859-1] (original)
+++ trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/unify.c [iso-8859-1] Sun Jul 6
15:49:03 2008
@@ -238,10 +238,40 @@
*/
int unify_hash(const char *fname)
{
+#ifdef _WIN32
+ HANDLE file;
+ HANDLE section;
+ MEMORY_BASIC_INFORMATION minfo;
+ char *map;
+
+ file = CreateFileA(fname, GENERIC_READ, FILE_SHARE_READ, NULL,
+ OPEN_EXISTING, 0, NULL);
+ if (file == INVALID_HANDLE_VALUE)
+ return -1;
+
+ section = CreateFileMappingA(file, NULL, PAGE_READONLY, 0, 0, NULL);
+ CloseHandle(file);
+ if (section == NULL)
+ return -1;
+
+ map = MapViewOfFile(section, FILE_MAP_READ, 0, 0, 0);
+ CloseHandle(section);
+ if (map == NULL)
+ return -1;
+
+ if (VirtualQuery(map, &minfo, sizeof(minfo)) != sizeof(minfo)) {
+ UnmapViewOfFile(map);
+ return -1;
+ }
+
+ /* pass it through the unifier */
+ unify((unsigned char *)map, minfo.RegionSize);
+
+ UnmapViewOfFile(map);
+#else
int fd;
struct stat st;
char *map;
- HANDLE view;
fd = open(fname, O_RDONLY|O_BINARY);
if (fd == -1 || fstat(fd, &st) != 0) {
@@ -250,33 +280,6 @@
return -1;
}
-#ifdef _WIN32
- /* win32 equivalent of mmap is ViewMapOfFile, but malloc+read
- may be better */
- view = CreateFileMapping((HANDLE)_get_osfhandle(fd), NULL,
- PAGE_READONLY|SEC_COMMIT, 0,0 , NULL);
- if (NULL == view) {
- cc_log("Failed to create file mapping %s: %s\n",
- fname, strerror(errno));
- stats_update(STATS_PREPROCESSOR);
- return -1;
- }
-
- map = MapViewOfFile(view, FILE_MAP_READ, 0, 0, st.st_size);
- if (NULL == map) {
- cc_log("Failed to map view of file %s: %s\n",
- fname, strerror(errno));
- stats_update(STATS_PREPROCESSOR);
- return -1;
- }
-
- /* pass it through the unifier */
- unify((unsigned char *)map, st.st_size);
-
- UnmapViewOfFile(map);
- CloseHandle(view);
- close(fd);
-#else
/* we use mmap() to make it easy to handle arbitrarily long
lines in preprocessor output. I have seen lines of over
100k in length, so this is well worth it */
@@ -292,6 +295,7 @@
munmap(map, st.st_size);
#endif
+
return 0;
}
Modified: trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/util.c
URL:
http://svn.reactos.org/svn/reactos/trunk/tools/RosBE/RosBE-Windows/Tools/cc…
==============================================================================
--- trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/util.c [iso-8859-1] (original)
+++ trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/util.c [iso-8859-1] Sun Jul 6
15:49:03 2008
@@ -20,19 +20,6 @@
static FILE *logfile;
-#ifdef _WIN32
-#define fchmod(a, b)
-#endif
-
-#ifndef HAVE_MKSTEMP
-/* cheap and nasty mkstemp replacement */
-int mkstemp(char *template)
-{
- _mktemp(template);
- return open(template, O_RDWR|O_CREAT|O_EXCL|O_BINARY, 0600);
-}
-#endif
-
/* log a message to the CCACHE_LOGFILE location */
void cc_log(const char *format, ...)
{
@@ -79,7 +66,10 @@
char buf[10240];
int n;
char *tmp_name;
+
+#ifndef _WIN32
mode_t mask;
+#endif
x_asprintf(&tmp_name, "%s.XXXXXX", dest);
@@ -109,9 +99,11 @@
close(fd1);
/* get perms right on the tmp file */
+#ifndef _WIN32
mask = umask(0);
fchmod(fd2, 0666 & ~mask);
umask(mask);
+#endif
/* the close can fail on NFS if out of space */
if (close(fd2) == -1) {
@@ -483,8 +475,8 @@
#ifdef _WIN32
static char szPath[MAX_PATH];
- /* "Documents and Settings\user\Application Data" is CSIDL_APPDATA */
- if(SHGetSpecialFolderPathA(NULL, szPath, CSIDL_PROFILE, FALSE))
+ /* "Documents and Settings\user\Application Data" is CSIDL_LOCAL_APPDATA
*/
+ if(SHGetSpecialFolderPathA(NULL, szPath, CSIDL_LOCAL_APPDATA, FALSE))
{
return szPath;
}