Arcane  v3.14.10.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
Process.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2022 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* Process.cc (C) 2000-2016 */
9/* */
10/* Gestion des processus. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/utils/ArcanePrecomp.h"
15
16#include "arcane/utils/NotImplementedException.h"
17#include "arcane/utils/OStringStream.h"
18#include "arcane/utils/Process.h"
19
20/*
21 * NOTE: pour l'instant cette classe n'est implémentée que pour Linux
22 * (elle devrait cependant fonctionner avec les autres Unix).
23 */
24
25#ifdef ARCANE_OS_LINUX
26#include <unistd.h>
27#include <sys/wait.h>
28#include <fcntl.h>
29#endif
30
31/*---------------------------------------------------------------------------*/
32/*---------------------------------------------------------------------------*/
33
34ARCANE_BEGIN_NAMESPACE
35
36/*---------------------------------------------------------------------------*/
37/*---------------------------------------------------------------------------*/
38
39/*---------------------------------------------------------------------------*/
40/*---------------------------------------------------------------------------*/
41
43execute(ProcessExecArgs& args)
44{
45#ifdef ARCANE_OS_LINUX
46 args.m_output_bytes.clear();
47 ByteConstArrayView input_bytes = args.inputBytes();
48
49 // Créé deux pipes pour rediriger les entrées et les sorties du
50 // processus qu'on va lancer.
51 int pipefd_out[2];
52 int pipefd_in[2];
53 int r0 = pipe2(pipefd_out,O_CLOEXEC);
54 if (r0!=0)
55 return ProcessExecArgs::ExecStatus::CanNotCreatePipe;
56 r0 = pipe2(pipefd_in,O_CLOEXEC);
57 if (r0!=0)
58 return ProcessExecArgs::ExecStatus::CanNotCreatePipe;
59 pid_t cpid = ::fork();
60 if (cpid<0)
61 return ProcessExecArgs::ExecStatus::CanNotFork;
62
63 ProcessExecArgs::ExecStatus exec_status = ProcessExecArgs::ExecStatus::OK;
64 if (cpid==0){
65 // Je suis le processus fils.
66
67 // TODO: vérifier les erreurs des close() et dup2().
68
69 // Indique que pipefd_out[1] correspond à mon STDOUT
70 ::close(STDOUT_FILENO);
71 ::close(pipefd_out[0]);
72 ::dup2(pipefd_out[1],STDOUT_FILENO);
73
74 // Indique que pipefd_in[0] correspond à mon STDIN
75 ::close(STDIN_FILENO);
76 ::close(pipefd_in[1]);
77 ::dup2(pipefd_in[0],STDIN_FILENO);
78
79 const char* cmd_name = args.command().localstr();
80
81 StringConstArrayView arguments = args.arguments();
82 Integer nb_arg = arguments.size();
83 // Le tableau passé à execve() pour les arguments doit se terminer par NULL
84 // et commencer par le nom de l'exécutable
85 UniqueArray<const char*> command_args(nb_arg+2);
86 for( Integer i=0; i<nb_arg; ++i )
87 command_args[i+1] = arguments[i].localstr();
88 command_args[0] = cmd_name;
89 command_args[nb_arg+1] = nullptr;
90
91 const char *const newenviron[] = { NULL };
92 ::execve(cmd_name, (char* const*)command_args.data(), (char* const*)newenviron);
93 // L'appel à execve() ne retourne pas.
94
95 }
96 else{
97 ::close(pipefd_out[1]);
98 ::close(pipefd_in[0]);
99 // Ecrit sur le pipe d'entrée les octets de \a input_bytes
100 Int64 nb_wanted_write = input_bytes.size();
101 Int64 nb_written = ::write(pipefd_in[1],input_bytes.data(),nb_wanted_write);
102 if (nb_written!=nb_wanted_write)
103 std::cerr << "Error writing to pipe\n";
104 ::close(pipefd_in[1]);
105 const int BUF_SIZE=4096;
106 Byte buf[BUF_SIZE];
107 ssize_t r = 0;
108 // TODO: gérer les interruptions et recommencer si nécessaire
109 while ((r=::read(pipefd_out[0], buf, BUF_SIZE)) > 0){
110 args.m_output_bytes.addRange(ByteConstArrayView((Integer)r,buf));
111 //::write(STDOUT_FILENO, buf, r);
112 }
113 // Attend que le processus fils soit fini.
114 int status = 0;
115 ::waitpid(cpid,&status,0); /* Wait for child */
116 if (WIFEXITED(status)){
117 args.m_exit_code = WEXITSTATUS(status);
118 //printf("exited, status=%d\n", WEXITSTATUS(status));
119 }
120 else
121 exec_status = ProcessExecArgs::ExecStatus::AbnormalExit;
122
123 close(pipefd_out[0]);
124
125 // Ajoute un '\0' terminal au flux de sortie.
126 args.m_output_bytes.add('\0');
127 }
128 return exec_status;
129#else
130 throw NotImplementedException(A_FUNCINFO);
131#endif
132}
133
134/*---------------------------------------------------------------------------*/
135/*---------------------------------------------------------------------------*/
136
137ARCANE_END_NAMESPACE
138
139/*---------------------------------------------------------------------------*/
140/*---------------------------------------------------------------------------*/
String command() const
Commande à exécuter. Doit correspondre à un exécutable.
Definition Process.h:47
ByteConstArrayView inputBytes() const
Chaîne de caractère à envoyer sur l'entrée standard (STDIN) du processsus.
Definition Process.h:56
StringConstArrayView arguments() const
Liste des arguments.
Definition Process.h:51
const T * data() const
Accès à la racine du tableau hors toute protection.
void addRange(ConstReferenceType val, Int64 n)
Ajoute n élément de valeur val à la fin du tableau.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
void clear()
Supprime les éléments du tableau.
Vue constante d'un tableau de type T.
constexpr Integer size() const noexcept
Nombre d'éléments du tableau.
constexpr const_pointer data() const noexcept
Pointeur sur la mémoire allouée.
const char * localstr() const
Retourne la conversion de l'instance dans l'encodage UTF-8.
Definition String.cc:227
Vecteur 1D de données avec sémantique par valeur (style STL).
unsigned char Byte
Type d'un octet.
Definition UtilsTypes.h:142