+#endif
+
+/*
+ * Goes through the list of arguments (for exec()) and checks if the given argument
+ * is present. If not, it copies the arguments (because we cannot realloc it) and
+ * appends the given argument.
+ *
+ */
+static char **append_argument(char **original, char *argument) {
+ int num_args;
+ for (num_args = 0; original[num_args] != NULL; num_args++) {
+ DLOG("original argument: \"%s\"\n", original[num_args]);
+ /* If the argument is already present we return the original pointer */
+ if (strcmp(original[num_args], argument) == 0)
+ return original;
+ }
+ /* Copy the original array */
+ char **result = smalloc((num_args+2) * sizeof(char*));
+ memcpy(result, original, num_args * sizeof(char*));
+ result[num_args] = argument;
+ result[num_args+1] = NULL;
+
+ return result;
+}
+
+#define y(x, ...) yajl_gen_ ## x (gen, ##__VA_ARGS__)
+#define ystr(str) yajl_gen_string(gen, (unsigned char*)str, strlen(str))
+
+void store_restart_layout() {
+ yajl_gen gen = yajl_gen_alloc(NULL, NULL);
+
+ dump_node(gen, croot, true);
+
+ const unsigned char *payload;
+ unsigned int length;
+ y(get_buf, &payload, &length);
+
+ char *globbed = glob_path("~/.i3/_restart.json");
+ int fd = open(globbed, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
+ free(globbed);
+ if (fd == -1) {
+ perror("open()");
+ return;
+ }
+
+ int written = 0;
+ while (written < length) {
+ int n = write(fd, payload + written, length - written);
+ /* TODO: correct error-handling */
+ if (n == -1) {
+ perror("write()");
+ return;
+ }
+ if (n == 0) {
+ printf("write == 0?\n");
+ return;
+ }
+ written += n;
+ printf("written: %d of %d\n", written, length);
+ }
+ close(fd);
+
+ printf("layout: %.*s\n", length, payload);
+
+ y(free);
+}
+
+/*
+ * Restart i3 in-place
+ * appends -a to argument list to disable autostart
+ *
+ */
+void i3_restart() {
+ store_restart_layout();
+ restore_geometry();
+
+ //ipc_shutdown();
+
+ LOG("restarting \"%s\"...\n", start_argv[0]);
+ /* make sure -a is in the argument list or append it */
+ start_argv = append_argument(start_argv, "-a");
+
+ execvp(start_argv[0], start_argv);
+ /* not reached */
+}
+
+#if 0
+
+#if defined(__OpenBSD__)
+
+/*
+ * Taken from FreeBSD
+ * Find the first occurrence of the byte string s in byte string l.
+ *
+ */
+void *memmem(const void *l, size_t l_len, const void *s, size_t s_len) {
+ register char *cur, *last;
+ const char *cl = (const char *)l;
+ const char *cs = (const char *)s;
+
+ /* we need something to compare */
+ if (l_len == 0 || s_len == 0)
+ return NULL;
+
+ /* "s" must be smaller or equal to "l" */
+ if (l_len < s_len)
+ return NULL;
+
+ /* special case where s_len == 1 */
+ if (s_len == 1)
+ return memchr(l, (int)*cs, l_len);
+
+ /* the last position where its possible to find "s" in "l" */
+ last = (char *)cl + l_len - s_len;
+
+ for (cur = (char *)cl; cur <= last; cur++)
+ if (cur[0] == cs[0] && memcmp(cur, cs, s_len) == 0)
+ return cur;
+
+ return NULL;
+}
+
+#endif
+#endif