File: | fr-process.c |
Warning: | line 1067, column 13 Value stored to 'ret' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ |
2 | |
3 | /* |
4 | * Grapa |
5 | * |
6 | * Copyright (C) 2001, 2003, 2008 Free Software Foundation, Inc. |
7 | * |
8 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License as published by |
10 | * the Free Software Foundation; either version 2 of the License, or |
11 | * (at your option) any later version. |
12 | * |
13 | * This program is distributed in the hope that it will be useful, |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | * GNU General Public License for more details. |
17 | * |
18 | * You should have received a copy of the GNU General Public License |
19 | * along with this program; if not, write to the Free Software |
20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
21 | */ |
22 | |
23 | #include <config.h> |
24 | #include <errno(*__errno_location ()).h> |
25 | #include <fcntl.h> |
26 | #include <stdio.h> |
27 | #include <signal.h> |
28 | #include <stdlib.h> |
29 | #include <string.h> |
30 | #include <sys/types.h> |
31 | #include <sys/wait.h> |
32 | #include <unistd.h> |
33 | #include <glib.h> |
34 | #include "fr-proc-error.h" |
35 | #include "fr-process.h" |
36 | #include "fr-marshal.h" |
37 | #include "glib-utils.h" |
38 | |
39 | #define REFRESH_RATE20 20 |
40 | #define BUFFER_SIZE16384 16384 |
41 | |
42 | enum { |
43 | START, |
44 | DONE, |
45 | STICKY_ONLY, |
46 | LAST_SIGNAL |
47 | }; |
48 | |
49 | static GObjectClass *parent_class; |
50 | static guint fr_process_signals[LAST_SIGNAL] = { 0 }; |
51 | |
52 | static void fr_process_class_init (FrProcessClass *class); |
53 | static void fr_process_init (FrProcess *process); |
54 | static void fr_process_finalize (GObject *object); |
55 | |
56 | |
57 | typedef struct { |
58 | GList *args; /* command to execute */ |
59 | char *dir; /* working directory */ |
60 | guint sticky : 1; /* whether the command must be |
61 | * executed even if a previous |
62 | * command has failed. */ |
63 | guint ignore_error : 1; /* whether to continue to execute |
64 | * other commands if this command |
65 | * fails. */ |
66 | ContinueFunc continue_func; |
67 | gpointer continue_data; |
68 | ProcFunc begin_func; |
69 | gpointer begin_data; |
70 | ProcFunc end_func; |
71 | gpointer end_data; |
72 | } FrCommandInfo; |
73 | |
74 | |
75 | static FrCommandInfo * |
76 | fr_command_info_new (void) |
77 | { |
78 | FrCommandInfo *info; |
79 | |
80 | info = g_new0 (FrCommandInfo, 1)((FrCommandInfo *) g_malloc0_n ((1), sizeof (FrCommandInfo))); |
81 | info->args = NULL((void*)0); |
82 | info->dir = NULL((void*)0); |
83 | info->sticky = FALSE(0); |
84 | info->ignore_error = FALSE(0); |
85 | |
86 | return info; |
87 | } |
88 | |
89 | |
90 | static void |
91 | fr_command_info_free (FrCommandInfo *info) |
92 | { |
93 | if (info == NULL((void*)0)) |
94 | return; |
95 | |
96 | if (info->args != NULL((void*)0)) { |
97 | g_list_free_full (info->args, g_free); |
98 | info->args = NULL((void*)0); |
99 | } |
100 | |
101 | if (info->dir != NULL((void*)0)) { |
102 | g_free (info->dir); |
103 | info->dir = NULL((void*)0); |
104 | } |
105 | |
106 | g_free (info); |
107 | } |
108 | |
109 | |
110 | static void |
111 | fr_channel_data_init (FrChannelData *channel) |
112 | { |
113 | channel->source = NULL((void*)0); |
114 | channel->raw = NULL((void*)0); |
115 | channel->status = G_IO_STATUS_NORMAL; |
116 | channel->error = NULL((void*)0); |
117 | } |
118 | |
119 | |
120 | static void |
121 | fr_channel_data_close_source (FrChannelData *channel) |
122 | { |
123 | if (channel->source != NULL((void*)0)) { |
124 | g_io_channel_shutdown (channel->source, FALSE(0), NULL((void*)0)); |
125 | g_io_channel_unref (channel->source); |
126 | channel->source = NULL((void*)0); |
127 | } |
128 | } |
129 | |
130 | |
131 | static GIOStatus |
132 | fr_channel_data_read (FrChannelData *channel) |
133 | { |
134 | char *line; |
135 | gsize length; |
136 | gsize terminator_pos; |
137 | |
138 | channel->status = G_IO_STATUS_NORMAL; |
139 | g_clear_error (&channel->error); |
140 | |
141 | while ((channel->status = g_io_channel_read_line (channel->source, |
142 | &line, |
143 | &length, |
144 | &terminator_pos, |
145 | &channel->error)) == G_IO_STATUS_NORMAL) |
146 | { |
147 | line[terminator_pos] = 0; |
148 | channel->raw = g_list_prepend (channel->raw, line); |
149 | if (channel->line_func != NULL((void*)0)) |
150 | (*channel->line_func) (line, channel->line_data); |
151 | } |
152 | |
153 | return channel->status; |
154 | } |
155 | |
156 | |
157 | static GIOStatus |
158 | fr_channel_data_flush (FrChannelData *channel) |
159 | { |
160 | GIOStatus status; |
161 | |
162 | while (((status = fr_channel_data_read (channel)) != G_IO_STATUS_ERROR) && (status != G_IO_STATUS_EOF)) |
163 | /* void */; |
164 | fr_channel_data_close_source (channel); |
165 | |
166 | return status; |
167 | } |
168 | |
169 | |
170 | static void |
171 | fr_channel_data_reset (FrChannelData *channel) |
172 | { |
173 | fr_channel_data_close_source (channel); |
174 | |
175 | if (channel->raw != NULL((void*)0)) { |
176 | g_list_free_full (channel->raw, g_free); |
177 | channel->raw = NULL((void*)0); |
178 | } |
179 | } |
180 | |
181 | |
182 | static void |
183 | fr_channel_data_free (FrChannelData *channel) |
184 | { |
185 | fr_channel_data_reset (channel); |
186 | } |
187 | |
188 | |
189 | static void |
190 | fr_channel_data_set_fd (FrChannelData *channel, |
191 | int fd, |
192 | const char *charset) |
193 | { |
194 | fr_channel_data_reset (channel); |
195 | |
196 | channel->source = g_io_channel_unix_new (fd); |
197 | g_io_channel_set_flags (channel->source, G_IO_FLAG_NONBLOCK, NULL((void*)0)); |
198 | g_io_channel_set_buffer_size (channel->source, BUFFER_SIZE16384); |
199 | if (charset != NULL((void*)0)) |
200 | g_io_channel_set_encoding (channel->source, charset, NULL((void*)0)); |
201 | } |
202 | |
203 | |
204 | const char *try_charsets[] = { "UTF-8", "ISO-8859-1", "WINDOW-1252" }; |
205 | int n_charsets = G_N_ELEMENTS (try_charsets)(sizeof (try_charsets) / sizeof ((try_charsets)[0])); |
206 | |
207 | |
208 | struct _FrProcessPrivate { |
209 | GPtrArray *comm; /* FrCommandInfo elements. */ |
210 | gint n_comm; /* total number of commands */ |
211 | gint current_comm; /* currenlty editing command. */ |
212 | |
213 | GPid command_pid; |
214 | guint check_timeout; |
215 | |
216 | FrProcError first_error; |
217 | |
218 | gboolean running; |
219 | gboolean stopping; |
220 | gboolean suspend; |
221 | gint current_command; |
222 | gint error_command; /* command that coused an error. */ |
223 | |
224 | gboolean use_standard_locale; |
225 | gboolean sticky_only; /* whether to execute only sticky |
226 | * commands. */ |
227 | int current_charset; |
228 | }; |
229 | |
230 | |
231 | GType |
232 | fr_process_get_type (void) |
233 | { |
234 | static GType type = 0; |
235 | |
236 | if (! type) { |
237 | GTypeInfo type_info = { |
238 | sizeof (FrProcessClass), |
239 | NULL((void*)0), |
240 | NULL((void*)0), |
241 | (GClassInitFunc) fr_process_class_init, |
242 | NULL((void*)0), |
243 | NULL((void*)0), |
244 | sizeof (FrProcess), |
245 | 0, |
246 | (GInstanceInitFunc) fr_process_init, |
247 | NULL((void*)0) |
248 | }; |
249 | |
250 | type = g_type_register_static (G_TYPE_OBJECT((GType) ((20) << (2))), |
251 | "FRProcess", |
252 | &type_info, |
253 | 0); |
254 | } |
255 | |
256 | return type; |
257 | } |
258 | |
259 | |
260 | static void |
261 | fr_process_class_init (FrProcessClass *class) |
262 | { |
263 | GObjectClass *gobject_class = G_OBJECT_CLASS (class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((class)), (((GType) ((20) << (2)))))))); |
264 | |
265 | parent_class = g_type_class_peek_parent (class); |
266 | |
267 | fr_process_signals[START] = |
268 | g_signal_new ("start", |
269 | G_TYPE_FROM_CLASS (class)(((GTypeClass*) (class))->g_type), |
270 | G_SIGNAL_RUN_LAST, |
271 | G_STRUCT_OFFSET (FrProcessClass, start)((glong) __builtin_offsetof(FrProcessClass, start)), |
272 | NULL((void*)0), NULL((void*)0), |
273 | fr_marshal_VOID__VOIDg_cclosure_marshal_VOID__VOID, |
274 | G_TYPE_NONE((GType) ((1) << (2))), 0); |
275 | fr_process_signals[DONE] = |
276 | g_signal_new ("done", |
277 | G_TYPE_FROM_CLASS (class)(((GTypeClass*) (class))->g_type), |
278 | G_SIGNAL_RUN_LAST, |
279 | G_STRUCT_OFFSET (FrProcessClass, done)((glong) __builtin_offsetof(FrProcessClass, done)), |
280 | NULL((void*)0), NULL((void*)0), |
281 | fr_marshal_VOID__BOXEDg_cclosure_marshal_VOID__BOXED, |
282 | G_TYPE_NONE((GType) ((1) << (2))), 1, |
283 | FR_TYPE_PROC_ERROR(fr_proc_error_get_type ())); |
284 | fr_process_signals[STICKY_ONLY] = |
285 | g_signal_new ("sticky_only", |
286 | G_TYPE_FROM_CLASS (class)(((GTypeClass*) (class))->g_type), |
287 | G_SIGNAL_RUN_LAST, |
288 | G_STRUCT_OFFSET (FrProcessClass, sticky_only)((glong) __builtin_offsetof(FrProcessClass, sticky_only)), |
289 | NULL((void*)0), NULL((void*)0), |
290 | fr_marshal_VOID__VOIDg_cclosure_marshal_VOID__VOID, |
291 | G_TYPE_NONE((GType) ((1) << (2))), 0); |
292 | |
293 | gobject_class->finalize = fr_process_finalize; |
294 | |
295 | class->start = NULL((void*)0); |
296 | class->done = NULL((void*)0); |
297 | } |
298 | |
299 | |
300 | static void |
301 | fr_process_init (FrProcess *process) |
302 | { |
303 | process->priv = g_new0 (FrProcessPrivate, 1)((FrProcessPrivate *) g_malloc0_n ((1), sizeof (FrProcessPrivate ))); |
304 | |
305 | process->term_on_stop = TRUE(!(0)); |
306 | |
307 | process->priv->comm = g_ptr_array_new (); |
308 | process->priv->n_comm = -1; |
309 | process->priv->current_comm = -1; |
310 | |
311 | process->priv->command_pid = 0; |
312 | fr_channel_data_init (&process->out); |
313 | fr_channel_data_init (&process->err); |
314 | |
315 | process->error.gerror = NULL((void*)0); |
316 | process->priv->first_error.gerror = NULL((void*)0); |
317 | |
318 | process->priv->check_timeout = 0; |
319 | process->priv->running = FALSE(0); |
320 | process->priv->stopping = FALSE(0); |
321 | process->restart = FALSE(0); |
322 | |
323 | process->priv->current_charset = -1; |
324 | |
325 | process->priv->use_standard_locale = FALSE(0); |
326 | } |
327 | |
328 | |
329 | FrProcess * |
330 | fr_process_new (void) |
331 | { |
332 | return FR_PROCESS (g_object_new (FR_TYPE_PROCESS, NULL))((((FrProcess*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((g_object_new ((fr_process_get_type ()), ((void*)0)))), ( (fr_process_get_type ())))))); |
333 | } |
334 | |
335 | |
336 | static void fr_process_stop_priv (FrProcess *process, gboolean emit_signal); |
337 | static int fr_switch_process_state (FrProcess *process); |
338 | |
339 | static void |
340 | fr_process_finalize (GObject *object) |
341 | { |
342 | FrProcess *process; |
343 | |
344 | g_return_if_fail (object != NULL)do { if ((object != ((void*)0))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "object != NULL") ; return; } } while (0); |
345 | g_return_if_fail (FR_IS_PROCESS (object))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((object)); GType __t = ((fr_process_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "FR_IS_PROCESS (object)"); return; } } while ( 0); |
346 | |
347 | process = FR_PROCESS (object)((((FrProcess*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((object)), ((fr_process_get_type ())))))); |
348 | |
349 | fr_process_stop_priv (process, FALSE(0)); |
350 | fr_process_clear (process); |
351 | |
352 | g_ptr_array_free (process->priv->comm, FALSE(0)); |
353 | |
354 | fr_channel_data_free (&process->out); |
355 | fr_channel_data_free (&process->err); |
356 | |
357 | g_clear_error (&process->error.gerror); |
358 | g_clear_error (&process->priv->first_error.gerror); |
359 | |
360 | g_free (process->priv); |
361 | |
362 | /* Chain up */ |
363 | |
364 | if (G_OBJECT_CLASS (parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((parent_class)), (((GType) ((20) << (2))))))))->finalize) |
365 | G_OBJECT_CLASS (parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((parent_class)), (((GType) ((20) << (2))))))))->finalize (object); |
366 | } |
367 | |
368 | |
369 | void |
370 | fr_process_begin_command (FrProcess *process, |
371 | const char *arg) |
372 | { |
373 | FrCommandInfo *info; |
374 | |
375 | g_return_if_fail (process != NULL)do { if ((process != ((void*)0))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "process != NULL" ); return; } } while (0); |
376 | |
377 | info = fr_command_info_new (); |
378 | info->args = g_list_prepend (NULL((void*)0), g_strdup (arg)g_strdup_inline (arg)); |
379 | |
380 | g_ptr_array_add (process->priv->comm, info); |
381 | |
382 | process->priv->n_comm++; |
383 | process->priv->current_comm = process->priv->n_comm; |
384 | } |
385 | |
386 | |
387 | void |
388 | fr_process_begin_command_at (FrProcess *process, |
389 | const char *arg, |
390 | int index) |
391 | { |
392 | FrCommandInfo *info, *old_c_info; |
393 | |
394 | g_return_if_fail (process != NULL)do { if ((process != ((void*)0))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "process != NULL" ); return; } } while (0); |
395 | g_return_if_fail (index >= 0 && index <= process->priv->n_comm)do { if ((index >= 0 && index <= process->priv ->n_comm)) { } else { g_return_if_fail_warning (((gchar*) 0 ), ((const char*) (__func__)), "index >= 0 && index <= process->priv->n_comm" ); return; } } while (0); |
396 | |
397 | process->priv->current_comm = index; |
398 | |
399 | old_c_info = g_ptr_array_index (process->priv->comm, index)((process->priv->comm)->pdata)[index]; |
400 | |
401 | if (old_c_info != NULL((void*)0)) |
402 | fr_command_info_free (old_c_info); |
403 | |
404 | info = fr_command_info_new (); |
405 | info->args = g_list_prepend (NULL((void*)0), g_strdup (arg)g_strdup_inline (arg)); |
406 | |
407 | g_ptr_array_index (process->priv->comm, index)((process->priv->comm)->pdata)[index] = info; |
408 | } |
409 | |
410 | |
411 | void |
412 | fr_process_set_working_dir (FrProcess *process, |
413 | const char *dir) |
414 | { |
415 | FrCommandInfo *info; |
416 | |
417 | g_return_if_fail (process != NULL)do { if ((process != ((void*)0))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "process != NULL" ); return; } } while (0); |
418 | g_return_if_fail (process->priv->current_comm >= 0)do { if ((process->priv->current_comm >= 0)) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__ )), "process->priv->current_comm >= 0"); return; } } while (0); |
419 | |
420 | info = g_ptr_array_index (process->priv->comm, process->priv->current_comm)((process->priv->comm)->pdata)[process->priv-> current_comm]; |
421 | if (info->dir != NULL((void*)0)) |
422 | g_free (info->dir); |
423 | info->dir = g_strdup (dir)g_strdup_inline (dir); |
424 | } |
425 | |
426 | |
427 | void |
428 | fr_process_set_sticky (FrProcess *process, |
429 | gboolean sticky) |
430 | { |
431 | FrCommandInfo *info; |
432 | |
433 | g_return_if_fail (process != NULL)do { if ((process != ((void*)0))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "process != NULL" ); return; } } while (0); |
434 | g_return_if_fail (process->priv->current_comm >= 0)do { if ((process->priv->current_comm >= 0)) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__ )), "process->priv->current_comm >= 0"); return; } } while (0); |
435 | |
436 | info = g_ptr_array_index (process->priv->comm, process->priv->current_comm)((process->priv->comm)->pdata)[process->priv-> current_comm]; |
437 | info->sticky = sticky; |
438 | } |
439 | |
440 | |
441 | void |
442 | fr_process_set_ignore_error (FrProcess *process, |
443 | gboolean ignore_error) |
444 | { |
445 | FrCommandInfo *info; |
446 | |
447 | g_return_if_fail (process != NULL)do { if ((process != ((void*)0))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "process != NULL" ); return; } } while (0); |
448 | g_return_if_fail (process->priv->current_comm >= 0)do { if ((process->priv->current_comm >= 0)) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__ )), "process->priv->current_comm >= 0"); return; } } while (0); |
449 | |
450 | info = g_ptr_array_index (process->priv->comm, process->priv->current_comm)((process->priv->comm)->pdata)[process->priv-> current_comm]; |
451 | info->ignore_error = ignore_error; |
452 | } |
453 | |
454 | |
455 | void |
456 | fr_process_add_arg (FrProcess *process, |
457 | const char *arg) |
458 | { |
459 | FrCommandInfo *info; |
460 | |
461 | g_return_if_fail (process != NULL)do { if ((process != ((void*)0))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "process != NULL" ); return; } } while (0); |
462 | g_return_if_fail (process->priv->current_comm >= 0)do { if ((process->priv->current_comm >= 0)) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__ )), "process->priv->current_comm >= 0"); return; } } while (0); |
463 | |
464 | info = g_ptr_array_index (process->priv->comm, process->priv->current_comm)((process->priv->comm)->pdata)[process->priv-> current_comm]; |
465 | info->args = g_list_prepend (info->args, g_strdup (arg)g_strdup_inline (arg)); |
466 | } |
467 | |
468 | |
469 | void |
470 | fr_process_add_arg_concat (FrProcess *process, |
471 | const char *arg1, |
472 | ...) |
473 | { |
474 | GString *arg; |
475 | va_list args; |
476 | char *s; |
477 | |
478 | arg = g_string_new (arg1); |
479 | |
480 | va_start (args, arg1)__builtin_va_start(args, arg1); |
481 | while ((s = va_arg (args, char*)__builtin_va_arg(args, char*)) != NULL((void*)0)) |
482 | g_string_append (arg, s)(__builtin_constant_p (s) ? __extension__ ({ const char * const __val = (s); g_string_append_len_inline (arg, __val, (__val != ((void*)0)) ? (gssize) strlen (((__val) + !(__val))) : (gssize ) -1); }) : g_string_append_len_inline (arg, s, (gssize) -1)); |
483 | va_end (args)__builtin_va_end(args); |
484 | |
485 | fr_process_add_arg (process, arg->str); |
486 | g_string_free (arg, TRUE)(__builtin_constant_p ((!(0))) ? (((!(0))) ? (g_string_free) ( (arg), ((!(0)))) : g_string_free_and_steal (arg)) : (g_string_free ) ((arg), ((!(0))))); |
487 | } |
488 | |
489 | |
490 | void |
491 | fr_process_add_arg_printf (FrProcess *fr_proc, |
492 | const char *format, |
493 | ...) |
494 | { |
495 | va_list args; |
496 | char *arg; |
497 | |
498 | va_start (args, format)__builtin_va_start(args, format); |
499 | arg = g_strdup_vprintf (format, args); |
500 | va_end (args)__builtin_va_end(args); |
501 | |
502 | fr_process_add_arg (fr_proc, arg); |
503 | |
504 | g_free (arg); |
505 | } |
506 | |
507 | |
508 | void |
509 | fr_process_set_arg_at (FrProcess *process, |
510 | int n_comm, |
511 | int n_arg, |
512 | const char *arg_value) |
513 | { |
514 | FrCommandInfo *info; |
515 | GList *arg; |
516 | |
517 | g_return_if_fail (process != NULL)do { if ((process != ((void*)0))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "process != NULL" ); return; } } while (0); |
518 | |
519 | info = g_ptr_array_index (process->priv->comm, n_comm)((process->priv->comm)->pdata)[n_comm]; |
520 | arg = g_list_nth (info->args, n_arg); |
521 | g_return_if_fail (arg != NULL)do { if ((arg != ((void*)0))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "arg != NULL"); return ; } } while (0); |
522 | |
523 | g_free (arg->data); |
524 | arg->data = g_strdup (arg_value)g_strdup_inline (arg_value); |
525 | } |
526 | |
527 | |
528 | void |
529 | fr_process_set_begin_func (FrProcess *process, |
530 | ProcFunc func, |
531 | gpointer func_data) |
532 | { |
533 | FrCommandInfo *info; |
534 | |
535 | g_return_if_fail (process != NULL)do { if ((process != ((void*)0))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "process != NULL" ); return; } } while (0); |
536 | |
537 | info = g_ptr_array_index (process->priv->comm, process->priv->current_comm)((process->priv->comm)->pdata)[process->priv-> current_comm]; |
538 | info->begin_func = func; |
539 | info->begin_data = func_data; |
540 | } |
541 | |
542 | |
543 | void |
544 | fr_process_set_end_func (FrProcess *process, |
545 | ProcFunc func, |
546 | gpointer func_data) |
547 | { |
548 | FrCommandInfo *info; |
549 | |
550 | g_return_if_fail (process != NULL)do { if ((process != ((void*)0))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "process != NULL" ); return; } } while (0); |
551 | |
552 | info = g_ptr_array_index (process->priv->comm, process->priv->current_comm)((process->priv->comm)->pdata)[process->priv-> current_comm]; |
553 | info->end_func = func; |
554 | info->end_data = func_data; |
555 | } |
556 | |
557 | |
558 | void |
559 | fr_process_set_continue_func (FrProcess *process, |
560 | ContinueFunc func, |
561 | gpointer func_data) |
562 | { |
563 | FrCommandInfo *info; |
564 | |
565 | g_return_if_fail (process != NULL)do { if ((process != ((void*)0))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "process != NULL" ); return; } } while (0); |
566 | |
567 | if (process->priv->current_comm < 0) |
568 | return; |
569 | |
570 | info = g_ptr_array_index (process->priv->comm, process->priv->current_comm)((process->priv->comm)->pdata)[process->priv-> current_comm]; |
571 | info->continue_func = func; |
572 | info->continue_data = func_data; |
573 | } |
574 | |
575 | |
576 | void |
577 | fr_process_end_command (FrProcess *process) |
578 | { |
579 | FrCommandInfo *info; |
580 | |
581 | g_return_if_fail (process != NULL)do { if ((process != ((void*)0))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "process != NULL" ); return; } } while (0); |
582 | |
583 | info = g_ptr_array_index (process->priv->comm, process->priv->current_comm)((process->priv->comm)->pdata)[process->priv-> current_comm]; |
584 | info->args = g_list_reverse (info->args); |
585 | } |
586 | |
587 | |
588 | void |
589 | fr_process_clear (FrProcess *process) |
590 | { |
591 | gint i; |
592 | |
593 | g_return_if_fail (process != NULL)do { if ((process != ((void*)0))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "process != NULL" ); return; } } while (0); |
594 | |
595 | for (i = 0; i <= process->priv->n_comm; i++) { |
596 | FrCommandInfo *info; |
597 | |
598 | info = g_ptr_array_index (process->priv->comm, i)((process->priv->comm)->pdata)[i]; |
599 | fr_command_info_free (info); |
600 | g_ptr_array_index (process->priv->comm, i)((process->priv->comm)->pdata)[i] = NULL((void*)0); |
601 | } |
602 | |
603 | for (i = 0; i <= process->priv->n_comm; i++) |
604 | g_ptr_array_remove_index_fast (process->priv->comm, 0); |
605 | |
606 | process->priv->n_comm = -1; |
607 | process->priv->current_comm = -1; |
608 | } |
609 | |
610 | |
611 | void |
612 | fr_process_set_out_line_func (FrProcess *process, |
613 | LineFunc func, |
614 | gpointer data) |
615 | { |
616 | g_return_if_fail (process != NULL)do { if ((process != ((void*)0))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "process != NULL" ); return; } } while (0); |
617 | |
618 | process->out.line_func = func; |
619 | process->out.line_data = data; |
620 | } |
621 | |
622 | |
623 | void |
624 | fr_process_set_err_line_func (FrProcess *process, |
625 | LineFunc func, |
626 | gpointer data) |
627 | { |
628 | g_return_if_fail (process != NULL)do { if ((process != ((void*)0))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "process != NULL" ); return; } } while (0); |
629 | |
630 | process->err.line_func = func; |
631 | process->err.line_data = data; |
632 | } |
633 | |
634 | |
635 | static gboolean check_child (gpointer data); |
636 | |
637 | |
638 | static void |
639 | child_setup (gpointer user_data) |
640 | { |
641 | FrProcess *process = user_data; |
642 | |
643 | if (process->priv->use_standard_locale) { |
644 | putenv ("LC_MESSAGES=C"); |
645 | putenv ("LC_TIME=C"); |
646 | putenv ("LC_NUMERIC=C"); |
647 | } |
648 | |
649 | /* detach from the tty */ |
650 | |
651 | setsid (); |
652 | |
653 | /* create a process group to kill all the child processes when |
654 | * canceling the operation. */ |
655 | |
656 | setpgid (0, 0); |
657 | } |
658 | |
659 | |
660 | static const char * |
661 | fr_process_get_charset (FrProcess *process) |
662 | { |
663 | const char *charset = NULL((void*)0); |
664 | |
665 | if (process->priv->current_charset >= 0) |
666 | charset = try_charsets[process->priv->current_charset]; |
667 | else if (g_get_charset (&charset)) |
668 | charset = NULL((void*)0); |
669 | |
670 | return charset; |
671 | } |
672 | |
673 | |
674 | static void |
675 | start_current_command (FrProcess *process) |
676 | { |
677 | FrCommandInfo *info; |
678 | GList *scan; |
679 | char **argv; |
680 | int out_fd, err_fd; |
681 | int i = 0; |
682 | GString *commandline = g_string_new (""); |
683 | gboolean fixname = FALSE(0); |
684 | |
685 | debug (DEBUG_INFO"fr-process.c", 685, __FUNCTION__, "%d/%d) ", process->priv->current_command, process->priv->n_comm); |
686 | |
687 | info = g_ptr_array_index (process->priv->comm, process->priv->current_command)((process->priv->comm)->pdata)[process->priv-> current_command]; |
688 | |
689 | argv = g_new (char *, g_list_length (info->args) + 1)((char * *) g_malloc_n ((g_list_length (info->args) + 1), sizeof (char *))); |
690 | |
691 | for (scan = info->args; scan; scan = scan->next) { |
692 | argv[i++] = scan->data; |
693 | |
694 | if (g_str_has_prefix (commandline->str, "mv")(__builtin_constant_p ("mv")? __extension__ ({ const char * const __str = (commandline->str); const char * const __prefix = ("mv"); gboolean __result = (0); if (__str == ((void*)0) || __prefix == ((void*)0)) __result = (g_str_has_prefix) (__str, __prefix ); else { const size_t __str_len = strlen (((__str) + !(__str ))); const size_t __prefix_len = strlen (((__prefix) + !(__prefix ))); if (__str_len >= __prefix_len) __result = memcmp (((__str ) + !(__str)), ((__prefix) + !(__prefix)), __prefix_len) == 0 ; } __result; }) : (g_str_has_prefix) (commandline->str, "mv" ) )) { |
695 | |
696 | if ((i == 3) && (!g_file_test (argv[2], G_FILE_TEST_EXISTS)) && (!fixname)) { |
697 | char rarfile[strlen (argv[2]) + 7]; |
698 | |
699 | g_strlcpy (rarfile, argv[2], sizeof (rarfile)); |
700 | rarfile[strlen (rarfile) - 3] = 0; |
701 | g_strlcat (rarfile, "part1.rar", sizeof (rarfile)); |
702 | |
703 | if (g_str_has_suffix (argv[2], ".7z")(__builtin_constant_p (".7z")? __extension__ ({ const char * const __str = (argv[2]); const char * const __suffix = (".7z"); gboolean __result = (0); if (__str == ((void*)0) || __suffix == ((void *)0)) __result = (g_str_has_suffix) (__str, __suffix); else { const size_t __str_len = strlen (((__str) + !(__str))); const size_t __suffix_len = strlen (((__suffix) + !(__suffix))); if (__str_len >= __suffix_len) __result = memcmp (__str + __str_len - __suffix_len, ((__suffix) + !(__suffix)), __suffix_len) == 0; } __result; }) : (g_str_has_suffix) (argv[2], ".7z") )) { |
704 | g_string_append (commandline, " ")(__builtin_constant_p (" ") ? __extension__ ({ const char * const __val = (" "); g_string_append_len_inline (commandline, __val , (__val != ((void*)0)) ? (gssize) strlen (((__val) + !(__val ))) : (gssize) -1); }) : g_string_append_len_inline (commandline , " ", (gssize) -1)); |
705 | |
706 | gchar *tempstr = g_shell_quote (argv[2]); |
707 | g_string_append (commandline, tempstr)(__builtin_constant_p (tempstr) ? __extension__ ({ const char * const __val = (tempstr); g_string_append_len_inline (commandline , __val, (__val != ((void*)0)) ? (gssize) strlen (((__val) + ! (__val))) : (gssize) -1); }) : g_string_append_len_inline (commandline , tempstr, (gssize) -1)); |
708 | g_free (tempstr); |
709 | |
710 | g_string_append (commandline, ".*")(__builtin_constant_p (".*") ? __extension__ ({ const char * const __val = (".*"); g_string_append_len_inline (commandline, __val , (__val != ((void*)0)) ? (gssize) strlen (((__val) + !(__val ))) : (gssize) -1); }) : g_string_append_len_inline (commandline , ".*", (gssize) -1)); |
711 | fixname = TRUE(!(0)); |
712 | } |
713 | else if (g_str_has_suffix (argv[2], ".rar")(__builtin_constant_p (".rar")? __extension__ ({ const char * const __str = (argv[2]); const char * const __suffix = (".rar" ); gboolean __result = (0); if (__str == ((void*)0) || __suffix == ((void*)0)) __result = (g_str_has_suffix) (__str, __suffix ); else { const size_t __str_len = strlen (((__str) + !(__str ))); const size_t __suffix_len = strlen (((__suffix) + !(__suffix ))); if (__str_len >= __suffix_len) __result = memcmp (__str + __str_len - __suffix_len, ((__suffix) + !(__suffix)), __suffix_len ) == 0; } __result; }) : (g_str_has_suffix) (argv[2], ".rar") )) { |
714 | rarfile[strlen(rarfile) - 5] = 0; |
715 | g_string_append (commandline, " ")(__builtin_constant_p (" ") ? __extension__ ({ const char * const __val = (" "); g_string_append_len_inline (commandline, __val , (__val != ((void*)0)) ? (gssize) strlen (((__val) + !(__val ))) : (gssize) -1); }) : g_string_append_len_inline (commandline , " ", (gssize) -1)); |
716 | |
717 | gchar *tempstr = g_shell_quote (rarfile); |
718 | g_string_append (commandline, tempstr)(__builtin_constant_p (tempstr) ? __extension__ ({ const char * const __val = (tempstr); g_string_append_len_inline (commandline , __val, (__val != ((void*)0)) ? (gssize) strlen (((__val) + ! (__val))) : (gssize) -1); }) : g_string_append_len_inline (commandline , tempstr, (gssize) -1)); |
719 | g_free (tempstr); |
720 | |
721 | g_string_append (commandline, "*.rar")(__builtin_constant_p ("*.rar") ? __extension__ ({ const char * const __val = ("*.rar"); g_string_append_len_inline (commandline , __val, (__val != ((void*)0)) ? (gssize) strlen (((__val) + ! (__val))) : (gssize) -1); }) : g_string_append_len_inline (commandline , "*.rar", (gssize) -1)); |
722 | fixname = TRUE(!(0)); |
723 | } |
724 | } |
725 | else if ((i == 4) && (fixname)) { |
726 | g_string_append (commandline, " \"$(dirname ")(__builtin_constant_p (" \"$(dirname ") ? __extension__ ({ const char * const __val = (" \"$(dirname "); g_string_append_len_inline (commandline, __val, (__val != ((void*)0)) ? (gssize) strlen (((__val) + !(__val))) : (gssize) -1); }) : g_string_append_len_inline (commandline, " \"$(dirname ", (gssize) -1)); |
727 | |
728 | gchar *tempstr = g_shell_quote (argv[3]); |
729 | g_string_append (commandline, tempstr)(__builtin_constant_p (tempstr) ? __extension__ ({ const char * const __val = (tempstr); g_string_append_len_inline (commandline , __val, (__val != ((void*)0)) ? (gssize) strlen (((__val) + ! (__val))) : (gssize) -1); }) : g_string_append_len_inline (commandline , tempstr, (gssize) -1)); |
730 | g_free (tempstr); |
731 | |
732 | g_string_append (commandline, ")\"")(__builtin_constant_p (")\"") ? __extension__ ({ const char * const __val = (")\""); g_string_append_len_inline (commandline , __val, (__val != ((void*)0)) ? (gssize) strlen (((__val) + ! (__val))) : (gssize) -1); }) : g_string_append_len_inline (commandline , ")\"", (gssize) -1)); |
733 | } |
734 | else { |
735 | g_string_append (commandline, " ")(__builtin_constant_p (" ") ? __extension__ ({ const char * const __val = (" "); g_string_append_len_inline (commandline, __val , (__val != ((void*)0)) ? (gssize) strlen (((__val) + !(__val ))) : (gssize) -1); }) : g_string_append_len_inline (commandline , " ", (gssize) -1)); |
736 | g_string_append (commandline, argv[(i - 1)])(__builtin_constant_p (argv[(i - 1)]) ? __extension__ ({ const char * const __val = (argv[(i - 1)]); g_string_append_len_inline (commandline, __val, (__val != ((void*)0)) ? (gssize) strlen (((__val) + !(__val))) : (gssize) -1); }) : g_string_append_len_inline (commandline, argv[(i - 1)], (gssize) -1)); |
737 | } |
738 | } |
739 | else if (g_str_has_prefix (argv[0], "mv")(__builtin_constant_p ("mv")? __extension__ ({ const char * const __str = (argv[0]); const char * const __prefix = ("mv"); gboolean __result = (0); if (__str == ((void*)0) || __prefix == ((void *)0)) __result = (g_str_has_prefix) (__str, __prefix); else { const size_t __str_len = strlen (((__str) + !(__str))); const size_t __prefix_len = strlen (((__prefix) + !(__prefix))); if (__str_len >= __prefix_len) __result = memcmp (((__str) + !(__str)), ((__prefix) + !(__prefix)), __prefix_len) == 0; } __result; }) : (g_str_has_prefix) (argv[0], "mv") )) { |
740 | g_string_append (commandline, "mv")(__builtin_constant_p ("mv") ? __extension__ ({ const char * const __val = ("mv"); g_string_append_len_inline (commandline, __val , (__val != ((void*)0)) ? (gssize) strlen (((__val) + !(__val ))) : (gssize) -1); }) : g_string_append_len_inline (commandline , "mv", (gssize) -1)); |
741 | } |
742 | } |
743 | |
744 | argv[i] = NULL((void*)0); |
745 | |
746 | #ifdef CAFE_ENABLE_DEBUG |
747 | { |
748 | int j; |
749 | |
750 | if (process->priv->use_standard_locale) { |
751 | g_print ("\tLC_MESSAGES=C\n"); |
752 | g_print ("\tLC_TIME=C\n"); |
753 | g_print ("\tLC_NUMERIC=C\n"); |
754 | } |
755 | |
756 | if (info->dir != NULL((void*)0)) |
757 | g_print ("\tcd %s\n", info->dir); |
758 | |
759 | g_print ("\t"); |
760 | for (j = 0; j < i; j++) |
761 | g_print ("%s ", argv[j]); |
762 | g_print ("\n"); |
763 | } |
764 | #endif |
765 | |
766 | if ((fixname) && (system (commandline->str) != 0)) |
767 | g_warning ("The files could not be move: %s\n", commandline->str); |
768 | |
769 | if (info->begin_func != NULL((void*)0)) |
770 | (*info->begin_func) (info->begin_data); |
771 | |
772 | if (! g_spawn_async_with_pipes (info->dir, |
773 | argv, |
774 | NULL((void*)0), |
775 | (G_SPAWN_LEAVE_DESCRIPTORS_OPEN |
776 | | G_SPAWN_SEARCH_PATH |
777 | | G_SPAWN_DO_NOT_REAP_CHILD), |
778 | child_setup, |
779 | process, |
780 | &process->priv->command_pid, |
781 | NULL((void*)0), |
782 | &out_fd, |
783 | &err_fd, |
784 | &process->error.gerror)) |
785 | { |
786 | process->error.type = FR_PROC_ERROR_SPAWN; |
787 | g_signal_emit (G_OBJECT (process)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((process)), (((GType) ((20) << (2)))))))), |
788 | fr_process_signals[DONE], |
789 | 0, |
790 | &process->error); |
791 | g_string_free (commandline, TRUE)(__builtin_constant_p ((!(0))) ? (((!(0))) ? (g_string_free) ( (commandline), ((!(0)))) : g_string_free_and_steal (commandline )) : (g_string_free) ((commandline), ((!(0))))); |
792 | g_free (argv); |
793 | return; |
794 | } |
795 | |
796 | g_string_free (commandline, TRUE)(__builtin_constant_p ((!(0))) ? (((!(0))) ? (g_string_free) ( (commandline), ((!(0)))) : g_string_free_and_steal (commandline )) : (g_string_free) ((commandline), ((!(0))))); |
797 | g_free (argv); |
798 | |
799 | fr_channel_data_set_fd (&process->out, out_fd, fr_process_get_charset (process)); |
800 | fr_channel_data_set_fd (&process->err, err_fd, fr_process_get_charset (process)); |
801 | |
802 | process->priv->check_timeout = g_timeout_add (REFRESH_RATE20, |
803 | check_child, |
804 | process); |
805 | } |
806 | |
807 | |
808 | static gboolean |
809 | command_is_sticky (FrProcess *process, |
810 | int i) |
811 | { |
812 | FrCommandInfo *info; |
813 | |
814 | info = g_ptr_array_index (process->priv->comm, i)((process->priv->comm)->pdata)[i]; |
815 | return info->sticky; |
816 | } |
817 | |
818 | |
819 | static void |
820 | allow_sticky_processes_only (FrProcess *process, |
821 | gboolean emit_signal) |
822 | { |
823 | if (! process->priv->sticky_only) { |
824 | /* Remember the first error. */ |
825 | process->priv->error_command = process->priv->current_command; |
826 | process->priv->first_error.type = process->error.type; |
827 | process->priv->first_error.status = process->error.status; |
828 | g_clear_error (&process->priv->first_error.gerror); |
829 | if (process->error.gerror != NULL((void*)0)) |
830 | process->priv->first_error.gerror = g_error_copy (process->error.gerror); |
831 | } |
832 | |
833 | process->priv->sticky_only = TRUE(!(0)); |
834 | if (emit_signal) |
835 | g_signal_emit (G_OBJECT (process)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((process)), (((GType) ((20) << (2)))))))), |
836 | fr_process_signals[STICKY_ONLY], |
837 | 0); |
838 | } |
839 | |
840 | |
841 | static void |
842 | fr_process_set_error (FrProcess *process, |
843 | FrProcErrorType type, |
844 | int status, |
845 | GError *gerror) |
846 | { |
847 | process->error.type = type; |
848 | process->error.status = status; |
849 | if (gerror != process->error.gerror) { |
850 | g_clear_error (&process->error.gerror); |
851 | if (gerror != NULL((void*)0)) |
852 | process->error.gerror = g_error_copy (gerror); |
853 | } |
854 | } |
855 | |
856 | |
857 | static gint |
858 | check_child (gpointer data) |
859 | { |
860 | FrProcess *process = data; |
861 | FrCommandInfo *info; |
862 | pid_t pid; |
863 | int status; |
864 | gboolean continue_process; |
865 | gboolean channel_error = FALSE(0); |
866 | |
867 | info = g_ptr_array_index (process->priv->comm, process->priv->current_command)((process->priv->comm)->pdata)[process->priv-> current_command]; |
868 | |
869 | /* Remove check. */ |
870 | |
871 | g_source_remove (process->priv->check_timeout); |
872 | process->priv->check_timeout = 0; |
873 | |
874 | if (fr_channel_data_read (&process->out) == G_IO_STATUS_ERROR) { |
875 | fr_process_set_error (process, FR_PROC_ERROR_IO_CHANNEL, 0, process->out.error); |
876 | channel_error = TRUE(!(0)); |
877 | } |
878 | else if (fr_channel_data_read (&process->err) == G_IO_STATUS_ERROR) { |
879 | fr_process_set_error (process, FR_PROC_ERROR_IO_CHANNEL, 0, process->err.error); |
880 | channel_error = TRUE(!(0)); |
881 | } |
882 | else { |
883 | pid = waitpid (process->priv->command_pid, &status, WNOHANG1); |
884 | if (pid != process->priv->command_pid) { |
885 | /* Add check again. */ |
886 | process->priv->check_timeout = g_timeout_add (REFRESH_RATE20, |
887 | check_child, |
888 | process); |
889 | return FALSE(0); |
890 | } |
891 | } |
892 | |
893 | if (info->ignore_error) { |
894 | process->error.type = FR_PROC_ERROR_NONE; |
895 | debug (DEBUG_INFO"fr-process.c", 895, __FUNCTION__, "[ignore error]\n"); |
896 | } |
897 | else if (! channel_error && (process->error.type != FR_PROC_ERROR_STOPPED)) { |
898 | if (WIFEXITED (status)(((status) & 0x7f) == 0)) { |
899 | if (WEXITSTATUS (status)(((status) & 0xff00) >> 8) == 0) |
900 | process->error.type = FR_PROC_ERROR_NONE; |
901 | else if (WEXITSTATUS (status)(((status) & 0xff00) >> 8) == 255) |
902 | process->error.type = FR_PROC_ERROR_COMMAND_NOT_FOUND; |
903 | else |
904 | process->error.type = FR_PROC_ERROR_COMMAND_ERROR; |
905 | |
906 | process->error.status = WEXITSTATUS (status)(((status) & 0xff00) >> 8); |
907 | } |
908 | else { |
909 | process->error.type = FR_PROC_ERROR_EXITED_ABNORMALLY; |
910 | process->error.status = 255; |
911 | } |
912 | } |
913 | |
914 | process->priv->command_pid = 0; |
915 | |
916 | if (fr_channel_data_flush (&process->out) == G_IO_STATUS_ERROR) { |
917 | fr_process_set_error (process, FR_PROC_ERROR_IO_CHANNEL, 0, process->out.error); |
918 | channel_error = TRUE(!(0)); |
919 | } |
920 | else if (fr_channel_data_flush (&process->err) == G_IO_STATUS_ERROR) { |
921 | fr_process_set_error (process, FR_PROC_ERROR_IO_CHANNEL, 0, process->err.error); |
922 | channel_error = TRUE(!(0)); |
923 | } |
924 | |
925 | if (info->end_func != NULL((void*)0)) |
926 | (*info->end_func) (info->end_data); |
927 | |
928 | /**/ |
929 | |
930 | if (channel_error |
931 | && (process->error.type == FR_PROC_ERROR_IO_CHANNEL) |
932 | && g_error_matches (process->error.gerror, G_CONVERT_ERRORg_convert_error_quark(), G_CONVERT_ERROR_ILLEGAL_SEQUENCE)) |
933 | { |
934 | if (process->priv->current_charset < n_charsets - 1) { |
935 | /* try with another charset */ |
936 | process->priv->current_charset++; |
937 | process->priv->running = FALSE(0); |
938 | process->restart = TRUE(!(0)); |
939 | fr_process_start (process); |
940 | return FALSE(0); |
941 | } |
942 | /*fr_process_set_error (process, FR_PROC_ERROR_NONE, 0, NULL);*/ |
943 | fr_process_set_error (process, FR_PROC_ERROR_BAD_CHARSET, 0, process->error.gerror); |
944 | } |
945 | |
946 | /* Check whether to continue or stop the process */ |
947 | |
948 | continue_process = TRUE(!(0)); |
949 | if (info->continue_func != NULL((void*)0)) |
950 | continue_process = (*info->continue_func) (info->continue_data); |
951 | |
952 | /* Execute next command. */ |
953 | if (continue_process) { |
954 | if (process->error.type != FR_PROC_ERROR_NONE) { |
955 | allow_sticky_processes_only (process, TRUE(!(0))); |
956 | #ifdef CAFE_ENABLE_DEBUG |
957 | { |
958 | GList *scan; |
959 | |
960 | g_print ("** ERROR **\n"); |
961 | for (scan = process->err.raw; scan; scan = scan->next) |
962 | g_print ("%s\n", (char *)scan->data); |
963 | } |
964 | #endif |
965 | } |
966 | |
967 | if (process->priv->sticky_only) { |
968 | do { |
969 | process->priv->current_command++; |
970 | } while ((process->priv->current_command <= process->priv->n_comm) |
971 | && ! command_is_sticky (process, process->priv->current_command)); |
972 | } |
973 | else |
974 | process->priv->current_command++; |
975 | |
976 | if (process->priv->current_command <= process->priv->n_comm) { |
977 | start_current_command (process); |
978 | return FALSE(0); |
979 | } |
980 | } |
981 | |
982 | /* Done */ |
983 | |
984 | process->priv->current_command = -1; |
985 | process->priv->use_standard_locale = FALSE(0); |
986 | |
987 | if (process->out.raw != NULL((void*)0)) |
988 | process->out.raw = g_list_reverse (process->out.raw); |
989 | if (process->err.raw != NULL((void*)0)) |
990 | process->err.raw = g_list_reverse (process->err.raw); |
991 | |
992 | process->priv->running = FALSE(0); |
993 | process->priv->stopping = FALSE(0); |
994 | |
995 | if (process->priv->sticky_only) { |
996 | /* Restore the first error. */ |
997 | fr_process_set_error (process, |
998 | process->priv->first_error.type, |
999 | process->priv->first_error.status, |
1000 | process->priv->first_error.gerror); |
1001 | } |
1002 | |
1003 | g_signal_emit (G_OBJECT (process)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((process)), (((GType) ((20) << (2)))))))), |
1004 | fr_process_signals[DONE], |
1005 | 0, |
1006 | &process->error); |
1007 | |
1008 | return FALSE(0); |
1009 | } |
1010 | |
1011 | |
1012 | void |
1013 | fr_process_use_standard_locale (FrProcess *process, |
1014 | gboolean use_stand_locale) |
1015 | { |
1016 | g_return_if_fail (process != NULL)do { if ((process != ((void*)0))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "process != NULL" ); return; } } while (0); |
1017 | process->priv->use_standard_locale = use_stand_locale; |
1018 | } |
1019 | |
1020 | |
1021 | void |
1022 | fr_process_start (FrProcess *process) |
1023 | { |
1024 | g_return_if_fail (process != NULL)do { if ((process != ((void*)0))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "process != NULL" ); return; } } while (0); |
1025 | |
1026 | if (process->priv->running) |
1027 | return; |
1028 | |
1029 | fr_channel_data_reset (&process->out); |
1030 | fr_channel_data_reset (&process->err); |
1031 | |
1032 | process->priv->sticky_only = FALSE(0); |
1033 | process->priv->current_command = 0; |
1034 | fr_process_set_error (process, FR_PROC_ERROR_NONE, 0, NULL((void*)0)); |
1035 | |
1036 | if (! process->restart) { |
1037 | process->priv->current_charset = -1; |
1038 | g_signal_emit (G_OBJECT (process)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((process)), (((GType) ((20) << (2)))))))), |
1039 | fr_process_signals[START], |
1040 | 0); |
1041 | } |
1042 | |
1043 | process->priv->stopping = FALSE(0); |
1044 | |
1045 | if (process->priv->n_comm == -1) { |
1046 | process->priv->running = FALSE(0); |
1047 | g_signal_emit (G_OBJECT (process)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((process)), (((GType) ((20) << (2)))))))), |
1048 | fr_process_signals[DONE], |
1049 | 0, |
1050 | &process->error); |
1051 | } |
1052 | else { |
1053 | process->priv->running = TRUE(!(0)); |
1054 | start_current_command (process); |
1055 | } |
1056 | } |
1057 | static int |
1058 | fr_close_suspend_process(FrProcess *process) |
1059 | { |
1060 | int ret = -1; |
1061 | g_return_val_if_fail(process != NULL, ret)do { if ((process != ((void*)0))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "process != NULL" ); return (ret); } } while (0); |
1062 | |
1063 | if (process->priv->suspend) |
1064 | { |
1065 | if (process->priv->command_pid > 0) |
1066 | { |
1067 | ret = killpg (process->priv->command_pid,SIGTERM15); |
Value stored to 'ret' is never read | |
1068 | ret = killpg (process->priv->command_pid,SIGCONT18); |
1069 | } |
1070 | if(ret == 0) |
1071 | process->priv->suspend = FALSE(0); |
1072 | } |
1073 | |
1074 | return ret; |
1075 | } |
1076 | static int |
1077 | fr_switch_process_state (FrProcess *process) |
1078 | { |
1079 | int ret = -1; |
1080 | g_return_val_if_fail(process != NULL, ret)do { if ((process != ((void*)0))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "process != NULL" ); return (ret); } } while (0); |
1081 | |
1082 | if (process->priv->stopping) |
1083 | return ret; |
1084 | |
1085 | if (process->priv->suspend) |
1086 | { |
1087 | |
1088 | if (process->priv->command_pid > 0) |
1089 | ret = killpg (process->priv->command_pid,SIGCONT18); |
1090 | if(ret == 0) |
1091 | process->priv->suspend = FALSE(0); |
1092 | } |
1093 | else |
1094 | { |
1095 | if (process->priv->command_pid > 0) |
1096 | ret = killpg (process->priv->command_pid,SIGSTOP19); |
1097 | if(ret == 0) |
1098 | process->priv->suspend = TRUE(!(0)); |
1099 | } |
1100 | |
1101 | return ret; |
1102 | } |
1103 | static void |
1104 | fr_process_stop_priv (FrProcess *process, |
1105 | gboolean emit_signal) |
1106 | { |
1107 | g_return_if_fail (process != NULL)do { if ((process != ((void*)0))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "process != NULL" ); return; } } while (0); |
1108 | |
1109 | if (! process->priv->running) |
1110 | return; |
1111 | |
1112 | if (process->priv->stopping) |
1113 | return; |
1114 | |
1115 | process->priv->stopping = TRUE(!(0)); |
1116 | process->error.type = FR_PROC_ERROR_STOPPED; |
1117 | |
1118 | if (command_is_sticky (process, process->priv->current_command)) |
1119 | allow_sticky_processes_only (process, emit_signal); |
1120 | |
1121 | else if (process->term_on_stop && (process->priv->command_pid > 0)) |
1122 | killpg (process->priv->command_pid, SIGTERM15); |
1123 | |
1124 | else { |
1125 | if (process->priv->check_timeout != 0) { |
1126 | g_source_remove (process->priv->check_timeout); |
1127 | process->priv->check_timeout = 0; |
1128 | } |
1129 | |
1130 | process->priv->command_pid = 0; |
1131 | fr_channel_data_close_source (&process->out); |
1132 | fr_channel_data_close_source (&process->err); |
1133 | |
1134 | process->priv->running = FALSE(0); |
1135 | |
1136 | if (emit_signal) |
1137 | g_signal_emit (G_OBJECT (process)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((process)), (((GType) ((20) << (2)))))))), |
1138 | fr_process_signals[DONE], |
1139 | 0, |
1140 | &process->error); |
1141 | } |
1142 | } |
1143 | |
1144 | |
1145 | void |
1146 | fr_process_stop (FrProcess *process) |
1147 | { |
1148 | fr_process_stop_priv (process, TRUE(!(0))); |
1149 | } |
1150 | int start_switch_state (FrProcess *process) |
1151 | { |
1152 | return fr_switch_process_state (process); |
1153 | } |
1154 | void start_close_suspend_process(FrProcess *process) |
1155 | { |
1156 | fr_close_suspend_process(process); |
1157 | } |
1158 |