nexmon – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | /* GLIB - Library of useful routines for C programming |
2 | * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald |
||
3 | * |
||
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. |
||
8 | * |
||
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. |
||
13 | * |
||
14 | * You should have received a copy of the GNU Lesser General Public |
||
15 | * License along with this library; if not, see <http://www.gnu.org/licenses/>. |
||
16 | */ |
||
17 | |||
18 | /* |
||
19 | * Modified by the GLib Team and others 1997-2000. See the AUTHORS |
||
20 | * file for a list of people on the GLib Team. See the ChangeLog |
||
21 | * files for a list of changes. These files are distributed with |
||
22 | * GLib at ftp://ftp.gtk.org/pub/gtk/. |
||
23 | */ |
||
24 | |||
25 | #include <sys/types.h> |
||
26 | #include <stdlib.h> |
||
27 | |||
28 | #include <glib.h> |
||
29 | |||
30 | #ifdef G_OS_UNIX |
||
31 | #include <unistd.h> |
||
32 | #endif |
||
33 | |||
34 | #ifdef G_OS_WIN32 |
||
35 | #include <windows.h> |
||
36 | #endif |
||
37 | |||
38 | #ifdef G_OS_WIN32 |
||
39 | #define GPID_FORMAT "%p" |
||
40 | #else |
||
41 | #define GPID_FORMAT "%d" |
||
42 | #endif |
||
43 | |||
44 | GMainLoop *main_loop; |
||
45 | gint alive; |
||
46 | |||
47 | #ifdef G_OS_WIN32 |
||
48 | char *argv0; |
||
49 | #endif |
||
50 | |||
51 | static GPid |
||
52 | get_a_child (gint ttl) |
||
53 | { |
||
54 | GPid pid; |
||
55 | |||
56 | #ifdef G_OS_WIN32 |
||
57 | STARTUPINFO si; |
||
58 | PROCESS_INFORMATION pi; |
||
59 | gchar *cmdline; |
||
60 | |||
61 | memset (&si, 0, sizeof (si)); |
||
62 | si.cb = sizeof (&si); |
||
63 | memset (&pi, 0, sizeof (pi)); |
||
64 | |||
65 | cmdline = g_strdup_printf( "child-test -c%d", ttl); |
||
66 | |||
67 | if (!CreateProcess (argv0, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) |
||
68 | g_error ("CreateProcess failed: %s\n", g_win32_error_message (GetLastError ())); |
||
69 | |||
70 | g_free(cmdline); |
||
71 | |||
72 | CloseHandle (pi.hThread); |
||
73 | pid = pi.hProcess; |
||
74 | |||
75 | return pid; |
||
76 | #else |
||
77 | pid = fork (); |
||
78 | if (pid < 0) |
||
79 | exit (1); |
||
80 | |||
81 | if (pid > 0) |
||
82 | return pid; |
||
83 | |||
84 | sleep (ttl); |
||
85 | _exit (0); |
||
86 | #endif /* G_OS_WIN32 */ |
||
87 | } |
||
88 | |||
89 | static gboolean |
||
90 | child_watch_callback (GPid pid, gint status, gpointer data) |
||
91 | { |
||
92 | #ifdef VERBOSE |
||
93 | gint ttl = GPOINTER_TO_INT (data); |
||
94 | |||
95 | g_print ("child " GPID_FORMAT " (ttl %d) exited, status %d\n", pid, ttl, status); |
||
96 | #endif |
||
97 | |||
98 | g_spawn_close_pid (pid); |
||
99 | |||
100 | if (--alive == 0) |
||
101 | g_main_loop_quit (main_loop); |
||
102 | |||
103 | return TRUE; |
||
104 | } |
||
105 | |||
106 | static gboolean |
||
107 | quit_loop (gpointer data) |
||
108 | { |
||
109 | GMainLoop *main_loop = data; |
||
110 | |||
111 | g_main_loop_quit (main_loop); |
||
112 | |||
113 | return TRUE; |
||
114 | } |
||
115 | |||
116 | #ifdef TEST_THREAD |
||
117 | static gpointer |
||
118 | test_thread (gpointer data) |
||
119 | { |
||
120 | GMainLoop *new_main_loop; |
||
121 | GSource *source; |
||
122 | GPid pid; |
||
123 | gint ttl = GPOINTER_TO_INT (data); |
||
124 | |||
125 | new_main_loop = g_main_loop_new (NULL, FALSE); |
||
126 | |||
127 | pid = get_a_child (ttl); |
||
128 | source = g_child_watch_source_new (pid); |
||
129 | g_source_set_callback (source, (GSourceFunc) child_watch_callback, data, NULL); |
||
130 | g_source_attach (source, g_main_loop_get_context (new_main_loop)); |
||
131 | g_source_unref (source); |
||
132 | |||
133 | #ifdef VERBOSE |
||
134 | g_print ("whee! created pid: " GPID_FORMAT " (ttl %d)\n", pid, ttl); |
||
135 | #endif |
||
136 | |||
137 | g_main_loop_run (new_main_loop); |
||
138 | |||
139 | return NULL; |
||
140 | } |
||
141 | #endif |
||
142 | |||
143 | int |
||
144 | main (int argc, char *argv[]) |
||
145 | { |
||
146 | #ifndef TEST_THREAD |
||
147 | GPid pid; |
||
148 | #endif |
||
149 | #ifdef G_OS_WIN32 |
||
150 | argv0 = argv[0]; |
||
151 | if (argc > 1 && argv[1][0] == '-' && argv[1][1] == 'c') |
||
152 | { |
||
153 | int ttl = atoi (argv[1] + 2); |
||
154 | Sleep (ttl * 1000); |
||
155 | /* Exit on purpose with STILL_ACTIVE (which isn't a very common |
||
156 | * exit status) to verify that g_child_watch_check() in gmain.c |
||
157 | * doesn't believe a child still to be active if it happens to |
||
158 | * exit with that status. |
||
159 | */ |
||
160 | exit (STILL_ACTIVE); |
||
161 | } |
||
162 | #endif |
||
163 | |||
164 | main_loop = g_main_loop_new (NULL, FALSE); |
||
165 | |||
166 | #ifdef G_OS_WIN32 |
||
167 | system ("ipconfig /all"); |
||
168 | #else |
||
169 | system ("true"); |
||
170 | #endif |
||
171 | |||
172 | alive = 2; |
||
173 | g_timeout_add_seconds (30, quit_loop, main_loop); |
||
174 | |||
175 | #ifdef TEST_THREAD |
||
176 | g_thread_create (test_thread, GINT_TO_POINTER (10), FALSE, NULL); |
||
177 | g_thread_create (test_thread, GINT_TO_POINTER (20), FALSE, NULL); |
||
178 | #else |
||
179 | pid = get_a_child (10); |
||
180 | g_child_watch_add (pid, (GChildWatchFunc) child_watch_callback, |
||
181 | GINT_TO_POINTER (10)); |
||
182 | pid = get_a_child (20); |
||
183 | g_child_watch_add (pid, (GChildWatchFunc) child_watch_callback, |
||
184 | GINT_TO_POINTER (20)); |
||
185 | #endif |
||
186 | |||
187 | g_main_loop_run (main_loop); |
||
188 | |||
189 | g_main_loop_unref (main_loop); |
||
190 | |||
191 | if (alive > 0) |
||
192 | { |
||
193 | g_warning ("%d children still alive\n", alive); |
||
194 | return 1; |
||
195 | } |
||
196 | |||
197 | return 0; |
||
198 | } |