aboutsummaryrefslogtreecommitdiff
path: root/libcpp/files.c
diff options
context:
space:
mode:
Diffstat (limited to 'libcpp/files.c')
-rw-r--r--libcpp/files.c210
1 files changed, 204 insertions, 6 deletions
diff --git a/libcpp/files.c b/libcpp/files.c
index 593e5ebf0c8..0ea5722c02f 100644
--- a/libcpp/files.c
+++ b/libcpp/files.c
@@ -36,7 +36,9 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
# define FAB_C_VAR 2 /* variable length records (see Starlet fabdef.h) */
# define STAT_SIZE_RELIABLE(ST) ((ST).st_fab_rfm != FAB_C_VAR)
#else
-# define STAT_SIZE_RELIABLE(ST) true
+/* APPLE LOCAL begin predictive compilation */
+# define STAT_SIZE_RELIABLE(ST) (!CPP_OPTION (pfile, predictive_compilation))
+/* APPLE LOCAL end predictive compilation */
#endif
#ifdef __DJGPP__
@@ -177,6 +179,11 @@ static int pchf_save_compare (const void *e1, const void *e2);
static int pchf_compare (const void *d_p, const void *e_p);
static bool check_file_against_entries (cpp_reader *, _cpp_file *, bool);
+/* APPLE LOCAL begin distcc pch indirection --mrs */
+#include <sys/param.h>
+char *indirect_file (char *, const int);
+/* APPLE LOCAL end distcc pch indirection --mrs */
+
/* Given a filename in FILE->PATH, with the empty string interpreted
as <stdin>, open it.
@@ -248,9 +255,11 @@ pch_open_file (cpp_reader *pfile, _cpp_file *file, bool *invalid_pch)
struct stat st;
bool valid = false;
- /* No PCH on <stdin> or if not requested. */
- if (file->name[0] == '\0' || !pfile->cb.valid_pch)
+ /* APPLE LOCAL begin predictive compilation */
+ /* No PCH on <stdin> or if predictive compilation or if not requested. */
+ if (pfile->is_main_file || file->name[0] == '\0' || !pfile->cb.valid_pch)
return false;
+ /* APPLE LOCAL end predictive compilation */
flen = strlen (path);
len = flen + sizeof (extension);
@@ -258,6 +267,11 @@ pch_open_file (cpp_reader *pfile, _cpp_file *file, bool *invalid_pch)
memcpy (pchname, path, flen);
memcpy (pchname + flen, extension, sizeof (extension));
+ /* APPLE LOCAL begin distcc pch indirection --mrs */
+ if (! file->main_file)
+ pchname = indirect_file (pchname, 0);
+ /* APPLE LOCAL end distcc pch indirection --mrs */
+
if (stat (pchname, &st) == 0)
{
DIR *pchdir;
@@ -321,11 +335,21 @@ find_file_in_dir (cpp_reader *pfile, _cpp_file *file, bool *invalid_pch)
if (path)
{
+ /* APPLE LOCAL predictive compilation */
+ bool res_open_file;
file->path = path;
if (pch_open_file (pfile, file, invalid_pch))
return true;
- if (open_file (file))
+ /* APPLE LOCAL begin predictive compilation */
+ /* Temporary path change to force opening stdin */
+ if (pfile->is_main_file)
+ file->path = "";
+ res_open_file = open_file (file);
+ file->path = path;
+
+ if (res_open_file)
+ /* APPLE LOCAL end predictive compilation */
return true;
if (file->err_no != ENOENT)
@@ -542,6 +566,17 @@ read_file_guts (cpp_reader *pfile, _cpp_file *file)
size = file->st.st_size;
}
+ /* APPLE LOCAL begin predictive compilation */
+ else
+ if (CPP_OPTION (pfile, predictive_compilation))
+ {
+ size = CPP_OPTION (pfile, predictive_compilation_size);
+ regular = size >= 0;
+ if (size < 0)
+ size = 8 * 1024;
+ CPP_OPTION(pfile, predictive_compilation_size) = -1;
+ }
+ /* APPLE LOCAL end predictive compilation */
else
/* 8 kilobytes is a sensible starting size. It ought to be bigger
than the kernel pipe buffer, and it's definitely bigger than
@@ -601,8 +636,13 @@ read_file (cpp_reader *pfile, _cpp_file *file)
}
file->dont_read = !read_file_guts (pfile, file);
- close (file->fd);
- file->fd = -1;
+ /* APPLE LOCAL begin predictive compilation */
+ if (file->fd != 0) /* Don't close stdin */
+ {
+ close (file->fd);
+ file->fd = -1;
+ }
+ /* APPLE LOCAL end predictive compilation */
return !file->dont_read;
}
@@ -974,6 +1014,22 @@ new_file_hash_entry (cpp_reader *pfile)
return &pfile->file_hash_entries[pfile->file_hash_entries_used++];
}
+/* APPLE LOCAL begin predictive compilation */
+bool read_from_stdin (cpp_reader *pfile)
+{
+ _cpp_file *file;
+
+ if (pfile->buffer->file->fd != 0)
+ return false;
+
+ file = pfile->main_file;
+ file->dont_read = !read_file_guts (pfile, file);
+ pfile->buffer->next_line = file->buffer;
+ pfile->buffer->rlimit = file->buffer + file->st.st_size;
+ return !file->dont_read;
+}
+/* APPLE LOCAL end predictive compilation */
+
/* Returns TRUE if a file FNAME has ever been successfully opened.
This routine is not intended to correctly handle filenames aliased
by links or redundant . or .. traversals etc. */
@@ -1615,3 +1671,145 @@ check_file_against_entries (cpp_reader *pfile ATTRIBUTE_UNUSED,
return bsearch (&d, pchf->entries, pchf->count, sizeof (struct pchf_entry),
pchf_compare) != NULL;
}
+
+/* APPLE LOCAL begin distcc pch indirection --mrs */
+static const char message_terminator = '\n';
+
+/* Communications routine to communicate with filename translation
+ server for distributed builds. This routine reads data from the
+ server. */
+
+static int
+read_from_parent (int fd, char *buffer, int size)
+{
+ int index = 0;
+ int result;
+
+ if (size <= 0)
+ return 0;
+
+ do {
+ result = read (fd, &buffer[index], size - index);
+
+ if (result <= 0 || index >= size )
+ return 0;
+ else
+ index += result;
+ } while (buffer[index - 1] != message_terminator);
+
+ /* Straighten out the string termination. */
+ buffer[index - 1] = '\0';
+
+ return 1;
+}
+
+/* Communications routine to communicate with filename translation server
+ for distributed builds. This routine writes data to the server. */
+
+static int
+write_to_parent (int fd, const char *message)
+{
+ int result;
+
+ if (message) {
+ const int length = strlen (message);
+ int index = 0;
+
+ while (index < length) {
+ result = write (fd, &message[index], length - index);
+
+ if (result < 0)
+ return 0;
+ else
+ index += result;
+ }
+ }
+
+ result = write (fd, &message_terminator, 1);
+
+ if (result < 0)
+ return 0;
+
+ return 1;
+}
+
+
+/* Initialize the filename translation service. */
+
+static int
+init_indirect_pipes (int *read_fd, int *write_fd)
+{
+ const char *file_indirect_pipes = getenv ("GCC_INDIRECT_FILES");
+ const char *protocol_operation = "VERS";
+ const char *protocol_version = "1";
+ char response[MAXPATHLEN];
+
+ if (!file_indirect_pipes)
+ return -1;
+
+ /* The environment variable indicates that the process that invoked
+ gcc would like to provide a different path for certain files.
+ This is mainly intended to be used with PCH headers and symbol
+ separation files (.cinfo) files under certain circumstances. */
+
+ if (sscanf (file_indirect_pipes, "%d, %d", read_fd, write_fd) != 2)
+ return -1;
+
+ /* Verify the protocol version. */
+ if (write_to_parent (*write_fd, protocol_operation))
+ if (write_to_parent (*write_fd, protocol_version))
+ if (read_from_parent (*read_fd, response, MAXPATHLEN))
+ if (strcmp ("OK", response) == 0)
+ return 1;
+
+ return -1;
+}
+
+/* Redirect file I/O at the direction of a translation server. fname
+ is the filename to transform. OPERATION is:
+
+ 0 for reading
+ 1 for writing
+ 2 for reading and writing */
+
+char *
+indirect_file (char *fname, int operation)
+{
+ static int indirection_initialized;
+ static int read_fd;
+ static int write_fd;
+ const char *operation_identifier = NULL;
+
+ if (!indirection_initialized)
+ indirection_initialized = init_indirect_pipes (&read_fd, &write_fd);
+
+ if (indirection_initialized != 1)
+ return fname;
+
+ switch (operation)
+ {
+ case 0:
+ operation_identifier = "PULL";
+ break;
+ case 1:
+ operation_identifier = "PUSH";
+ break;
+ case 2:
+ operation_identifier = "BOTH";
+ break;
+ default:
+ return fname;
+ }
+
+ if (write_to_parent (write_fd, operation_identifier))
+ if (write_to_parent (write_fd, fname))
+ {
+ char response[MAXPATHLEN];
+
+ if (read_from_parent (read_fd, response, MAXPATHLEN))
+ fname = xstrdup (response);
+ }
+
+ return fname;
+}
+/* APPLE LOCAL end distcc pch indirection --mrs */