[distcc] patches to 2.12.1 for Windows, AIX, HPUX

Martin Pool mbp at samba.org
Fri Mar 5 00:01:39 GMT 2004


On  4 Mar 2004, Joe Buehler <jbuehler at hekimian.com> wrote:
> Attached are some patches for 2.12.1 that I did to get distcc working
> well with an existing build system (not gmake -- AT&T nmake) using
> AIX xlC, HPUX aCC and Microsoft Visual C++ under Cygwin.

Thanks for the patch.  The features are pretty cool.

I think open source maintainers in general like to get smaller patches
with single changes, rather than one big one.  It can make it easier
to review and to work out what went wrong if there is a problem.

Can you please document your changes in the man page and NEWS file, or
at least as text that can be pasted in?

Also, could you please update it for 2.13?  I think at least some of
the portability fixes are already in.

> Contents:
> 
> - partial support for Microsoft Visual C++ /Fd option (two output
>   files, .o and .pdb, instead of just the usual .o); some attempt was
>   made to make the code handle multiple output files in a generic
>   way

.pdbs are some kind of debug info file, aren't they?  So they would be
pretty useful, but not absolutely mandatory to use msvc?

> - compiler identification (by looking at its name) so we can alter
>   behavior accordingly for things like file suffixes

That's probably not a bad idea.

Perhaps people also need a way to statically fix it, e.g. from a
$DISTCC_DIR file, in case they're invoking something other than gcc as
'cc'.  Perhaps that can wait.

> - disabled mmap() for HPUX -- some UNIX versions do not integrate the
>   file cache and mmap() and modifying a file both ways can be
>   problematic

Is this fixed in 2.13 or not?

> - dynamically increase buffer size when uncompressing files --
>   Microsoft .pdb files compress REALLY well

OK.

> - compensation for some compiler oddities -- AIX xlC does not have any
>   suffix for preprocessed C input so you have to feed it a .c file so
>   it knows what it is and does not treat it as C++ -- HPUX aCC wants
>   .i file as C++ input
> 
> - had some problems with running from / under AIX -- the compiler
>   could not write some temp files as I recall

The concept of doing things in a writable temporary directory is OK.
But it shouldn't be hardcoded to /tmp, it should be dcc_get_tmp_top().

I wonder if it is secure to run the compiler in a 1777 directory?  Do
you suppose xlC really uses secure tempfiles?  Probably not.  Oh well.

> - switched to stdio and increased default output buffer size and
>   forced line-buffering to alleviate output interleaving problems from
>   large command lines

Hm.

> - fixed some minor syntax errors and prototyping problems that gcc
>   doesn't care about
> 
> note that I changed the wire protocol to be able to handle multiple
> compiler output files -- this needs compatibility work

I think I would like that, at least, to go in as a separate patch.

