static bool jbuffer_flush(struct jbuffer_write_data *data) { int x; while (data->jr->wpos - data->jr->rpos) { x = w_stm_write(data->stm, data->jr->buf + data->jr->rpos, data->jr->wpos - data->jr->rpos); if (x <= 0) { return false; } data->jr->rpos += x; } data->jr->rpos = data->jr->wpos = 0; return true; }
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; }