[incremental] Patch: FYI: set working directory

Tom Tromey tromey@redhat.com
Tue Dec 11 21:59:00 GMT 2007


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 */



More information about the Gcc-patches mailing list