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 }