]> git.sur5r.net Git - i3/i3/commitdiff
Implement shmlog command
authorAlexander Berntsen <alexander@plaimi.net>
Wed, 5 Jun 2013 13:04:57 +0000 (15:04 +0200)
committerMichael Stapelberg <michael@stapelberg.de>
Sun, 23 Jun 2013 19:48:02 +0000 (21:48 +0200)
Add shmlog command that takes <size>|toggle|on|off. Separate logbuffer
management into open_logbuffer() and close_logbuffer(). Make
t/187-commands-parser.t expect 'shmlog'. Add update_shmlog_atom() to
update the SHMLOG_PATH. Document the shmlog command in userguide.

docs/userguide
include/commands.h
include/log.h
include/x.h
parser-specs/commands.spec
src/commands.c
src/log.c
src/x.c
testcases/t/187-commands-parser.t

index 09cd72bf3905d0f9a92e32bd9e410074052f66b5..73187fa74fe29090425c68bfc87c9110b8e2c3ae 100644 (file)
@@ -1762,6 +1762,22 @@ stack-limit rows 5
 image:stacklimit.png[Container limited to two columns]
 ///////////////////////////////////////////////////////////////////////////////
 
+== Starting/stopping/changing the size of the shm log
+
+You may start or stop the shm log with +shmlog+, or change the size of the log.
+If you pass a size to the shmlog command, it will change the running log's
+size, or, if the log is not running, start the log with the provided size. You
+may also toggle the log. This is useful if you want to bind the command to a
+key.
+
+*Examples*:
+---------------
+shmlog 26214400
+shmlog toggle
+shmlog on
+shmlog off
+---------------
+
 === Reloading/Restarting/Exiting
 
 You can make i3 reload its configuration file with +reload+. You can also
index 87f0ac1ac775f7bee549378b283c0d65d859072d..a09e7466aa05a26013bb9913b188938399faeb85 100644 (file)
@@ -271,4 +271,10 @@ void cmd_rename_workspace(I3_CMD, char *old_name, char *new_name);
  */
 void cmd_bar(I3_CMD, char *bar_type, char *bar_value, char *bar_id);
 
+/*
+ * Implementation of 'shmlog <size>|toggle|on|off'
+ *
+ */
+void cmd_shmlog(I3_CMD, char *argument);
+
 #endif
index 6fabeca339fdd3283a35e039a6fd2c7922f1e697..c9d1d0cd67a15e4f7652fb7128b327022e7fc543 100644 (file)
@@ -38,6 +38,18 @@ extern int shmlog_size;
  */
 void init_logging(void);
 
+/**
+ * Opens the logbuffer.
+ *
+ */
+void open_logbuffer(void);
+
+/**
+ * Closes the logbuffer.
+ *
+ */
+void close_logbuffer(void);
+
 /**
  * Set debug logging.
  *
index b712c78692646ab961d52c420cbd21619f60f115..b6bb4a5283702dd2f0110f2122b2d28574f77710 100644 (file)
@@ -108,6 +108,12 @@ void x_raise_con(Con *con, bool above_all);
  */
 void x_set_name(Con *con, const char *name);
 
+/**
+ * Set up the SHMLOG_PATH atom.
+ *
+ */
+void update_shmlog_atom(void);
+
 /**
  * Sets up i3 specific atoms (I3_SOCKET_PATH and I3_CONFIG_PATH)
  *
index 12737a22838a010021a99cf67ffaae5b415ab352..4407158cb6398c49fb358f48158c484190a80c64 100644 (file)
@@ -19,6 +19,7 @@ state INITIAL:
   'exit' -> call cmd_exit()
   'restart' -> call cmd_restart()
   'reload' -> call cmd_reload()
+  'shmlog' -> SHMLOG
   'border' -> BORDER
   'layout' -> LAYOUT
   'append_layout' -> APPEND_LAYOUT
@@ -62,6 +63,12 @@ state EXEC:
   command = string
       -> call cmd_exec($nosn, $command)
 
+# shmlog <size>|toggle|on|off
+state SHMLOG:
+  # argument may be a number
+  argument = string
+    -> call cmd_shmlog($argument)
+
 # border normal|none|1pixel|toggle|1pixel
 state BORDER:
   border_style = 'normal', 'pixel'
index f361f8670eae220889813dbadd234eedeba6162b..fbe4b11723e0c3567e7769d177c1f53466925cd3 100644 (file)
@@ -13,6 +13,7 @@
 #include <stdarg.h>
 
 #include "all.h"
+#include "shmlog.h"
 
 // Macros to make the YAJL API a bit easier to use.
 #define y(x, ...) yajl_gen_ ## x (cmd_output->json_gen, ##__VA_ARGS__)
@@ -2027,3 +2028,34 @@ void cmd_bar(I3_CMD, char *bar_type, char *bar_value, char *bar_id) {
 
     update_barconfig();
 }
+
+/*
+ * Implementation of 'shmlog <size>|toggle|on|off'
+ *
+ */
+void cmd_shmlog(I3_CMD, char *argument) {
+    if (!strcmp(argument,"toggle"))
+        /* Toggle shm log, if size is not 0. If it is 0, set it to default. */
+        shmlog_size = shmlog_size ? -shmlog_size : default_shmlog_size;
+    else if (!strcmp(argument, "on"))
+        shmlog_size = default_shmlog_size;
+    else if (!strcmp(argument, "off"))
+        shmlog_size = 0;
+    else {
+        /* If shm logging now, restart logging with the new size. */
+        if (shmlog_size > 0) {
+            shmlog_size = 0;
+            LOG("Restarting shm logging...\n");
+            init_logging();
+        }
+        shmlog_size = atoi(argument);
+        /* Make a weakly attempt at ensuring the argument is valid. */
+        if (shmlog_size <= 0)
+            shmlog_size = default_shmlog_size;
+    }
+    LOG("%s shm logging\n", shmlog_size > 0 ? "Enabling" : "Disabling");
+    init_logging();
+    update_shmlog_atom();
+    // XXX: default reply for now, make this a better reply
+    ysuccess(true);
+}
index 0269fb21ff9b7078a6f94ecd787c7e4a2dd4a1f6..5530f66f9f5358681e45a1bcdbf5150494f53548 100644 (file)
--- a/src/log.c
+++ b/src/log.c
@@ -89,10 +89,21 @@ void init_logging(void) {
             }
         }
     }
