LCOV - code coverage report
Current view: top level - tools - Subprocess.h (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 4 4 100.0 %
Date: 2024-10-18 14:00:25 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2019-2023 The plumed team
       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
       4             : 
       5             :    See http://www.plumed.org for more information.
       6             : 
       7             :    This file is part of plumed, version 2.
       8             : 
       9             :    plumed is free software: you can redistribute it and/or modify
      10             :    it under the terms of the GNU Lesser General Public License as published by
      11             :    the Free Software Foundation, either version 3 of the License, or
      12             :    (at your option) any later version.
      13             : 
      14             :    plumed is distributed in the hope that it will be useful,
      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :    GNU Lesser General Public License for more details.
      18             : 
      19             :    You should have received a copy of the GNU Lesser General Public License
      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
      22             : #ifndef __PLUMED_tools_Subprocess_h
      23             : #define __PLUMED_tools_Subprocess_h
      24             : 
      25             : #include "OFile.h"
      26             : #include "IFile.h"
      27             : #include <string>
      28             : #include <cstdio>
      29             : #include <memory>
      30             : 
      31             : namespace PLMD {
      32             : 
      33             : /// Small class to avoid including unistd.h here
      34             : class SubprocessPid;
      35             : 
      36             : /**
      37             : Class managing a subprocess.
      38             : 
      39             : The subprocess is launched and one can interact with it through a pipe.
      40             : 
      41             : In order not to consume resources, it might be possible to use this syntax:
      42             : 
      43             : \verbatim
      44             : // at construction:
      45             : Subprocess sp;
      46             : sp.stop();
      47             : 
      48             : // when needed
      49             : {
      50             :   auto h=sp.contStop();
      51             :   sp<<"command\n";
      52             :   sp.flush();
      53             :   sp.getline(answer);
      54             : }
      55             : // when h goes out of scope, subprocess is stopped again.
      56             : // If an exception is raised in the block, the subprocess is stopped as well.
      57             : \endverbatim
      58             : 
      59             : \warning
      60             : Currently `stop` and `cont` are giving problems with some MPI implementation,
      61             : In addition, notice that the stop signal is only sent to the child process and
      62             : not to the subsequently spawn processes, so it might not work as intended.
      63             : This feature is left here but is probably no a good idea to use it.
      64             : It can be enabled with `export PLUMED_ENABLE_SIGNALS=1`.
      65             : 
      66             : */
      67             : class Subprocess {
      68             :   /// Process ID.
      69             :   /// We store this rather than pid_t to avoid including <unistd.h> in this header file.
      70             :   /// This remains nullptr in the child process.
      71             :   std::unique_ptr<SubprocessPid> pid;
      72             :   /// File descriptor, parent to child
      73             :   int fpc=0;
      74             :   /// File descriptor, child to parent
      75             :   int fcp=0;
      76             :   /// File pointer, parent to child
      77             :   FILE* fppc=NULL;
      78             :   /// File pointer, child to parent
      79             :   FILE* fpcp=NULL;
      80             :   /// PLUMED file object, parent to child.
      81             :   /// Used to simplify formatting
      82             :   OFile parent_to_child;
      83             :   /// PLUMED file object, child to parent.
      84             :   /// Used to simplify formatting
      85             :   IFile child_to_parent;
      86             : public:
      87             :   /// Class used to cont/stop a Subprocess in an exception safe manner.
      88             :   class Handler {
      89             :     Subprocess* sp=nullptr;
      90             :     /// Private constructor.
      91             :     /// Only to be called by Subprocess::contStop()
      92             :     explicit Handler(Subprocess* sp) noexcept;
      93             :     friend class Subprocess;
      94             :   public:
      95             :     /// Default constructor
      96             :     Handler() = default;
      97             :     /// Destructor stops the subprocess.
      98             :     ~Handler();
      99             :     /// Default copy constructor is deleted (not copyable)
     100             :     Handler(const Handler &) = delete;
     101             :     /// Default copy assignment is deleted (not copyable)
     102             :     Handler & operator=(const Handler & handler) = delete;
     103             :     /// Move constructor.
     104             :     Handler(Handler &&) noexcept;
     105             :     /// Move assignment.
     106             :     Handler & operator=(Handler && handler) noexcept;
     107             :   };
     108             : /// Constructor with a command line.
     109             :   explicit Subprocess(const std::string & cmd);
     110             : /// Destructor
     111             :   ~Subprocess();
     112             : /// Flush communication to process.
     113             :   void flush();
     114             : /// Check if subprocess facilities are available.
     115             : /// If it returns false, any call to Subprocess constructor will raise an exception.
     116             :   static bool available() noexcept;
     117             : /// Get a line from the subprocess.
     118             :   Subprocess & getline(std::string &);
     119             : /// Write something to the subprocess.
     120             :   template <class T> friend Subprocess& operator<<(Subprocess& ep,const T &t);
     121             : /// Send a SIGCONT to the subprocess.
     122             : /// Better used through contStop() method.
     123             :   void cont() noexcept;
     124             : /// Send a SIGSTOP to the subprocess.
     125             : /// Better used through contStop() method.
     126             :   void stop() noexcept;
     127             : /// Returns a handler to temporarily resume the process.
     128             :   Handler contStop() noexcept {
     129          16 :     return Handler(this);
     130             :   }
     131             : };
     132             : 
     133             : template <class T>
     134          32 : Subprocess& operator<<(Subprocess& ep,const T &t) {
     135          32 :   ep.parent_to_child<<t;
     136          32 :   return ep;
     137             : }
     138             : 
     139             : }
     140             : 
     141             : #endif
     142             : 

Generated by: LCOV version 1.16