mirror of
https://github.com/reactos/RosBE.git
synced 2024-11-27 13:20:23 +00:00
apply patch from Christophe Gisquet <christophe dot gisquet at free.fr> with some modifications
-don't use access with X_OK, it won't work on Vista http://lists.samba.org/archive/ccache/2006q3/000242.html svn path=/trunk/tools/RosBE/; revision=684
This commit is contained in:
parent
127da9910c
commit
60196c1e4c
@ -38,7 +38,7 @@ ARGS *args_init(int init_argc, char **init_args)
|
||||
void args_add(ARGS *args, const char *s)
|
||||
{
|
||||
args->argv = (char**)x_realloc(args->argv, (args->argc + 2) * sizeof(char *));
|
||||
args->argv[args->argc] = x_strdup(s);
|
||||
args->argv[args->argc] = x_quote_strdup(s);
|
||||
args->argc++;
|
||||
args->argv[args->argc] = NULL;
|
||||
}
|
||||
@ -69,7 +69,7 @@ void args_add_prefix(ARGS *args, const char *s)
|
||||
args->argv = (char**)x_realloc(args->argv, (args->argc + 2) * sizeof(char *));
|
||||
memmove(&args->argv[1], &args->argv[0],
|
||||
(args->argc+1) * sizeof(args->argv[0]));
|
||||
args->argv[0] = x_strdup(s);
|
||||
args->argv[0] = x_quote_strdup(s);
|
||||
args->argc++;
|
||||
}
|
||||
|
||||
|
@ -87,6 +87,38 @@ static struct {
|
||||
{"ii", "ii"},
|
||||
{NULL, NULL}};
|
||||
|
||||
static int first_is_meh(const char* first)
|
||||
{
|
||||
const char* exe = strrchr(first, PATH_SEP_CHAR);
|
||||
const size_t len = strlen(MYNAME);
|
||||
|
||||
if (exe) exe++;
|
||||
else exe=first;
|
||||
return (strlen(exe) >= len && strncmp(exe, MYNAME, len) == 0 &&
|
||||
(exe[len]==0 || strcmp(exe+len, ".exe")==0) );
|
||||
}
|
||||
|
||||
char *build_command(char **argv)
|
||||
{
|
||||
char *cmd;
|
||||
int i, length = 0;
|
||||
|
||||
for(i = 0; argv[i]; i++) {
|
||||
length++;
|
||||
length += (int)strlen(argv[i]);
|
||||
}
|
||||
|
||||
cmd = (char *)malloc(length);
|
||||
strcpy(cmd, argv[0]);
|
||||
|
||||
for(i = 1; argv[i]; i++) {
|
||||
strcat(cmd, " ");
|
||||
strcat(cmd, argv[i]);
|
||||
}
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
||||
/*
|
||||
something went badly wrong - just execute the real compiler
|
||||
*/
|
||||
@ -155,12 +187,15 @@ static void to_cache(ARGS *args)
|
||||
{
|
||||
char *path_stderr;
|
||||
char *tmp_stdout, *tmp_stderr, *tmp_hashname;
|
||||
struct stat st1, st2;
|
||||
struct stat st;
|
||||
int status;
|
||||
off_t size = 0;
|
||||
|
||||
x_asprintf(&tmp_stdout, "%s/tmp.stdout.%s", temp_dir, tmp_string());
|
||||
x_asprintf(&tmp_stderr, "%s/tmp.stderr.%s", temp_dir, tmp_string());
|
||||
x_asprintf(&tmp_hashname, "%s/tmp.hash.%s.o", temp_dir, tmp_string());
|
||||
/* No quoting, unique arguments */
|
||||
x_asprintf(&tmp_stdout, "%s"PATH_SEP"tmp.stdout.%s", temp_dir, tmp_string());
|
||||
x_asprintf(&tmp_stderr, "%s"PATH_SEP"tmp.stderr.%s", temp_dir, tmp_string());
|
||||
/* Must be quoted as it will belong to a command-line */
|
||||
x_asprintf(&tmp_hashname, "%s"PATH_SEP"tmp.hash.%s.o", temp_dir, tmp_string());
|
||||
|
||||
args_add(args, "-o");
|
||||
args_add(args, tmp_hashname);
|
||||
@ -181,7 +216,7 @@ static void to_cache(ARGS *args)
|
||||
status = execute(args->argv, tmp_stdout, tmp_stderr);
|
||||
args_pop(args, 3);
|
||||
|
||||
if (stat(tmp_stdout, &st1) != 0 || st1.st_size != 0) {
|
||||
if (stat(tmp_stdout, &st) != 0 || st.st_size != 0) {
|
||||
cc_log("compiler produced stdout for %s\n", output_file);
|
||||
stats_update(STATS_STDOUT);
|
||||
unlink(tmp_stdout);
|
||||
@ -198,7 +233,7 @@ static void to_cache(ARGS *args)
|
||||
|
||||
fd = open(tmp_stderr, O_RDONLY | O_BINARY);
|
||||
if (fd != -1) {
|
||||
if (strcmp(output_file, "/dev/null") == 0 ||
|
||||
if (strcmp(output_file, DEV_NULL) == 0 ||
|
||||
rename(tmp_hashname, output_file) == 0 || errno == ENOENT) {
|
||||
if (cpp_stderr) {
|
||||
/* we might have some stderr from cpp */
|
||||
@ -211,8 +246,7 @@ static void to_cache(ARGS *args)
|
||||
}
|
||||
}
|
||||
|
||||
/* we can use a quick method of
|
||||
getting the failed output */
|
||||
/* we can use a quick method of getting the failed output */
|
||||
copy_fd(fd, 2);
|
||||
close(fd);
|
||||
unlink(tmp_stderr);
|
||||
@ -228,19 +262,32 @@ static void to_cache(ARGS *args)
|
||||
failed();
|
||||
}
|
||||
|
||||
x_asprintf(&path_stderr, "%s.stderr", hashname);
|
||||
if (stat(tmp_hashname, &st) != 0 || rename(tmp_hashname, hashname) != 0) {
|
||||
cc_log("failed to rename output: %s\n"
|
||||
" '%s'\n"
|
||||
" -> '%s': \n",
|
||||
strerror(errno), tmp_hashname, hashname);
|
||||
stats_update(STATS_ERROR);
|
||||
failed();
|
||||
}
|
||||
cc_log("Moved '%s' to '%s'\n", tmp_hashname, hashname);
|
||||
size += file_size(&st);
|
||||
|
||||
if (stat(tmp_stderr, &st1) != 0 ||
|
||||
stat(tmp_hashname, &st2) != 0 ||
|
||||
rename(tmp_hashname, hashname) != 0 ||
|
||||
rename(tmp_stderr, path_stderr) != 0) {
|
||||
cc_log("failed to rename tmp files - %s\n", strerror(errno));
|
||||
x_asprintf(&path_stderr, "%s.stderr", hashname);
|
||||
if (stat(tmp_stderr, &st) != 0 || rename(tmp_stderr, path_stderr) != 0) {
|
||||
cc_log("failed to rename stderr: %s\n"
|
||||
" '%s'\n"
|
||||
" -> '%s': \n",
|
||||
strerror(errno), tmp_stderr, path_stderr);
|
||||
stats_update(STATS_ERROR);
|
||||
failed();
|
||||
}
|
||||
|
||||
cc_log("Moved '%s' to '%s'\n", tmp_stderr, path_stderr);
|
||||
size += file_size(&st);
|
||||
|
||||
cc_log("Placed %s into cache\n", output_file);
|
||||
stats_tocache(file_size(&st1) + file_size(&st2));
|
||||
stats_tocache(size);
|
||||
|
||||
free(tmp_hashname);
|
||||
free(tmp_stderr);
|
||||
@ -331,8 +378,8 @@ static void find_hash(ARGS *args)
|
||||
hash_string(str_basename(args->argv[0]));
|
||||
}
|
||||
|
||||
hash_int(st.st_size);
|
||||
hash_int(st.st_mtime);
|
||||
hash_int((int)st.st_size);
|
||||
hash_int((int)st.st_mtime);
|
||||
|
||||
/* possibly hash the current working directory */
|
||||
if (getenv("CCACHE_HASHDIR")) {
|
||||
@ -356,11 +403,11 @@ static void find_hash(ARGS *args)
|
||||
input_base[10] = 0;
|
||||
}
|
||||
|
||||
/* now the run */
|
||||
x_asprintf(&path_stdout, "%s/%s.tmp.%s.%s", temp_dir,
|
||||
input_base, tmp_string(),
|
||||
i_extension);
|
||||
x_asprintf(&path_stderr, "%s/tmp.cpp_stderr.%s", temp_dir, tmp_string());
|
||||
/* now the run - path_std* are unique args => no quoting */
|
||||
x_asprintf(&path_stdout, "%s"PATH_SEP"%s.tmp.%s.%s", temp_dir,
|
||||
input_base, tmp_string(),
|
||||
i_extension);
|
||||
x_asprintf(&path_stderr, "%s"PATH_SEP"tmp.cpp_stderr.%s", temp_dir, tmp_string());
|
||||
|
||||
if (!direct_i_file) {
|
||||
/* run cpp on the input file to obtain the .i */
|
||||
@ -423,17 +470,18 @@ static void find_hash(ARGS *args)
|
||||
|
||||
/* we use a N level subdir for the cache path to reduce the impact
|
||||
on filesystems which are slow for large directories
|
||||
Quoting not necessary because unique argument, or not used yet.
|
||||
*/
|
||||
s = hash_result();
|
||||
x_asprintf(&hash_dir, "%s/%c", cache_dir, s[0]);
|
||||
x_asprintf(&stats_file, "%s/stats", hash_dir);
|
||||
x_asprintf(&hash_dir, "%s"PATH_SEP"%c", cache_dir, s[0]);
|
||||
x_asprintf(&stats_file, "%s"PATH_SEP"stats", hash_dir);
|
||||
for (i=1; i<nlevels; i++) {
|
||||
char *p;
|
||||
if (create_dir(hash_dir) != 0) {
|
||||
cc_log("failed to create %s\n", hash_dir);
|
||||
failed();
|
||||
}
|
||||
x_asprintf(&p, "%s/%c", hash_dir, s[i]);
|
||||
x_asprintf(&p, "%s"PATH_SEP"%c", hash_dir, s[i]);
|
||||
free(hash_dir);
|
||||
hash_dir = p;
|
||||
}
|
||||
@ -441,7 +489,7 @@ static void find_hash(ARGS *args)
|
||||
cc_log("failed to create %s\n", hash_dir);
|
||||
failed();
|
||||
}
|
||||
x_asprintf(&hashname, "%s/%s", hash_dir, s+nlevels);
|
||||
x_asprintf(&hashname, "%s"PATH_SEP"%s", hash_dir, s+nlevels);
|
||||
free(hash_dir);
|
||||
}
|
||||
|
||||
@ -483,7 +531,7 @@ static void from_cache(int first)
|
||||
|
||||
utime(stderr_file, NULL);
|
||||
|
||||
if (strcmp(output_file, "/dev/null") == 0) {
|
||||
if (strcmp(output_file, DEV_NULL) == 0) {
|
||||
ret = 0;
|
||||
} else {
|
||||
unlink(output_file);
|
||||
@ -562,10 +610,10 @@ static void find_compiler(int argc, char **argv)
|
||||
base = str_basename(argv[0]);
|
||||
|
||||
/* we might be being invoked like "ccache gcc -c foo.c" */
|
||||
if (strcmp(base, MYNAME) == 0) {
|
||||
if (first_is_meh(argv[0])) {
|
||||
args_remove_first(orig_args);
|
||||
free(base);
|
||||
if (strchr(argv[1],'/')) {
|
||||
if (strchr(argv[1],PATH_SEP_CHAR)) {
|
||||
/* a full path was given */
|
||||
return;
|
||||
}
|
||||
@ -801,7 +849,7 @@ static void process_args(int argc, char **argv)
|
||||
if (!output_file) {
|
||||
char *p;
|
||||
output_file = x_strdup(input_file);
|
||||
if ((p = strrchr(output_file, '/'))) {
|
||||
if ((p = strrchr(output_file, PATH_SEP_CHAR))) {
|
||||
output_file = p+1;
|
||||
}
|
||||
p = strrchr(output_file, '.');
|
||||
@ -815,7 +863,7 @@ static void process_args(int argc, char **argv)
|
||||
}
|
||||
|
||||
/* cope with -o /dev/null */
|
||||
if (strcmp(output_file,"/dev/null") != 0 && stat(output_file, &st) == 0 && !S_ISREG(st.st_mode)) {
|
||||
if (strcmp(output_file, DEV_NULL) != 0 && stat(output_file, &st) == 0 && !S_ISREG(st.st_mode)) {
|
||||
cc_log("Not a regular file %s\n", output_file);
|
||||
stats_update(STATS_DEVICE);
|
||||
failed();
|
||||
@ -934,14 +982,15 @@ static int ccache_main(int argc, char *argv[])
|
||||
|
||||
case 'F':
|
||||
v = atoi(optarg);
|
||||
stats_set_limits(v, -1);
|
||||
stats_set_limits((long)v, -1);
|
||||
printf("Set cache file limit to %u\n", (unsigned)v);
|
||||
break;
|
||||
|
||||
case 'M':
|
||||
v = value_units(optarg);
|
||||
stats_set_limits(-1, v);
|
||||
stats_set_limits(-1, (long) v);
|
||||
printf("Set cache size limit to %uk\n", (unsigned)v);
|
||||
printf("not implemented");
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -983,7 +1032,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
cache_dir = getenv("CCACHE_DIR");
|
||||
if (!cache_dir) {
|
||||
x_asprintf(&cache_dir, "%s/.ccache", get_home_directory());
|
||||
x_asprintf(&cache_dir, "%s"PATH_SEP".ccache", get_home_directory());
|
||||
}
|
||||
|
||||
temp_dir = getenv("CCACHE_TEMPDIR");
|
||||
@ -1009,8 +1058,8 @@ int main(int argc, char *argv[])
|
||||
|
||||
|
||||
/* check if we are being invoked as "ccache" */
|
||||
if (strlen(argv[0]) >= strlen(MYNAME) &&
|
||||
strcmp(argv[0] + strlen(argv[0]) - strlen(MYNAME), MYNAME) == 0) {
|
||||
if (first_is_meh(argv[0]))
|
||||
{
|
||||
if (argc < 2) {
|
||||
usage();
|
||||
exit(1);
|
||||
|
@ -1,23 +1,38 @@
|
||||
#define CCACHE_VERSION "2.4"
|
||||
|
||||
#include "config.h"
|
||||
#define USUAL_PATH_SEP_CHAR '/'
|
||||
#define USUAL_PATH_SEP "/"
|
||||
#define WIN32_PATH_SEP_CHAR '\\'
|
||||
#define WIN32_PATH_SEP "\\"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/stat.h>
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include <sys/locking.h>
|
||||
#define PATH_SEP WIN32_PATH_SEP
|
||||
#define PATH_SEP_CHAR WIN32_PATH_SEP_CHAR
|
||||
#define DEV_NULL "NUL"
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/file.h>
|
||||
#include <utime.h>
|
||||
#include <dirent.h>
|
||||
#define PATH_SEP USUAL_PATH_SEP
|
||||
#define PATH_SEP_CHAR USUAL_PATH_SEP_CHAR
|
||||
#define DEV_NULL "/dev/null"
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <utime.h>
|
||||
#include <stdarg.h>
|
||||
#include <dirent.h>
|
||||
#include <limits.h>
|
||||
#ifdef HAVE_PWD_H
|
||||
#include <pwd.h>
|
||||
@ -83,6 +98,7 @@ int copy_file(const char *src, const char *dest);
|
||||
int create_dir(const char *dir);
|
||||
void x_asprintf(char **ptr, const char *format, ...);
|
||||
char *x_strdup(const char *s);
|
||||
char *x_quote_strdup(const char* s);
|
||||
void *x_realloc(void *ptr, size_t size);
|
||||
void *x_malloc(size_t size);
|
||||
void traverse(const char *dir, void (*fn)(const char *, struct stat *));
|
||||
|
@ -50,7 +50,9 @@ static void traverse_fn(const char *fname, struct stat *st)
|
||||
{
|
||||
char *p;
|
||||
|
||||
#ifndef WIN32
|
||||
if (!S_ISREG(st->st_mode)) return;
|
||||
#endif
|
||||
|
||||
p = str_basename(fname);
|
||||
if (strcmp(p, "stats") == 0) {
|
||||
@ -107,8 +109,8 @@ void cleanup_dir(const char *dir, size_t maxfiles, size_t maxsize)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
size_threshold = maxsize * LIMIT_MULTIPLE;
|
||||
files_threshold = maxfiles * LIMIT_MULTIPLE;
|
||||
size_threshold = maxsize * (size_t) LIMIT_MULTIPLE;
|
||||
files_threshold = maxfiles * (size_t) LIMIT_MULTIPLE;
|
||||
|
||||
num_files = 0;
|
||||
total_size = 0;
|
||||
@ -143,8 +145,9 @@ void cleanup_all(const char *dir)
|
||||
int i;
|
||||
|
||||
for (i=0;i<=0xF;i++) {
|
||||
x_asprintf(&dname, "%s/%1x", dir, i);
|
||||
x_asprintf(&sfile, "%s/%1x/stats", dir, i);
|
||||
/* No need to quote, unique argument */
|
||||
x_asprintf(&dname, "%s"PATH_SEP"%1x", dir, i);
|
||||
x_asprintf(&sfile, "%s"PATH_SEP"%1x"PATH_SEP"stats", dir, i);
|
||||
|
||||
memset(counters, 0, sizeof(counters));
|
||||
stats_read(sfile, counters);
|
||||
@ -183,7 +186,7 @@ void wipe_all(const char *dir)
|
||||
int i;
|
||||
|
||||
for (i=0;i<=0xF;i++) {
|
||||
x_asprintf(&dname, "%s/%1x", dir, i);
|
||||
x_asprintf(&dname, "%s"PATH_SEP"%1x", dir, i);
|
||||
traverse(dir, wipe_fn);
|
||||
free(dname);
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ int execute(char **argv,
|
||||
const char *path_stdout,
|
||||
const char *path_stderr)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
pid_t pid;
|
||||
int status;
|
||||
|
||||
@ -64,9 +65,88 @@ int execute(char **argv,
|
||||
}
|
||||
|
||||
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], 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
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Check that the executable exists
|
||||
*/
|
||||
char is_exec_file(const char *fname, const char *exclude_name)
|
||||
{
|
||||
struct stat st1, st2;
|
||||
|
||||
if (access(fname, 0) == 0 &&
|
||||
#ifndef _WIN32 /* Symlinks not used under windows */
|
||||
lstat(fname, &st1) == 0 &&
|
||||
#endif
|
||||
stat(fname, &st2) == 0 &&
|
||||
S_ISREG(st2.st_mode)) {
|
||||
#ifndef _WIN32 /* Symlinks not used under windows */
|
||||
/* 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);
|
||||
return -1;
|
||||
}
|
||||
free(buf);
|
||||
free(p);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* found it! */
|
||||
return 1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
find an executable by name in $PATH. Exclude any that are links to exclude_name
|
||||
*/
|
||||
@ -74,9 +154,9 @@ char *find_executable(const char *name, const char *exclude_name)
|
||||
{
|
||||
char *path;
|
||||
char *tok;
|
||||
struct stat st1, st2;
|
||||
const char *sep = ":";
|
||||
|
||||
if (*name == '/') {
|
||||
if (*name == PATH_SEP_CHAR) {
|
||||
return x_strdup(name);
|
||||
}
|
||||
|
||||
@ -91,39 +171,37 @@ char *find_executable(const char *name, const char *exclude_name)
|
||||
|
||||
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,":"); tok; tok = strtok(NULL, ":")) {
|
||||
for (tok=strtok(path, sep); tok; tok = strtok(NULL, sep)) {
|
||||
char *fname;
|
||||
x_asprintf(&fname, "%s/%s", tok, name);
|
||||
x_asprintf(&fname, "%s"PATH_SEP"%s", tok, name);
|
||||
/* look for a normal executable file */
|
||||
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! */
|
||||
if (is_exec_file(fname, exclude_name) > 0)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ void hash_start(void)
|
||||
|
||||
void hash_string(const char *s)
|
||||
{
|
||||
hash_buffer(s, strlen(s));
|
||||
hash_buffer(s, (int)strlen(s));
|
||||
}
|
||||
|
||||
void hash_int(int x)
|
||||
|
@ -126,7 +126,7 @@ static void stats_update_size(enum stats stat, size_t size)
|
||||
|
||||
if (!stats_file) {
|
||||
if (!cache_dir) return;
|
||||
x_asprintf(&stats_file, "%s/stats", cache_dir);
|
||||
x_asprintf(&stats_file, "%s"PATH_SEP"stats", cache_dir);
|
||||
}
|
||||
|
||||
/* open safely to try to prevent symlink races */
|
||||
@ -215,9 +215,9 @@ void stats_summary(void)
|
||||
char *fname;
|
||||
|
||||
if (dir == -1) {
|
||||
x_asprintf(&fname, "%s/stats", cache_dir);
|
||||
x_asprintf(&fname, "%s"PATH_SEP"stats", cache_dir);
|
||||
} else {
|
||||
x_asprintf(&fname, "%s/%1x/stats", cache_dir, dir);
|
||||
x_asprintf(&fname, "%s"PATH_SEP"%1x"PATH_SEP"stats", cache_dir, dir);
|
||||
}
|
||||
|
||||
stats_read(fname, counters);
|
||||
@ -259,12 +259,12 @@ void stats_zero(void)
|
||||
char *fname;
|
||||
unsigned counters[STATS_END];
|
||||
|
||||
x_asprintf(&fname, "%s/stats", cache_dir);
|
||||
x_asprintf(&fname, "%s"PATH_SEP"stats", cache_dir);
|
||||
unlink(fname);
|
||||
free(fname);
|
||||
|
||||
for (dir=0;dir<=0xF;dir++) {
|
||||
x_asprintf(&fname, "%s/%1x/stats", cache_dir, dir);
|
||||
x_asprintf(&fname, "%s"PATH_SEP"%1x"PATH_SEP"stats", cache_dir, dir);
|
||||
fd = safe_open(fname);
|
||||
if (fd == -1) {
|
||||
free(fname);
|
||||
@ -305,9 +305,9 @@ void stats_set_limits(long maxfiles, long maxsize)
|
||||
char *fname, *cdir;
|
||||
int fd;
|
||||
|
||||
x_asprintf(&cdir, "%s/%1x", cache_dir, dir);
|
||||
x_asprintf(&cdir, "%s"PATH_SEP"%1x", cache_dir, dir);
|
||||
create_dir(cdir);
|
||||
x_asprintf(&fname, "%s/stats", cdir);
|
||||
x_asprintf(&fname, "%s"PATH_SEP"stats", cdir);
|
||||
free(cdir);
|
||||
|
||||
memset(counters, 0, sizeof(counters));
|
||||
@ -336,7 +336,7 @@ void stats_set_sizes(const char *dir, size_t num_files, size_t total_size)
|
||||
char *stats_file;
|
||||
|
||||
create_dir(dir);
|
||||
x_asprintf(&stats_file, "%s/stats", dir);
|
||||
x_asprintf(&stats_file, "%s"PATH_SEP"stats", dir);
|
||||
|
||||
memset(counters, 0, sizeof(counters));
|
||||
|
||||
|
@ -209,7 +209,7 @@ static void unify(unsigned char *p, size_t size)
|
||||
q = p[ofs];
|
||||
for (i=0;i<tokens[q].num_toks;i++) {
|
||||
unsigned char *s = (unsigned char *)tokens[q].toks[i];
|
||||
int len = strlen((char *)s);
|
||||
int len = (int) strlen((char *)s);
|
||||
if (size >= ofs+len && memcmp(&p[ofs], s, len) == 0) {
|
||||
int j;
|
||||
for (j=0;s[j];j++) {
|
||||
@ -241,6 +241,7 @@ int unify_hash(const char *fname)
|
||||
int fd;
|
||||
struct stat st;
|
||||
char *map;
|
||||
HANDLE view;
|
||||
|
||||
fd = open(fname, O_RDONLY|O_BINARY);
|
||||
if (fd == -1 || fstat(fd, &st) != 0) {
|
||||
@ -249,6 +250,33 @@ int unify_hash(const char *fname)
|
||||
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 */
|
||||
@ -263,7 +291,7 @@ int unify_hash(const char *fname)
|
||||
unify((unsigned char *)map, st.st_size);
|
||||
|
||||
munmap(map, st.st_size);
|
||||
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,22 @@
|
||||
|
||||
static FILE *logfile;
|
||||
|
||||
#ifdef _WIN32
|
||||
int fchmod(int fildes, mode_t mode)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#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, ...)
|
||||
{
|
||||
@ -154,6 +170,34 @@ void x_asprintf(char **ptr, const char *format, ...)
|
||||
if (!ptr) fatal("out of memory in x_asprintf");
|
||||
}
|
||||
|
||||
/*
|
||||
this is like strdup() but dies if the malloc fails and add quotes
|
||||
around the argument if it contains spaces.
|
||||
*/
|
||||
char*
|
||||
x_quote_strdup(const char* s)
|
||||
{
|
||||
/* Protect against args containing spaces in them - unicode-able ? */
|
||||
if (strchr(s, ' ') != NULL) {
|
||||
size_t len = strlen(s); /* at least 1 as it holds ' ' */
|
||||
char *new_arg = x_malloc(len+2*1+1); /* Make room for quoting */
|
||||
|
||||
/* Quote */
|
||||
new_arg[0] = '"';
|
||||
memcpy(new_arg+1, s, len);
|
||||
new_arg[len+1] = '"';
|
||||
new_arg[len+2] = 0;
|
||||
|
||||
/* Done */
|
||||
cc_log("Quoted %s\n", new_arg);
|
||||
return new_arg;
|
||||
}
|
||||
else
|
||||
return x_strdup(s);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
this is like strdup() but dies if the malloc fails
|
||||
*/
|
||||
@ -220,7 +264,7 @@ void traverse(const char *dir, void (*fn)(const char *, struct stat *))
|
||||
|
||||
if (strlen(de->d_name) == 0) continue;
|
||||
|
||||
x_asprintf(&fname, "%s/%s", dir, de->d_name);
|
||||
x_asprintf(&fname, "%s"PATH_SEP"%s", dir, de->d_name);
|
||||
if (lstat(fname, &st)) {
|
||||
if (errno != ENOENT) {
|
||||
perror(fname);
|
||||
@ -244,7 +288,7 @@ void traverse(const char *dir, void (*fn)(const char *, struct stat *))
|
||||
/* return the base name of a file - caller frees */
|
||||
char *str_basename(const char *s)
|
||||
{
|
||||
char *p = strrchr(s, '/');
|
||||
char *p = strrchr(s, PATH_SEP_CHAR);
|
||||
if (p) {
|
||||
return x_strdup(p+1);
|
||||
}
|
||||
@ -257,7 +301,7 @@ char *dirname(char *s)
|
||||
{
|
||||
char *p;
|
||||
s = x_strdup(s);
|
||||
p = strrchr(s, '/');
|
||||
p = strrchr(s, PATH_SEP_CHAR);
|
||||
if (p) {
|
||||
*p = 0;
|
||||
}
|
||||
@ -266,6 +310,9 @@ char *dirname(char *s)
|
||||
|
||||
int lock_fd(int fd)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return _locking(fd, _LK_NBLCK, 1);
|
||||
#else
|
||||
struct flock fl;
|
||||
int ret;
|
||||
|
||||
@ -281,17 +328,23 @@ int lock_fd(int fd)
|
||||
ret = fcntl(fd, F_SETLKW, &fl);
|
||||
} while (ret == -1 && errno == EINTR);
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* return size on disk of a file */
|
||||
size_t file_size(struct stat *st)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return st->st_size;
|
||||
#else
|
||||
size_t size = st->st_blocks * 512;
|
||||
if ((size_t)st->st_size > size) {
|
||||
/* probably a broken stat() call ... */
|
||||
size = (st->st_size + 1023) & ~1023;
|
||||
}
|
||||
return size;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -351,6 +404,7 @@ size_t value_units(const char *s)
|
||||
a sane realpath() function, trying to cope with stupid path limits and
|
||||
a broken API
|
||||
*/
|
||||
#ifndef WIN32
|
||||
char *x_realpath(const char *path)
|
||||
{
|
||||
int maxlen;
|
||||
@ -389,6 +443,7 @@ char *x_realpath(const char *path)
|
||||
free(ret);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* a getcwd that will returns an allocated buffer */
|
||||
char *gnu_getcwd(void)
|
||||
@ -397,7 +452,7 @@ char *gnu_getcwd(void)
|
||||
|
||||
while (1) {
|
||||
char *buffer = (char *)x_malloc(size);
|
||||
if (getcwd(buffer, size) == buffer) {
|
||||
if (_getcwd(buffer, size) == buffer) {
|
||||
return buffer;
|
||||
}
|
||||
free(buffer);
|
||||
@ -408,16 +463,6 @@ char *gnu_getcwd(void)
|
||||
}
|
||||
}
|
||||
|
||||
#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
|
||||
|
||||
|
||||
/* create an empty file */
|
||||
int create_empty_file(const char *fname)
|
||||
{
|
||||
@ -436,7 +481,18 @@ int create_empty_file(const char *fname)
|
||||
*/
|
||||
const char *get_home_directory(void)
|
||||
{
|
||||
const char *p = getenv("HOME");
|
||||
const char *p = NULL;
|
||||
|
||||
#ifdef _WIN32
|
||||
static char szPath[MAX_PATH];
|
||||
|
||||
// "Documents and Settings\user\Application Data" is CSIDL_APPDATA
|
||||
if(SHGetSpecialFolderPathA(NULL, szPath, CSIDL_PROFILE, FALSE))
|
||||
{
|
||||
return szPath;
|
||||
}
|
||||
#endif
|
||||
p = getenv("HOME");
|
||||
if (p) {
|
||||
return p;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user