initial win32 support mostly using ccache-win32-2.4 patches to ccache-2.4
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@10982 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
4b79eb9219
commit
5964f3e27d
5 changed files with 255 additions and 30 deletions
|
|
@ -136,7 +136,7 @@ static void failed(void)
|
||||||
putenv("CCACHE_OUTFILES");
|
putenv("CCACHE_OUTFILES");
|
||||||
}
|
}
|
||||||
|
|
||||||
execv(orig_args->argv[0], orig_args->argv);
|
execv(orig_args->argv[0], (const char *const *)orig_args->argv);
|
||||||
cc_log("execv returned (%s)!\n", strerror(errno));
|
cc_log("execv returned (%s)!\n", strerror(errno));
|
||||||
perror(orig_args->argv[0]);
|
perror(orig_args->argv[0]);
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
@ -722,7 +722,11 @@ static void find_compiler(int argc, char **argv)
|
||||||
if (strcmp(base, MYNAME) == 0) {
|
if (strcmp(base, MYNAME) == 0) {
|
||||||
args_remove_first(orig_args);
|
args_remove_first(orig_args);
|
||||||
free(base);
|
free(base);
|
||||||
if (strchr(argv[1],'/')) {
|
if (strchr(argv[1],'/')
|
||||||
|
#ifdef _WIN32
|
||||||
|
|| strchr(argv[1],'\\')
|
||||||
|
#endif
|
||||||
|
) {
|
||||||
/* a full path was given */
|
/* a full path was given */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,11 @@
|
||||||
|
|
||||||
#define CCACHE_VERSION SWIG_VERSION
|
#define CCACHE_VERSION SWIG_VERSION
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#else
|
||||||
|
#define PACKAGE_NAME "ccache-swig.exe"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
@ -10,8 +14,16 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/wait.h>
|
|
||||||
#include <sys/mman.h>
|
#ifndef _WIN32
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#else
|
||||||
|
#define _WIN32_WINNT 0x0500
|
||||||
|
#include <windows.h>
|
||||||
|
#include <shlobj.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <sys/file.h>
|
#include <sys/file.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,33 @@
|
||||||
|
|
||||||
#include "ccache.h"
|
#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
|
execute a compiler backend, capturing all output to the given paths
|
||||||
|
|
@ -27,6 +54,60 @@ int execute(char **argv,
|
||||||
const char *path_stdout,
|
const char *path_stdout,
|
||||||
const char *path_stderr)
|
const char *path_stderr)
|
||||||
{
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
PROCESS_INFORMATION pinfo;
|
||||||
|
STARTUPINFO sinfo;
|
||||||
|
BOOL ret;
|
||||||
|
DWORD exitcode;
|
||||||
|
char *args;
|
||||||
|
HANDLE fd_out, fd_err;
|
||||||
|
SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE};
|
||||||
|
|
||||||
|
/* TODO: needs moving after possible exit() below, but before stdout is redirected */
|
||||||
|
if (ccache_verbose) {
|
||||||
|
display_execute_args(argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
fd_out = CreateFile(path_stdout, GENERIC_WRITE, 0, &sa, CREATE_ALWAYS,
|
||||||
|
FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
if (fd_out == INVALID_HANDLE_VALUE) {
|
||||||
|
return STATUS_NOCACHE;
|
||||||
|
}
|
||||||
|
|
||||||
|
fd_err = CreateFile(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(STARTUPINFO));
|
||||||
|
|
||||||
|
sinfo.cb = sizeof(STARTUPINFO);
|
||||||
|
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;
|
pid_t pid;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
|
|
@ -69,6 +150,7 @@ int execute(char **argv,
|
||||||
}
|
}
|
||||||
|
|
||||||
return WEXITSTATUS(status);
|
return WEXITSTATUS(status);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -77,6 +159,19 @@ int execute(char **argv,
|
||||||
*/
|
*/
|
||||||
char *find_executable(const char *name, const char *exclude_name)
|
char *find_executable(const char *name, const char *exclude_name)
|
||||||
{
|
{
|
||||||
|
#if _WIN32
|
||||||
|
(void)exclude_name;
|
||||||
|
DWORD ret;
|
||||||
|
char namebuf[MAX_PATH];
|
||||||
|
|
||||||
|
ret = SearchPathA(getenv("CCACHE_PATH"), name, ".exe",
|
||||||
|
sizeof(namebuf), namebuf, NULL);
|
||||||
|
if (ret != 0) {
|
||||||
|
return x_strdup(namebuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
#else
|
||||||
char *path;
|
char *path;
|
||||||
char *tok;
|
char *tok;
|
||||||
struct stat st1, st2;
|
struct stat st1, st2;
|
||||||
|
|
@ -131,6 +226,7 @@ char *find_executable(const char *name, const char *exclude_name)
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void display_execute_args(char **argv)
|
void display_execute_args(char **argv)
|
||||||
|
|
|
||||||
|
|
@ -238,6 +238,39 @@ static void unify(unsigned char *p, size_t size)
|
||||||
*/
|
*/
|
||||||
int unify_hash(const char *fname)
|
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);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
int fd;
|
int fd;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
char *map;
|
char *map;
|
||||||
|
|
@ -265,5 +298,6 @@ int unify_hash(const char *fname)
|
||||||
munmap(map, st.st_size);
|
munmap(map, st.st_size);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
129
CCache/util.c
129
CCache/util.c
|
|
@ -46,19 +46,24 @@ void fatal(const char *msg)
|
||||||
|
|
||||||
int safe_rename(const char* oldpath, const char* newpath)
|
int safe_rename(const char* oldpath, const char* newpath)
|
||||||
{
|
{
|
||||||
/* safe_rename is for creating entries in the cache.
|
/* safe_rename is for creating entries in the cache.
|
||||||
|
|
||||||
Works like rename(), but it never overwrites an existing
|
Works like rename(), but it never overwrites an existing
|
||||||
cache entry. This avoids corruption on NFS. */
|
cache entry. This avoids corruption on NFS. */
|
||||||
int status = link( oldpath, newpath );
|
#ifndef _WIN32
|
||||||
if( status == 0 || errno == EEXIST )
|
int status = link(oldpath, newpath);
|
||||||
{
|
if( status == 0 || errno == EEXIST )
|
||||||
return unlink( oldpath );
|
#else
|
||||||
}
|
int status = CreateHardLinkA(newpath, oldpath, NULL) ? 0 : -1;
|
||||||
else
|
if( status == 0 || GetLastError() == ERROR_ALREADY_EXISTS )
|
||||||
{
|
#endif
|
||||||
return -1;
|
{
|
||||||
}
|
return unlink( oldpath );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef ENABLE_ZLIB
|
#ifndef ENABLE_ZLIB
|
||||||
|
|
@ -75,6 +80,15 @@ void copy_fd(int fd_in, int fd_out)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef HAVE_MKSTEMP
|
||||||
|
/* cheap and nasty mkstemp replacement */
|
||||||
|
static int mkstemp(char *template)
|
||||||
|
{
|
||||||
|
mktemp(template);
|
||||||
|
return open(template, O_RDWR | O_CREAT | O_EXCL | O_BINARY, 0600);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* move a file using rename */
|
/* move a file using rename */
|
||||||
int move_file(const char *src, const char *dest) {
|
int move_file(const char *src, const char *dest) {
|
||||||
return safe_rename(src, dest);
|
return safe_rename(src, dest);
|
||||||
|
|
@ -119,9 +133,13 @@ static int copy_file(const char *src, const char *dest)
|
||||||
close(fd1);
|
close(fd1);
|
||||||
|
|
||||||
/* get perms right on the tmp file */
|
/* get perms right on the tmp file */
|
||||||
|
#ifndef _WIN32
|
||||||
mask = umask(0);
|
mask = umask(0);
|
||||||
fchmod(fd2, 0666 & ~mask);
|
fchmod(fd2, 0666 & ~mask);
|
||||||
umask(mask);
|
umask(mask);
|
||||||
|
#else
|
||||||
|
(void)mask;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* the close can fail on NFS if out of space */
|
/* the close can fail on NFS if out of space */
|
||||||
if (close(fd2) == -1) {
|
if (close(fd2) == -1) {
|
||||||
|
|
@ -333,7 +351,11 @@ int commit_to_cache(const char *src, const char *dest, int hardlink)
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
unlink(dest);
|
unlink(dest);
|
||||||
if (hardlink) {
|
if (hardlink) {
|
||||||
|
#ifdef _WIN32
|
||||||
|
ret = CreateHardLinkA(dest, src, NULL) ? 0 : -1;
|
||||||
|
#else
|
||||||
ret = link(src, dest);
|
ret = link(src, dest);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
if (ret == -1) {
|
if (ret == -1) {
|
||||||
ret = copy_file_to_cache(src, dest);
|
ret = copy_file_to_cache(src, dest);
|
||||||
|
|
@ -358,7 +380,11 @@ int retrieve_from_cache(const char *src, const char *dest, int hardlink)
|
||||||
unlink(dest);
|
unlink(dest);
|
||||||
/* only make a hardlink if the cache file is uncompressed */
|
/* only make a hardlink if the cache file is uncompressed */
|
||||||
if (hardlink && test_if_compressed(src) == 0) {
|
if (hardlink && test_if_compressed(src) == 0) {
|
||||||
|
#ifdef _WIN32
|
||||||
|
ret = CreateHardLinkA(dest, src, NULL) ? 0 : -1;
|
||||||
|
#else
|
||||||
ret = link(src, dest);
|
ret = link(src, dest);
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
ret = copy_file_from_cache(src, dest);
|
ret = copy_file_from_cache(src, dest);
|
||||||
}
|
}
|
||||||
|
|
@ -393,9 +419,15 @@ int create_dir(const char *dir)
|
||||||
errno = ENOTDIR;
|
errno = ENOTDIR;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
#ifdef _WIN32
|
||||||
|
if (mkdir(dir) != 0 && errno != EEXIST) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#else
|
||||||
if (mkdir(dir, 0777) != 0 && errno != EEXIST) {
|
if (mkdir(dir, 0777) != 0 && errno != EEXIST) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -526,7 +558,12 @@ void traverse(const char *dir, void (*fn)(const char *, struct stat *))
|
||||||
if (strlen(de->d_name) == 0) continue;
|
if (strlen(de->d_name) == 0) continue;
|
||||||
|
|
||||||
x_asprintf(&fname, "%s/%s", dir, de->d_name);
|
x_asprintf(&fname, "%s/%s", dir, de->d_name);
|
||||||
if (lstat(fname, &st)) {
|
#ifdef _WIN32
|
||||||
|
if (stat(fname, &st))
|
||||||
|
#else
|
||||||
|
if (lstat(fname, &st))
|
||||||
|
#endif
|
||||||
|
{
|
||||||
if (errno != ENOENT) {
|
if (errno != ENOENT) {
|
||||||
perror(fname);
|
perror(fname);
|
||||||
}
|
}
|
||||||
|
|
@ -551,9 +588,17 @@ char *str_basename(const char *s)
|
||||||
{
|
{
|
||||||
char *p = strrchr(s, '/');
|
char *p = strrchr(s, '/');
|
||||||
if (p) {
|
if (p) {
|
||||||
return x_strdup(p+1);
|
s = (p+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
p = strrchr(s, '\\');
|
||||||
|
|
||||||
|
if (p) {
|
||||||
|
s = (p+1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return x_strdup(s);
|
return x_strdup(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -563,6 +608,9 @@ char *dirname(char *s)
|
||||||
char *p;
|
char *p;
|
||||||
s = x_strdup(s);
|
s = x_strdup(s);
|
||||||
p = strrchr(s, '/');
|
p = strrchr(s, '/');
|
||||||
|
#ifdef _WIN32
|
||||||
|
p = strrchr(s, '\\');
|
||||||
|
#endif
|
||||||
if (p) {
|
if (p) {
|
||||||
*p = 0;
|
*p = 0;
|
||||||
}
|
}
|
||||||
|
|
@ -571,6 +619,7 @@ char *dirname(char *s)
|
||||||
|
|
||||||
int lock_fd(int fd)
|
int lock_fd(int fd)
|
||||||
{
|
{
|
||||||
|
#ifndef _WIN32
|
||||||
struct flock fl;
|
struct flock fl;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
|
@ -586,17 +635,26 @@ int lock_fd(int fd)
|
||||||
ret = fcntl(fd, F_SETLKW, &fl);
|
ret = fcntl(fd, F_SETLKW, &fl);
|
||||||
} while (ret == -1 && errno == EINTR);
|
} while (ret == -1 && errno == EINTR);
|
||||||
return ret;
|
return ret;
|
||||||
|
#else
|
||||||
|
(void)fd;
|
||||||
|
#warning "missing implementation???"
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* return size on disk of a file */
|
/* return size on disk of a file */
|
||||||
size_t file_size(struct stat *st)
|
size_t file_size(struct stat *st)
|
||||||
{
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
return (st->st_size + 1023) & ~1023;
|
||||||
|
#else
|
||||||
size_t size = st->st_blocks * 512;
|
size_t size = st->st_blocks * 512;
|
||||||
if ((size_t)st->st_size > size) {
|
if ((size_t)st->st_size > size) {
|
||||||
/* probably a broken stat() call ... */
|
/* probably a broken stat() call ... */
|
||||||
size = (st->st_size + 1023) & ~1023;
|
size = (st->st_size + 1023) & ~1023;
|
||||||
}
|
}
|
||||||
return size;
|
return size;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -658,6 +716,17 @@ size_t value_units(const char *s)
|
||||||
*/
|
*/
|
||||||
char *x_realpath(const char *path)
|
char *x_realpath(const char *path)
|
||||||
{
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
char namebuf[MAX_PATH];
|
||||||
|
DWORD ret;
|
||||||
|
|
||||||
|
ret = GetFullPathNameA(path, sizeof(namebuf), namebuf, NULL);
|
||||||
|
if (ret == 0 || ret >= sizeof(namebuf)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return x_strdup(namebuf);
|
||||||
|
#else
|
||||||
int maxlen;
|
int maxlen;
|
||||||
char *ret, *p;
|
char *ret, *p;
|
||||||
#ifdef PATH_MAX
|
#ifdef PATH_MAX
|
||||||
|
|
@ -693,6 +762,7 @@ char *x_realpath(const char *path)
|
||||||
}
|
}
|
||||||
free(ret);
|
free(ret);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* a getcwd that will returns an allocated buffer */
|
/* a getcwd that will returns an allocated buffer */
|
||||||
|
|
@ -713,16 +783,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 */
|
/* create an empty file */
|
||||||
int create_empty_file(const char *fname)
|
int create_empty_file(const char *fname)
|
||||||
{
|
{
|
||||||
|
|
@ -741,6 +801,24 @@ int create_empty_file(const char *fname)
|
||||||
*/
|
*/
|
||||||
const char *get_home_directory(void)
|
const char *get_home_directory(void)
|
||||||
{
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
static char home_path[MAX_PATH] = {0};
|
||||||
|
HRESULT ret;
|
||||||
|
|
||||||
|
/* we already have the path */
|
||||||
|
if (home_path[0] != 0) {
|
||||||
|
return home_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get the path to "Application Data" folder */
|
||||||
|
ret = SHGetFolderPathA(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, home_path);
|
||||||
|
if (SUCCEEDED(ret)) {
|
||||||
|
return home_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "ccache: Unable to determine home directory\n");
|
||||||
|
return NULL;
|
||||||
|
#else
|
||||||
const char *p = getenv("HOME");
|
const char *p = getenv("HOME");
|
||||||
if (p) {
|
if (p) {
|
||||||
return p;
|
return p;
|
||||||
|
|
@ -753,8 +831,9 @@ const char *get_home_directory(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
cc_log("Unable to determine home directory");
|
fatal("Unable to determine home directory");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int x_utimes(const char *filename)
|
int x_utimes(const char *filename)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue