+ /* If the user passes more arguments, we act like i3-msg would: Just send
+ * the arguments as an IPC message to i3. This allows for nice semantic
+ * commands such as 'i3 border none'. */
+ if (optind < argc) {
+ /* We enable verbose mode so that the user knows what’s going on.
+ * This should make it easier to find mistakes when the user passes
+ * arguments by mistake. */
+ set_verbosity(true);
+
+ LOG("Additional arguments passed. Sending them as a command to i3.\n");
+ char *payload = NULL;
+ while (optind < argc) {
+ if (!payload) {
+ payload = sstrdup(argv[optind]);
+ } else {
+ char *both;
+ sasprintf(&both, "%s %s", payload, argv[optind]);
+ free(payload);
+ payload = both;
+ }
+ optind++;
+ }
+ LOG("Command is: %s (%d bytes)\n", payload, strlen(payload));
+ char *socket_path = root_atom_contents("I3_SOCKET_PATH");
+ if (!socket_path) {
+ ELOG("Could not get i3 IPC socket path\n");
+ return 1;
+ }
+
+ int sockfd = socket(AF_LOCAL, SOCK_STREAM, 0);
+ if (sockfd == -1)
+ err(EXIT_FAILURE, "Could not create socket");
+
+ struct sockaddr_un addr;
+ memset(&addr, 0, sizeof(struct sockaddr_un));
+ addr.sun_family = AF_LOCAL;
+ strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path) - 1);
+ if (connect(sockfd, (const struct sockaddr*)&addr, sizeof(struct sockaddr_un)) < 0)
+ err(EXIT_FAILURE, "Could not connect to i3");
+
+ if (ipc_send_message(sockfd, strlen(payload), I3_IPC_MESSAGE_TYPE_COMMAND,
+ (uint8_t*)payload) == -1)
+ err(EXIT_FAILURE, "IPC: write()");
+
+ uint32_t reply_length;
+ uint8_t *reply;
+ int ret;
+ if ((ret = ipc_recv_message(sockfd, I3_IPC_MESSAGE_TYPE_COMMAND,
+ &reply_length, &reply)) != 0) {
+ if (ret == -1)
+ err(EXIT_FAILURE, "IPC: read()");
+ return 1;
+ }
+ printf("%.*s\n", reply_length, reply);
+ return 0;
+ }
+
+ /* Enable logging to handle the case when the user did not specify --shmlog-size */
+ init_logging();
+
+ /* Try to enable core dumps by default when running a debug build */
+ if (debug_build) {
+ struct rlimit limit = { RLIM_INFINITY, RLIM_INFINITY };
+ setrlimit(RLIMIT_CORE, &limit);
+
+ /* The following code is helpful, but not required. We thus don’t pay
+ * much attention to error handling, non-linux or other edge cases. */
+ char cwd[PATH_MAX];
+ LOG("CORE DUMPS: You are running a development version of i3, so coredumps were automatically enabled (ulimit -c unlimited).\n");
+ if (getcwd(cwd, sizeof(cwd)) != NULL)
+ LOG("CORE DUMPS: Your current working directory is \"%s\".\n", cwd);
+ int patternfd;
+ if ((patternfd = open("/proc/sys/kernel/core_pattern", O_RDONLY)) >= 0) {
+ memset(cwd, '\0', sizeof(cwd));
+ if (read(patternfd, cwd, sizeof(cwd)) > 0)
+ /* a trailing newline is included in cwd */
+ LOG("CORE DUMPS: Your core_pattern is: %s", cwd);
+ close(patternfd);
+ }
+ }
+