+    /* Start SHM logging if shmlog_size is > 0. shmlog_size is SHMLOG_SIZE by
+     * default on development versions, and 0 on release versions. If it is
+     * not > 0, the user has turned it off, so let's close the logbuffer. */
+     if (shmlog_size > 0 && logbuffer == NULL)
+        open_logbuffer();
+     else if (shmlog_size <= 0 && logbuffer)
+        close_logbuffer();
+     atexit(purge_zerobyte_logfile);
+}
 
-    /* If this is a debug build (not a release version), we will enable SHM
-     * logging by default, unless the user turned it off explicitly. */
-    if (logbuffer == NULL && shmlog_size > 0) {
+/*
+ * Opens the logbuffer.
+ *
+ */
+void open_logbuffer(void) {
         /* Reserve 1% of the RAM for the logfile, but at max 25 MiB.
          * For 512 MiB of RAM this will lead to a 5 MiB log buffer.
          * At the moment (2011-12-10), no testcase leads to an i3 log
@@ -127,10 +138,8 @@ void init_logging(void) {
 
         logbuffer = mmap(NULL, logbuffer_size, PROT_READ | PROT_WRITE, MAP_SHARED, logbuffer_shm, 0);
         if (logbuffer == MAP_FAILED) {
-            close(logbuffer_shm);
-            shm_unlink(shmlogname);
+            close_logbuffer();
             fprintf(stderr, "Could not mmap SHM segment for the i3 log: %s\n", strerror(errno));
-            logbuffer = NULL;
             return;
         }
 
@@ -148,8 +157,16 @@ void init_logging(void) {
         logwalk = logbuffer + sizeof(i3_shmlog_header);
         loglastwrap = logbuffer + logbuffer_size;
         store_log_markers();
-    }
-    atexit(purge_zerobyte_logfile);
+}
+
+/*
+ * Closes the logbuffer.
+ *
+ */
+void close_logbuffer(void) {
+    close(logbuffer_shm);
+    shm_unlink(shmlogname);
+    logbuffer = NULL;
 }
 
 /*
diff --git a/src/x.c b/src/x.c
index f86559460ed213722fa70bbc1714d0e04636e13a..27d92acad13687499c207414ac0b15f7c2fb99d3 100644 (file)
--- a/src/x.c
+++ b/src/x.c
@@ -1063,6 +1063,16 @@ void x_set_name(Con *con, const char *name) {
     state->name = sstrdup(name);
 }
 
+/*
+ * Set up the I3_SHMLOG_PATH atom.
+ *
+ */
+void update_shmlog_atom() {
+    xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root,
+            A_I3_SHMLOG_PATH, A_UTF8_STRING, 8,
+            strlen(shmlogname), shmlogname);
+}
+
 /*
  * Sets up i3 specific atoms (I3_SOCKET_PATH and I3_CONFIG_PATH)
  *
@@ -1075,8 +1085,7 @@ void x_set_i3_atoms(void) {
     xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root, A_I3_PID, XCB_ATOM_CARDINAL, 32, 1, &pid);
     xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root, A_I3_CONFIG_PATH, A_UTF8_STRING, 8,
                         strlen(current_configpath), current_configpath);
-    xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root, A_I3_SHMLOG_PATH, A_UTF8_STRING, 8,
-                        strlen(shmlogname), shmlogname);
+    update_shmlog_atom();
 }
 
 /*
index 65c72125861388a4ad80b0a39ad274320278ebe9..a6bb1c5a0fd6410659327e6bc1a1fd06180bfe71 100644 (file)
@@ -144,7 +144,7 @@ is(parser_calls("\nworkspace test"),
 ################################################################################
 
 is(parser_calls('unknown_literal'),
-   "ERROR: Expected one of these tokens: <end>, '[', 'move', 'exec', 'exit', 'restart', 'reload', 'border', 'layout', 'append_layout', 'workspace', 'focus', 'kill', 'open', 'fullscreen', 'split', 'floating', 'mark', 'resize', 'rename', 'nop', 'scratchpad', 'mode', 'bar'\n" .
+   "ERROR: Expected one of these tokens: <end>, '[', 'move', 'exec', 'exit', 'restart', 'reload', 'shmlog', 'border', 'layout', 'append_layout', 'workspace', 'focus', 'kill', 'open', 'fullscreen', 'split', 'floating', 'mark', 'resize', 'rename', 'nop', 'scratchpad', 'mode', 'bar'\n" .
    "ERROR: Your command: unknown_literal\n" .
    "ERROR:               ^^^^^^^^^^^^^^^",
    'error for unknown literal ok');