#include <sys/types.h>
#include <sys/stat.h>
-#include <sys/mman.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
struct file_hash *h;
struct mdfour fhash;
struct stat st;
- int fd = -1;
char *data = (char *)-1;
char *source;
int result;
}
/* Let's hash the include file. */
- fd = open(path, O_RDONLY|O_BINARY);
- if (fd == -1) {
- cc_log("Failed to open include file %s", path);
- goto failure;
- }
if (!(sloppiness & SLOPPY_INCLUDE_FILE_MTIME)
&& st.st_mtime >= time_of_compilation) {
cc_log("Include file %s too new", path);
goto failure;
}
if (st.st_size > 0) {
- data = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+ data = x_fmmap(path, &st.st_size, "include file");
if (data == (char *)-1) {
- cc_log("Failed to mmap %s", path);
goto failure;
}
source = data;
} else {
source = "";
}
- close(fd);
hash_start(&fhash);
result = hash_source_code_string(&fhash, source, st.st_size, path);
hash_result_as_bytes(&fhash, h->hash);
h->size = fhash.totalN;
hashtable_insert(included_files, path, h);
- munmap(data, st.st_size);
+ x_munmap(data, st.st_size);
return;
failure:
ignore:
free(path);
if (data != (char *)-1) {
- munmap(data, st.st_size);
- }
- if (fd != -1) {
- close(fd);
+ x_munmap(data, st.st_size);
}
}
*/
static int process_preprocessed_file(struct mdfour *hash, const char *path)
{
- int fd;
char *data;
char *p, *q, *end;
off_t size;
- struct stat st;
- fd = open(path, O_RDONLY);
- if (fd == -1) {
- cc_log("Failed to open %s", path);
- return 0;
- }
- if (fstat(fd, &st) != 0) {
- cc_log("Failed to fstat %s", path);
- return 0;
- }
- size = st.st_size;
- data = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
- close(fd);
+ data = x_fmmap(path, &size, "preprocessed file");
if (data == (void *)-1) {
- cc_log("Failed to mmap %s", path);
return 0;
}
q++;
if (q >= end) {
cc_log("Failed to parse included file path");
- munmap(data, size);
+ x_munmap(data, size);
return 0;
}
/* q points to the beginning of an include file path */
}
hash_buffer(hash, p, (end - p));
- munmap(data, size);
+ x_munmap(data, size);
return 1;
}
size_t common_dir_prefix_length(const char *s1, const char *s2);
char *get_relative_path(const char *from, const char *to);
void update_mtime(const char *path);
+void *x_fmmap(const char *fname, off_t *size, const char *errstr);
+int x_munmap(void *addr, size_t length);
void stats_update(enum stats stat);
void stats_flush(void);
AC_HEADER_TIME
AC_HEADER_SYS_WAIT
-AC_CHECK_HEADERS(ctype.h pwd.h stdlib.h string.h strings.h sys/time.h)
+AC_CHECK_HEADERS(ctype.h pwd.h stdlib.h string.h strings.h sys/time.h sys/mman.h)
AC_CHECK_FUNCS(asprintf)
AC_CHECK_FUNCS(gethostname)
#include "murmurhashneutral2.h"
#include <string.h>
-#include <sys/mman.h>
#include <fcntl.h>
#include <time.h>
int
hash_source_code_file(struct mdfour *hash, const char *path)
{
- int fd;
struct stat st;
char *data;
int result;
if (st.st_size == 0) {
return HASH_SOURCE_CODE_OK;
}
- fd = open(path, O_RDONLY|O_BINARY);
- if (fd == -1) {
- cc_log("Failed to open %s", path);
- return HASH_SOURCE_CODE_ERROR;
- }
- data = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
- close(fd);
+
+ data = x_fmmap(path, &st.st_size, "source code file");
if (data == (void *)-1) {
- cc_log("Failed to mmap %s", path);
return HASH_SOURCE_CODE_ERROR;
}
result = hash_source_code_string(hash, data, st.st_size, path);
- munmap(data, st.st_size);
+ x_munmap(data, st.st_size);
return result;
}
#include "ccache.h"
#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
#include <ctype.h>
#include <fcntl.h>
#include <string.h>
*/
int unify_hash(struct mdfour *hash, const char *fname)
{
- int fd;
- struct stat st;
+ off_t size;
char *map;
- fd = open(fname, O_RDONLY|O_BINARY);
- if (fd == -1 || fstat(fd, &st) != 0) {
- cc_log("Failed to open preprocessor output %s", fname);
+ map = x_fmmap(fname, &size, "preprocessor output");
+ if (map == (void *) -1) {
stats_update(STATS_PREPROCESSOR);
return -1;
}
- /* 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 */
- map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
- close(fd);
- if (map == (char *)-1) {
- cc_log("Failed to mmap %s", fname);
- return -1;
- }
-
/* pass it through the unifier */
- unify(hash, (unsigned char *)map, st.st_size);
+ unify(hash, (unsigned char *)map, size);
- munmap(map, st.st_size);
+ x_munmap(map, size);
return 0;
}
#include <sys/types.h>
#include <sys/stat.h>
+#ifdef HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif
#include <fcntl.h>
#include <ctype.h>
#include <unistd.h>
utime(path, NULL);
#endif
}
+
+/*
+ * Map file into memory. Return a pointer to the mapped area if successful or
+ * -1 if any error occurred. The file size is also returned,
+ */
+void *x_fmmap(const char *fname, off_t *size, const char *errstr)
+{
+ struct stat st;
+ void *data = (void *) -1;
+ int fd = -1;
+ fd = open(fname, O_RDONLY | O_BINARY);
+ if (fd == -1) {
+ cc_log("Failed to open %s %s", errstr, fname);
+ goto error;
+ }
+ if (fstat(fd, &st) == -1) {
+ cc_log("Failed to fstat %s %s", errstr, fname);
+ close(fd);
+ goto error;
+ }
+ data = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+ close(fd);
+ if (data == (void *) -1) {
+ cc_log("Failed to mmap %s %s", errstr, fname);
+ }
+ *size = st.st_size;
+error:
+ return data;
+}
+
+/*
+ * Unmap file from memory.
+ */
+int x_munmap(void *addr, size_t length)
+{
+ return munmap(addr, length);
+}