#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;
+
+ fp = fdopen(report_fd, "r");
+
+ while (fgets(buff, sizeof(buff), fp)) {
+ if (sscanf(buff, "PID = %d", &pid) == 1)
+ break;
+ }
+ if (pid < 0)
+ 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 (int 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 (int i = 0; i < list_count; i++)
+ free_record(&list[i]);
+ free(list);
+
+ 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;
}
- if (copy_bytes(fd, in_fd, NULL) == -1) {
+ if (report_entry == INFO_PID)
+ write_pid(fd, in_fd);
+ else if (copy_bytes(fd, in_fd, NULL) == -1) {
_E("Copy data error");
result = false;
goto out;
dco->report_type = BR_COREDUMP_TAR;
} else if (strcmp(optarg, "fullreport") == 0) {
dco->report_type = BR_FULLREPORT;
- } else {
+ } 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);
return false;
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");
}