Merge branch 'master' into next

Conflicts:
	testcases/t/159-socketpaths.t
next
Michael Stapelberg 2011-12-18 18:02:08 +00:00
commit 1f2c9306a2
5 changed files with 51 additions and 23 deletions

View File

@ -11,8 +11,10 @@ workspace bar.
The method of choice for IPC in our case is a unix socket because it has very The method of choice for IPC in our case is a unix socket because it has very
little overhead on both sides and is usually available without headaches in little overhead on both sides and is usually available without headaches in
most languages. In the default configuration file, the ipc-socket gets created most languages. In the default configuration file, the ipc-socket gets created
in +/tmp/i3-%u/ipc-socket.%p+ where +%u+ is your UNIX username and +%p+ is the in +/tmp/i3-%u.XXXXXX/ipc-socket.%p+ where +%u+ is your UNIX username, +%p+ is
PID of i3. You can get the socketpath from i3 by calling +i3 --get-socketpath+. the PID of i3 and XXXXXX is a string of random characters from the portable
filename character set (see mkdtemp(3)). You can get the socketpath from i3 by
calling +i3 --get-socketpath+.
All i3 utilities, like +i3-msg+ and +i3-input+ will read the +I3_SOCKET_PATH+ All i3 utilities, like +i3-msg+ and +i3-input+ will read the +I3_SOCKET_PATH+
X11 property, stored on the X11 root window. X11 property, stored on the X11 root window.

View File

@ -643,16 +643,19 @@ programs to get information from i3, such as the current workspaces
(to display a workspace bar), and to control i3. (to display a workspace bar), and to control i3.
The IPC socket is enabled by default and will be created in The IPC socket is enabled by default and will be created in
+/tmp/i3-%u/ipc-socket.%p+ where +%u+ is your UNIX username and +%p+ is the PID +/tmp/i3-%u.XXXXXX/ipc-socket.%p+ where +%u+ is your UNIX username, +%p+ is
of i3. the PID of i3 and XXXXXX is a string of random characters from the portable
filename character set (see mkdtemp(3)).
You can override the default path through the environment-variable +I3SOCK+ or You can override the default path through the environment-variable +I3SOCK+ or
by specifying the +ipc-socket+ directive. This is discouraged, though, since i3 by specifying the +ipc-socket+ directive. This is discouraged, though, since i3
does the right thing by default. does the right thing by default. If you decide to change it, it is strongly
recommended to set this to a location in your home directory so that no other
user can create that directory.
*Examples*: *Examples*:
---------------------------- ----------------------------
ipc-socket /tmp/i3-ipc.sock ipc-socket ~/.i3/i3-ipc.sock
---------------------------- ----------------------------
You can then use the +i3-msg+ application to perform any command listed in You can then use the +i3-msg+ application to perform any command listed in

View File

@ -294,9 +294,10 @@ exec /usr/bin/i3 -V -d all >> ~/.i3/logfile
=== I3SOCK === I3SOCK
This variable overwrites the IPC socket path (placed in This variable overwrites the IPC socket path (placed in
/tmp/i3-%u/ipc-socket.%p by default, where %u is replaced with your UNIX /tmp/i3-%u.XXXXXX/ipc-socket.%p by default, where %u is replaced with your UNIX
username and %p is replaced with i3s PID). The IPC socket is used by external username, %p is replaced with i3s PID and XXXXXX is a string of random
programs like i3-msg(1) or i3bar(1). characters from the portable filename character set (see mkdtemp(3))). The IPC
socket is used by external programs like i3-msg(1) or i3bar(1).
== TODO == TODO

View File

@ -186,25 +186,36 @@ static char **append_argument(char **original, char *argument) {
* *
*/ */
char *get_process_filename(const char *prefix) { char *get_process_filename(const char *prefix) {
char *dir = getenv("XDG_RUNTIME_DIR"); /* dir stores the directory path for this and all subsequent calls so that
* we only create a temporary directory once per i3 instance. */
static char *dir = NULL;
if (dir == NULL) { if (dir == NULL) {
struct passwd *pw = getpwuid(getuid()); /* Check if XDG_RUNTIME_DIR is set. If so, we use XDG_RUNTIME_DIR/i3 */
const char *username = pw ? pw->pw_name : "unknown"; if ((dir = getenv("XDG_RUNTIME_DIR"))) {
sasprintf(&dir, "/tmp/i3-%s", username); char *tmp;
} else { sasprintf(&tmp, "%s/i3", dir);
char *tmp; dir = tmp;
sasprintf(&tmp, "%s/i3", dir); if (!path_exists(dir)) {
dir = tmp; if (mkdir(dir, 0700) == -1) {
} perror("mkdir()");
if (!path_exists(dir)) { return NULL;
if (mkdir(dir, 0700) == -1) { }
perror("mkdir()"); }
return NULL; } else {
/* If not, we create a (secure) temp directory using the template
* /tmp/i3-<user>.XXXXXX */
struct passwd *pw = getpwuid(getuid());
const char *username = pw ? pw->pw_name : "unknown";
sasprintf(&dir, "/tmp/i3-%s.XXXXXX", username);
/* mkdtemp modifies dir */
if (mkdtemp(dir) == NULL) {
perror("mkdtemp()");
return NULL;
}
} }
} }
char *filename; char *filename;
sasprintf(&filename, "%s/%s.%d", dir, prefix, getpid()); sasprintf(&filename, "%s/%s.%d", dir, prefix, getpid());
free(dir);
return filename; return filename;
} }

View File

@ -19,9 +19,20 @@ EOT
# ensure XDG_RUNTIME_DIR is not set # ensure XDG_RUNTIME_DIR is not set
delete $ENV{XDG_RUNTIME_DIR}; delete $ENV{XDG_RUNTIME_DIR};
# See which files exist in /tmp before to not mistakenly check an already
# existing tmpdir of another i3 instance.
my @files_before = </tmp/i3-*>;
my $pid = launch_with_config($config, dont_add_socket_path => 1); my $pid = launch_with_config($config, dont_add_socket_path => 1);
my @files_after = </tmp/i3-*>;
@files_after = grep { !($_ ~~ @files_before) } @files_after;
is(@files_after, 1, 'one new temp directory');
my $folder = "/tmp/i3-" . getpwuid(getuid()); my $folder = "/tmp/i3-" . getpwuid(getuid());
like($files_after[0], qr/^$folder/, 'temp directory matches expected pattern');
$folder = $files_after[0];
ok(-d $folder, "folder $folder exists"); ok(-d $folder, "folder $folder exists");
my $socketpath = "$folder/ipc-socket." . $pid; my $socketpath = "$folder/ipc-socket." . $pid;
ok(-S $socketpath, "file $socketpath exists and is a socket"); ok(-S $socketpath, "file $socketpath exists and is a socket");