⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 io.c

📁 linux subdivision ying gai ke yi le ba
💻 C
📖 第 1 页 / 共 5 页
字号:
                             cmdproc_attr, pool);
  if (apr_err)
    return svn_error_wrap_apr (apr_err, "Can't start process '%s'", cmd);

  /* The Win32 apr_proc_wait doesn't set this... */
  exitwhy_val = APR_PROC_EXIT;

  /* Wait for the cmd command to finish. */
  apr_err = apr_proc_wait (&cmd_proc, &exitcode_val, &exitwhy_val, APR_WAIT);
  if (APR_STATUS_IS_CHILD_NOTDONE (apr_err))
    return svn_error_wrap_apr (apr_err, "Error waiting for process '%s'", cmd);

  if (exitwhy)
    *exitwhy = exitwhy_val;
  else if (! APR_PROC_CHECK_EXIT(exitwhy_val))
    return svn_error_createf
      (SVN_ERR_EXTERNAL_PROGRAM, NULL,
       "Process '%s' failed (exitwhy %d)", cmd, exitwhy_val);

  if (exitcode)
    *exitcode = exitcode_val;
  else if (exitcode_val != 0)
    return svn_error_createf
      (SVN_ERR_EXTERNAL_PROGRAM, NULL,
       "Process '%s' returned error exitcode %d", cmd, exitcode_val);

  return SVN_NO_ERROR;
}


svn_error_t *
svn_io_run_diff (const char *dir, 
                 const char *const *user_args,
                 int num_user_args, 
                 const char *label1,
                 const char *label2,
                 const char *from,
                 const char *to,
                 int *pexitcode, 
                 apr_file_t *outfile, 
                 apr_file_t *errfile, 
                 const char *diff_cmd,
                 apr_pool_t *pool)
{
  const char **args;
  int i; 
  int exitcode;
  int nargs = 4; /* the diff command itself, two paths, plus a trailing NULL */
  const char *diff_utf8;
  apr_pool_t *subpool = svn_pool_create (pool);

  SVN_ERR (svn_path_cstring_to_utf8 (&diff_utf8, diff_cmd, pool));

  if (pexitcode == NULL)
    pexitcode = &exitcode;

  if (user_args != NULL)
    nargs += num_user_args;
  else
    nargs += 1; /* -u */

  if (label1 != NULL)
    nargs += 2; /* the -L and the label itself */
  if (label2 != NULL)
    nargs += 2; /* the -L and the label itself */

  args = apr_palloc (subpool, nargs * sizeof(char *));

  i = 0;
  args[i++] = diff_utf8;

  if (user_args != NULL)
    {
      int j;
      for (j = 0; j < num_user_args; ++j)
        args[i++] = user_args[j];
    }
  else
    args[i++] = "-u"; /* assume -u if the user didn't give us any args */

  if (label1 != NULL)
    {
      args[i++] = "-L";
      args[i++] = label1;
    }
  if (label2 != NULL)
    {
      args[i++] = "-L";
      args[i++] = label2;
    }

  args[i++] = svn_path_local_style (from, subpool);
  args[i++] = svn_path_local_style (to, subpool);
  args[i++] = NULL;

  assert (i == nargs);

  SVN_ERR (svn_io_run_cmd (dir, diff_utf8, args, pexitcode, NULL, TRUE, 
                           NULL, outfile, errfile, subpool));

  /* The man page for (GNU) diff describes the return value as:

       "An exit status of 0 means no differences were found, 1 means
        some differences were found, and 2 means trouble."

     A return value of 2 typically occurs when diff cannot read its input
     or write to its output, but in any case we probably ought to return an
     error for anything other than 0 or 1 as the output is likely to be
     corrupt.
   */
  if (*pexitcode != 0 && *pexitcode != 1)
    return svn_error_createf (SVN_ERR_EXTERNAL_PROGRAM, NULL, 
                              "'%s' returned %d", diff_utf8, *pexitcode);

  svn_pool_destroy (subpool);

  return SVN_NO_ERROR;
}



