Exemplo n.º 1
0
static w_stm_t prepare_stdin(
  struct watchman_trigger_command *cmd,
  w_query_res *res)
{
  uint32_t n_files;
  char stdin_file_name[WATCHMAN_NAME_MAX];
  w_stm_t stdin_file = NULL;

  if (cmd->stdin_style == input_dev_null) {
    return w_stm_open("/dev/null", O_RDONLY|O_CLOEXEC);
  }

  n_files = res->num_results;

  if (cmd->max_files_stdin > 0) {
    n_files = MIN(cmd->max_files_stdin, n_files);
  }

  /* prepare the input stream for the child process */
  snprintf(stdin_file_name, sizeof(stdin_file_name), "%s%cwmanXXXXXX",
      watchman_tmp_dir, WATCHMAN_DIR_SEP);
  stdin_file = w_mkstemp(stdin_file_name);
  if (!stdin_file) {
    w_log(W_LOG_ERR, "unable to create a temporary file: %s %s\n",
        stdin_file_name, strerror(errno));
    return NULL;
  }

  /* unlink the file, we don't need it in the filesystem;
   * we'll pass the fd on to the child as stdin */
  unlink(stdin_file_name); // FIXME: windows path translation

  switch (cmd->stdin_style) {
    case input_json:
      {
        w_jbuffer_t buffer;
        json_t *file_list;

        if (!w_json_buffer_init(&buffer)) {
          w_log(W_LOG_ERR, "failed to init json buffer\n");
          w_stm_close(stdin_file);
          return NULL;
        }

        file_list = w_query_results_to_json(&cmd->field_list,
            n_files, res->results);
        w_log(W_LOG_ERR, "input_json: sending json object to stm\n");
        if (!w_json_buffer_write(&buffer, stdin_file, file_list, 0)) {
          w_log(W_LOG_ERR,
              "input_json: failed to write json data to stream: %s\n",
              strerror(errno));
          w_stm_close(stdin_file);
          return NULL;
        }
        w_json_buffer_free(&buffer);
        json_decref(file_list);
        break;
      }
    case input_name_list:
      {
        uint32_t i;

        for (i = 0; i < n_files; i++) {
          if (w_stm_write(stdin_file, res->results[i].relname->buf,
              res->results[i].relname->len) != (int)res->results[i].relname->len
              || w_stm_write(stdin_file, "\n", 1) != 1) {
            w_log(W_LOG_ERR,
              "write failure while producing trigger stdin: %s\n",
              strerror(errno));
            w_stm_close(stdin_file);
            return NULL;
          }
        }
        break;
      }
    case input_dev_null:
      // already handled above
      break;
  }

  w_stm_rewind(stdin_file);
  return stdin_file;
}
Exemplo n.º 2
0
static std::unique_ptr<watchman_stream> prepare_stdin(
    struct watchman_trigger_command* cmd,
    w_query_res* res) {
  char stdin_file_name[WATCHMAN_NAME_MAX];

  if (cmd->stdin_style == trigger_input_style::input_dev_null) {
    return w_stm_open("/dev/null", O_RDONLY|O_CLOEXEC);
  }

  // Adjust result to fit within the specified limit
  if (cmd->max_files_stdin > 0) {
    auto& fileList = res->resultsArray.array();
    auto n_files = std::min(size_t(cmd->max_files_stdin), fileList.size());
    fileList.resize(std::min(fileList.size(), n_files));
  }

  /* prepare the input stream for the child process */
  snprintf(
      stdin_file_name,
      sizeof(stdin_file_name),
      "%s/wmanXXXXXX",
      watchman_tmp_dir);
  auto stdin_file = w_mkstemp(stdin_file_name);
  if (!stdin_file) {
    w_log(W_LOG_ERR, "unable to create a temporary file: %s %s\n",
        stdin_file_name, strerror(errno));
    return NULL;
  }

  /* unlink the file, we don't need it in the filesystem;
   * we'll pass the fd on to the child as stdin */
  unlink(stdin_file_name); // FIXME: windows path translation

  switch (cmd->stdin_style) {
    case input_json:
      {
        w_jbuffer_t buffer;

        w_log(W_LOG_ERR, "input_json: sending json object to stm\n");
        if (!buffer.jsonEncodeToStream(
                res->resultsArray, stdin_file.get(), 0)) {
          w_log(W_LOG_ERR,
              "input_json: failed to write json data to stream: %s\n",
              strerror(errno));
          return NULL;
        }
        break;
      }
    case input_name_list:
      for (auto& name : res->resultsArray.array()) {
        auto& nameStr = json_to_w_string(name);
        if (stdin_file->write(nameStr.data(), nameStr.size()) !=
                (int)nameStr.size() ||
            stdin_file->write("\n", 1) != 1) {
          w_log(
              W_LOG_ERR,
              "write failure while producing trigger stdin: %s\n",
              strerror(errno));
          return nullptr;
        }
      }
      break;
    case input_dev_null:
      // already handled above
      break;
  }

  stdin_file->rewind();
  return stdin_file;
}