(You might like to look at the 'quilt' tool for managing patches,
http://savannah.nongnu.org/projects/quilt)

If we're going to change the protocol, which probably needs to happen
eventually, then I would like to have one clean change if we can.
Perhaps there are some other changes that ought to go in.  For
example, I think I would like for the client to do all of the command
line processing, and for the server to just execute what it is given,
aside from deciding on temporary filenames.

Another protocol change might be something to make sure the compiler
versions are equal.  This seems to be one of the most common problems
for users at the moment.  In a sense it is user error but it might be
good to prevent it.

> The .pdb handling for Microsoft Visual C++ is incomplete -- There is
> an assumption that there is one .pdb per .o, which is not necessarily
> the case (that's what my build system does), and the .pdb file names
> embedded in the .o result file are wrong (the .o output file needs to
> be corrected by distcc before exiting and I didn't implement that yet
> anyone wants to work on it).

The other thing that would be good, if you want to work on Windows,
would be to make distcc use some kind of spawn() rather than fork+exec
to execute the compiler.  There should be a large performance profit
here because Cygwin's synthesized fork() is so slow.

> +++ src/arg.c	2004-02-10 08:35:01.000000000 -0500
> @@ -122,13 +122,15 @@
>   *
>   * @returns 0 if it's ok to distribute this compilation, or an error code.
>   **/
> -int dcc_scan_args(char *argv[], char **input_file, char **output_file,
> -                  char ***ret_newargv)
> +int dcc_scan_args(char *argv[], char **input_file, struct output_files *of,
> +                  char ***ret_newargv, enum compiler_id *cid)
>  {
>      int seen_opt_c = 0, seen_opt_s = 0;
>      int i;
>      char *a;
>      int ret;
> +    char *s;
> +    char *s2;
>  
>       /* allow for -o foo.o */
>      if ((ret = dcc_shallowcopy_argv(argv, ret_newargv, 2)) != 0)
> @@ -145,24 +147,57 @@
>          exit(EXIT_BAD_ARGUMENTS);
>      }
>  
> -    *input_file = *output_file = NULL;
> +    *input_file = NULL;
> +    memset(of, 0, sizeof(*of));
> +
> +    /* strip directory from compiler name */
> +    rs_log_info("argv[0] %s", argv[0]);
> +    s = strrchr(argv[0], '/');
> +    if (s) {
> +        s = s + 1;
> +    } else {
> +        s = argv[0];
> +    }
> +    rs_log_info("s %s", s);
> +    s2 = strrchr(s, '\\');
> +    if (s2) {
> +        s = s2 + 1;
> +    }
> +    rs_log_info("s %s", s);
> +    /* figure out which compiler we are using */
> +    if (!strncmp(s, "xlC", 3)) {
> +        *cid = COMPILER_ID_AIX_XLC;
> +    } else if (!strcmp(s, "aCC")) {
> +        *cid = COMPILER_ID_HPUX_ACC;
> +    } else if (!strcmp(s, "cl")) {
> +        *cid = COMPILER_ID_WINDOWS_MSVC;
> +    } else if (!strcmp(s, "cl.exe")) {
> +        *cid = COMPILER_ID_WINDOWS_MSVC;
> +    } else if (!strcmp(s, "CL")) {
> +        *cid = COMPILER_ID_WINDOWS_MSVC;
> +    } else if (!strcmp(s, "CL.EXE")) {
> +        *cid = COMPILER_ID_WINDOWS_MSVC;
> +    } else {
> +        *cid = COMPILER_ID_GCC;
> +    }
> +    rs_log_info("compiler id %d", *cid);

This could probably stand to be in a different function.  It's getting
too big.

In fact, this dcc_scan_args probably needs different variants for
different compilers, plus a common part.

>  
>      for (i = 0; (a = argv[i]); i++) {
>          if (a[0] == '-') {
>              if (!strcmp(a, "-E")) {
>                  rs_trace("-E call for cpp must be local");
>                  return EXIT_DISTCC_FAILED;
> -            } else if (!strcmp(a, "-MD") || !strcmp(a, "-MMD")) {
> +            } else if (*cid == COMPILER_ID_GCC && (!strcmp(a, "-MD") || !strcmp(a, "-MMD"))) {
>                  /* These two generate dependencies as a side effect.  They
>                   * should work with the way we call cpp. */
> -            } else if (!strcmp(a, "-MG") || !strcmp(a, "-MP")) {
> +            } else if (*cid == COMPILER_ID_GCC && (!strcmp(a, "-MG") || !strcmp(a, "-MP"))) {
>                  /* These just modify the behaviour of other -M* options and do
>                   * nothing by themselves. */
> -            } else if (!strcmp(a, "-MF") || !strcmp(a, "-MT") || 
> -                       !strcmp(a, "-MQ")) {
> +            } else if (*cid == COMPILER_ID_GCC && (!strcmp(a, "-MF") || !strcmp(a, "-MT") || 
> +                       !strcmp(a, "-MQ"))) {
>                  /* as above but with extra argument */
>                  i++;
> -            } else if (a[1] == 'M') {
> +            } else if (*cid == COMPILER_ID_GCC && (a[1] == 'M')) {
>                  /* -M(anything else) causes the preprocessor to
>                      produce a list of make-style dependencies on
>                      header files, either to stdout or to a local file.
> @@ -213,14 +248,25 @@
>                      return EXIT_DISTCC_FAILED;
>                  }
>                  *input_file = a;
> +            } else if (*cid == COMPILER_ID_WINDOWS_MSVC && str_startswith("/Fd", a)) {
> +                a += 3;         /* skip "/Fd" */
> +                rs_trace("found debug/output file \"%s\"", a);
> +                if (of->debug_file) {
> +                    rs_log_info("two debug output files?  i give up");
> +                    return EXIT_DISTCC_FAILED;
> +                }
> +                of->debug_file = a;
> +            } else if (*cid == COMPILER_ID_WINDOWS_MSVC && str_startswith("/Fo", a)) {
> +                a += 3;         /* skip "/Fo" */
> +                goto GOT_OUTPUT;
>              } else if (str_endswith(".o", a)) {
>                GOT_OUTPUT:
>                  rs_trace("found object/output file \"%s\"", a);
> -                if (*output_file) {
> +                if (of->object_file) {
>                      rs_log_info("called for link?  i give up");
>                      return EXIT_DISTCC_FAILED;
>                  }
> -                *output_file = a;
> +                of->object_file = a;
>              }
>          }
>      }
> @@ -239,7 +285,7 @@
>          return EXIT_DISTCC_FAILED;
>      }
>  
> -    if (!*output_file) {
> +    if (!of->object_file) {
>          /* This is a commandline like "gcc -c hello.c".  They want
>           * hello.o, but they don't say so.  For example, the Ethereal
>           * makefile does this. 
> @@ -266,12 +312,12 @@
>                        ofile);
>          dcc_argv_append(argv, strdup("-o"));
>          dcc_argv_append(argv, ofile);
> -        *output_file = ofile;
> +        of->object_file = ofile;
>      }
>  
> -    dcc_note_compiled(*input_file, *output_file);
> +    dcc_note_compiled(*input_file, of->object_file);
>  
> -    if (strcmp(*output_file, "-") == 0) {
> +    if (strcmp(of->object_file, "-") == 0) {
>          /* Different compilers may treat "-o -" as either "write to
>           * stdout", or "write to a file called '-'".  We can't know,
>           * so we just always run it locally.  Hopefully this is a
> @@ -322,29 +368,52 @@
>   * detected by dcc_scan_args(), it's also correctly identified here.
>   * It might be better to make the code shared.
>   **/
> -int dcc_set_output(char **a, char *ofname)
> +int dcc_set_output(char **a, struct output_files *of, enum compiler_id cid)
>  {
>      int i;
> +    int ok = 0;
>      
>      for (i = 0; a[i]; i++) 
>          if (0 == strcmp(a[i], "-o")  &&  a[i+1] != NULL) {
>              rs_trace("changed output from \"%s\" to \"%s\"", a[i+1],
> -                     ofname);
> -            a[i+1] = ofname;
> +                     of->object_file);
> +            a[i+1] = of->object_file;
>              dcc_trace_argv("command after", a);
> -            return 0;
> +            ok = 1;
>          } else if (0 == strncmp(a[i], "-o", 2)) {
>              char *newptr;
>  
> -            if (asprintf(&newptr, "-o%s", ofname) == -1) {
> +            if (asprintf(&newptr, "-o%s", of->object_file) == -1) {
>                  rs_fatal("failed to allocate space for output parameter");
>              }
>              
>              a[i] = newptr;
>              dcc_trace_argv("command after", a);
> -            return 0;
> -        }
> +            ok = 1;
> +        } else if (cid == COMPILER_ID_WINDOWS_MSVC && !strncmp(a[i], "/Fd", 3)) {
> +            char *newptr;
>  
> +            if (asprintf(&newptr, "/Fd%s", of->debug_file) == -1) {
> +                rs_fatal("failed to allocate space for debug parameter");
> +            }
> +            
> +            a[i] = newptr;
> +            dcc_trace_argv("command after", a);
> +            /* ok = 1; */ /* debug output file is optional */
> +        } else if (cid == COMPILER_ID_WINDOWS_MSVC && !strncmp(a[i], "/Fo", 3)) {
> +            char *newptr;
> +
> +            if (asprintf(&newptr, "/Fo%s", of->object_file) == -1) {
> +                rs_fatal("failed to allocate space for output parameter");
> +            }
> +            
> +            a[i] = newptr;
> +            dcc_trace_argv("command after", a);
> +            ok = 1;
> +        }
> +    if (ok) {
> +        return 0;
> +    }
>      rs_log_error("failed to find \"-o\"");
>      return EXIT_DISTCC_FAILED;
>  }
> +++ src/arg.h	2004-02-10 08:35:01.000000000 -0500
> @@ -1,9 +1,9 @@
>  /* arg.c */
>  int dcc_set_action_opt(char **, const char *);
> -int dcc_set_output(char **, char *);
> +int dcc_set_output(char **, struct output_files *of, enum compiler_id cid);
>  int dcc_set_input(char **, char *);
> -int dcc_scan_args(char *argv[], /*@out@*/ /*@relnull@*/ char **orig_o,
> -                  char **orig_i, char ***ret_newargv);
> +int dcc_scan_args(char *argv[], /*@out@*/ /*@relnull@*/ char **input_file,
> +                  struct output_files *of, char ***ret_newargv, enum compiler_id *cid);
>  
>  /* argutil.c */
>  int dcc_argv_len(char **a);
> +++ src/clirpc.c	2004-02-10 08:35:01.000000000 -0500
> @@ -206,7 +206,7 @@
>   **/
>  int dcc_retrieve_results(int net_fd,
>                           int *status,
> -                         const char *output_fname,
> +                         struct output_files *of,
>                           struct dcc_hostdef *host)
>  {
>      unsigned len;
> @@ -225,13 +225,32 @@
>          || (ret = dcc_r_bulk(STDERR_FILENO, net_fd, len, host->compr))
>          || (ret = dcc_r_token_int(net_fd, "SOUT", &len))
>          || (ret = dcc_r_bulk(STDOUT_FILENO, net_fd, len, host->compr))
> -        || (ret = dcc_r_token_int(net_fd, "DOTO", &o_len)))
> +        || (ret = dcc_r_token_int(net_fd, "RSLT", &o_len)))
>          return ret;
>  
>      /* If the compiler succeeded, then we always retrieve the result,
>       * even if it's 0 bytes.  */
>      if (*status == 0) {
> -        return dcc_r_file_timed(net_fd, output_fname, o_len, host->compr);
> +        len = 0;
> +        if (of->object_file) ++len;
> +        if (of->debug_file) ++len;
> +        if (o_len != len) {
> +            rs_log_error("remote compiler returned unexpected number of files: "
> +                         "I don't know what to do");
> +        } else {
> +            if (of->object_file) {
> +                ret = dcc_r_token_int(net_fd, "FILE", &len);
> +                if (ret) return ret;
> +                ret = dcc_r_file_timed(net_fd, of->object_file, len, host->compr);
> +                if (ret) return ret;
> +            }
> +            if (of->debug_file) {
> +                ret = dcc_r_token_int(net_fd, "FILE", &len);
> +                if (ret) return ret;
> +                ret = dcc_r_file_timed(net_fd, of->debug_file, len, host->compr);
> +                if (ret) return ret;
> +            }
> +        }
>      } else if (o_len != 0) {
>          rs_log_error("remote compiler failed but also returned output: "
>                       "I don't know what to do");
> +++ src/compile.c	2004-02-10 08:35:01.000000000 -0500
> @@ -115,19 +115,22 @@
>                                 int sg_level,
>                                 int *status)
>  {
> -    char *input_fname = NULL, *output_fname, *cpp_fname;
> +    char *input_fname = NULL, *cpp_fname;
>      char **argv_stripped;
>      pid_t cpp_pid = 0;
>      int cpu_lock_fd;
>      int ret;
> +    int is_cplusplus = 0;
>      struct dcc_hostdef *host = NULL;
> +    struct output_files of;
> +    enum compiler_id cid;
>  
>      if (sg_level)
>          goto run_local;
>  
>      /* TODO: Perhaps tidy up these gotos. */
>  
> -    if (dcc_scan_args(argv, &input_fname, &output_fname, &argv) != 0) {
> +    if (dcc_scan_args(argv, &input_fname, &of, &argv, &cid) != 0) {
>          /* we need to scan the arguments even if we already know it's
>           * local, so that we can pick up distcc client options. */
>          goto lock_local;
> @@ -147,16 +150,16 @@
>      if (host->mode == DCC_MODE_LOCAL)
>          goto run_local;
>  
> -    if ((ret = dcc_cpp_maybe(argv, input_fname, &cpp_fname, &cpp_pid) != 0))
> +    if ((ret = dcc_cpp_maybe(argv, input_fname, &cpp_fname, &cpp_pid, &is_cplusplus, cid) != 0))
>          goto fallback;
>  
> -    if ((ret = dcc_strip_local_args(argv, &argv_stripped)))
> +    if ((ret = dcc_strip_local_args(argv, &argv_stripped, is_cplusplus, cid)))
>          goto fallback;
>  
>      if ((ret = dcc_compile_remote(argv_stripped,
>                                    input_fname,
>                                    cpp_fname,
> -                                  output_fname,
> +                                  &of,
>                                    cpp_pid, host, status)) != 0) {
>          /* Returns zero if we successfully ran the compiler, even if
>           * the compiler itself bombed out. */
> +++ src/compile.h	2004-02-10 08:35:01.000000000 -0500
> @@ -24,7 +24,7 @@
>  int dcc_compile_remote(char **argv,
>                         char *input_fname,
>                         char *cpp_fname,
> -                       char *output_fname,
> +                       struct output_files *of,
>                         pid_t cpp_pid,
>                         struct dcc_hostdef *host,
>                         int *status);
> +++ src/compress.c	2004-02-10 09:21:12.000000000 -0500
> @@ -95,7 +95,7 @@
>      int is_mmapped = 0;
>  
>      if (in_len >= 65536 && dcc_want_mmap()) {
> -#ifdef HAVE_MMAP
> +#if defined(HAVE_MMAP) && !defined(__hpux)
>          in_buf = mmap(NULL,            /* suggested address */
>                        in_len, PROT_READ, MAP_SHARED, in_fd,
>                        0);              /* offset */
> @@ -229,8 +229,10 @@
>      /* Generously sized output buffer */
>      out_size = 64 * in_len;
>  
> +    try_again_with_a_bigger_buffer:
> +
>      if (out_size >= 65536  &&  dcc_want_mmap()) {
> -#ifdef HAVE_MMAP
> +#if defined(HAVE_MMAP) && !defined(__hpux)
>          /* First truncate the file, so that we have space to write to it.  This
>           * will fail if we're e.g. writing to stdout. */
>      
> @@ -274,9 +276,26 @@
>      lzo_ret = lzo1x_decompress_safe((lzo_byte*)in_buf, in_len,
>                                      (lzo_byte*)out_buf, &out_len, work_mem);
>      if (lzo_ret != LZO_E_OK) {
> -        rs_log_error("LZO1X1 decompression failed: %d", lzo_ret);
> -        ret = EXIT_IO_ERROR;
> -        goto out;
> +        if (lzo_ret != LZO_E_OUTPUT_OVERRUN) {
> +            rs_log_error("LZO1X1 decompression failed: %d", lzo_ret);
> +            ret = EXIT_IO_ERROR;
> +            goto out;
> +        }
> +        out_size *= 2;
> +        rs_log_error("LZO_E_OUTPUT_OVERRUN, trying again with a bigger buffer (%d)", out_size);
> +        if (is_mmapped) {
> +            if (munmap(out_buf, out_size) == -1) {
> +                rs_log_error("munmap (output) failed: %s",
> +                             strerror(errno));
> +                ret = EXIT_IO_ERROR;
> +                goto out;
> +            }
> +            is_mmapped = 0;
> +        } else if (out_buf != NULL) {
> +            free(out_buf);
> +            out_buf = 0;
> +        }
> +        goto try_again_with_a_bigger_buffer;
>      }
>  
>      rs_trace("decompressed %ld bytes to %ld bytes: %d%%",
> +++ src/cpp.c	2004-02-10 08:35:01.000000000 -0500
> @@ -57,13 +57,14 @@
>   * use many cycles, with running the preprocessor.
>   **/
>  int dcc_cpp_maybe(char **argv, char *input_fname, char **cpp_fname,
> -		  pid_t *cpp_pid)
> +		  pid_t *cpp_pid, int *is_cplusplus, enum compiler_id cid)
>  {
>      char **cpp_argv;
>      int ret;
>      char *input_exten;
>      const char *output_exten;
>  
> +    *is_cplusplus = 0;
>      *cpp_pid = 0;
>      
>      if (dcc_is_preprocessed(input_fname)) {
> @@ -79,7 +80,7 @@
>      }
>  
>      input_exten = dcc_find_extension(input_fname);
> -    output_exten = dcc_preproc_exten(input_exten);
> +    output_exten = dcc_preproc_exten(input_exten, is_cplusplus, cid);
>      if ((ret = dcc_make_tmpnam("distcc", output_exten, cpp_fname)))
>          return ret;
>  
> +++ src/cpp.h	2004-02-10 08:35:01.000000000 -0500
> @@ -1,2 +1,2 @@
>  int dcc_cpp_maybe(char **argv, char *input_fname, char **cpp_fname,
> -		  pid_t *cpp_pid);
> +		  pid_t *cpp_pid, int *is_cplusplus, enum compiler_id cid);
> +++ src/daemon.c	2004-02-10 08:35:01.000000000 -0500
> @@ -181,8 +181,8 @@
>      /* Do everything from root directory.  Allows start directory to be
>       * unmounted, should make accidental writing of local files cause a
>       * failure... */
> -    if (chdir("/") == -1) {
> -        rs_log_error("failed to chdir to /: %s", strerror(errno));
> +    if (chdir("/tmp") == -1) {
> +        rs_log_error("failed to chdir to /tmp: %s", strerror(errno));
>          ret = EXIT_IO_ERROR;
>          goto out;
>      }
> +++ src/distcc.c	2004-02-10 08:35:01.000000000 -0500
> @@ -163,6 +163,9 @@
>  
>      dcc_trace_version();
>  
> +    setvbuf(stdout, 0, _IOLBF, 32768);
> +    setvbuf(stderr, 0, _IOLBF, 32768);
> +
>      compiler_name = (char *) dcc_find_basename(argv[0]);
>  
>      /* Ignore SIGPIPE; we consistently check error codes and will
> +++ src/distcc.h	2004-02-10 08:35:01.000000000 -0500
> @@ -53,10 +53,17 @@
>  
>  struct dcc_hostdef;
>  
> +struct output_files {
> +    char *object_file;
> +    char *debug_file;
> +};
>  
> -
> -
> -
> +enum compiler_id {
> +    COMPILER_ID_GCC = 0,
> +    COMPILER_ID_WINDOWS_MSVC = 1,
> +    COMPILER_ID_AIX_XLC = 2,
> +    COMPILER_ID_HPUX_ACC = 3
> +};
>  
>  enum dcc_compress {
>      /* wierd values to catch errors */
> @@ -125,7 +132,8 @@
>                          struct dcc_hostdef *);
>  
>  int dcc_retrieve_results(int net_fd,
> -                         int *status, const char *output_fname,
> +                         int *status,
> +                         struct output_files *of,
>                           struct dcc_hostdef *);
>  
>  /* climasq.c */
> @@ -183,4 +191,3 @@
>  #ifndef MAXPATHLEN
>  #define MAXPATHLEN 4096
>  #endif
> -
> +++ src/exitcode.h	2004-02-10 08:35:01.000000000 -0500
> @@ -53,7 +53,7 @@
>      EXIT_BUSY                     = 114, /**< In use by another process. */
>      EXIT_NO_SUCH_FILE             = 115,
>      EXIT_NO_HOSTS                 = 116,
> -    EXIT_GONE                     = 117, /**< No longer relevant */
> +    EXIT_GONE                     = 117 /**< No longer relevant */
>  };
>  
>  
> +++ src/filename.c	2004-02-10 08:35:01.000000000 -0500
> @@ -133,18 +133,29 @@
>   * @returns preprocessed extension, (e.g. ".i"), or NULL if
>   * unrecognized.
>   **/
> -const char * dcc_preproc_exten(const char *e)
> +const char * dcc_preproc_exten(const char *e, int *is_cplusplus, enum compiler_id cid)
>  {
>      if (e[0] != '.')
>          return NULL;
>      e++;
>      if (!strcmp(e, "i") || !strcmp(e, "c")) {
> -        return ".i";
> +        if (cid == COMPILER_ID_AIX_XLC) {
> +            /* AIX xlC C/C++ compiler treats .i file as C++ so we have to leave it .c */
> +            return ".c";
> +        } else {
> +            return ".i";
> +        }
>      } else if (!strcmp(e, "c") || !strcmp(e, "cc")
>                 || !strcmp(e, "cpp") || !strcmp(e, "cxx")
>                 || !strcmp(e, "cp") || !strcmp(e, "c++")
>                 || !strcmp(e, "C") || !strcmp(e, "ii")) {
> -        return ".ii";
> +        *is_cplusplus = 1;
> +        if (cid == COMPILER_ID_HPUX_ACC) {
> +            /* HPUX aCC C++ compiler wants .i file as C++ input */
> +            return ".i";
> +        } else {
> +            return ".ii";
> +        }
>      } else if(!strcmp(e,"mi") || !strcmp(e, "m")) {
>          return ".mi";
>      } else if(!strcmp(e,"mii") || !strcmp(e,"mm")
> +++ src/filename.h	2004-02-10 08:35:01.000000000 -0500
> @@ -7,5 +7,5 @@
>  int dcc_output_from_source(const char *sfile, const char *out_extn,
>                             char **ofile);
>  
> -const char * dcc_preproc_exten(const char *e);
> +const char * dcc_preproc_exten(const char *e, int *is_cplusplus, enum compiler_id cid);
>  const char * dcc_find_basename(const char *sfile);
> +++ src/h_scanargs.c	2004-02-10 08:35:01.000000000 -0500
> @@ -49,8 +49,12 @@
>  int main(int argc, char *argv[])
>  {
>      int result;
> -    char *infname, *outfname;
> +    char *infname;
>      char **newargv, **outargv;
> +    struct output_files of;
> +    enum compiler_id cid;
> +
> +    memset(&of, 0, sizeof(of));
>  
>      rs_trace_set_level(RS_LOG_DEBUG);
>  
> @@ -64,11 +68,11 @@
>      if (result)
>  	return result;
>  
> -    result = dcc_scan_args(newargv, &infname, &outfname, &outargv);
> +    result = dcc_scan_args(newargv, &infname, &of, &outargv, &cid);
>  
>      printf("%s %s %s\n",
>  	   result == 0 ? "distribute" : "local",
> -	   infname ? infname : "(NULL)", outfname ? outfname : "(NULL)");
> +	   infname ? infname : "(NULL)", of->object_file ? of->object_file : "(NULL)");
>  
>      return 0;
>  }
> +++ src/h_strip.c	2004-02-10 08:35:01.000000000 -0500
> @@ -56,7 +56,8 @@
>          return 1;
>      }
>  
> -    if ((ret = dcc_strip_local_args(argv + 1, &new_args))) {
> +    if ((ret = dcc_strip_local_args(argv + 1, &new_args, 0 /* is_cplusplus */,
> +                                    COMPILER_ID_GCC))) {
>          return ret;
>      }
>  
> +++ src/hosts.c	2004-02-10 08:35:01.000000000 -0500
> @@ -383,7 +383,7 @@
>          }
>  
>          /* Store verbatim hostname */
> -        if (!(curr->hostdef_string = strndup(token_start, token_len))) {
> +        if (!(curr->hostdef_string = (char *)strndup(token_start, token_len))) {
>              rs_log_crit("failed to allocate hostdef_string");
>              return EXIT_OUT_OF_MEMORY;
>          }
> +++ src/io.c	2004-02-10 08:35:01.000000000 -0500
> @@ -72,7 +72,7 @@
>  
>  int dcc_want_mmap(void)
>  {
> -#ifdef HAVE_MMAP
> +#if defined(HAVE_MMAP) && !defined(__hpux)
>      return dcc_getenv_bool("DISTCC_MMAP", 1);
>  #else
>      return 0;
> @@ -166,7 +166,7 @@
>      int ret;
>  
>      while (len > 0) {
> -	r = read(fd, buf, len);
> +        r = read(fd, buf, len);
>  
>          if (r == -1 && errno == EAGAIN) {
>              if ((ret = dcc_select_for_read(fd, dcc_io_timeout)))
> @@ -176,15 +176,15 @@
>          } else if (r == -1 && errno == EAGAIN) {
>              continue;
>          } else if (r == -1) {
> -	    rs_log_error("failed to read: %s", strerror(errno));
> -	    return EXIT_IO_ERROR;
> -	} else if (r == 0) {
> -	    rs_log_error("unexpected eof on fd%d", fd);
> -	    return EXIT_TRUNCATED;
> -	} else {
> -	    buf = &((char *) buf)[r];
> -	    len -= r;
> -	}
> +            rs_log_error("failed to read: %s", strerror(errno));
> +            return EXIT_IO_ERROR;
> +        } else if (r == 0) {
> +            rs_log_error("dcc_readx() unexpected eof on fd%d", fd);
> +            return EXIT_TRUNCATED;
> +        } else {
> +            buf = &((char *) buf)[r];
> +            len -= r;
> +        }
>      }
>  
>      return 0;
> @@ -203,7 +203,15 @@
>      int ret;
>  	
>      while (len > 0) {
> -        r = write(fd, buf, len);
> +        if (fd == STDOUT_FILENO) {
> +            r = (fwrite(buf, len, 1, stdout) == 1) ? len : -1;
> +            /* fflush(stdout); */
> +        } else if (fd == STDERR_FILENO) {
> +            r = (fwrite(buf, len, 1, stderr) == 1) ? len : -1;
> +            /* fflush(stderr); */
> +        } else {
> +            r = write(fd, buf, len);
> +        }
>  
>          if (r == -1 && errno == EAGAIN) {
>              if ((ret = dcc_select_for_write(fd, dcc_io_timeout)))
> @@ -216,7 +224,7 @@
>              rs_log_error("failed to write: %s", strerror(errno));
>              return EXIT_IO_ERROR;
>          } else if (r == 0) {
> -            rs_log_error("unexpected eof on fd%d", fd);
> +            rs_log_error("dcc_writex() unexpected eof on fd%d", fd);
>              return EXIT_TRUNCATED;
>          } else {
>              buf = &((char *) buf)[r];
> +++ src/pump.c	2004-02-10 08:35:01.000000000 -0500
> @@ -75,7 +75,7 @@
>          return 0;               /* just check */
>  
>      if (len >= 65536  &&  dcc_want_mmap()) {
> -#ifdef HAVE_MMAP
> +#if defined(HAVE_MMAP) && !defined(__hpux)
>          /* First truncate the file, so that we have space to write to it.  This
>           * will fail if we're e.g. writing to stdout. */
>      
> @@ -204,7 +204,7 @@
>                           (long) wanted, strerror(errno));
>              return EXIT_IO_ERROR;
>          } else if (r_in == 0) {
> -            rs_log_error("unexpected eof on fd%d", ifd);
> +            rs_log_error("dcc_pump_readwrite() unexpected eof on fd%d", ifd);
>              return EXIT_IO_ERROR;
>          }
>          
> +++ src/remote.c	2004-02-10 08:35:01.000000000 -0500
> @@ -127,7 +127,7 @@
>  int dcc_compile_remote(char **argv, 
>                         char *input_fname,
>                         char *cpp_fname,
> -                       char *output_fname,
> +                       struct output_files *of,
>                         pid_t cpp_pid,
>                         struct dcc_hostdef *host,
>                         int *status)
> @@ -168,8 +168,7 @@
>      /* If cpp failed, just abandon the connection, without trying to
>       * receive results. */
>      if (ret == 0 && *status == 0) {
> -        ret = dcc_retrieve_results(from_net_fd, status, output_fname,
> -                                   host);
> +        ret = dcc_retrieve_results(from_net_fd, status, of, host);
>      }
>  
>      /* Close socket so that the server can terminate, rather than
> +++ src/serve.c	2004-02-10 08:35:01.000000000 -0500
> @@ -162,14 +162,16 @@
>  
>  
>  static int dcc_input_tmpnam(char * orig_input,
> -                            char **tmpnam_ret)
> +                            char **tmpnam_ret,
> +                            enum compiler_id cid)
>  {
> +    int is_cplusplus = 0;
>      const char *input_exten;
>      
>      rs_trace("input file %s", orig_input);
>      input_exten = dcc_find_extension(orig_input);
>      if (input_exten)
> -        input_exten = dcc_preproc_exten(input_exten);
> +        input_exten = dcc_preproc_exten(input_exten, &is_cplusplus, cid);
>      if (!input_exten)           /* previous line might return NULL */
>          input_exten = ".tmp";
>      return dcc_make_tmpnam("distccd", input_exten, tmpnam_ret);
> @@ -252,13 +254,19 @@
>  {
>      char **argv;
>      int status;
> -    char *temp_i, *temp_o, *err_fname, *out_fname;
> +    char *temp_i, *err_fname, *out_fname;
>      int ret, compile_ret;
> -    char *orig_input, *orig_output;
> +    char *orig_input;
>      pid_t cc_pid;
>      enum dcc_protover protover;
>      enum dcc_compress compr;
> +    struct output_files of_orig;
> +    struct output_files of_temp;
> +    enum compiler_id cid;
>      
> +    memset(&of_temp, 0, sizeof(of_temp));
> +    memset(&of_orig, 0, sizeof(of_orig));
> +
>      if ((ret = dcc_make_tmpnam("distcc", ".stderr", &err_fname)))
>          return ret;
>      if ((ret = dcc_make_tmpnam("distcc", ".stdout", &out_fname)))
> @@ -282,21 +290,28 @@
>  
>      if ((ret = dcc_r_request_header(in_fd, &protover))
>          || (ret = dcc_r_argv(in_fd, &argv))
> -        || (ret = dcc_scan_args(argv, &orig_input, &orig_output, &argv)))
> +        || (ret = dcc_scan_args(argv, &orig_input, &of_orig, &argv, &cid)))
>          goto out_cleanup;
>      
> -    rs_trace("output file %s", orig_output);
> +    rs_trace("output file %s", of_orig.object_file);
> +    rs_trace("debug file %s", of_orig.debug_file ? of_orig.debug_file : "not present");
>  
> -    if ((ret = dcc_input_tmpnam(orig_input, &temp_i)))
> -        goto out_cleanup;
> -    if ((ret = dcc_make_tmpnam("distccd", ".o", &temp_o)))
> +    if ((ret = dcc_input_tmpnam(orig_input, &temp_i, cid)))
>          goto out_cleanup;
> +    if (of_orig.object_file) {
> +        if ((ret = dcc_make_tmpnam("distccd", ".o", &of_temp.object_file)))
> +            goto out_cleanup;
> +    }
> +    if (of_orig.debug_file) {
> +        if ((ret = dcc_make_tmpnam("distccd", ".pdb", &of_temp.debug_file)))
> +            goto out_cleanup;
> +    }
>  
>      compr = (protover == 2) ? DCC_COMPRESS_LZO1X : DCC_COMPRESS_NONE;
>  
>      if ((ret = dcc_r_token_file(in_fd, "DOTI", temp_i, compr))
>          || (ret = dcc_set_input(argv, temp_i))
> -        || (ret = dcc_set_output(argv, temp_o)))
> +        || (ret = dcc_set_output(argv, &of_temp, cid)))
>          goto out_cleanup;
>  
>      if ((ret = dcc_check_compiler_masq(argv[0])))
> @@ -315,10 +330,19 @@
>          || (ret = dcc_x_file(out_fd, out_fname, "SOUT", compr))
>          || WIFSIGNALED(status)
>          || WEXITSTATUS(status)) {
> -        /* Something went wrong, so send DOTO 0 */
> -        dcc_x_token_int(out_fd, "DOTO", 0);
> +        /* Something went wrong, so send RSLT 0 */
> +        ret = dcc_x_token_int(out_fd, "RSLT", 0);
>      } else {
> -        ret = dcc_x_file(out_fd, temp_o, "DOTO", compr);
> +        int len = 0;
> +        if (of_orig.object_file) ++len;
> +        if (of_orig.debug_file) ++len;
> +        ret = dcc_x_token_int(out_fd, "RSLT", len);
> +        if (of_orig.object_file) {
> +            ret = ret || dcc_x_file(out_fd, of_temp.object_file, "FILE", compr);
> +        }
> +        if (of_orig.debug_file) {
> +            ret = ret || dcc_x_file(out_fd, of_temp.debug_file, "FILE", compr);
> +        }
>      }
>  
>      dcc_critique_status(status, argv[0], dcc_hostdef_local, 0);
> +++ src/strip.c	2004-02-10 08:35:01.000000000 -0500
> @@ -59,14 +59,14 @@
>   * passed directly to cpp.  When given to gcc they have different
>   * meanings.
>   **/
> -int dcc_strip_local_args(char **from, char ***out_argv)
> +int dcc_strip_local_args(char **from, char ***out_argv, int is_cplusplus, enum compiler_id cid)
>  {
>      char **to;
>      int from_i, to_i;
>      int from_len;
>  
>      from_len = dcc_argv_len(from);
> -    *out_argv = to = malloc((from_len + 1) * sizeof (char *));
> +    *out_argv = to = malloc((from_len + 1 + (is_cplusplus && cid == COMPILER_ID_AIX_XLC)) * sizeof (char *));
>  
>      if (!to) {
>          rs_log_error("failed to allocate space for arguments");
> @@ -81,9 +81,9 @@
>              || str_equal("-U", from[from_i])
>              || str_equal("-L", from[from_i])
>              || str_equal("-l", from[from_i])
> -            || str_equal("-MF", from[from_i])
> -            || str_equal("-MT", from[from_i])
> -            || str_equal("-MQ", from[from_i])
> +            || (cid == COMPILER_ID_GCC && str_equal("-MF", from[from_i]))
> +            || (cid == COMPILER_ID_GCC && str_equal("-MT", from[from_i]))
> +            || (cid == COMPILER_ID_GCC && str_equal("-MQ", from[from_i]))
>              || str_equal("-include", from[from_i])
>              || str_equal("-imacros", from[from_i])
>              || str_equal("-iprefix", from[from_i])
> @@ -109,16 +109,20 @@
>          else if (str_equal("-undef", from[from_i])
>                   || str_equal("-nostdinc", from[from_i])
>                   || str_equal("-nostdinc++", from[from_i])
> -                 || str_equal("-MD", from[from_i])
> -                 || str_equal("-MMD", from[from_i])
> -                 || str_equal("-MG", from[from_i])
> -                 || str_equal("-MP", from[from_i])) {
> +                 || (cid == COMPILER_ID_GCC && str_equal("-MD", from[from_i]))
> +                 || (cid == COMPILER_ID_GCC && str_equal("-MMD", from[from_i]))
> +                 || (cid == COMPILER_ID_GCC && str_equal("-MG", from[from_i]))
> +                 || (cid == COMPILER_ID_GCC && str_equal("-MP", from[from_i]))) {
>              /* Options that only affect cpp; skip */
>              ;
>          }
>          else {
>              to[to_i++] = from[from_i];
>          }
> +        if (from_i == 0 && is_cplusplus && cid == COMPILER_ID_AIX_XLC) {
> +            /* force AIX xlC to compile as C++ if the input is indeed C++ */
> +            to[to_i++] = "-+";
> +        }
>      }
>      
>      /* NULL-terminate */
> +++ src/strip.h	2004-02-10 08:35:01.000000000 -0500
> @@ -21,5 +21,5 @@
>   * USA
>   */
>  
> -int dcc_strip_local_args(char **from, char ***out_argv);
> +int dcc_strip_local_args(char **from, char ***out_argv, int is_cplusplus, enum compiler_id cid);
>  int dcc_strip_dasho(char **from, char ***out_argv);
> +++ src/tempfile.c	2004-02-10 08:49:18.000000000 -0500
> @@ -268,6 +268,12 @@
>                       suffix) == -1)
>              return EXIT_OUT_OF_MEMORY;
>  
> +        if (!strcmp(suffix, ".pdb")) {
> +            /* do NOT create .pdb file for compiler -- in fact, make sure it does not exist */
> +            unlink(s);
> +            break;
> +        }
> +
>          /* Note that if the name already exists as a symlink, this
>           * open call will fail.
>           *

> __ 
> distcc mailing list            http://distcc.samba.org/
> To unsubscribe or change options: 
> http://lists.samba.org/mailman/listinfo/distcc
-- 
Martin 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
Url : http://lists.samba.org/archive/distcc/attachments/20040305/20391af7/attachment.bin


More information about the distcc mailing list