svn_error_t *
svn_io_run_diff3 (const char *dir,
                  const char *mine,
                  const char *older,
                  const char *yours,
                  const char *mine_label,
                  const char *older_label,
                  const char *yours_label,
                  apr_file_t *merged,
                  int *exitcode,
                  const char *diff3_cmd,
                  apr_pool_t *pool)
{
  const char *args[14];
  const char *diff3_utf8;
#ifndef NDEBUG
  int nargs = 13;
#endif
  int i = 0;

  SVN_ERR (svn_path_cstring_to_utf8 (&diff3_utf8, diff3_cmd, pool));

  /* Labels fall back to sensible defaults if not specified. */
  if (mine_label == NULL)
    mine_label = ".working";
  if (older_label == NULL)
    older_label = ".old";
  if (yours_label == NULL)
    yours_label = ".new";
  
  /* Set up diff3 command line. */
  args[i++] = diff3_utf8;
  args[i++] = "-E";             /* We tried "-A" here, but that caused
                                   overlapping identical changes to
                                   conflict.  See issue #682. */
  args[i++] = "-m";
  args[i++] = "-L";
  args[i++] = mine_label;
  args[i++] = "-L";
  args[i++] = older_label;      /* note:  this label is ignored if
                                   using 2-part markers, which is the
                                   case with "-E". */
  args[i++] = "-L";
  args[i++] = yours_label;
#ifdef SVN_DIFF3_HAS_DIFF_PROGRAM_ARG
  {
    svn_boolean_t has_arg;

    /* ### FIXME: we really shouldn't be reading the config here;
       instead, the necessary bits should be passed in by the caller.
       But should we add another parameter to this function, when the
       whole external diff3 thing might eventually go away?  */
    apr_hash_t *config;
    svn_config_t *cfg;

    SVN_ERR (svn_config_get_config (&config, pool));
    cfg = config ? apr_hash_get (config, SVN_CONFIG_CATEGORY_CONFIG,
                                 APR_HASH_KEY_STRING) : NULL;
    SVN_ERR (svn_config_get_bool (cfg, &has_arg, SVN_CONFIG_SECTION_HELPERS,
                                  SVN_CONFIG_OPTION_DIFF3_HAS_PROGRAM_ARG,
                                  TRUE));
    if (has_arg)
      {
        const char *diff_cmd, *diff_utf8;
        svn_config_get (cfg, &diff_cmd, SVN_CONFIG_SECTION_HELPERS,
                        SVN_CONFIG_OPTION_DIFF_CMD, SVN_CLIENT_DIFF);
        SVN_ERR (svn_path_cstring_to_utf8 (&diff_utf8, diff_cmd, pool));
        args[i++] = apr_pstrcat(pool, "--diff-program=", diff_utf8, NULL);
#ifndef NDEBUG
        ++nargs;
#endif
      }
  }
#endif
  args[i++] = svn_path_local_style (mine, pool);
  args[i++] = svn_path_local_style (older, pool);
  args[i++] = svn_path_local_style (yours, pool);
  args[i++] = NULL;
  assert (i == nargs);

  /* Run diff3, output the merged text into the scratch file. */
  SVN_ERR (svn_io_run_cmd (dir, diff3_utf8, args, 
                           exitcode, NULL, 
                           TRUE, /* keep environment */
                           NULL, merged, NULL,
                           pool));

  /* According to the diff3 docs, a '0' means the merge was clean, and
     '1' means conflict markers were found.  Anything else is real
     error. */
  if ((*exitcode != 0) && (*exitcode != 1))
    return svn_error_createf (SVN_ERR_EXTERNAL_PROGRAM, NULL, 
                              "Error running '%s':  exitcode was %d, args were:"
                              "\nin directory '%s', basenames:\n%s\n%s\n%s",
                              diff3_utf8, *exitcode,
                              dir, mine, older, yours);

  return SVN_NO_ERROR;
}


