#include <assert.h>
#include <dirent.h>
#include <fcntl.h>
+#include <getopt.h>
#include <gio/gio.h>
#include <iniparser.h>
#include <inttypes.h>
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;
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");
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);