2 // Automated Testing Framework (atf)
4 // Copyright (c) 2007, 2008 The NetBSD Foundation, Inc.
5 // All rights reserved.
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions
10 // 1. Redistributions of source code must retain the above copyright
11 // notice, this list of conditions and the following disclaimer.
12 // 2. Redistributions in binary form must reproduce the above copyright
13 // notice, this list of conditions and the following disclaimer in the
14 // documentation and/or other materials provided with the distribution.
16 // THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
17 // CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
18 // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 // IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
21 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
23 // GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 // IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26 // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 // IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 #if !defined(_ATF_CXX_IO_HPP_)
31 #define _ATF_CXX_IO_HPP_
37 #include <atf-c++/fs.hpp>
38 #include <atf-c++/utils.hpp>
43 // ------------------------------------------------------------------------
44 // The "file_handle" class.
45 // ------------------------------------------------------------------------
48 //! \brief Simple RAII model for system file handles.
50 //! The \a file_handle class is a simple RAII model for native system file
51 //! handles. This class wraps one of such handles grabbing its ownership,
52 //! and automaticaly closes it upon destruction. It is basically used
53 //! inside the library to avoid leaking open file handles, shall an
54 //! unexpected execution trace occur.
56 //! A \a file_handle object can be copied but doing so invalidates the
57 //! source object. There can only be a single valid \a file_handle object
58 //! for a given system file handle. This is similar to std::auto_ptr\<\>'s
61 //! This class also provides some convenience methods to issue special file
62 //! operations under their respective platforms.
68 //! \brief Opaque name for the native handle type.
70 //! Each operating system identifies file handles using a specific type.
71 //! The \a handle_type type is used to transparently refer to file
72 //! handles regarless of the operating system in which this class is
75 //! If this class is used in a POSIX system, \a NativeSystemHandle is
76 //! an integer type while it is a \a HANDLE in a Win32 system.
78 typedef int handle_type
;
81 //! \brief Constructs an invalid file handle.
83 //! This constructor creates a new \a file_handle object that represents
84 //! an invalid file handle. An invalid file handle can be copied but
85 //! cannot be manipulated in any way (except checking for its validity).
92 //! \brief Constructs a new file handle from a native file handle.
94 //! This constructor creates a new \a file_handle object that takes
95 //! ownership of the given \a h native file handle. The user must not
96 //! close \a h on his own during the lifetime of the new object.
97 //! Ownership can be reclaimed using disown().
99 //! \pre The native file handle must be valid; a close operation must
104 file_handle(handle_type h
);
107 //! \brief Copy constructor; invalidates the source handle.
109 //! This copy constructor creates a new file handle from a given one.
110 //! Ownership of the native file handle is transferred to the new
111 //! object, effectively invalidating the source file handle. This
112 //! avoids having two live \a file_handle objects referring to the
113 //! same native file handle. The source file handle need not be
114 //! valid in the name of simplicity.
116 //! \post The source file handle is invalid.
117 //! \post The new file handle owns the source's native file handle.
119 file_handle(const file_handle
& fh
);
122 //! \brief Releases resources if the handle is valid.
124 //! If the file handle is valid, the destructor closes it.
131 //! \brief Assignment operator; invalidates the source handle.
133 //! This assignment operator transfers ownership of the RHS file
134 //! handle to the LHS one, effectively invalidating the source file
135 //! handle. This avoids having two live \a file_handle objects
136 //! referring to the same native file handle. The source file
137 //! handle need not be valid in the name of simplicity.
139 //! \post The RHS file handle is invalid.
140 //! \post The LHS file handle owns RHS' native file handle.
141 //! \return A reference to the LHS file handle.
143 file_handle
& operator=(const file_handle
& fh
);
146 //! \brief Checks whether the file handle is valid or not.
148 //! Returns a boolean indicating whether the file handle is valid or
149 //! not. If the file handle is invalid, no other applications can be
150 //! executed other than the destructor.
152 //! \return True if the file handle is valid; false otherwise.
154 bool is_valid(void) const;
157 //! \brief Closes the file handle.
159 //! Explicitly closes the file handle, which must be valid. Upon
160 //! exit, the handle is not valid any more.
162 //! \pre The file handle is valid.
163 //! \post The file handle is invalid.
164 //! \post The native file handle is closed.
169 //! \brief Reclaims ownership of the native file handle.
171 //! Explicitly reclaims ownership of the native file handle contained
172 //! in the \a file_handle object, returning the native file handle.
173 //! The caller is responsible of closing it later on.
175 //! \pre The file handle is valid.
176 //! \post The file handle is invalid.
177 //! \return The native file handle.
179 handle_type
disown(void);
182 //! \brief Gets the native file handle.
184 //! Returns the native file handle for the \a file_handle object.
185 //! The caller can issue any operation on it except closing it.
186 //! If closing is required, disown() shall be used.
188 //! \pre The file handle is valid.
189 //! \return The native file handle.
191 handle_type
get(void) const;
194 //! \brief Changes the native file handle to the given one.
196 //! Given a new native file handle \a h, this operation assigns this
197 //! handle to the current object, closing its old native file handle.
198 //! In other words, it first calls dup2() to remap the old handle to
199 //! the new one and then closes the old handle.
201 //! If \a h matches the current value of the handle, this is a no-op.
202 //! This is done for simplicity, to avoid the caller having to check
203 //! this condition on its own.
205 //! If \a h is open, it is automatically closed by dup2().
207 //! This operation is only available in POSIX systems.
209 //! \pre The file handle is valid.
210 //! \pre The native file handle \a h is valid; i.e., it must be
212 //! \post The file handle's native file handle is \a h.
213 //! \throw system_error If the internal remapping operation fails.
215 void posix_remap(handle_type h
);
219 //! \brief Internal handle value.
221 //! This variable holds the native handle value for the file handle
222 //! hold by this object. It is interesting to note that this needs
223 //! to be mutable because the copy constructor and the assignment
224 //! operator invalidate the source object.
226 mutable handle_type m_handle
;
229 //! \brief Constant function representing an invalid handle value.
231 //! Returns the platform-specific handle value that represents an
232 //! invalid handle. This is a constant function rather than a regular
233 //! constant because, in the latter case, we cannot define it under
234 //! Win32 due to the value being of a complex type.
236 static handle_type
invalid_value(void);
239 // ------------------------------------------------------------------------
240 // The "systembuf" class.
241 // ------------------------------------------------------------------------
244 //! \brief std::streambuf implementation for system file handles.
246 //! systembuf provides a std::streambuf implementation for system file
247 //! handles. Contrarywise to file_handle, this class does \b not take
248 //! ownership of the native file handle; this should be taken care of
251 //! This class follows the expected semantics of a std::streambuf object.
252 //! However, it is not copyable to avoid introducing inconsistences with
253 //! the on-disk file and the in-memory buffers.
256 public std::streambuf
, utils::noncopyable
259 typedef int handle_type
;
262 //! \brief Constructs a new systembuf for the given file handle.
264 //! This constructor creates a new systembuf object that reads or
265 //! writes data from/to the \a h native file handle. This handle
266 //! is \b not owned by the created systembuf object; the code
267 //! should take care of it externally.
269 //! This class buffers input and output; the buffer size may be
270 //! tuned through the \a bufsize parameter, which defaults to 8192
273 //! \see pistream and postream.
275 explicit systembuf(handle_type h
, std::size_t bufsize
= 8192);
280 //! \brief Native file handle used by the systembuf object.
282 handle_type m_handle
;
285 //! \brief Internal buffer size used during read and write operations.
287 std::size_t m_bufsize
;
290 //! \brief Internal buffer used during read operations.
295 //! \brief Internal buffer used during write operations.
301 //! \brief Reads new data from the native file handle.
303 //! This operation is called by input methods when there are no more
304 //! data in the input buffer. The function fills the buffer with new
305 //! data, if available.
307 //! \pre All input positions are exhausted (gptr() >= egptr()).
308 //! \post The input buffer has new data, if available.
309 //! \returns traits_type::eof() if a read error occurrs or there are
310 //! no more data to be read. Otherwise returns
311 //! traits_type::to_int_type(*gptr()).
313 virtual int_type
underflow(void);
316 //! \brief Makes room in the write buffer for additional data.
318 //! This operation is called by output methods when there is no more
319 //! space in the output buffer to hold a new element. The function
320 //! first flushes the buffer's contents to disk and then clears it to
321 //! leave room for more characters. The given \a c character is
322 //! stored at the beginning of the new space.
324 //! \pre All output positions are exhausted (pptr() >= epptr()).
325 //! \post The output buffer has more space if no errors occurred
326 //! during the write to disk.
327 //! \post *(pptr() - 1) is \a c.
328 //! \returns traits_type::eof() if a write error occurrs. Otherwise
329 //! returns traits_type::not_eof(c).
331 virtual int_type
overflow(int c
);
334 //! \brief Flushes the output buffer to disk.
336 //! Synchronizes the systembuf buffers with the contents of the file
337 //! associated to this object through the native file handle. The
338 //! output buffer is flushed to disk and cleared to leave new room
341 //! \returns 0 on success, -1 if an error occurred.
343 virtual int sync(void);
346 // ------------------------------------------------------------------------
348 // ------------------------------------------------------------------------
351 //! \brief Simple RAII model for anonymous pipes.
353 //! The pipe class is a simple RAII model for anonymous pipes. It
354 //! provides a portable constructor that allocates a new %pipe and creates
355 //! a pipe object that owns the two file handles associated to it: the
356 //! read end and the write end.
358 //! These handles can be retrieved for modification according to
359 //! file_handle semantics. Optionally, their ownership can be transferred
360 //! to external \a file_handle objects which comes handy when the two
361 //! ends need to be used in different places (i.e. after a POSIX fork()
364 //! Pipes can be copied following the same semantics as file handles.
365 //! In other words, copying a %pipe object invalidates the source one.
372 //! \brief The %pipe's read end file handle.
374 file_handle m_read_end
;
377 //! \brief The %pipe's write end file handle.
379 file_handle m_write_end
;
383 //! \brief Creates a new %pipe.
385 //! The default pipe constructor allocates a new anonymous %pipe
386 //! and assigns its ownership to the created pipe object.
388 //! \throw system_error If the anonymous %pipe creation fails.
393 //! \brief Returns the %pipe's read end file handle.
395 //! Obtains a reference to the %pipe's read end file handle. Care
396 //! should be taken to not duplicate the returned object if ownership
397 //! shall remain to the %pipe.
399 //! Duplicating the returned object invalidates its corresponding file
400 //! handle in the %pipe.
402 //! \return A reference to the %pipe's read end file handle.
404 file_handle
& rend(void);
407 //! \brief Returns the %pipe's write end file handle.
409 //! Obtains a reference to the %pipe's write end file handle. Care
410 //! should be taken to not duplicate the returned object if ownership
411 //! shall remain to the %pipe.
413 //! Duplicating the returned object invalidates its corresponding file
414 //! handle in the %pipe.
416 //! \return A reference to the %pipe's write end file handle.
418 file_handle
& wend(void);
421 // ------------------------------------------------------------------------
422 // The "pistream" class.
423 // ------------------------------------------------------------------------
426 //! \brief Child process' output stream.
428 //! The pistream class represents an output communication channel with the
429 //! child process. The child process writes data to this stream and the
430 //! parent process can read it through the pistream object. In other
431 //! words, from the child's point of view, the communication channel is an
432 //! output one, but from the parent's point of view it is an input one;
433 //! hence the confusing pistream name.
435 //! pistream objects cannot be copied because they own the file handle
436 //! they use to communicate with the child and because they buffer data
437 //! that flows through the communication channel.
439 //! A pistream object behaves as a std::istream stream in all senses.
440 //! The class is only provided because it must provide a method to let
441 //! the caller explicitly close the communication channel.
443 //! \remark <b>Blocking remarks</b>: Functions that read data from this
444 //! stream can block if the associated file handle blocks during the read.
445 //! As this class is used to communicate with child processes through
446 //! anonymous pipes, the most typical blocking condition happens when the
447 //! child has no more data to send to the pipe's system buffer. When
448 //! this happens, the buffer eventually empties and the system blocks
449 //! until the writer generates some data.
452 public std::istream
, utils::noncopyable
455 //! \brief The file handle managed by this stream.
457 file_handle m_handle
;
460 //! \brief The systembuf object used to manage this stream's data.
462 systembuf m_systembuf
;
466 //! \brief Creates a new process' output stream.
468 //! Given a file handle, this constructor creates a new pistream
469 //! object that owns the given file handle \a fh. Ownership of
470 //! \a fh is transferred to the created pistream object.
472 //! \pre \a fh is valid.
473 //! \post \a fh is invalid.
474 //! \post The new pistream object owns \a fh.
476 explicit pistream(file_handle
& fh
);
479 //! \brief Closes the file handle managed by this stream.
481 //! Explicitly closes the file handle managed by this stream. This
482 //! function can be used by the user to tell the child process it's
483 //! not willing to receive more data.
488 //! \brief Returns the file descriptor attached to this stream.
490 file_handle
& handle(void);
493 // ------------------------------------------------------------------------
494 // The "postream" class.
495 // ------------------------------------------------------------------------
498 //! \brief Child process' input stream.
500 //! The postream class represents an input communication channel with the
501 //! child process. The child process reads data from this stream and the
502 //! parent process can write to it through the postream object. In other
503 //! words, from the child's point of view, the communication channel is an
504 //! input one, but from the parent's point of view it is an output one;
505 //! hence the confusing postream name.
507 //! postream objects cannot be copied because they own the file handle
508 //! they use to communicate with the child and because they buffer data
509 //! that flows through the communication channel.
511 //! A postream object behaves as a std::ostream stream in all senses.
512 //! The class is only provided because it must provide a method to let
513 //! the caller explicitly close the communication channel.
515 //! \remark <b>Blocking remarks</b>: Functions that write data to this
516 //! stream can block if the associated file handle blocks during the write.
517 //! As this class is used to communicate with child processes through
518 //! anonymous pipes, the most typical blocking condition happens when the
519 //! child is not processing the data in the pipe's system buffer. When
520 //! this happens, the buffer eventually fills up and the system blocks
521 //! until the reader consumes some data, leaving some new room.
524 public std::ostream
, utils::noncopyable
527 //! \brief The file handle managed by this stream.
529 file_handle m_handle
;
532 //! \brief The systembuf object used to manage this stream's data.
534 systembuf m_systembuf
;
538 //! \brief Creates a new process' input stream.
540 //! Given a file handle, this constructor creates a new postream
541 //! object that owns the given file handle \a fh. Ownership of
542 //! \a fh is transferred to the created postream object.
544 //! \pre \a fh is valid.
545 //! \post \a fh is invalid.
546 //! \post The new postream object owns \a fh.
548 explicit postream(file_handle
& fh
);
551 //! \brief Closes the file handle managed by this stream.
553 //! Explicitly closes the file handle managed by this stream. This
554 //! function can be used by the user to tell the child process there
555 //! is no more data to send.
560 //! \brief Returns the file descriptor attached to this stream.
562 file_handle
& handle(void);
565 // ------------------------------------------------------------------------
566 // The "unbuffered_istream" class.
567 // ------------------------------------------------------------------------
570 //! \brief An unbuffered input stream.
572 //! The unbuffered_istream class somewhat mimics the interface of
573 //! std::istream, but it provides unbuffered access to its attached
574 //! file descriptor. This is required in those situations where poll(2)
575 //! is needed, because buffering data will mangle the events reported by
576 //! this system call and break algorithms mysteriously on some platforms.
578 class unbuffered_istream
{
580 //! \brief The file descriptor attached to this stream.
585 //! \brief Whether the stream is good or not.
591 //! \brief Constructs a new unbuffered input stream.
593 //! Given a file handle, constructs a new unbuffered input stream to
594 //! handle it and takes ownership of that handle.
596 unbuffered_istream(file_handle
& fh
);
599 //! \brief Returns a reference to this stream's file handle.
601 file_handle
& get_fh(void);
604 //! \brief Checks whether the stream is good or not for reading.
606 bool good(void) const;
609 //! \brief Reads unformatted data.
611 //! Reads data from this stream onto the buffer specified and returns
612 //! the amount of data read. To detect errors, check for the stream's
613 //! status using the good method after a call to this function.
615 size_t read(void*, size_t);
618 //! \brief Closes the stream.
623 // ------------------------------------------------------------------------
625 // ------------------------------------------------------------------------
628 //! \brief Unbuffered getline implementation.
630 //! Reads a text line from the given stream without buffering any data.
631 //! This is inefficient but is the only way to safely use poll(2)...
633 unbuffered_istream
& getline(unbuffered_istream
&, std::string
&);
635 int cmp(const fs::path
&, const fs::path
&);
640 #endif // !defined(_ATF_CXX_IO_HPP_)