Merge remote-tracking branch 'gvdb/master'
[platform/upstream/glib.git] / gio / tests / gdbus-example-unix-fd-client.c
1 #include <string.h>
2 #include <stdlib.h>
3
4 #include <sys/types.h>
5 #include <unistd.h>
6
7 #include <time.h>
8
9 #include <gio/gio.h>
10 #include <gio/gunixfdlist.h>
11
12 /* see gdbus-example-server.c for the server implementation */
13 static gint
14 get_server_stdout (GDBusConnection  *connection,
15                    const gchar      *name_owner,
16                    GError          **error)
17 {
18   GDBusMessage *method_call_message;
19   GDBusMessage *method_reply_message;
20   GUnixFDList *fd_list;
21   gint fd;
22
23   fd = -1;
24   method_call_message = NULL;
25   method_reply_message = NULL;
26
27   method_call_message = g_dbus_message_new_method_call (name_owner,
28                                                         "/org/gtk/GDBus/TestObject",
29                                                         "org.gtk.GDBus.TestInterface",
30                                                         "GimmeStdout");
31   method_reply_message = g_dbus_connection_send_message_with_reply_sync (connection,
32                                                                          method_call_message,
33                                                                          G_DBUS_SEND_MESSAGE_FLAGS_NONE,
34                                                                          -1,
35                                                                          NULL, /* out_serial */
36                                                                          NULL, /* cancellable */
37                                                                          error);
38   if (method_reply_message == NULL)
39       goto out;
40
41   if (g_dbus_message_get_message_type (method_reply_message) == G_DBUS_MESSAGE_TYPE_ERROR)
42     {
43       g_dbus_message_to_gerror (method_reply_message, error);
44       goto out;
45     }
46
47   fd_list = g_dbus_message_get_unix_fd_list (method_reply_message);
48   fd = g_unix_fd_list_get (fd_list, 0, error);
49
50  out:
51   g_object_unref (method_call_message);
52   g_object_unref (method_reply_message);
53
54   return fd;
55 }
56
57 static void
58 on_name_appeared (GDBusConnection *connection,
59                   const gchar     *name,
60                   const gchar     *name_owner,
61                   gpointer         user_data)
62 {
63   gint fd;
64   GError *error;
65
66   error = NULL;
67   fd = get_server_stdout (connection, name_owner, &error);
68   if (fd == -1)
69     {
70       g_printerr ("Error invoking GimmeStdout(): %s\n",
71                   error->message);
72       g_error_free (error);
73       exit (1);
74     }
75   else
76     {
77       gchar now_buf[256];
78       time_t now;
79       gssize len;
80       gchar *str;
81
82       now = time (NULL);
83       strftime (now_buf,
84                 sizeof now_buf,
85                 "%c",
86                 localtime (&now));
87
88       str = g_strdup_printf ("On %s, gdbus-example-unix-fd-client with pid %d was here!\n",
89                              now_buf,
90                              (gint) getpid ());
91       len = strlen (str);
92       g_warn_if_fail (write (fd, str, len) == len);
93       close (fd);
94
95       g_print ("Wrote the following on server's stdout:\n%s", str);
96
97       g_free (str);
98       exit (0);
99     }
100 }
101
102 static void
103 on_name_vanished (GDBusConnection *connection,
104                   const gchar     *name,
105                   gpointer         user_data)
106 {
107   g_printerr ("Failed to get name owner for %s\n"
108               "Is ./gdbus-example-server running?\n",
109               name);
110   exit (1);
111 }
112
113 int
114 main (int argc, char *argv[])
115 {
116   guint watcher_id;
117   GMainLoop *loop;
118
119   g_type_init ();
120
121   watcher_id = g_bus_watch_name (G_BUS_TYPE_SESSION,
122                                  "org.gtk.GDBus.TestServer",
123                                  G_BUS_NAME_WATCHER_FLAGS_NONE,
124                                  on_name_appeared,
125                                  on_name_vanished,
126                                  NULL,
127                                  NULL);
128
129   loop = g_main_loop_new (NULL, FALSE);
130   g_main_loop_run (loop);
131
132   g_bus_unwatch_name (watcher_id);
133   return 0;
134 }