#include "shared/log.h"
#include "shared/util.h"
-enum BUGREPORT_REPORT_TYPE { BR_UNKNOWN, BR_BUGREPORT, BR_CRASHINFO, BR_CRASHINFO_JSON, BR_COREDUMP_TAR, BR_FULLREPORT };
+enum BUGREPORT_REPORT_TYPE { BR_UNKNOWN, BR_BUGREPORT, BR_CRASHINFO, BR_CRASHINFO_JSON, BR_COREDUMP_TAR, BR_FULLREPORT, BR_PID };
struct report_file {
char *file_name;
return NULL;
}
+static bool parse_pid_from_report_file(int report_fd, char *str)
+{
+ FILE *fp;
+ char buff[1024];
+ int pid = -1;
+
+ if (!str)
+ return false;
+
+ fp = fdopen(report_fd, "r");
+ if (!fp) {
+ _E("There is no report file");
+ return false;
+ }
+
+ while (fgets(buff, sizeof(buff), fp)) {
+ if (sscanf(buff, "PID = %d", &pid) == 1)
+ break;
+ }
+ if (pid < 0) {
+ _E("There is no PID information in the report file");
+ return false;
+ }
+
+ sprintf(str, "%d", pid);
+
+ return true;
+}
+
+static bool write_pid(int fd, int in_fd)
+{
+ char pid[10];
+
+ if (!parse_pid_from_report_file(in_fd, pid)) {
+ dprintf(fd, "Internal error\n");
+ return false;
+ }
+
+ if (write(fd, pid, strlen(pid)) < 0) {
+ dprintf(fd, "Internal error: %m\n");
+ return false;
+ }
+
+ return true;
+}
+
+static bool write_blank(int fd)
+{
+ if (write(fd, " ", 1) < 0) {
+ dprintf(fd, "Internal error: %m\n");
+ return false;
+ }
+
+ return true;
+}
+
+static bool write_pids(int fd, long time_from, long time_to)
+{
+ bool result = true;
+ size_t list_count = 0;
+ struct report_file *list = get_reports_from_range(time_from, time_to, &list_count);
+ if (list == NULL) {
+ dprintf(fd, "Internal error\n");
+ return false;
+ }
+
+ for (size_t i = 0; i < list_count; i++) {
+ int nfd = diagnostics_report_get_file(list[i].file_path, INFO_FILE);
+ if (nfd <= 0) {
+ _I("No INFO_FILE in %s file", list[i].file_path);
+ dprintf(nfd, "No INFO_FILE in %s\n", list[i].file_path);
+ continue;
+ }
+
+ if (!write_pid(fd, nfd)) {
+ _E("write_pid error");
+ close(nfd);
+ result = false;
+ break;
+ }
+
+ close(nfd);
+
+ if (!write_blank(fd)) {
+ _E("write_blank error");
+ result = false;
+ break;
+ }
+ }
+
+ for (size_t i = 0; i < list_count; i++)
+ free_record(&list[i]);
+ free(list);
+
+ return result;
+}
+
+static bool write_single_report(struct report_file *report, int fd, enum diagnostics_entry report_entry, const char *ident)
+{
+ bool result = true;
+ int in_fd = diagnostics_report_get_file(report->file_path, report_entry);
+ if (in_fd < 0) {
+ _E("Can not get report entry: %d from: %s (report ident: %s)",
+ report_entry, report->file_path, ident);
+ return false;
+ }
+
+ switch (report_entry) {
+ case INFO_PID:
+ if (!write_pid(fd, in_fd)) {
+ _E("Write pid error");
+ result = false;
+ }
+ break;
+ case LOG_FILE:
+ case INFO_FILE:
+ case INFO_JSON:
+ case COREDUMP_TAR:
+ case FULL_REPORT:
+ if (copy_bytes(fd, in_fd, NULL) == -1) {
+ _E("Copy data error");
+ result = false;
+ }
+ break;
+ default:
+ _E("Unsupported report type: %d", report_entry);
+ result = false;
+ break;
+ }
+
+ if (in_fd > 0)
+ close(in_fd);
+ return result;
+}
+
static bool write_single_file(int fd, enum BUGREPORT_REPORT_TYPE report_type, const char *ident)
{
assert(fd >= 0);
case BR_FULLREPORT:
report_entry = FULL_REPORT;
break;
+ case BR_PID:
+ report_entry = INFO_PID;
+ break;
default:
_E("Unsupported report type: %d", report_type);
result = false;
goto out;
}
- int in_fd = diagnostics_report_get_file(report->file_path, report_entry);
- if (in_fd < 0) {
- _E("Can not get report type: %d from: %s (report ident: %s)", report_type, report->file_path, ident);
- result = false;
- goto out;
- }
-
- if (copy_bytes(fd, in_fd, NULL) == -1) {
- _E("Copy data error");
- result = false;
- goto out;
- }
+ result = write_single_report(report, fd, report_entry, ident);
out:
for (size_t i = 0; i < list_count; i++)
free_record(&list[i]);
{
dprintf(out_fd, "Usage:\n\n"
" dumpsys org.tizen.bugreport-service [--type=<report_type>] [[--last <seconds> |--from <timestamp> [--to <timestamp>]]|[report_ident]]\n\n"
- " --type <report_type> Specify the type of report. Available types: bugreport, crash-info, crash-info-json. Additional types are available\n"
+ " --type <report_type> Specify the type of report. Available types: bugreport, crash-info, crash-info-json, pid. Additional types are available\n"
" if single report is specified by <report_ident>: fullreport, coredumptar (default: bugreport).\n"
" --last <seconds> Get reports generated in the last <seconds>.\n"
" --from <timestamp> Get reports generated after specified time.\n"
dco->report_type = BR_COREDUMP_TAR;
} else if (strcmp(optarg, "fullreport") == 0) {
dco->report_type = BR_FULLREPORT;
+ } else if (strcmp(optarg, "pid") == 0) {
+ dco->report_type = BR_PID;
} else {
_E("Incorrect report type: %s", optarg);
dprintf(out_fd, "Incorrect report type: %s\n", optarg);
case BR_FULLREPORT:
dprintf(fd, "Report type \"fullreport\" requires a specific report with report_ident argument.\n");
break;
+ case BR_PID:
+ write_pids(fd, dco.from, dco.to);
+ break;
default:
_E("Unknown report type\n");
}