This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[incremental] Patch: FYI: set working directory
- From: Tom Tromey <tromey at redhat dot com>
- To: Gcc Patch List <gcc-patches at gcc dot gnu dot org>
- Date: Tue, 11 Dec 2007 14:28:50 -0700
- Subject: [incremental] Patch: FYI: set working directory
- Reply-to: tromey at redhat dot com
I'm checking this in on the incremental-compiler branch.
This changes the client to send the working directory to the server,
and it changes the server to chdir to that directory before working.
This lets us handle the common case of a build that runs the compiler
in several different directories.
Tom
ChangeLog:
2007-12-11 Tom Tromey <tromey@redhat.com>
* gcc.c (execute): Call client_send_directory.
(server_callback): Add argument.
* server.c (client_send_directory): New function.
(request_and_response): Handle '.' request.
* server.h (client_send_directory): Declare.
(server_callback): Add argument.
* toplev.c (get_src_pwd): Ensure src_pwd is allocated. Use
getcwd.
(clear_src_pwd): New function.
(server_callback): Call it. Add argument. Set directory.
Index: gcc.c
===================================================================
--- gcc.c (revision 130053)
+++ gcc.c (working copy)
@@ -2950,6 +2950,8 @@
/* Maybe we should warn the user if the connection fails? */
if (use_server && client_connect (commands[0].argv[0]))
{
+ if (!client_send_directory ())
+ fatal ("couldn't send working directory to server");
for (i = 0; i < n_commands; ++i)
{
if (!client_send_command (commands[i].argv))
@@ -8006,6 +8008,7 @@
void
server_callback (int ARG_UNUSED (fd),
+ char * ARG_UNUSED (dir),
char ** ARG_UNUSED (cc1_argv),
char ** ARG_UNUSED (as_argv))
{
Index: toplev.c
===================================================================
--- toplev.c (revision 130603)
+++ toplev.c (working copy)
@@ -463,14 +463,24 @@
{
if (! src_pwd)
{
- src_pwd = getpwd ();
+ src_pwd = getcwd (NULL, 0);
if (!src_pwd)
- src_pwd = ".";
+ src_pwd = xstrdup (".");
}
return src_pwd;
}
+static void
+clear_src_pwd (void)
+{
+ if (src_pwd)
+ {
+ free (src_pwd);
+ src_pwd = NULL;
+ }
+}
+
/* Called when the start of a function definition is parsed,
this function prints on stderr the name of the function. */
void
@@ -2342,7 +2352,7 @@
}
void
-server_callback (int fd, char **cc1_argv, char **as_argv)
+server_callback (int fd, char *dir, char **cc1_argv, char **as_argv)
{
int n;
@@ -2365,6 +2375,9 @@
decode_options (n, VEC_address (cchar_p, job->cc1_arguments));
flag_unit_at_a_time = 1;
+ clear_src_pwd ();
+ chdir (dir);
+
init_local_tick ();
do_compile ();
Index: server.c
===================================================================
--- server.c (revision 130506)
+++ server.c (working copy)
@@ -143,6 +143,7 @@
static bool
request_and_response (int reqfd)
{
+ char *dir = NULL;
char **argvs[2];
int count = 0;
@@ -175,18 +176,37 @@
argvs[count++] = argv;
}
+ else if (cmd == '.')
+ {
+ /* Set working directory. */
+ int len;
+
+ if (dir)
+ {
+ fprintf (stderr, "DIE!\n");
+ break;
+ }
+ if (read (reqfd, &len, sizeof (len)) != sizeof (len))
+ break;
+ dir = (char *) xmalloc (len + 1);
+ if (read (reqfd, dir, len) != len)
+ break;
+ dir[len] = '\0';
+ }
else if (cmd == 'D')
{
/* Done with requests, compile away. */
- if (count != 2)
+ if (count != 2 || !dir)
{
fprintf (stderr, "DIE 2!\n");
count = 0; /* And leak memory while we're at it. */
continue;
}
- server_callback (reqfd, argvs[0], argvs[1]);
+ server_callback (reqfd, dir, argvs[0], argvs[1]);
+ free (dir);
freeargv (argvs[0]);
freeargv (argvs[1]);
+ dir = NULL;
count = 0;
break;
}
@@ -300,6 +320,28 @@
return true;
}
+/* Send the current working directory to the server. 'client_connect'
+ must already have been called successfully. Returns true on
+ success, false on failure. */
+bool
+client_send_directory (void)
+{
+ char *dir = getcwd (NULL, 0);
+ char cmd = '.';
+ int len = strlen (dir);
+ bool result;
+
+ gcc_assert (connection_fd >= 0);
+
+ if (write (connection_fd, &cmd, sizeof (cmd)) != sizeof (cmd)
+ || write (connection_fd, &len, sizeof (len)) != sizeof (len))
+ result = false;
+ else
+ result = (write (connection_fd, dir, len) == len);
+ free (dir);
+ return result;
+}
+
/* Send a command to the server. 'client_connect' must already have
been called successfully. ARGV is the command line that the server
should execute (or "emulate"). Returns true on success, false on
Index: server.h
===================================================================
--- server.h (revision 130053)
+++ server.h (working copy)
@@ -27,11 +27,12 @@
/* Functions for the client to use. */
extern bool client_connect (const char *);
+extern bool client_send_directory (void);
extern bool client_send_command (const char **);
extern void client_wait (void);
extern void client_kill_server (const char *);
/* The main loop calls this when a command is read. */
-extern void server_callback (int, char **, char **);
+extern void server_callback (int, char *, char **, char **);
#endif /* GCC_SERVER_H */