W systemach uniksopodobnych uruchomienie innego programu przeprowadza się w dwóch krokach:
- utworzenie kopii bieżącego procesu przy użyciu wywołania systemowego “fork”
- uruchomienie programu i zastąpienie tej kopii przy użyciu wywołania systemowego “exec”
Jednak są określone zależności, które powstają w wyniku utworzenia takiej kopii procesu oraz kolejne w wyniku uruchomienia programu. Te zależności wymagają wykonania określonych działań zabezpieczających. Powtarzają się one dla każdej sekwencji “fork”‐“exec”, dlatego zostały utworzone procedury obiektu “E_flow_Q_fork”, które wykonują większość tych działań. Uruchomienie programu ma następującą postać:
pid_t pid = E_flow_I_fork_I_begin();
if( !pid )
{ E_flow_I_fork_I_start();
E_flow_I_fork_I_exec( cwd, args, args_n );
exit( EXIT_FAILURE );
}
E_flow_I_fork_I_end(pid);
if( !~E_flow_I_fork_I_wait(pid) )
return ~0;“E_flow_I_fork_I_wait” jest procedurą służącą do oczekiwania na zakończenie uruchomionego procesu i nie jest wymagana.
Pierwszy parametr procedury “E_flow_I_fork_I_exec” (jeśli niezerowy) wskazuje na katalog bieżący, w którym zostanie uruchomiony program. Drugi parametr to tablica list argumentów zadeklarowana następująco:
struct E_flow_Z_args
{ N argc;
Pc *argv;
};Trzeci parametr to liczba elementów tej tablicy.
Tablica list argumentów jest sklejana w jedną listę i uruchamiany jako program jest pierwszy element tej listy, natomiast pozostałe elementy listy są podanymi mu parametrami wiersza polecenia, na przykład:
pid_t pid = E_flow_I_fork_I_begin();
if( !pid )
{ E_flow_I_fork_I_start();
struct E_flow_Z_args args[1];
args[0].argc = 1;
args[0].argv = ( Pc [] ){ "program", 0 };
E_flow_I_fork_I_exec( cwd, args, 1 );
exit( EXIT_FAILURE );
}
E_flow_I_fork_I_end(pid);Do właściwego uruchomienia innego programu potrzeba jeszcze w kopii procesu (po “E_flow_I_fork_I_start”) zamknąć wszystkie nie używane deskryptory plików. A używane deskryptory plików (na przykład deskryptory standardowego wejścia i wyjścia nowo uruchamianego programu) można ewentualnie przekierować (przy użyciu wywołania systemowego “dup2”) do “pipe” utworzonego przed wywołaniem “E_flow_I_fork_I_begin”.
