blob: c6ce0cbc6cc994157655cc06aa43f3cec5d4fbe6 [file] [log] [blame]
James Kuszmaul3224b8e2022-01-07 19:00:39 -08001#ifndef AOS_UTIL_SCOPED_PIPE_H_
2#define AOS_UTIL_SCOPED_PIPE_H_
3
Stephan Pleinesb1177672024-05-27 17:48:32 -07004#include <stddef.h>
James Kuszmaul3224b8e2022-01-07 19:00:39 -08005#include <stdint.h>
6
James Kuszmauld42edb42022-01-07 18:00:16 -08007#include <memory>
James Kuszmaul3224b8e2022-01-07 19:00:39 -08008#include <optional>
Stephan Pleinesb1177672024-05-27 17:48:32 -07009#include <string>
James Kuszmaul3224b8e2022-01-07 19:00:39 -080010
James Kuszmaul731a05d2022-01-07 17:59:26 -080011#include "absl/types/span.h"
12
James Kuszmaul3224b8e2022-01-07 19:00:39 -080013namespace aos::util {
14
15// RAII Pipe for sending individual ints between reader and writer.
16class ScopedPipe {
17 public:
18 class ScopedReadPipe;
Stephan Pleinesb1177672024-05-27 17:48:32 -070019
James Kuszmaul3224b8e2022-01-07 19:00:39 -080020 class ScopedWritePipe;
21
James Kuszmauld42edb42022-01-07 18:00:16 -080022 struct PipePair {
23 std::unique_ptr<ScopedReadPipe> read;
24 std::unique_ptr<ScopedWritePipe> write;
25 };
26
27 static PipePair MakePipe();
James Kuszmaul3224b8e2022-01-07 19:00:39 -080028
29 virtual ~ScopedPipe();
30
31 int fd() const { return fd_; }
James Kuszmauld42edb42022-01-07 18:00:16 -080032 // Sets FD_CLOEXEC on the file descriptor.
33 void SetCloexec();
James Kuszmaul3224b8e2022-01-07 19:00:39 -080034
35 private:
36 ScopedPipe(int fd = -1);
37
38 int fd_;
39
40 ScopedPipe(const ScopedPipe &) = delete;
41 ScopedPipe &operator=(const ScopedPipe &) = delete;
42 ScopedPipe(ScopedPipe &&);
43 ScopedPipe &operator=(ScopedPipe &&);
44};
45
46class ScopedPipe::ScopedReadPipe : public ScopedPipe {
47 public:
48 std::optional<uint32_t> Read();
James Kuszmaul731a05d2022-01-07 17:59:26 -080049 // Reads as many bytes as possible out of the pipe, appending them to the end
50 // of the provided buffer. Returns the number of bytes read. Dies on errors
51 // other than EAGAIN or EWOULDBLOCK.
52 size_t Read(std::string *buffer);
James Kuszmaul3224b8e2022-01-07 19:00:39 -080053
54 private:
55 using ScopedPipe::ScopedPipe;
56
57 friend class ScopedPipe;
58};
59
60class ScopedPipe::ScopedWritePipe : public ScopedPipe {
61 public:
62 void Write(uint32_t data);
James Kuszmaul731a05d2022-01-07 17:59:26 -080063 // Writes the entirety of the specified buffer to the pipe. Dies on failure.
64 void Write(absl::Span<const uint8_t> data);
James Kuszmaul3224b8e2022-01-07 19:00:39 -080065
66 private:
67 using ScopedPipe::ScopedPipe;
68
69 friend class ScopedPipe;
70};
71
72} // namespace aos::util
73
74#endif // AOS_UTIL_SCOPED_PIPE_H_