1
0

Allow whitespace in cmd_spawn/cmd_output args (fixes #16) (#19)

* Allow whitespace in cmd_spawn/cmd_output args

* Trim cmd no matter the content of the extra option field

* Don't mistake a stray colon in the actual command for a field separator

* Simplified quiet option for cmd_spawn, fixed up parsing
    * Fixed case where option could start with, but not actually be, quiet.
    * Fixed restoring the original command when no option is specified.
    * Simplified code.

* Fixed typos in comments

Co-authored-by: Patrick Gaskin <patrick@pgaskin.net>
This commit is contained in:
NiLuJe
2020-05-13 03:54:43 +02:00
committed by GitHub
parent 4cd4b1e5a8
commit fa1f08a369
3 changed files with 26 additions and 21 deletions

View File

@@ -345,7 +345,7 @@ NM_ACTION_(power) {
N3PowerWorkflowManager *(*N3PowerWorkflowManager_sharedInstance)();
reinterpret_cast<void*&>(N3PowerWorkflowManager_sharedInstance) = dlsym(RTLD_DEFAULT, "_ZN22N3PowerWorkflowManager14sharedInstanceEv");
NM_ASSERT(N3PowerWorkflowManager_sharedInstance, "could not dlsym N3PowerWorkflowManager::sharedInstance, so cannot perform action cleanly (if you must, report a bug and use cmd_spawn instead)");
N3PowerWorkflowManager *pwm = N3PowerWorkflowManager_sharedInstance();
NM_ASSERT(pwm, "could not get shared power manager pointer");
@@ -375,13 +375,15 @@ NM_ACTION_(power) {
NM_ACTION_(cmd_spawn) {
#define NM_ERR_RET nullptr
char *tmp = strdup(arg);
char *cmd = tmp;
bool quiet = false;
if (!strncmp(tmp, "quiet:", 6)) {
cmd += 6;
quiet = true;
}
char *tmp = strdup(arg); // strsep and strtrim will modify it
char *tmp1 = tmp; // so we can still free tmp later
char *tmp2 = strtrim(strsep(&tmp1, ":")); // get the part before the : into tmp2, if any
bool quiet = tmp1 && !strcmp(tmp2, "quiet");
const char *cmd = (tmp1 && quiet)
? strtrim(tmp1) // trim the actual command
: arg; // restore the original arg if there wasn't any option field or if it wasn't "quiet"
QProcess proc;
uint64_t pid;
bool ok = proc.startDetached(
@@ -393,6 +395,7 @@ NM_ACTION_(cmd_spawn) {
QStringLiteral("/"),
(qint64*)(&pid)
);
free(tmp);
NM_ASSERT(ok, "could not start process");
NM_RETURN_OK(quiet ? nm_action_result_silent() : nm_action_result_toast("Successfully started process with PID %lu.", (unsigned long)(pid)));
@@ -405,8 +408,9 @@ NM_ACTION_(cmd_output) {
char *tmp = strdup(arg);
char *cmd = tmp;
char *tmp1 = strsep(&cmd, ":"), *tmp2;
char *tmp1 = strtrim(strsep(&cmd, ":")), *tmp2;
long timeout = strtol(tmp1, &tmp2, 10);
cmd = strtrim(cmd);
NM_ASSERT(*tmp1 && !*tmp2 && timeout > 0 && timeout < 10000, "invalid timeout '%s'", tmp1);
QProcess proc;

View File

@@ -1,5 +1,4 @@
#define _GNU_SOURCE // asprintf
#include <ctype.h>
#include <dirent.h>
#include <errno.h>
#include <stdbool.h>
@@ -35,17 +34,6 @@ struct nm_config_t {
nm_config_t *next;
};
// strtrim trims ASCII whitespace in-place (i.e. don't give it a string literal)
// from the left/right of the string.
static char *strtrim(char *s){
if (!s) return NULL;
char *a = s, *b = s + strlen(s);
for (; a < b && isspace((unsigned char)(*a)); a++);
for (; b > a && isspace((unsigned char)(*(b-1))); b--);
*b = '\0';
return a;
}
static void nm_config_push_menu_item(nm_config_t **cfg, nm_menu_item_t *it) {
nm_config_t *tmp = calloc(1, sizeof(nm_config_t));
tmp->type = NM_CONFIG_TYPE_MENU_ITEM;

View File

@@ -8,9 +8,22 @@ extern "C" {
#define _GNU_SOURCE // asprintf
#endif
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <syslog.h>
// strtrim trims ASCII whitespace in-place (i.e. don't give it a string literal)
// from the left/right of the string.
inline char *strtrim(char *s){
if (!s) return NULL;
char *a = s, *b = s + strlen(s);
for (; a < b && isspace((unsigned char)(*a)); a++);
for (; b > a && isspace((unsigned char)(*(b-1))); b--);
*b = '\0';
return a;
}
// A bunch of useful macros to simplify error handling and logging.
// NM_LOG writes a log message.