svn_error_t *
svn_io_detect_mimetype (const char **mimetype,
                        const char *file,
                        apr_pool_t *pool)
{
  static const char * const generic_binary = "application/octet-stream";

  svn_node_kind_t kind;
  apr_file_t *fh;
  svn_error_t *err;
  unsigned char block[1024];
  apr_size_t amt_read = sizeof (block);

  /* Default return value is NULL. */
  *mimetype = NULL;

  /* See if this file even exists, and make sure it really is a file. */
  SVN_ERR (svn_io_check_path (file, &kind, pool));
  if (kind != svn_node_file)
    return svn_error_createf (SVN_ERR_BAD_FILENAME, NULL,
                              "Can't detect MIME type of non-file '%s'",
                              file);

  SVN_ERR (svn_io_file_open (&fh, file, APR_READ, 0, pool));

  /* Read a block of data from FILE. */
  err = svn_io_file_read (fh, block, &amt_read, pool);
  if (err && ! APR_STATUS_IS_EOF(err->apr_err))
    return err;
  svn_error_clear (err);

  /* Now close the file.  No use keeping it open any more.  */
  SVN_ERR (svn_io_file_close (fh, pool));


  /* Right now, this function is going to be really stupid.  It's
     going to examine the first block of data, and make sure that 85%
     of the bytes are such that their value is in the ranges 0x07-0x0D
     or 0x20-0x7F, and that 100% of those bytes is not 0x00.

     If those criteria are not met, we're calling it binary. */
  if (amt_read > 0)
    {
      apr_size_t i;
      int binary_count = 0;
      
      /* Run through the data we've read, counting the 'binary-ish'
         bytes.  HINT: If we see a 0x00 byte, we'll set our count to its
         max and stop reading the file. */
      for (i = 0; i < amt_read; i++)
        {
          if (block[i] == 0)
            {
              binary_count = amt_read;
              break;
            }
          if ((block[i] < 0x07)
              || ((block[i] > 0x0D) && (block[i] < 0x20))
              || (block[i] > 0x7F))
            {
              binary_count++;
            }
        }
      
      if (((binary_count * 1000) / amt_read) > 850)
        {
          *mimetype = generic_binary;
          return SVN_NO_ERROR;
        }
    }
  
  return SVN_NO_ERROR;
}


svn_error_t *
svn_io_file_open (apr_file_t **new_file, const char *fname,
                  apr_int32_t flag, apr_fileperms_t perm,
                  apr_pool_t *pool)
{
  const char *fname_apr;
  apr_status_t status;

  SVN_ERR (svn_path_cstring_from_utf8 (&fname_apr, fname, pool));
  status = apr_file_open (new_file, fname_apr, flag, perm, pool);

  if (status)
    return svn_error_wrap_apr (status, "Can't open file '%s'", fname);
  else
    return SVN_NO_ERROR;  
}


static svn_error_t *
do_io_file_wrapper_cleanup (apr_file_t *file, apr_status_t status, 
                            const char *op, apr_pool_t *pool)
{
  const char *name;
  svn_error_t *err;

  if (! status)
    return SVN_NO_ERROR;

  err = file_name_get (&name, file, pool);
  name = (! err && name) ? apr_psprintf (pool, "file '%s'", name) : "stream";
  svn_error_clear (err);

  return svn_error_wrap_apr (status, "Can't %s %s", op, name);
}


svn_error_t *
svn_io_file_close (apr_file_t *file, apr_pool_t *pool)
{
  return do_io_file_wrapper_cleanup
    (file, apr_file_close (file),
      "close", pool);
}


svn_error_t *
svn_io_file_getc (char *ch, apr_file_t *file, apr_pool_t *pool)
{
  return do_io_file_wrapper_cleanup
    (file, apr_file_getc (ch, file),
     "read", pool);
}


svn_error_t *
svn_io_file_info_get (apr_finfo_t *finfo, apr_int32_t wanted, 
                      apr_file_t *file, apr_pool_t *pool)
{
  return do_io_file_wrapper_cleanup
    (file, apr_file_info_get (finfo, wanted, file),
     "get attribute information from", pool);
}


svn_error_t *
svn_io_file_read (apr_file_t *file, void *buf, 
                  apr_size_t *nbytes, apr_pool_t *pool)
{
  return do_io_file_wrapper_cleanup
    (file, apr_file_read (file, buf, nbytes),
     "read", pool);
}


svn_error_t *
svn_io_file_read_full (apr_file_t *file, void *buf, 
                        apr_size_t nbytes, apr_size_t *bytes_read,
                        apr_pool_t *pool)
{
  return do_io_file_wrapper_cleanup
    (file, apr_file_read_full (file, buf, nbytes, bytes_read),
     "read", pool);
}


svn_error_t *
svn_io_file_seek (apr_file_t *file, apr_seek_where_t where, 
                  apr_off_t *offset, apr_pool_t *pool)
{
  return do_io_file_wrapper_cleanup
    (file, apr_file_seek (file, where, offset),
     "set position pointer in", pool);
}


svn_error_t *
svn_io_file_write (apr_file_t *file, const void *buf, 
                   apr_size_t *nbytes, apr_pool_t *pool)
{
  return do_io_file_wrapper_cleanup
    (file, apr_file_write (file, buf, nbytes),
     "write to", pool);
}


svn_error_t *
svn_io_file_write_full (apr_file_t *file, const void *buf, 
                        apr_size_t nbytes, apr_size_t *bytes_written,
                        apr_pool_t *pool)
{
  return do_io_file_wrapper_cleanup
    (file, apr_file_write_full (file, buf, nbytes, bytes_

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -