Index: uspace/lib/cpp/Makefile
===================================================================
--- uspace/lib/cpp/Makefile	(revision 7fb91dee8b143dccc9445e2f608d7034562ada01)
+++ uspace/lib/cpp/Makefile	(revision 7db6f5081e77d98fffe78697468eaec9f2537ba0)
@@ -40,4 +40,5 @@
 SOURCES = \
 	src/exception.cpp \
+	src/ios.cpp \
 	src/new.cpp \
 	src/string.cpp \
Index: uspace/lib/cpp/include/impl/ios.hpp
===================================================================
--- uspace/lib/cpp/include/impl/ios.hpp	(revision 7fb91dee8b143dccc9445e2f608d7034562ada01)
+++ uspace/lib/cpp/include/impl/ios.hpp	(revision 7db6f5081e77d98fffe78697468eaec9f2537ba0)
@@ -33,4 +33,6 @@
 #include <locale>
 #include <system_error>
+#include <utility>
+#include <vector>
 
 namespace std
@@ -64,20 +66,20 @@
              */
 
-            using fmtflags = uint32_t;
-            static constexpr fmtflags boolalpha   = 0b00'0000'0000'0000'0001;
-            static constexpr fmtflags dec         = 0b00'0000'0000'0000'0010;
-            static constexpr fmtflags fixed       = 0b00'0000'0000'0000'0100;
-            static constexpr fmtflags hex         = 0b00'0000'0000'0000'1000;
-            static constexpr fmtflags internal    = 0b00'0000'0000'0001'0000;
-            static constexpr fmtflags left        = 0b00'0000'0000'0010'0000;
-            static constexpr fmtflags oct         = 0b00'0000'0000'0100'0000;
-            static constexpr fmtflags right       = 0b00'0000'0000'1000'0000;
-            static constexpr fmtflags scientific  = 0b00'0000'0001'0000'0000;
-            static constexpr fmtflags showbase    = 0b00'0000'0010'0000'0000;
-            static constexpr fmtflags showpoint   = 0b00'0000'0100'0000'0000;
-            static constexpr fmtflags showpos     = 0b00'0000'1000'0000'0000;
-            static constexpr fmtflags skipws      = 0b00'0001'0000'0000'0000;
-            static constexpr fmtflags unitbuf     = 0b00'0010'0000'0000'0000;
-            static constexpr fmtflags uppercase   = 0b00'0100'0000'0000'0000;
+            using fmtflags = uint16_t;
+            static constexpr fmtflags boolalpha   = 0b'0000'0000'0000'0001;
+            static constexpr fmtflags dec         = 0b'0000'0000'0000'0010;
+            static constexpr fmtflags fixed       = 0b'0000'0000'0000'0100;
+            static constexpr fmtflags hex         = 0b'0000'0000'0000'1000;
+            static constexpr fmtflags internal    = 0b'0000'0000'0001'0000;
+            static constexpr fmtflags left        = 0b'0000'0000'0010'0000;
+            static constexpr fmtflags oct         = 0b'0000'0000'0100'0000;
+            static constexpr fmtflags right       = 0b'0000'0000'1000'0000;
+            static constexpr fmtflags scientific  = 0b'0000'0001'0000'0000;
+            static constexpr fmtflags showbase    = 0b'0000'0010'0000'0000;
+            static constexpr fmtflags showpoint   = 0b'0000'0100'0000'0000;
+            static constexpr fmtflags showpos     = 0b'0000'1000'0000'0000;
+            static constexpr fmtflags skipws      = 0b'0001'0000'0000'0000;
+            static constexpr fmtflags unitbuf     = 0b'0010'0000'0000'0000;
+            static constexpr fmtflags uppercase   = 0b'0100'0000'0000'0000;
             static constexpr fmtflags adjustfield = left | right | internal;
             static constexpr fmtflags basefield   = dec  | oct   | hex;
@@ -121,5 +123,10 @@
             class Init
             {
-                // TODO: implement
+                public:
+                    Init();
+                    ~Init();
+
+                private:
+                    static int init_cnt{};
             };
 
@@ -150,5 +157,12 @@
              */
 
-            static int xalloc();
+            static int xalloc()
+            {
+                // TODO: Concurrent access to this function
+                //       by multiple threads shall not result
+                //       in a data race.
+                return index_++;
+            }
+
             long& iword(int index);
             void*& pword(int index);
@@ -168,5 +182,11 @@
             void register_callback(event_callback fn, int index);
 
-            static bool sync_with_stdio(bool sync = true);
+            static bool sync_with_stdio(bool sync = true)
+            {
+                auto old = sync_;
+                sync_ = sync;
+
+                return old;
+            }
 
         protected:
