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
*/
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
*/
void init_logging(void);
+/**
+ * Opens the logbuffer.
+ *
+ */
+void open_logbuffer(void);
+
+/**
+ * Closes the logbuffer.
+ *
+ */
+void close_logbuffer(void);
+
/**
* Set debug logging.
*
*/
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)
*
'exit' -> call cmd_exit()
'restart' -> call cmd_restart()
'reload' -> call cmd_reload()
+ 'shmlog' -> SHMLOG
'border' -> BORDER
'layout' -> LAYOUT
'append_layout' -> APPEND_LAYOUT
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'
#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__)
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);
+}
}
}
}
+ /* 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
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;
}
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;
}
/*
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)
*
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();
}
/*
################################################################################
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');