diff options
author | Calvin Lee <cyrus296@gmail.com> | 2017-10-05 20:43:47 -0600 |
---|---|---|
committer | Calvin Lee <cyrus296@gmail.com> | 2017-10-05 20:46:31 -0600 |
commit | 419a1087ac46cd2f226a457dd6a3a41091d06870 (patch) | |
tree | 32fd93c7e450919a5a66181a3f8d801a595d5f6d | |
parent | Merge pull request #1379 from karjonas/variable_matching (diff) | |
download | sway-419a1087ac46cd2f226a457dd6a3a41091d06870.tar.gz sway-419a1087ac46cd2f226a457dd6a3a41091d06870.tar.zst sway-419a1087ac46cd2f226a457dd6a3a41091d06870.zip |
Clean up output command
Plugs memory leaks during failure of the output command and in other
circumstances and fixes `bg` option.
Fixes #1381
-rw-r--r-- | sway/commands/output.c | 74 | ||||
-rw-r--r-- | sway/config.c | 2 |
2 files changed, 51 insertions, 25 deletions
diff --git a/sway/commands/output.c b/sway/commands/output.c index e5d4b317..911391d2 100644 --- a/sway/commands/output.c +++ b/sway/commands/output.c | |||
@@ -46,7 +46,8 @@ struct cmd_results *cmd_output(int argc, char **argv) { | |||
46 | output->enabled = 0; | 46 | output->enabled = 0; |
47 | } else if (strcasecmp(command, "resolution") == 0 || strcasecmp(command, "res") == 0) { | 47 | } else if (strcasecmp(command, "resolution") == 0 || strcasecmp(command, "res") == 0) { |
48 | if (++i >= argc) { | 48 | if (++i >= argc) { |
49 | return cmd_results_new(CMD_INVALID, "output", "Missing resolution argument."); | 49 | error = cmd_results_new(CMD_INVALID, "output", "Missing resolution argument."); |
50 | goto fail; | ||
50 | } | 51 | } |
51 | char *res = argv[i]; | 52 | char *res = argv[i]; |
52 | char *x = strchr(res, 'x'); | 53 | char *x = strchr(res, 'x'); |
@@ -61,7 +62,8 @@ struct cmd_results *cmd_output(int argc, char **argv) { | |||
61 | // Format is 1234 4321 | 62 | // Format is 1234 4321 |
62 | width = atoi(res); | 63 | width = atoi(res); |
63 | if (++i >= argc) { | 64 | if (++i >= argc) { |
64 | return cmd_results_new(CMD_INVALID, "output", "Missing resolution argument (height)."); | 65 | error = cmd_results_new(CMD_INVALID, "output", "Missing resolution argument (height)."); |
66 | goto fail; | ||
65 | } | 67 | } |
66 | res = argv[i]; | 68 | res = argv[i]; |
67 | height = atoi(res); | 69 | height = atoi(res); |
@@ -70,7 +72,8 @@ struct cmd_results *cmd_output(int argc, char **argv) { | |||
70 | output->height = height; | 72 | output->height = height; |
71 | } else if (strcasecmp(command, "position") == 0 || strcasecmp(command, "pos") == 0) { | 73 | } else if (strcasecmp(command, "position") == 0 || strcasecmp(command, "pos") == 0) { |
72 | if (++i >= argc) { | 74 | if (++i >= argc) { |
73 | return cmd_results_new(CMD_INVALID, "output", "Missing position argument."); | 75 | error = cmd_results_new(CMD_INVALID, "output", "Missing position argument."); |
76 | goto fail; | ||
74 | } | 77 | } |
75 | char *res = argv[i]; | 78 | char *res = argv[i]; |
76 | char *c = strchr(res, ','); | 79 | char *c = strchr(res, ','); |
@@ -85,7 +88,8 @@ struct cmd_results *cmd_output(int argc, char **argv) { | |||
85 | // Format is 1234 4321 | 88 | // Format is 1234 4321 |
86 | x = atoi(res); | 89 | x = atoi(res); |
87 | if (++i >= argc) { | 90 | if (++i >= argc) { |
88 | return cmd_results_new(CMD_INVALID, "output", "Missing position argument (y)."); | 91 | error = cmd_results_new(CMD_INVALID, "output", "Missing position argument (y)."); |
92 | goto fail; | ||
89 | } | 93 | } |
90 | res = argv[i]; | 94 | res = argv[i]; |
91 | y = atoi(res); | 95 | y = atoi(res); |
@@ -94,25 +98,49 @@ struct cmd_results *cmd_output(int argc, char **argv) { | |||
94 | output->y = y; | 98 | output->y = y; |
95 | } else if (strcasecmp(command, "scale") == 0) { | 99 | } else if (strcasecmp(command, "scale") == 0) { |
96 | if (++i >= argc) { | 100 | if (++i >= argc) { |
97 | return cmd_results_new(CMD_INVALID, "output", "Missing scale parameter."); | 101 | error = cmd_results_new(CMD_INVALID, "output", "Missing scale parameter."); |
102 | goto fail; | ||
98 | } | 103 | } |
99 | output->scale = atoi(argv[i]); | 104 | output->scale = atoi(argv[i]); |
100 | } else if (strcasecmp(command, "background") == 0 || strcasecmp(command, "bg") == 0) { | 105 | } else if (strcasecmp(command, "background") == 0 || strcasecmp(command, "bg") == 0) { |
101 | wordexp_t p; | 106 | wordexp_t p; |
102 | if (++i >= argc) { | 107 | if (++i >= argc) { |
103 | return cmd_results_new(CMD_INVALID, "output", "Missing background file or color specification."); | 108 | error = cmd_results_new(CMD_INVALID, "output", "Missing background file or color specification."); |
109 | goto fail; | ||
104 | } | 110 | } |
105 | if (i + 1 >= argc) { | 111 | if (i + 1 >= argc) { |
106 | return cmd_results_new(CMD_INVALID, "output", "Missing background scaling mode or `solid_color`."); | 112 | error = cmd_results_new(CMD_INVALID, "output", "Missing background scaling mode or `solid_color`."); |
113 | goto fail; | ||
107 | } | 114 | } |
108 | if (strcasecmp(argv[argc - 1], "solid_color") == 0) { | 115 | if (strcasecmp(argv[i + 1], "solid_color") == 0) { |
109 | output->background = strdup(argv[argc - 2]); | 116 | output->background = strdup(argv[argc - 2]); |
110 | output->background_option = strdup("solid_color"); | 117 | output->background_option = strdup("solid_color"); |
111 | } else { | 118 | } else { |
112 | char *src = join_args(argv + i, argc - i - 1); | 119 | // argv[i+j]=bg_option |
113 | char *mode = argv[argc - 1]; | 120 | bool valid = false; |
121 | char *mode; | ||
122 | size_t j; | ||
123 | for (j = 0; j < (size_t) (argc - i); ++j) { | ||
124 | mode = argv[i + j]; | ||
125 | for (size_t k = 0; k < sizeof(bg_options) / sizeof(char *); ++k) { | ||
126 | if (strcasecmp(mode, bg_options[k]) == 0) { | ||
127 | valid = true; | ||
128 | break; | ||
129 | } | ||
130 | } | ||
131 | if (valid) { | ||
132 | break; | ||
133 | } | ||
134 | } | ||
135 | if (!valid) { | ||
136 | error = cmd_results_new(CMD_INVALID, "output", "Missing background scaling mode."); | ||
137 | goto fail; | ||
138 | } | ||
139 | |||
140 | char *src = join_args(argv + i, j); | ||
114 | if (wordexp(src, &p, 0) != 0 || p.we_wordv[0] == NULL) { | 141 | if (wordexp(src, &p, 0) != 0 || p.we_wordv[0] == NULL) { |
115 | return cmd_results_new(CMD_INVALID, "output", "Invalid syntax (%s)", src); | 142 | error = cmd_results_new(CMD_INVALID, "output", "Invalid syntax (%s)", src); |
143 | goto fail; | ||
116 | } | 144 | } |
117 | free(src); | 145 | free(src); |
118 | src = p.we_wordv[0]; | 146 | src = p.we_wordv[0]; |
@@ -132,27 +160,19 @@ struct cmd_results *cmd_output(int argc, char **argv) { | |||
132 | } | 160 | } |
133 | } | 161 | } |
134 | if (!src || access(src, F_OK) == -1) { | 162 | if (!src || access(src, F_OK) == -1) { |
135 | return cmd_results_new(CMD_INVALID, "output", "Background file unreadable (%s)", src); | 163 | error = cmd_results_new(CMD_INVALID, "output", "Background file unreadable (%s)", src); |
136 | } | 164 | wordfree(&p); |
137 | for (char *m = mode; *m; ++m) *m = tolower(*m); | 165 | goto fail; |
138 | // Check mode | ||
139 | bool valid = false; | ||
140 | size_t j; | ||
141 | for (j = 0; j < sizeof(bg_options) / sizeof(char *); ++j) { | ||
142 | if (strcasecmp(mode, bg_options[j]) == 0) { | ||
143 | valid = true; | ||
144 | break; | ||
145 | } | ||
146 | } | ||
147 | if (!valid) { | ||
148 | return cmd_results_new(CMD_INVALID, "output", "Invalid background scaling mode."); | ||
149 | } | 166 | } |
167 | |||
150 | output->background = strdup(src); | 168 | output->background = strdup(src); |
151 | output->background_option = strdup(mode); | 169 | output->background_option = strdup(mode); |
152 | if (src != p.we_wordv[0]) { | 170 | if (src != p.we_wordv[0]) { |
153 | free(src); | 171 | free(src); |
154 | } | 172 | } |
155 | wordfree(&p); | 173 | wordfree(&p); |
174 | |||
175 | i += j; | ||
156 | } | 176 | } |
157 | } | 177 | } |
158 | } | 178 | } |
@@ -192,4 +212,8 @@ struct cmd_results *cmd_output(int argc, char **argv) { | |||
192 | } | 212 | } |
193 | 213 | ||
194 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 214 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
215 | |||
216 | fail: | ||
217 | free_output_config(output); | ||
218 | return error; | ||
195 | } | 219 | } |
diff --git a/sway/config.c b/sway/config.c index e0b65615..4cb080ab 100644 --- a/sway/config.c +++ b/sway/config.c | |||
@@ -128,6 +128,8 @@ void free_output_config(struct output_config *oc) { | |||
128 | return; | 128 | return; |
129 | } | 129 | } |
130 | free(oc->name); | 130 | free(oc->name); |
131 | free(oc->background); | ||
132 | free(oc->background_option); | ||
131 | free(oc); | 133 | free(oc); |
132 | } | 134 | } |
133 | 135 | ||