Guidelines/Processes

From Apertis
Jump to: navigation, search

Contents

Processes

There are various things which affect an entire application process. They are not all related, so are covered in separate subsections; some apply to all applications, others to specific functionality.

Summary

  • Use libraries instead of subprocesses where possible. (#Subprocesses)
  • Use closed-loop subprocess management to keep track of when subprocesses exit. (#Subprocesses)
  • Do not use sigaction(): use g_unix_signal_add() instead. (#UNIX signals)
  • Do not use sleep(): use g_timeout_add_seconds() instead. (#Sleeping)
  • Do not use system(): use libraries or single subprocesses instead. (#Shell commands)
  • Use GApplication and GOptionContext to do command line parsing. (#Command line parsing)

Subprocesses

Launching subprocesses is sometimes necessary to perform specific tasks, though where possible it is generally better to link against and use an appropriate library to perform the same task, as it eliminates a lot of potential failure points, simplifies passing data around (as passing data to subprocesses involves pipes, and is complex), and generally allows for greater interaction between the parent process and the task.

Subprocesses should not be used to implement functionality which could be implemented by D-Bus service daemons.

When using subprocesses, closed-loop management should be used, by monitoring the child process’ PID after sending it kill signals, and waiting until the child process terminates before proceeding with further processing. The alternative, open-loop management, sends signals and never checks to see if the child responded to them, which is more fragile.

To do this, use g_spawn_async() to spawn child processes, and g_child_watch_add() to set up a callback to be invoked when the child exits.

UNIX signals

The standard UNIX function for setting up signal handlers, sigaction(), must not be used in GLib programs, as its callback must be re-entrancy safe, and no GLib code is re-entrancy safe. Instead, g_unix_signal_add() should be used, which doesn’t require its callback to be re-entrancy safe.

Sleeping

The sleep() function must not be used in GLib code, as it blocks the current thread. Instead, g_timeout_add_seconds() or g_timeout_add() should be used to schedule a callback to be invoked after a period of time; in the mean time, events can continue being processed by the main context.

Shell commands

The system() function must not be used. It is extremely prone to shell injection vulnerabilities, and any functionality which can be implemented using it can be implemented using libraries directly or, if that is not possible, spawning individual subprocesses.

For example, instead of calling system (g_strdup_printf ("mv %s %s", file_path1, file_path2)), use g_file_move(). In this situation, using system() exposes a shell injection vulnerability, and will not work with paths containing spaces in any case.

Command line parsing

Command line parsing should be implemented using GApplication and GOptionContext, rather than being implemented manually or using another library (such as popt).

By using GOptionContext, command line parsing follows the standard format used by most Linux applications. It gives automatic support for --help output, and short and long option parsing.

An example of using GApplication together with GOptionContext is here.

External links

Personal tools
Namespaces

Variants
Actions
Navigation
Tools