@@ -175,8 +195,357 @@
         private:
             static int index_{};
+            static bool sync_{true};
+
+            static long ierror_{0};
+            static long perror_{nullptr};
+            static constexpr size_t initial_size_{10};
 
             long* iarray_;
             void** parray_;
+            size_t iarray_size_;
+            size_t parray_size_;
+
+            fmtflags flags_;
+            streamsize precision_;
+            streamsize width_;
+            locale locale_;
+
+            vector<pair<event_callback, int>> callbacks_;
     };
+
+    /**
+     * 27.5.4, fpos:
+     */
+
+    template<class State>
+    class fpos
+    {
+        public:
+            State state() const
+            {
+                return state_;
+            }
+
+            void state(State st)
+            {
+                state_ = st;
+            }
+
+        private:
+            State state_;
+    };
+
+    /**
+     * 27.5.4.2, fpos requirements:
+     */
+
+    // TODO: implement
+
+    /**
+     * 27.5.5, basic_ios:
+     */
+
+    template<class Char, class Traits = char_traits<Char>>
+    class basic_ios: public ios_base
+    {
+        public:
+            using traits_type = Traits;
+            using char_type   = Char;
+            using int_type    = typename traits_type::int_type;
+            using pos_type    = typename traits_type::pos_type;
+            using off_type    = typename traits_type::off_type;
+
+            basic_ios(const basic_ios&) = delete;
+            basic_ios& operator=(const basic_ios&) = delete;
+
+            explicit operator bool() const
+            {
+                return !fail();
+            }
+
+            bool operator!() const
+            {
+                return fail();
+            }
+
+            iostate rdstate() const
+            {
+                return rdstate_;
+            }
+
+            void clear(iostate state = goodbit)
+            {
+                if (rdbuf_)
+                    rdstate_ = state;
+                else
+                    rdstate_ = state | badbit;
+
+                if (((state | (rdbuf_ ? goodbit | badbit)) & exceptions_) == 0)
+                    return;
+                // TODO: Else throw failure.
+                return;
+            }
+
+            void setstate(iostate state)
+            {
+                clear(rdstate_ | state);
+            }
+
+            bool good() const
+            {
+                return rdstate_ == 0;
+            }
+
+            bool eof() const
+            {
+                return (rdstate_ & eofbit) != 0;
+            }
+
+            bool fail() const
+            {
+                return (rdstate_ & (failbit | badbit)) != 0;
+            }
+
+            bool bad() const
+            {
+                return (rdstate_ & badbit) != 0;
+            }
+
+            iostate exceptions() const
+            {
+                return exceptions_;
+            }
+
+            void exceptions(iostate except)
+            {
+                exceptions_ = except;
+                clear(rdstate_);
+            }
+
+            /**
+             * 27.5.5.2, constructor/destructor:
+             */
+
+            explicit basic_ios(basic_streambuf<Char, Traits>* sb)
+            {
+                init(sb);
+            }
+
+            virtual ~basic_ios()
+            { /* DUMMY BODY */ }
+
+            /**
+             * 27.5.5.3, members:
+             */
+
+            basic_ostream<Char, Traits>* tie() const
+            {
+                return tie_;
+            }
+
+            basic_ostream<Char, Traits>* tie(basic_ostream<Char, Traits>* tiestr)
+            {
+                auto old = tie_;
+                tie_ = tiestr;
+
+                return old;
+            }
+
+            basic_streambuf<Char, Traits>* rdbuf() const
+            {
+                return rdbuf_;
+            }
+
+            basic_streambuf<Char, Traits>* rdbuf(basic_streambuf<Char, Traits>* sb)
+            {
+                auto old = rdbuf_;
+                rdbuf_ = sb;
+
+                clear();
+
+                return old;
+            }
+
+            basic_ios& copyfmt(const basic_ios& rhs)
+            {
+                if (this == &rhs)
+                    return *this;
+
+                for (auto& callback: callbacks_)
+                    callback.first(erase_event, *this, index_);
+
+                tie_        = rhs.tie_;
+                flags_      = rhs.flags_;
+                width_      = rhs.width_;
+                precision_  = rhs.precision_;
+                fille_      = rhs.fill_;
+                locale_     = rhs.locale_;
+
+                delete[] iarray;
+                iarray_size_ = rhs.iarray_size_;
+                iarray_ = new long[iarray_size_];
+
+                for (size_t i = 0; i < iarray_size_; ++i)
+                    iarrai_[i] = rhs.iarray_[i];
+
+                delete[] parray;
+                parray_size_ = rhs.parray_size_;
+                parray_ = new long[parray_size_];
+
+                for (size_t i = 0; i < parray_size_; ++i)
+                    iarrai_[i] = rhs.parray_[i];
+
+                for (auto& callback: callbacks_)
+                    callback.first(copyfmt_event, *this, index_);
+
+                exceptions(rhs.exceptions());
+            }
+
+            char_type fill() const
+            {
+                return fill_;
+            }
+
+            char_type fill(char_type c)
+            {
+                char_type old;
+                traits_type::assign(old, fill_);
+                traits_type::assign(fill_, c);
+
+                return old;
+            }
+
+            locale imbue(const locale& loc)
+            {
+                auto res = ios_base::imbue(loc);
+
+                if (rdbuf_)
+                    rdbuf_->pubimbue(loc);
+
+                return res;
+            }
+
+            char narrow(char_type c, char def) const
+            {
+                return use_facet<ctype<char_type>>(locale_).narrow(c, def);
+            }
+
+            char_type widen(char c) const
+            {
+                return use_facet<ctype<char_type>>(locale_).widen(c);
+            }
+
+        protected:
+            basic_ios()
+            { /* DUMMY BODY */ }
+
+            void init(basic_streambuf<Char, Traits>* sb)
+            {
+                // Initialized according to Table 128.
+                rdbuf_ = sb;
+                tie_ = nullptr;
+                rdstate_ = sb ? goodbit : badbit;
+                exceptions_ = goodbit;
+                flags(skipws | dec);
+
+                width(0);
+                precision(6);
+
+                fill_ = widen(' ');
+                locale_ = locale();
+
+                iarray = nullptr;
+                parray = nullptr
+            }
+
+            void move(basic_ios& rhs)
+            {
+                rdbuf_      = nullptr; // rhs keeps it!
+                tie_        = rhs.tie_;
+                exceptions_ = rhs.exceptions_;
+                flags_      = rhs.flags_;
+                width_      = rhs.width_;
+                precision_  = rhs.precision_;
+                fill_       = rhs.fill_;
+                locale_     = move(rhs.locale_);
+                rdstate_    = rhs.rdstate_;
+                callbacks_  = move(rhs.callbacks_);
+
+                delete[] iarray_;
+                iarray_      = rhs.iarray_;
+                iarray_size_ = rhs.iarray_size_;
+
+                delete[] parray_;
+                parray_      = rhs.parray_;
+                parray_size_ = rhs.parray_size_;
+
+                rhs.tie_ = nullptr;
+                rhs.iarray_ = nullptr;
+                rhs.parray_ = nullptr;
+            }
+
+            void move(basic_ios&& rhs)
+            {
+                rdbuf_      = nullptr; // rhs keeps it!
+                tie_        = rhs.tie_;
+                exceptions_ = rhs.exceptions_;
+                flags_      = rhs.flags_;
+                width_      = rhs.width_;
+                precision_  = rhs.precision_;
+                fill_       = rhs.fill_;
+                locale_     = move(rhs.locale_);
+                rdstate_    = rhs.rdstate_;
+                callbacks_.swap(rhs.callbacks_);
+
+                delete[] iarray_;
+                iarray_      = rhs.iarray_;
+                iarray_size_ = rhs.iarray_size_;
+
+                delete[] parray_;
+                parray_      = rhs.parray_;
+                parray_size_ = rhs.parray_size_;
+
+                rhs.tie_ = nullptr;
+                rhs.iarray_ = nullptr;
+                rhs.parray_ = nullptr;
+            }
+
+            void swap(basic_ios& rhs) noexcept
+            {
+                // Swap everything but rdbuf_.
+                swap(tie_, rhs.tie_);
+                swap(exceptions_, rhs.exceptions_);
+                swap(flags_, rhs.flags_);
+                swap(width_, rhs.width_);
+                swap(precision_, rhs.precision_);
+                swap(fill_, rhs.fill_);
+                swap(locale_, rhs.locale_);
+                swap(rdstate_, rhs.rdstate_);
+                swap(callbacks_, rhs.callbacks_);
+                swap(iarray_);
+                swap(iarray_size_);
+                swap(parray_);
+                swap(parray_size_)
+            }
+
+            void set_rdbuf(basic_streambuf<Char, Traits>* sb)
+            {
+                // No call to clear is intentional.
+                rdbuf_ = sb;
+            }
+
+        private:
+            basic_streambuf<Char, Traits>* rdbuf_;
+            basic_ostream<Char, Traits>* tie_;
+            iostate rdstate_;
+            iostate exceptions_;
+            char_type fill_;
+    };
+
+    /**
+     * 27.5.6, ios_base manipulators:
+     */
+
+    // TODO: implement
 }
 
