sl@0: /* GLIB - Library of useful routines for C programming sl@0: * Copyright (C) 2005 Matthias Clasen sl@0: * Portion Copyright © 2008-09 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. sl@0: * This library is free software; you can redistribute it and/or sl@0: * modify it under the terms of the GNU Lesser General Public sl@0: * License as published by the Free Software Foundation; either sl@0: * version 2 of the License, or (at your option) any later version. sl@0: * sl@0: * This library is distributed in the hope that it will be useful, sl@0: * but WITHOUT ANY WARRANTY; without even the implied warranty of sl@0: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU sl@0: * Lesser General Public License for more details. sl@0: * sl@0: * You should have received a copy of the GNU Lesser General Public sl@0: * License along with this library; if not, write to the sl@0: * Free Software Foundation, Inc., 59 Temple Place - Suite 330, sl@0: * Boston, MA 02111-1307, USA. sl@0: */ sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: #include "glib.h" sl@0: #include "gstdio.h" sl@0: sl@0: #ifdef SYMBIAN sl@0: #include "mrt2_glib2_test.h" sl@0: #endif /*SYMBIAN*/ sl@0: sl@0: sl@0: static gchar *dir, *filename, *displayname, *childname; sl@0: sl@0: static gboolean stop = FALSE; sl@0: sl@0: #ifndef G_OS_WIN32 sl@0: sl@0: static void sl@0: handle_usr1 (int signum) sl@0: { sl@0: stop = TRUE; sl@0: } sl@0: sl@0: #endif sl@0: sl@0: static gboolean sl@0: check_stop (gpointer data) sl@0: { sl@0: GMainLoop *loop = data; sl@0: sl@0: #if defined(G_OS_WIN32) || defined(SYMBIAN) sl@0: stop = g_file_test ("STOP", G_FILE_TEST_EXISTS); sl@0: #endif sl@0: sl@0: if (stop) sl@0: g_main_loop_quit (loop); sl@0: sl@0: return TRUE; sl@0: } sl@0: sl@0: static void sl@0: write_or_die (const gchar *filename, sl@0: const gchar *contents, sl@0: gssize length) sl@0: { sl@0: GError *error = NULL; sl@0: gchar *displayname; sl@0: sl@0: if (!g_file_set_contents (filename, contents, length, &error)) sl@0: { sl@0: displayname = g_filename_display_name (childname); sl@0: g_print ("failed to write '%s': %s\n", sl@0: displayname, error->message); sl@0: sl@0: g_assert(FALSE && "mapping-test failed"); sl@0: sl@0: #ifdef SYMBIAN sl@0: testResultXml("mapping-test"); sl@0: #endif /* EMULATOR */ sl@0: sl@0: exit (1); sl@0: } sl@0: } sl@0: sl@0: static GMappedFile * sl@0: map_or_die (const gchar *filename, sl@0: gboolean writable) sl@0: { sl@0: GError *error = NULL; sl@0: GMappedFile *map; sl@0: gchar *displayname; sl@0: sl@0: map = g_mapped_file_new (filename, writable, &error); sl@0: if (!map) sl@0: { sl@0: displayname = g_filename_display_name (childname); sl@0: g_print ("failed to map '%s' non-writable, shared: %s\n", sl@0: displayname, error->message); sl@0: sl@0: g_assert(FALSE && "mapping-test failed"); sl@0: sl@0: #ifdef SYMBIAN sl@0: testResultXml("mapping-test"); sl@0: #endif /* EMULATOR */ sl@0: sl@0: exit (1); sl@0: } sl@0: sl@0: return map; sl@0: } sl@0: sl@0: void *child_main (void *dummy) sl@0: { sl@0: GMappedFile *map; sl@0: GMainLoop *loop; sl@0: sl@0: map = map_or_die (filename, FALSE); sl@0: sl@0: loop = g_main_loop_new (NULL, FALSE); sl@0: sl@0: #if !defined(G_OS_WIN32) && !defined(SYMBIAN) sl@0: signal (SIGUSR1, handle_usr1); sl@0: #endif sl@0: g_idle_add (check_stop, loop); sl@0: g_main_loop_run (loop); sl@0: sl@0: write_or_die (childname, sl@0: g_mapped_file_get_contents (map), sl@0: g_mapped_file_get_length (map)); sl@0: sl@0: return NULL; sl@0: } sl@0: sl@0: static void sl@0: test_mapping (void) sl@0: { sl@0: GMappedFile *map; sl@0: sl@0: write_or_die (filename, "ABC", -1); sl@0: sl@0: map = map_or_die (filename, FALSE); sl@0: g_assert (g_mapped_file_get_length (map) == 3); sl@0: g_mapped_file_free (map); sl@0: sl@0: map = map_or_die (filename, TRUE); sl@0: g_assert (g_mapped_file_get_length (map) == 3); sl@0: g_mapped_file_free (map); sl@0: } sl@0: sl@0: static void sl@0: test_private (void) sl@0: { sl@0: GError *error = NULL; sl@0: GMappedFile *map; sl@0: gchar *buffer; sl@0: gsize len; sl@0: sl@0: write_or_die (filename, "ABC", -1); sl@0: map = map_or_die (filename, TRUE); sl@0: sl@0: buffer = (gchar *)g_mapped_file_get_contents (map); sl@0: buffer[0] = '1'; sl@0: buffer[1] = '2'; sl@0: buffer[2] = '3'; sl@0: g_mapped_file_free (map); sl@0: sl@0: if (!g_file_get_contents (filename, &buffer, &len, &error)) sl@0: { sl@0: g_print ("failed to read '%s': %s\n", sl@0: displayname, error->message); sl@0: sl@0: g_assert(FALSE && "mapping-test failed"); sl@0: sl@0: #ifdef SYMBIAN sl@0: testResultXml("mapping-test"); sl@0: #endif /* EMULATOR */ sl@0: sl@0: exit (1); sl@0: sl@0: } sl@0: g_assert (len == 3); sl@0: g_assert (strcmp (buffer, "ABC") == 0); sl@0: g_free (buffer); sl@0: sl@0: } sl@0: sl@0: static void sl@0: test_child_private (gchar *argv0) sl@0: { sl@0: GError *error = NULL; sl@0: GMappedFile *map; sl@0: gchar *buffer; sl@0: gsize len; sl@0: gchar *child_argv[3]; sl@0: GPid child_pid; sl@0: pthread_t child_thread; sl@0: sl@0: sl@0: #if defined(G_OS_WIN32) && defined(SYMBIAN) sl@0: g_remove ("STOP"); sl@0: g_assert (!g_file_test ("STOP", G_FILE_TEST_EXISTS)); sl@0: #endif sl@0: sl@0: write_or_die (filename, "ABC", -1); sl@0: map = map_or_die (filename, TRUE); sl@0: sl@0: child_argv[0] = argv0; sl@0: child_argv[1] = "mapchild"; sl@0: child_argv[2] = NULL; sl@0: pthread_create(&child_thread, NULL, child_main, NULL); sl@0: //pthread_join(thread1, NULL); sl@0: sl@0: /*if (!g_spawn_async (dir, child_argv, NULL, sl@0: 0, NULL, NULL, &child_pid, &error)) sl@0: { sl@0: g_print ("failed to spawn child: %s\n", sl@0: error->message); sl@0: exit (1); sl@0: }*/ sl@0: sl@0: /* give the child some time to set up its mapping */ sl@0: g_usleep (2000000); sl@0: sl@0: buffer = (gchar *)g_mapped_file_get_contents (map); sl@0: buffer[0] = '1'; sl@0: buffer[1] = '2'; sl@0: buffer[2] = '3'; sl@0: g_mapped_file_free (map); sl@0: sl@0: #if !defined(G_OS_WIN32) && !defined(SYMBIAN) sl@0: kill (child_pid, SIGUSR1); sl@0: #else sl@0: g_file_set_contents ("STOP", "Hey there\n", -1, NULL); sl@0: #endif sl@0: sl@0: /* give the child some time to write the file */ sl@0: g_usleep (2000000); sl@0: pthread_join(child_thread, NULL); sl@0: sl@0: if (!g_file_get_contents (childname, &buffer, &len, &error)) sl@0: { sl@0: gchar *name; sl@0: sl@0: name = g_filename_display_name (childname); sl@0: g_print ("failed to read '%s': %s\n", name, error->message); sl@0: sl@0: g_assert(FALSE && "mapping-test failed"); sl@0: sl@0: #ifdef SYMBIAN sl@0: testResultXml("mapping-test"); sl@0: #endif /* EMULATOR */ sl@0: sl@0: exit (1); sl@0: } sl@0: g_assert (len == 3); sl@0: g_assert (strcmp (buffer, "ABC") == 0); sl@0: g_free (buffer); sl@0: } sl@0: sl@0: static int sl@0: parent_main (int argc, sl@0: char *argv[]) sl@0: { sl@0: /* test mapping with various flag combinations */ sl@0: test_mapping (); sl@0: sl@0: /* test private modification */ sl@0: test_private (); sl@0: sl@0: /* test multiple clients, non-shared */ sl@0: test_child_private (argv[0]); sl@0: sl@0: return 0; sl@0: } sl@0: sl@0: int sl@0: main (int argc, sl@0: char *argv[]) sl@0: { sl@0: int retval; sl@0: sl@0: #ifndef EMULATOR sl@0: mkdir("C:\\Private\\e0000009", 0666); sl@0: chdir("C:\\Private\\e0000009"); sl@0: #endif//EMULATOR sl@0: sl@0: dir = g_get_current_dir (); sl@0: filename = g_build_filename (dir, "maptest", NULL); sl@0: displayname = g_filename_display_name (filename); sl@0: childname = g_build_filename (dir, "mapchild", NULL); sl@0: sl@0: #ifdef SYMBIAN sl@0: g_log_set_handler (NULL, (GLogLevelFlags)(G_LOG_FLAG_FATAL| G_LOG_FLAG_RECURSION | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG), &mrtLogHandler, NULL); sl@0: g_set_print_handler(mrtPrintHandler); sl@0: #endif sl@0: /*if (argc > 1) sl@0: return child_main (argc, argv); sl@0: else */ sl@0: sl@0: retval = parent_main (argc, argv); sl@0: sl@0: #ifdef SYMBIAN sl@0: testResultXml("mapping-test"); sl@0: #endif /* EMULATOR */ sl@0: sl@0: return retval; sl@0: }