static int new_pstream(char *suffix, const char *name, struct pstream **pstreamp, int dscp, char *unlink_path, bool kernel_print_port) { struct sockaddr_storage ss; int error; int fd; fd = inet_open_passive(SOCK_STREAM, suffix, -1, &ss, dscp, kernel_print_port); if (fd < 0) { return -fd; } struct ds bound_name = DS_EMPTY_INITIALIZER; if (!name) { ds_put_format(&bound_name, "ptcp:%"PRIu16":", ss_get_port(&ss)); ss_format_address(&ss, &bound_name); } else { ds_put_cstr(&bound_name, name); } error = new_fd_pstream(ds_steal_cstr(&bound_name), fd, ptcp_accept, unlink_path, pstreamp); if (!error) { pstream_set_bound_port(*pstreamp, htons(ss_get_port(&ss))); } return error; }
/* Converts 'match' to a string and returns the string. If 'priority' is * different from OFP_DEFAULT_PRIORITY, includes it in the string. The caller * must free the string (with free()). */ char * match_to_string(const struct match *match, unsigned int priority) { struct ds s = DS_EMPTY_INITIALIZER; match_format(match, &s, priority); return ds_steal_cstr(&s); }
static char * cell_to_text(struct cell *cell, const struct table_style *style) { if (!cell->text) { if (cell->json) { if (style->cell_format == CF_JSON || !cell->type) { cell->text = json_to_string(cell->json, JSSF_SORT); } else { struct ovsdb_datum datum; struct ovsdb_error *error; struct ds s; error = ovsdb_datum_from_json(&datum, cell->type, cell->json, NULL); if (!error) { ds_init(&s); if (style->cell_format == CF_STRING) { ovsdb_datum_to_string(&datum, cell->type, &s); } else { ovsdb_datum_to_bare(&datum, cell->type, &s); } ovsdb_datum_destroy(&datum, cell->type); cell->text = ds_steal_cstr(&s); } else { cell->text = json_to_string(cell->json, JSSF_SORT); ovsdb_error_destroy(error); } } } else { cell->text = xstrdup(""); } } return cell->text; }
action_syntax_error(struct action_context *ctx, const char *message, ...) { if (action_error_handle_common(ctx)) { return; } struct ds s; ds_init(&s); ds_put_cstr(&s, "Syntax error"); if (ctx->lexer->token.type == LEX_T_END) { ds_put_cstr(&s, " at end of input"); } else if (ctx->lexer->start) { ds_put_format(&s, " at `%.*s'", (int) (ctx->lexer->input - ctx->lexer->start), ctx->lexer->start); } if (message) { ds_put_char(&s, ' '); va_list args; va_start(args, message); ds_put_format_valist(&s, message, args); va_end(args); } ds_put_char(&s, '.'); ctx->error = ds_steal_cstr(&s); }
/* Returns a single string that consists of each of the strings in SA concatenated, separated from each other with SEPARATOR. The caller is responsible for freeing the returned string with free(). */ char * string_array_join (const struct string_array *sa, const char *separator) { struct string dst; const char *s; size_t i; ds_init_empty (&dst); STRING_ARRAY_FOR_EACH (s, i, sa) { if (i > 0) ds_put_cstr (&dst, separator); ds_put_cstr (&dst, s); } return ds_steal_cstr (&dst); }
/* Returns a string that represents 'protocols'. The return value might be a * comma-separated list if 'protocols' doesn't have a simple name. The return * value is "none" if 'protocols' is 0. * * The caller must free the returned string (with free()). */ char * ofputil_protocols_to_string(enum ofputil_protocol protocols) { struct ds s; ovs_assert(!(protocols & ~OFPUTIL_P_ANY)); if (protocols == 0) { return xstrdup("none"); } ds_init(&s); while (protocols) { const struct proto_abbrev *p; int i; if (s.length) { ds_put_char(&s, ','); } for (p = proto_abbrevs; p < &proto_abbrevs[N_PROTO_ABBREVS]; p++) { if ((protocols & p->protocol) == p->protocol) { ds_put_cstr(&s, p->name); protocols &= ~p->protocol; goto match; } } for (i = 0; i < CHAR_BIT * sizeof(enum ofputil_protocol); i++) { enum ofputil_protocol bit = 1u << i; if (protocols & bit) { ds_put_cstr(&s, ofputil_protocol_to_string(bit)); protocols &= ~bit; goto match; } } OVS_NOT_REACHED(); match: ; } return ds_steal_cstr(&s); }
/* Starts the process whose arguments are given in the null-terminated array * 'argv' and waits for it to exit. On success returns 0 and stores the * process exit value (suitable for passing to process_status_msg()) in * '*status'. On failure, returns a positive errno value and stores 0 in * '*status'. * * If 'stdout_log' is nonnull, then the subprocess's output to stdout (up to a * limit of PROCESS_MAX_CAPTURE bytes) is captured in a memory buffer, which * when this function returns 0 is stored as a null-terminated string in * '*stdout_log'. The caller is responsible for freeing '*stdout_log' (by * passing it to free()). When this function returns an error, '*stdout_log' * is set to NULL. * * If 'stderr_log' is nonnull, then it is treated like 'stdout_log' except * that it captures the subprocess's output to stderr. */ int process_run_capture(char **argv, char **stdout_log, char **stderr_log, int *status) { struct stream s_stdout, s_stderr; sigset_t oldsigs; pid_t pid; int error; COVERAGE_INC(process_run_capture); if (stdout_log) { *stdout_log = NULL; } if (stderr_log) { *stderr_log = NULL; } *status = 0; error = process_prestart(argv); if (error) { return error; } error = stream_open(&s_stdout); if (error) { return error; } error = stream_open(&s_stderr); if (error) { stream_close(&s_stdout); return error; } block_sigchld(&oldsigs); pid = fork(); if (pid < 0) { int error = errno; unblock_sigchld(&oldsigs); VLOG_WARN("fork failed: %s", strerror(error)); stream_close(&s_stdout); stream_close(&s_stderr); *status = 0; return error; } else if (pid) { /* Running in parent process. */ struct process *p; p = process_register(argv[0], pid); unblock_sigchld(&oldsigs); close(s_stdout.fds[1]); close(s_stderr.fds[1]); while (!process_exited(p)) { stream_read(&s_stdout); stream_read(&s_stderr); stream_wait(&s_stdout); stream_wait(&s_stderr); process_wait(p); poll_block(); } stream_read(&s_stdout); stream_read(&s_stderr); if (stdout_log) { *stdout_log = ds_steal_cstr(&s_stdout.log); } if (stderr_log) { *stderr_log = ds_steal_cstr(&s_stderr.log); } stream_close(&s_stdout); stream_close(&s_stderr); *status = process_status(p); process_destroy(p); return 0; } else { /* Running in child process. */ int max_fds; int i; fatal_signal_fork(); unblock_sigchld(&oldsigs); dup2(get_null_fd(), 0); dup2(s_stdout.fds[1], 1); dup2(s_stderr.fds[1], 2); max_fds = get_max_fds(); for (i = 3; i < max_fds; i++) { close(i); } execvp(argv[0], argv); fprintf(stderr, "execvp(\"%s\") failed: %s\n", argv[0], strerror(errno)); exit(EXIT_FAILURE); } }