Apache Mesos
write.hpp
Go to the documentation of this file.
1 // Licensed under the Apache License, Version 2.0 (the "License");
2 // you may not use this file except in compliance with the License.
3 // You may obtain a copy of the License at
4 //
5 // http://www.apache.org/licenses/LICENSE-2.0
6 //
7 // Unless required by applicable law or agreed to in writing, software
8 // distributed under the License is distributed on an "AS IS" BASIS,
9 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 // See the License for the specific language governing permissions and
11 // limitations under the License.
12 
13 #ifndef __STOUT_OS_WRITE_HPP__
14 #define __STOUT_OS_WRITE_HPP__
15 
16 #include <cstring>
17 
18 #include <stout/error.hpp>
19 #include <stout/nothing.hpp>
20 #include <stout/try.hpp>
21 
22 #include <stout/os/close.hpp>
23 #include <stout/os/int_fd.hpp>
24 #include <stout/os/open.hpp>
25 #include <stout/os/socket.hpp>
26 
27 #ifdef __WINDOWS__
29 #else
30 #include <stout/os/posix/write.hpp>
31 #endif // __WINDOWS__
32 
33 
34 namespace os {
35 
36 namespace signal_safe {
37 
38 inline ssize_t write_impl(int_fd fd, const char* buffer, size_t count)
39 {
40  size_t offset = 0;
41 
42  while (offset < count) {
43  ssize_t length = os::write(fd, buffer + offset, count - offset);
44 
45  if (length < 0) {
46 #ifdef __WINDOWS__
47  int error = WSAGetLastError();
48 #else
49  int error = errno;
50 #endif // __WINDOWS__
51 
52  // TODO(benh): Handle a non-blocking fd? (EAGAIN, EWOULDBLOCK).
53  if (net::is_restartable_error(error)) {
54  continue;
55  }
56  return -1;
57  }
58 
59  offset += length;
60  }
61 
62  return offset;
63 }
64 
65 
66 inline ssize_t write(int_fd fd, const char* message)
67 {
68  // `strlen` declared as async-signal safe in POSIX.1-2016 standard.
69  return write_impl(fd, message, std::strlen(message));
70 }
71 
72 
73 inline ssize_t write(int_fd fd, const std::string& message)
74 {
75  return write_impl(fd, message.data(), message.length());
76 }
77 
78 
79 template <typename T, typename... Args>
80 inline ssize_t write(int_fd fd, const T& message, Args... args)
81 {
82  ssize_t result = write(fd, message);
83  if (result < 0) {
84  return result;
85  }
86 
87  return write(fd, args...);
88 }
89 
90 } // namespace signal_safe {
91 
92 
93 // Write out the string to the file at the current fd position.
94 inline Try<Nothing> write(int_fd fd, const std::string& message)
95 {
96  ssize_t result = signal_safe::write(fd, message);
97  if (result < 0) {
98  return ErrnoError();
99  }
100 
101  return Nothing();
102 }
103 
104 
105 // A wrapper function that wraps the above write() with
106 // open and closing the file.
107 inline Try<Nothing> write(const std::string& path, const std::string& message)
108 {
109  Try<int_fd> fd = os::open(
110  path,
113 
114  if (fd.isError()) {
115  return ErrnoError("Failed to open file '" + path + "'");
116  }
117 
118  Try<Nothing> result = write(fd.get(), message);
119 
120  // We ignore the return value of close(). This is because users
121  // calling this function are interested in the return value of
122  // write(). Also an unsuccessful close() doesn't affect the write.
123  os::close(fd.get());
124 
125  return result;
126 }
127 
128 
129 // NOTE: This overload is necessary to disambiguate between arguments
130 // of type `HANDLE` (`typedef void*`) and `char*` on Windows.
131 inline Try<Nothing> write(const char* path, const std::string& message)
132 {
133  return write(std::string(path), message);
134 }
135 
136 } // namespace os {
137 
138 
139 #endif // __STOUT_OS_WRITE_HPP__
SSIZE_T ssize_t
Definition: windows.hpp:192
#define O_WRONLY
Definition: fcntl.hpp:26
Definition: nothing.hpp:16
#define O_TRUNC
Definition: fcntl.hpp:29
const mode_t S_IRGRP
Definition: windows.hpp:319
Definition: try.hpp:34
#define O_CLOEXEC
Definition: fcntl.hpp:31
ssize_t write(const WindowsFD &fd, const void *data, size_t size)
Definition: write.hpp:29
const mode_t S_IWUSR
Definition: windows.hpp:312
Definition: errorbase.hpp:49
#define O_CREAT
Definition: fcntl.hpp:28
const mode_t S_IRUSR
Definition: windows.hpp:311
bool is_restartable_error(int error)
Definition: socket.hpp:33
Try< Nothing > close(int fd)
Definition: close.hpp:24
ssize_t write_impl(int_fd fd, const char *buffer, size_t count)
Definition: write.hpp:38
bool isError() const
Definition: try.hpp:71
Try< int_fd > open(const std::string &path, int oflag, mode_t mode=0)
Definition: open.hpp:39
std::string error(const std::string &msg, uint32_t code)
int int_fd
Definition: int_fd.hpp:35
const mode_t S_IROTH
Definition: windows.hpp:327
const T & get() const
Definition: try.hpp:73
ssize_t write(int_fd fd, const char *message)
Definition: write.hpp:66