github.com/cptmikhailov/conmon@v2.0.20+incompatible/src/parent_pipe_fd.c (about)

     1  #include "parent_pipe_fd.h"
     2  #include "utils.h"
     3  #include "cli.h"
     4  
     5  #include <glib.h>
     6  
     7  int sync_pipe_fd = -1;
     8  
     9  static char *escape_json_string(const char *str);
    10  
    11  int get_pipe_fd_from_env(const char *envname)
    12  {
    13  	char *endptr = NULL;
    14  
    15  	char *pipe_str = getenv(envname);
    16  	if (pipe_str == NULL)
    17  		return -1;
    18  
    19  	errno = 0;
    20  	int pipe_fd = strtol(pipe_str, &endptr, 10);
    21  	if (errno != 0 || *endptr != '\0')
    22  		pexitf("unable to parse %s", envname);
    23  	if (fcntl(pipe_fd, F_SETFD, FD_CLOEXEC) == -1)
    24  		pexitf("unable to make %s CLOEXEC", envname);
    25  
    26  	return pipe_fd;
    27  }
    28  
    29  void write_sync_fd(int fd, int res, const char *message)
    30  {
    31  	const char *res_key;
    32  	if (opt_api_version >= 1)
    33  		res_key = "data";
    34  	else if (opt_exec)
    35  		res_key = "exit_code";
    36  	else
    37  		res_key = "pid";
    38  
    39  	ssize_t len;
    40  
    41  	if (fd == -1)
    42  		return;
    43  
    44  	_cleanup_free_ char *json = NULL;
    45  	if (message) {
    46  		_cleanup_free_ char *escaped_message = escape_json_string(message);
    47  		json = g_strdup_printf("{\"%s\": %d, \"message\": \"%s\"}\n", res_key, res, escaped_message);
    48  	} else {
    49  		json = g_strdup_printf("{\"%s\": %d}\n", res_key, res);
    50  	}
    51  
    52  	len = strlen(json);
    53  	if (write_all(fd, json, len) != len) {
    54  		pexit("Unable to send container stderr message to parent");
    55  	}
    56  }
    57  
    58  static char *escape_json_string(const char *str)
    59  {
    60  	const char *p = str;
    61  	GString *escaped = g_string_sized_new(strlen(str));
    62  
    63  	while (*p != 0) {
    64  		char c = *p++;
    65  		if (c == '\\' || c == '"') {
    66  			g_string_append_c(escaped, '\\');
    67  			g_string_append_c(escaped, c);
    68  		} else if (c == '\n') {
    69  			g_string_append_printf(escaped, "\\n");
    70  		} else if (c == '\t') {
    71  			g_string_append_printf(escaped, "\\t");
    72  		} else if ((c > 0 && c < 0x1f) || c == 0x7f) {
    73  			g_string_append_printf(escaped, "\\u00%02x", (guint)c);
    74  		} else {
    75  			g_string_append_c(escaped, c);
    76  		}
    77  	}
    78  
    79  	return g_string_free(escaped, FALSE);
    80  }