If I restart i3 4.10.2 twice, e.g. with
$ i3-msg restart; sleep 3; i3-msg restart
the second time I get the following two errors:
05/22/15 10:46:03 - ERROR: mkdir(/tmp/i3-theo.toAK7N) failed: File exists
05/22/15 10:46:03 - ERROR: Could not create "/tmp/i3-theo.toAK7N" for storing the restart layout, layout will be lost.
The first one is from mkdirp() in src/ipc.c and the second one is from
store_restart_layout() in src/util.c.
Notice that I do _not_ get the ``open()'' or ``Could not write restart layout to
...'' error messages, so the layout writing code after line 260 in
store_restart_layout() succeeded and the layout isn't actually lost. Thus,
these error messages are a bit misleading, especially the second one (which is
triggered by the failure of mkdirp()).
POSIX says about `mkdir -p':
``Each dir operand that names an existing directory shall be ignored without
error.''
Therefore, I suggest the following simple patch that makes mkdirp() succeed if
the named file exists and actually is a directory. This silences the second
error as well.
bool mkdirp(const char *path) {
if (mkdir(path, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) == 0)
return true;
- if (errno != ENOENT) {
+ if (errno == EEXIST) {
+ struct stat st;
+ /* Check that the named file actually is a directory. */
+ if (stat(path, &st)) {
+ ELOG("stat(%s) failed: %s\n", path, strerror(errno));
+ return false;
+ }
+ if (!S_ISDIR(st.st_mode)) {
+ ELOG("mkdir(%s) failed: %s\n", path, strerror(ENOTDIR));
+ return false;
+ }
+ return true;
+ } else if (errno != ENOENT) {
ELOG("mkdir(%s) failed: %s\n", path, strerror(errno));
return false;
}