Branch data Line data Source code
1 : : /* 2 : : ** Copyright (C) 2022 CERN 3 : : ** 4 : : ** This software is provided 'as-is', without any express or implied 5 : : ** warranty. In no event will the authors be held liable for any damages 6 : : ** arising from the use of this software. 7 : : ** 8 : : ** Permission is granted to anyone to use this software for any purpose, 9 : : ** including commercial applications, and to alter it and redistribute it 10 : : ** freely, subject to the following restrictions: 11 : : ** 12 : : ** 1. The origin of this software must not be misrepresented; you must not 13 : : ** claim that you wrote the original software. If you use this software 14 : : ** in a product, an acknowledgment in the product documentation would be 15 : : ** appreciated but is not required. 16 : : ** 2. Altered source versions must be plainly marked as such, and must not be 17 : : ** misrepresented as being the original software. 18 : : ** 3. This notice may not be removed or altered from any source distribution. 19 : : ** 20 : : ** Created on: 2022-11-29T10:48:00 21 : : ** Author: Sylvain Fargier <sylvain.fargier@cern.ch> 22 : : */ 23 : : 24 : : #include "Pipe.hpp" 25 : : 26 : : #include <vector> 27 : : 28 : : #include <fcntl.h> 29 : : #include <unistd.h> 30 : : 31 : : #include "Exception.hpp" 32 : : 33 : : namespace ccut { 34 : : 35 : 18 : Pipe::Pipe() 36 : : { 37 : 18 : ::pipe(m_fd); 38 : 54 : for (size_t i = 0; i < 2; ++i) 39 : : { 40 : 36 : ::fcntl(m_fd[i], F_SETFL, ::fcntl(m_fd[i], F_GETFL, 0) | O_NONBLOCK); 41 : 36 : ::fcntl(m_fd[i], F_SETFD, FD_CLOEXEC); 42 : : } 43 : 18 : } 44 : : 45 : 18 : Pipe::~Pipe() 46 : : { 47 : 18 : ::close(m_fd[0]); 48 : 18 : ::close(m_fd[1]); 49 : 18 : } 50 : : 51 : 16 : void Pipe::flush() 52 : : { 53 : 16 : std::vector<char> buffer{10}; 54 : 31 : while (read(buffer.data(), buffer.size()) == buffer.size()) 55 : : ; 56 : 16 : } 57 : : 58 : 28 : size_t Pipe::write(const void *data, size_t size) 59 : : { 60 : 28 : ssize_t sz = ::write(m_fd[1], data, size); 61 : 28 : if (sz < 0) 62 : 1 : throw ccut::make_errno_exception(); 63 : 27 : return size_t(sz); 64 : : } 65 : : 66 : 36 : size_t Pipe::read(void *data, size_t size) 67 : : { 68 : 36 : ssize_t sz = ::read(m_fd[0], data, size); 69 : 36 : if (sz < 0) 70 : : { 71 : 20 : if (errno == EAGAIN) 72 : 18 : sz = 0; 73 : : else 74 : 2 : throw ccut::make_errno_exception(); 75 : : } 76 : 34 : return size_t(sz); 77 : : } 78 : : 79 : 27 : void Pipe::write(const std::string &msg) 80 : : { 81 : 27 : if (write(msg.data(), msg.size()) != msg.size()) 82 : 0 : throw Exception(ErrorCode::Runtime, "failed to write on pipe"); 83 : 26 : } 84 : : 85 : : } // namespace ccut