Index: uspace/lib/cpp/src/ios.cpp
===================================================================
--- uspace/lib/cpp/src/ios.cpp	(revision 7db6f5081e77d98fffe78697468eaec9f2537ba0)
+++ uspace/lib/cpp/src/ios.cpp	(revision 7db6f5081e77d98fffe78697468eaec9f2537ba0)
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2017 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <ios>
+
+namespace std
+{
+    ios_base::ios_base()
+        : iarray_{}, parray_{}, iarray_size_{}, parray_size_{},
+          flags_{}, precision_{}, width_{}, locale_{/* TODO: use locale()? */},
+          callbacks_{}
+    { /* DUMMY BODY */ }
+
+    ~ios_base::ios_base()
+    {
+        for (auto& callback: callbacks_)
+            callback.first(erase_event, *this, callback.second);
+    }
+
+    auto ios_base::flags() -> fmtflags const
+    {
+        return flags_;
+    }
+
+    auto ios_base::flags(fmtflags fmtfl) -> fmtflags
+    {
+        auto old = flags_;
+        flags_ = fmtfl;
+
+        return old;
+    }
+
+    auto ios_base::setf(fmtflags fmtfl) -> fmtflags
+    {
+        auto old = flags_;
+        flags_ |= fmtfl;
+
+        return old;
+    }
+
+    auto ios_base::setf(fmtflags fmtfl, fmtflags mask) -> fmtflags
+    {
+        auto old = flags_;
+        flags_ &= ~mask;
+        flags_ |= fmtfl & mask;
+
+        return old;
+    }
+
+    void ios_base::unsetf(fmtflags fmtfl)
+    {
+        flags_ &= ~fmtflags;
+    }
+
+    streamsize ios_base::precision() const
+    {
+        return precision_;
+    }
+
+    streamsize ios_base::precision(streamsize prec)
+    {
+        auto old = precision_;
+        precision_ = prec;
+
+        return old;
+    }
+
+    streamsize ios_base::width() const
+    {
+        return width_;
+    }
+
+    streamsize ios_base::width(streamsize wide)
+    {
+        auto old = width_;
+        width_ = wide;
+
+        return old;
+    }
+
+    locale ios_base::imbue(const locale& loc)
+    {
+        auto old = locale_;
+        locale_ = loc;
+
+        for (auto& callback: callbacks_)
+            callback.first(imbue_event, *this, callback.second);
+
+        return old;
+    }
+
+    locale ios_base::get_loc() const
+    {
+        return locale_;
+    }
+
+    long& ios_base::iword(int index)
+    {
+        if (!iarray_)
+        {
+            iarray_ = new long[initial_size_];
+            iarray_size_ = initial_size_;
+        }
+
+        auto idx = static_cast<size_t>(index);
+        if (idx > iarray_size_)
+        { // TODO: Enclose in try block and set failbit if needed
+          //       and return ierror_.
+            size_t new_size = max(iarray_size_ * 2, idx + 1);
+            auto tmp = new long[new_size];
+
+            for (size_t i = 0; i < iarray_size_; ++i)
+                tmp[i] = iarray_[i];
+            for (size_t i = iarray_size_; i < new_size; ++i)
+                tmp[i] = 0;
+
+            swap(tmp, iarray_);
+            delete[] tmp;
+            iarray_size_ = new_size;
+
+            return iarray_[idx];
+        }
+        else
+            return iarray_[idx];
+
+        return ierror_;
+    }
+
+    void*& ios_base::pword(int index)
+    {
+        if (!parray_)
+        {
+            parray_ = new long[initial_size_];
+            parray_size_ = initial_size_;
+        }
+
+        auto idx = static_cast<size_t>(index);
+        if (idx > parray_size_)
+        { // TODO: Enclose in try block and set failbit if needed
+          //       and return perror_.
+            size_t new_size = max(parray_size_ * 2, idx + 1);
+            auto tmp = new long[new_size];
+
+            for (size_t i = 0; i < parray_size_; ++i)
+                tmp[i] = parray_[i];
+            for (size_t i = parray_size_; i < new_size; ++i)
+                tmp[i] = nullptr;
+
+            swap(tmp, parray_);
+            delete[] tmp;
+            parray_size_ = new_size;
+
+            return parray_[idx];
+        }
+        else
+            return parray_[idx];
+
+        return perror_;
+    }
+
+    void ios_base::register_callback(event_callback fn, int index)
+    {
+        callbacks.emplace_back(fn, index);
+    }
+}
