#include <fcntl.h>
#include <pwd.h>
#include <yajl/yajl_version.h>
+#include <libgen.h>
#include "all.h"
void *srealloc(void *ptr, size_t size) {
void *result = realloc(ptr, size);
- exit_if_null(result, "Error: out memory (realloc(%zd))\n", size);
+ if (result == NULL && size > 0)
+ die("Error: out memory (realloc(%zd))\n", size);
return result;
}
wait(0);
}
+/*
+ * exec()s an i3 utility, for example the config file migration script or
+ * i3-nagbar. This function first searches $PATH for the given utility named,
+ * then falls back to the dirname() of the i3 executable path and then falls
+ * back to the dirname() of the target of /proc/self/exe (on linux).
+ *
+ * This function should be called after fork()ing.
+ *
+ * The first argument of the given argv vector will be overwritten with the
+ * executable name, so pass NULL.
+ *
+ * If the utility cannot be found in any of these locations, it exits with
+ * return code 2.
+ *
+ */
+void exec_i3_utility(char *name, char *argv[]) {
+ /* start the migration script, search PATH first */
+ char *migratepath = name;
+ argv[0] = migratepath;
+ execvp(migratepath, argv);
+
+ /* if the script is not in path, maybe the user installed to a strange
+ * location and runs the i3 binary with an absolute path. We use
+ * argv[0]’s dirname */
+ char *pathbuf = strdup(start_argv[0]);
+ char *dir = dirname(pathbuf);
+ asprintf(&migratepath, "%s/%s", dir, name);
+ argv[0] = migratepath;
+ execvp(migratepath, argv);
+
+#if defined(__linux__)
+ /* on linux, we have one more fall-back: dirname(/proc/self/exe) */
+ char buffer[BUFSIZ];
+ if (readlink("/proc/self/exe", buffer, BUFSIZ) == -1) {
+ warn("could not read /proc/self/exe");
+ exit(1);
+ }
+ dir = dirname(buffer);
+ asprintf(&migratepath, "%s/%s", dir, name);
+ argv[0] = migratepath;
+ execvp(migratepath, argv);
+#endif
+
+ warn("Could not start %s", name);
+ exit(2);
+}
+
/*
* Checks a generic cookie for errors and quits with the given message if there
* was an error.
if (n == -1) {
perror("write()");
free(filename);
+ close(fd);
return NULL;
}
if (n == 0) {
printf("write == 0?\n");
free(filename);
+ close(fd);
return NULL;
}
written += n;
void i3_restart(bool forget_layout) {
char *restart_filename = forget_layout ? NULL : store_restart_layout();
+ kill_configerror_nagbar(true);
+
restore_geometry();
ipc_shutdown();
/* not reached */
}
-#if 0
-
-#if defined(__OpenBSD__)
+#if defined(__OpenBSD__) || defined(__APPLE__)
/*
* Taken from FreeBSD
*
*/
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;
+ 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;
+ /* 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;
+ /* "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);
+ /* 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;
+ /* 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;
+ for (cur = (char *)cl; cur <= last; cur++)
+ if (cur[0] == cs[0] && memcmp(cur, cs, s_len) == 0)
+ return cur;
- return NULL;
+ return NULL;
}
#endif
+
+#if defined(__APPLE__)
+
+/*
+ * Taken from FreeBSD
+ * Returns a pointer to a new string which is a duplicate of the
+ * string, but only copies at most n characters.
+ *
+ */
+char *strndup(const char *str, size_t n) {
+ size_t len;
+ char *copy;
+
+ for (len = 0; len < n && str[len]; len++)
+ continue;
+
+ if ((copy = malloc(len + 1)) == NULL)
+ return (NULL);
+ memcpy(copy, str, len);
+ copy[len] = '\0';
+ return (copy);
+}
+
#endif