i3 - improved tiling WM


Implement shmlog command

Patch status: needinfo

Patch by Alexander Berntsen

Long description:

Add shmlog command that takes <size>|flip|on|off. Separate logbuffer
management into open_logbuffer() and close_logbuffer(). Make
t/187-commands-parser.t expect 'shmlog'.

To apply this patch, use:
curl http://cr.i3wm.org/patch/173/raw.patch | git am

b/include/commands.h

21
@@ -271,4 +271,10 @@ void cmd_rename_workspace(I3_CMD, char *old_name, char *new_name);
22
  */
23
 void cmd_bar(I3_CMD, char *bar_type, char *bar_value, char *bar_id);
24
 
25
+/*
26
+ * Implementation of 'shmlog <size>|flip|on|off'
27
+ *
28
+ */
29
+void cmd_shmlog(I3_CMD, char *argument);
30
+
31
 #endif

b/include/log.h

36
@@ -39,6 +39,18 @@ extern int shmlog_size;
37
 void init_logging(void);
38
 
39
 /**
40
+ * Opens the logbuffer.
41
+ *
42
+ */
43
+void open_logbuffer(void);
44
+
45
+/**
46
+ * Closes the logbuffer.
47
+ *
48
+ */
49
+void close_logbuffer(void);
50
+
51
+/**
52
  * Set debug logging.
53
  *
54
  */

b/parser-specs/commands.spec

59
@@ -19,6 +19,7 @@ state INITIAL:
60
   'exit' -> call cmd_exit()
61
   'restart' -> call cmd_restart()
62
   'reload' -> call cmd_reload()
63
+  'shmlog' -> SHMLOG
64
   'border' -> BORDER
65
   'layout' -> LAYOUT
66
   'append_layout' -> APPEND_LAYOUT
67
@@ -62,6 +63,12 @@ state EXEC:
68
   command = string
69
       -> call cmd_exec($nosn, $command)
70
 
71
+# shmlog <size>|flip|on|off
72
+state SHMLOG:
73
+  # argument may be a number
74
+  argument = string
75
+    -> call cmd_shmlog($argument)
76
+
77
 # border normal|none|1pixel|toggle|1pixel
78
 state BORDER:
79
   border_style = 'normal', 'pixel'

b/src/commands.c

84
@@ -13,6 +13,8 @@
85
 #include <stdarg.h>
86
 
87
 #include "all.h"
88
+/* SHMLOG_SIZE */
89
+#include "shmlog.h"
90
 
91
 // Macros to make the YAJL API a bit easier to use.
92
 #define y(x, ...) yajl_gen_ ## x (cmd_output->json_gen, ##__VA_ARGS__)
93
@@ -2027,3 +2029,16 @@ void cmd_bar(I3_CMD, char *bar_type, char *bar_value, char *bar_id) {
94
 
95
     update_barconfig();
96
 }
97
+
98
+/*
99
+ * Implementation of 'shmlog <size>|flip|on|off'
100
+ *
101
+ */
102
+void cmd_shmlog(I3_CMD, char *argument) {
103
+    shmlog_size = !strcmp(argument, "flip") ? shmlog_size ? -shmlog_size :
104
+        SHMLOG_SIZE : !strcmp(argument, "off") ? 0 : !strcmp(argument, "on") ?
105
+        SHMLOG_SIZE : atoi(argument);
106
+    LOG("%s shm logging\n", shmlog_size > 0 ? "Enabling" : "Disabling");
107
+    init_logging();
108
+    ysuccess(true);
109
+}

b/src/log.c

114
@@ -89,10 +89,23 @@ void init_logging(void) {
115
             }
116
         }
117
     }
118
+    /* Start SHM logging if shmlog_size is > 0. shmlog_size is SHMLOG_SIZE by
119
+     * default on development versions, and 0 on release versions. If it is
120
+     * not > 0, the user has turned it off, so let's close the logbuffer. Note
121
+     * that this does not handle size changes, only turning the log off or on
122
+     * (optionally with a size defined). */
123
+     if (shmlog_size > 0 && logbuffer == NULL)
124
+        open_logbuffer();
125
+     else if (logbuffer)
126
+        close_logbuffer();
127
+     atexit(purge_zerobyte_logfile);
128
+}
129
 
130
-    /* If this is a debug build (not a release version), we will enable SHM
131
-     * logging by default, unless the user turned it off explicitly. */
132
-    if (logbuffer == NULL && shmlog_size > 0) {
133
+/*
134
+ * Opens the logbuffer.
135
+ *
136
+ */
137
+void open_logbuffer(void) {
138
         /* Reserve 1% of the RAM for the logfile, but at max 25 MiB.
139
          * For 512 MiB of RAM this will lead to a 5 MiB log buffer.
140
          * At the moment (2011-12-10), no testcase leads to an i3 log
141
@@ -127,10 +140,8 @@ void init_logging(void) {
142
 
143
         logbuffer = mmap(NULL, logbuffer_size, PROT_READ | PROT_WRITE, MAP_SHARED, logbuffer_shm, 0);
144
         if (logbuffer == MAP_FAILED) {
145
-            close(logbuffer_shm);
146
-            shm_unlink(shmlogname);
147
+            close_logbuffer();
148
             fprintf(stderr, "Could not mmap SHM segment for the i3 log: %s\n", strerror(errno));
149
-            logbuffer = NULL;
150
             return;
151
         }
152
 
153
@@ -148,8 +159,16 @@ void init_logging(void) {
154
         logwalk = logbuffer + sizeof(i3_shmlog_header);
155
         loglastwrap = logbuffer + logbuffer_size;
156
         store_log_markers();
157
-    }
158
-    atexit(purge_zerobyte_logfile);
159
+}
160
+
161
+/*
162
+ * Closes the logbuffer.
163
+ *
164
+ */
165
+void close_logbuffer(void) {
166
+    close(logbuffer_shm);
167
+    shm_unlink(shmlogname);
168
+    logbuffer = NULL;
169
 }
170
 
171
 /*

b/testcases/t/187-commands-parser.t

176
@@ -144,7 +144,7 @@ is(parser_calls("\nworkspace test"),
177
 ################################################################################
178
 
179
 is(parser_calls('unknown_literal'),
180
-   "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" .
181
+   "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" .
182
    "ERROR: Your command: unknown_literal\n" .
183
    "ERROR:               ^^^^^^^^^^^^^^^",
184
    'error for unknown literal ok');