Use getopt to parse command line arguments 42/205842/6
authorMateusz Moscicki <m.moscicki2@partner.samsung.com>
Wed, 8 May 2019 10:27:18 +0000 (12:27 +0200)
committerMateusz Moscicki <m.moscicki2@partner.samsung.com>
Thu, 23 May 2019 12:16:59 +0000 (14:16 +0200)
Change-Id: If8fcb875d19f4547348b72341e342251cb8b7fb2

src/crash-manager/99-crash-manager.conf.in
src/crash-manager/crash-manager.c
tests/system/critical_process/critical_process.sh.template
tests/system/wait_for_opt_usr/wait_for_opt_usr.sh.template

index e1900b9..b7dfe62 100644 (file)
@@ -1,5 +1,5 @@
 # Tizen crash-manager
-kernel.core_pattern=|/usr/bin/crash-manager %p %u %g %s %t %i
+kernel.core_pattern=|/usr/bin/crash-manager -p %p -u %u -g %g -s %s -t %t
 kernel.core_pipe_limit=10
 # All processes should be dumped
 fs.suid_dumpable=2
index de63b5d..7a4c0b5 100644 (file)
@@ -19,6 +19,7 @@
 #include <assert.h>
 #include <dirent.h>
 #include <fcntl.h>
+#include <getopt.h>
 #include <gio/gio.h>
 #include <iniparser.h>
 #include <inttypes.h>
@@ -301,6 +302,91 @@ close_fd:
        return -1;
 }
 
+static void print_help(const char *name)
+{
+       printf("Syntax: %s [OPTIONS]\n"
+              "\n"
+              "    -p  --pid=PID           PID of dumped process\n"
+              "    -u  --uid=UID           real UID of dumped process\n"
+              "    -g  --gid=GID           real GID of dumped process\n"
+              "    -i  --tid=TID           TID of thread that triggered core dump\n"
+              "    -s  --signal=SIG        number of signal causing dump\n"
+              "    -t  --time=TIME         time of dump, expressed as seconds since the Epoch\n"
+              "    -h  --help              this message\n"
+              "\n", name);
+}
+
+static bool parse_args(struct crash_info *cinfo, int argc, char *argv[])
+{
+#define QUOTE(member) #member
+#define GET_NUMBER(member) \
+       errno = 0; \
+       cinfo->member##_info = strtol(optarg, NULL, 10); \
+       if (errno != 0) { \
+               _D("%s argument error\n", QUOTE(member)); \
+               printf("%s argument error\n", QUOTE(member)); \
+               return false; \
+       }
+
+       bool result = true;
+       int opt;
+       bool pid_set = false;
+       bool uid_set = false;
+       bool gid_set = false;
+       bool sig_set = false;
+
+       struct option long_options[] = {
+               {"pid",             required_argument, NULL, 'p'},
+               {"uid",             required_argument, NULL, 'u'},
+               {"gid",             required_argument, NULL, 'g'},
+               {"tid",             required_argument, NULL, 'i'},
+               {"signal",          required_argument, NULL, 's'},
+               {"time",            required_argument, NULL, 't'},
+               {"help",                  no_argument, NULL, 'h'},
+       };
+
+       while ((opt = getopt_long(argc, argv, "p:u:g:i:s:t:h", long_options, NULL)) != -1) {
+               switch (opt) {
+               case 'p':
+                       GET_NUMBER(pid)
+                       pid_set = true;
+                       break;
+               case 'u':
+                       GET_NUMBER(uid)
+                       uid_set = true;
+                       break;
+               case 'g':
+                       GET_NUMBER(gid)
+                       gid_set = true;
+                       break;
+               case 'i':
+                       GET_NUMBER(tid)
+                       break;
+               case 's':
+                       GET_NUMBER(sig)
+                       sig_set = true;
+                       break;
+               case 't':
+                       GET_NUMBER(time)
+                       break;
+               case 'h':
+               default:
+                       print_help(argv[0]);
+                       result = false;
+                       break;
+               }
+       }
+
+       if (result && (!pid_set || !uid_set || !gid_set || !sig_set)) {
+               printf("Not enough parameters.\n\n");
+               print_help(argv[0]);
+               result = false;
+       }
+       return result;
+#undef QUOTE
+#undef GET_NUMBER
+}
+
 static int set_crash_info(struct crash_info *cinfo, int argc, char *argv[])
 {
        int ret;
@@ -308,11 +394,13 @@ static int set_crash_info(struct crash_info *cinfo, int argc, char *argv[])
        char date[80];
        struct tm loc_tm;
 
-       cinfo->pid_info = strtol(argv[1], NULL, 10);
-       cinfo->sig_info = atoi(argv[4]);
-       if (argc > 6)
-               cinfo->tid_info = strtol(argv[6], NULL, 10);
-       else {
+       cinfo->tid_info = -1;
+       cinfo->time_info = 0;
+
+       if (!parse_args(cinfo, argc, argv))
+               return -1;
+
+       if (cinfo->tid_info == -1) {
                cinfo->tid_info = find_crash_tid(cinfo->pid_info);
                if (cinfo->tid_info < 0) {
                        _I("TID not found");
@@ -326,7 +414,9 @@ static int set_crash_info(struct crash_info *cinfo, int argc, char *argv[])
                return -1;
        }
 
-       cinfo->time_info = strtol(argv[5], NULL, 10);
+       if (cinfo->time_info == 0)
+               cinfo->time_info = time(NULL);
+
        localtime_r(&cinfo->time_info, &loc_tm);
        strftime(date, sizeof(date), "%Y%m%d%H%M%S", &loc_tm);
 
index 8eacf37..b2cbb8c 100755 (executable)
@@ -52,7 +52,7 @@ fi
 
 save_core_pattern
 trap restore_core_pattern 0
-echo "|/usr/bin/crash-manager %p %u %g %s %t %i" > /proc/sys/kernel/core_pattern
+echo "|/usr/bin/crash-manager -p %p -u %u -g %g -s %s -t %t" > /proc/sys/kernel/core_pattern
 
 tlm-client -s --username test1 --password tizen --seat seat0 1> /dev/null 2>&1
 sleep 4
index aa4cf28..bb36e4f 100755 (executable)
@@ -22,7 +22,7 @@ fi
 save_core_pattern
 trap restore_core_pattern 0
 
-echo "|/usr/bin/crash-manager %p %u %g %s %t %i" > /proc/sys/kernel/core_pattern
+echo "|/usr/bin/crash-manager -p %p -u %u -g %g -s %s -t %t" > /proc/sys/kernel/core_pattern
 
 {
     ${CRASH_WORKER_SYSTEM_TESTS}/utils/kenny 10 &