Add crash manager API
[platform/core/system/crash-worker.git] / src / crash-service / libcrash-service.c
1 /*
2  * Copyright (c) 2016-2019 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <gio/gio.h>
18 #include <stdbool.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22
23 #define LOG_TAG "LIBCRASH-SERVICE"
24
25 #include "shared/log.h"
26
27 #define BUS_NAME "org.tizen.system.crash.livedump"
28 #define OBJECT_PATH "/Org/Tizen/System/Crash/Livedump"
29 #define INTERFACE_NAME "org.tizen.system.crash.livedump"
30 #define METHOD_NAME "livedump_pid"
31
32 static GDBusConnection* dbus_init(void)
33 {
34         GError *error = NULL;
35         GDBusConnection *conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
36
37         if (!conn || error) {
38                 _E("Failed to get dbus: %s", error ? error->message : "");
39                 if (error)
40                         g_error_free(error);
41                 return NULL;
42         }
43
44         return conn;
45 }
46
47 bool livedump_pid(pid_t pid, const char *dump_reason, char *report_path, size_t report_path_len)
48 {
49         bool res = true;
50         GDBusConnection *conn = dbus_init();
51
52         if (!conn)
53                 return false;
54
55         GVariant *parameters = g_variant_new("(is)", pid, dump_reason);
56
57         GError *error = NULL;
58         GVariant *reply = g_dbus_connection_call_sync(conn,
59                                        BUS_NAME,
60                                        OBJECT_PATH,
61                                        INTERFACE_NAME,
62                                        METHOD_NAME,
63                                        parameters,
64                                        G_VARIANT_TYPE("(s)"),
65                                        G_DBUS_CALL_FLAGS_NONE,
66                                        -1,
67                                        NULL,
68                                        &error);
69         if (!reply || error) {
70                 _E("Error while calling livedump_pid via dbus (pid=%d, reason=%s): %s", pid, dump_reason, error ? error->message : "");
71                 if (error)
72                         g_error_free(error);
73                 res = false;
74                 goto exit;
75         }
76
77         if (!g_variant_is_of_type(reply, G_VARIANT_TYPE("(s)"))) {
78                 _E("reply is not of the correct type (s)");
79                 res = false;
80                 goto exit;
81         }
82
83         gchar *reply_str;
84         g_variant_get(reply, "(&s)", &reply_str);
85         if (strlen(reply_str) <= (report_path_len + 1)) {
86                 strncpy(report_path, reply_str, report_path_len);
87         } else {
88                 _E("Report path (%s) is longer than report_path_len", reply_str);
89                 res = false;
90         }
91 exit:
92         g_object_unref(conn);
93         return res;
94 }