[kdbus] KDBUS_ITEM_PAYLOAD_OFF items are (once again) relative to msg header
[platform/upstream/glib.git] / gio / tests / send-data.c
1 #include <gio/gio.h>
2 #include <string.h>
3 #include <stdio.h>
4
5 GMainLoop *loop;
6
7 int cancel_timeout = 0;
8 int io_timeout = 0;
9 gboolean async = FALSE;
10 gboolean graceful = FALSE;
11 gboolean verbose = FALSE;
12 static GOptionEntry cmd_entries[] = {
13   {"cancel", 'c', 0, G_OPTION_ARG_INT, &cancel_timeout,
14    "Cancel any op after the specified amount of seconds", NULL},
15   {"async", 'a', 0, G_OPTION_ARG_NONE, &async,
16    "Use async ops", NULL},
17   {"graceful-disconnect", 'g', 0, G_OPTION_ARG_NONE, &graceful,
18    "Use graceful disconnect", NULL},
19   {"timeout", 't', 0, G_OPTION_ARG_INT, &io_timeout,
20    "Time out socket I/O after the specified number of seconds", NULL},
21   {"verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose,
22    "Verbose debugging output", NULL},
23   {NULL}
24 };
25
26 static gpointer
27 cancel_thread (gpointer data)
28 {
29   GCancellable *cancellable = data;
30
31   g_usleep (1000*1000*cancel_timeout);
32   g_print ("Cancelling\n");
33   g_cancellable_cancel (cancellable);
34   return NULL;
35 }
36
37 static char *
38 socket_address_to_string (GSocketAddress *address)
39 {
40   GInetAddress *inet_address;
41   char *str, *res;
42   int port;
43
44   inet_address = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (address));
45   str = g_inet_address_to_string (inet_address);
46   port = g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (address));
47   res = g_strdup_printf ("%s:%d", str, port);
48   g_free (str);
49   return res;
50 }
51
52 static void
53 async_cb (GObject *source_object,
54           GAsyncResult *res,
55           gpointer user_data)
56 {
57   GAsyncResult **resp = user_data;
58   *resp = g_object_ref (res);
59   g_main_loop_quit (loop);
60 }
61
62 static void
63 socket_client_event (GSocketClient *client,
64                      GSocketClientEvent event,
65                      GSocketConnectable *connectable,
66                      GSocketConnection *connection)
67 {
68   static GEnumClass *event_class;
69   GTimeVal tv;
70
71   if (!event_class)
72     event_class = g_type_class_ref (G_TYPE_SOCKET_CLIENT_EVENT);
73
74   g_get_current_time (&tv);
75   printf ("% 12ld.%06ld GSocketClient => %s [%s]\n",
76           tv.tv_sec, tv.tv_usec,
77           g_enum_get_value (event_class, event)->value_nick,
78           connection ? G_OBJECT_TYPE_NAME (connection) : "");
79 }
80
81 int
82 main (int argc, char *argv[])
83 {
84   GOptionContext *context;
85   GSocketClient *client;
86   GSocketConnection *connection;
87   GSocketAddress *address;
88   GCancellable *cancellable;
89   GOutputStream *out;
90   GError *error = NULL;
91   char buffer[1000];
92
93   context = g_option_context_new (" <hostname>[:port] - send data to tcp host");
94   g_option_context_add_main_entries (context, cmd_entries, NULL);
95   if (!g_option_context_parse (context, &argc, &argv, &error))
96     {
97       g_printerr ("%s: %s\n", argv[0], error->message);
98       return 1;
99     }
100
101   if (argc != 2)
102     {
103       g_printerr ("%s: %s\n", argv[0], "Need to specify hostname");
104       return 1;
105     }
106
107   if (async)
108     loop = g_main_loop_new (NULL, FALSE);
109
110   if (cancel_timeout)
111     {
112       GThread *thread;
113       cancellable = g_cancellable_new ();
114       thread = g_thread_new ("cancel", cancel_thread, cancellable);
115       g_thread_unref (thread);
116     }
117   else
118     {
119       cancellable = NULL;
120     }
121
122   client = g_socket_client_new ();
123   if (io_timeout)
124     g_socket_client_set_timeout (client, io_timeout);
125   if (verbose)
126     g_signal_connect (client, "event", G_CALLBACK (socket_client_event), NULL);
127
128   if (async)
129     {
130       GAsyncResult *res;
131       g_socket_client_connect_to_host_async (client, argv[1], 7777,
132                                              cancellable, async_cb, &res);
133       g_main_loop_run (loop);
134       connection = g_socket_client_connect_to_host_finish (client, res, &error);
135       g_object_unref (res);
136     }
137   else
138     {
139       connection = g_socket_client_connect_to_host (client,
140                                                     argv[1],
141                                                     7777,
142                                                     cancellable, &error);
143     }
144   if (connection == NULL)
145     {
146       g_printerr ("%s can't connect: %s\n", argv[0], error->message);
147       return 1;
148     }
149   g_object_unref (client);
150
151   address = g_socket_connection_get_remote_address (connection, &error);
152   if (!address)
153     {
154       g_printerr ("Error getting remote address: %s\n",
155                   error->message);
156       return 1;
157     }
158   g_print ("Connected to address: %s\n",
159            socket_address_to_string (address));
160   g_object_unref (address);
161
162   if (graceful)
163     g_tcp_connection_set_graceful_disconnect (G_TCP_CONNECTION (connection), TRUE);
164
165   out = g_io_stream_get_output_stream (G_IO_STREAM (connection));
166
167   while (fgets(buffer, sizeof (buffer), stdin) != NULL)
168     {
169       /* FIXME if (async) */
170       if (!g_output_stream_write_all (out, buffer, strlen (buffer),
171                                       NULL, cancellable, &error))
172         {
173           g_warning ("send error: %s\n",  error->message);
174           g_error_free (error);
175           error = NULL;
176         }
177     }
178
179   g_print ("closing stream\n");
180   if (async)
181     {
182       GAsyncResult *res;
183       g_io_stream_close_async (G_IO_STREAM (connection),
184                                0, cancellable, async_cb, &res);
185       g_main_loop_run (loop);
186       if (!g_io_stream_close_finish (G_IO_STREAM (connection),
187                                      res, &error))
188         {
189           g_object_unref (res);
190           g_warning ("close error: %s\n",  error->message);
191           return 1;
192         }
193       g_object_unref (res);
194     }
195   else
196     {
197       if (!g_io_stream_close (G_IO_STREAM (connection), cancellable, &error))
198         {
199           g_warning ("close error: %s\n",  error->message);
200           return 1;
201         }
202     }
203
204   g_object_unref (connection);
205
206   return 0;
207 }