1 /* GLIB - Library of useful routines for C programming
2 * Copyright (C) 2005 Matthias Clasen
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
23 #include <sys/types.h>
28 static gchar *dir, *filename, *displayname, *childname;
30 static gboolean stop = FALSE;
33 handle_usr1 (int signum)
39 check_stop (gpointer data)
41 GMainLoop *loop = data;
44 g_main_loop_quit (loop);
50 write_or_die (const gchar *filename,
51 const gchar *contents,
57 if (!g_file_set_contents (filename, contents, length, &error))
59 displayname = g_filename_display_name (childname);
60 g_print ("failed to write '%s': %s\n",
61 displayname, error->message);
67 map_or_die (const gchar *filename,
74 map = g_mapped_file_new (filename, writable, &error);
77 displayname = g_filename_display_name (childname);
78 g_print ("failed to map '%s' non-writable, shared: %s\n",
79 displayname, error->message);
87 child_main (int argc, char *argv[])
92 map = map_or_die (filename, FALSE);
94 loop = g_main_loop_new (NULL, FALSE);
96 signal (SIGUSR1, handle_usr1);
97 g_idle_add (check_stop, loop);
98 g_main_loop_run (loop);
100 write_or_die (childname,
101 g_mapped_file_get_contents (map),
102 g_mapped_file_get_length (map));
112 write_or_die (filename, "ABC", -1);
114 map = map_or_die (filename, FALSE);
115 g_assert (g_mapped_file_get_length (map) == 3);
116 g_mapped_file_free (map);
118 map = map_or_die (filename, TRUE);
119 g_assert (g_mapped_file_get_length (map) == 3);
120 g_mapped_file_free (map);
126 GError *error = NULL;
131 write_or_die (filename, "ABC", -1);
132 map = map_or_die (filename, TRUE);
134 buffer = (gchar *)g_mapped_file_get_contents (map);
138 g_mapped_file_free (map);
140 if (!g_file_get_contents (filename, &buffer, &len, &error))
142 g_print ("failed to read '%s': %s\n",
143 displayname, error->message);
148 g_assert (strcmp (buffer, "ABC") == 0);
154 test_child_private (gchar *argv0)
156 GError *error = NULL;
160 gchar *child_argv[3];
163 write_or_die (filename, "ABC", -1);
164 map = map_or_die (filename, TRUE);
166 child_argv[0] = argv0;
167 child_argv[1] = "mapchild";
168 child_argv[2] = NULL;
169 if (!g_spawn_async (dir, child_argv, NULL,
170 0, NULL, NULL, &child_pid, &error))
172 g_print ("failed to spawn child: %s\n",
177 /* give the child some time to set up its mapping */
180 buffer = (gchar *)g_mapped_file_get_contents (map);
184 g_mapped_file_free (map);
186 kill (child_pid, SIGUSR1);
188 /* give the child some time to write the file */
191 if (!g_file_get_contents (childname, &buffer, &len, &error))
195 name = g_filename_display_name (childname);
196 g_print ("failed to read '%s': %s\n", name, error->message);
200 g_assert (strcmp (buffer, "ABC") == 0);
205 parent_main (int argc,
208 /* test mapping with various flag combinations */
211 /* test private modification */
214 /* test multiple clients, non-shared */
215 test_child_private (argv[0]);
224 dir = g_get_current_dir ();
225 filename = g_build_filename (dir, "maptest", NULL);
226 displayname = g_filename_display_name (filename);
227 childname = g_build_filename (dir, "mapchild", NULL);
230 return child_main (argc, argv);
232 return parent_main (argc, argv);