:mod:`os` -- basic "operating system" services
==============================================

.. module:: os
   :synopsis: basic "operating system" services

|see_cpython_module| :mod:`python:os`.

The ``os`` module contains functions for filesystem access and mounting,
terminal redirection and duplication, and the ``uname`` and ``urandom``
functions.

General functions
-----------------

.. function:: uname()

   Return a tuple (possibly a named tuple) containing information about the
   underlying machine and/or its operating system.  The tuple has five fields
   in the following order, each of them being a string:

        * ``sysname`` -- the name of the underlying system
        * ``nodename`` -- the network name (can be the same as ``sysname``)
        * ``release`` -- the version of the underlying system
        * ``version`` -- the MicroPython version and build date
        * ``machine`` -- an identifier for the underlying hardware (eg board, CPU)

.. function:: urandom(n)

   Return a bytes object with *n* random bytes. Whenever possible, it is
   generated by the hardware random number generator.

Filesystem access
-----------------

.. function:: chdir(path)

   Change current directory.

.. function:: getcwd()

   Get the current directory.

.. function:: ilistdir([dir])

   This function returns an iterator which then yields tuples corresponding to
   the entries in the directory that it is listing.  With no argument it lists the
   current directory, otherwise it lists the directory given by *dir*.

   The tuples have the form *(name, type, inode[, size])*:

    - *name* is a string (or bytes if *dir* is a bytes object) and is the name of
      the entry;
    - *type* is an integer that specifies the type of the entry, with 0x4000 for
      directories and 0x8000 for regular files;
    - *inode* is an integer corresponding to the inode of the file, and may be 0
      for filesystems that don't have such a notion.
    - Some platforms may return a 4-tuple that includes the entry's *size*.  For
      file entries, *size* is an integer representing the size of the file
      or -1 if unknown.  Its meaning is currently undefined for directory
      entries.

.. function:: listdir([dir])

   With no argument, list the current directory.  Otherwise list the given directory.

.. function:: mkdir(path)

   Create a new directory.

.. function:: remove(path)

   Remove a file.

.. function:: rmdir(path)

   Remove a directory.

.. function:: rename(old_path, new_path)

   Rename a file.

.. function:: stat(path)

   Get the status of a file or directory.

.. function:: statvfs(path)

   Get the status of a filesystem.

   Returns a tuple with the filesystem information in the following order:

        * ``f_bsize`` -- file system block size
        * ``f_frsize`` -- fragment size
        * ``f_blocks`` -- size of fs in f_frsize units
        * ``f_bfree`` -- number of free blocks
        * ``f_bavail`` -- number of free blocks for unprivileged users
        * ``f_files`` -- number of inodes
        * ``f_ffree`` -- number of free inodes
        * ``f_favail`` -- number of free inodes for unprivileged users
        * ``f_flag`` -- mount flags
        * ``f_namemax`` -- maximum filename length

   Parameters related to inodes: ``f_files``, ``f_ffree``, ``f_avail``
   and the ``f_flags`` parameter may return ``0`` as they can be unavailable
   in a port-specific implementation.

.. function:: sync()

   Sync all filesystems.

Terminal redirection and duplication
------------------------------------

.. function:: dupterm(stream_object, index=0, /)

   Duplicate or switch the MicroPython terminal (the REPL) on the given `stream`-like
   object. The *stream_object* argument must be a native stream object, or derive
   from ``io.IOBase`` and implement the ``readinto()`` and
   ``write()`` methods.  The stream should be in non-blocking mode and
   ``readinto()`` should return ``None`` if there is no data available for reading.

   After calling this function all terminal output is repeated on this stream,
   and any input that is available on the stream is passed on to the terminal input.

   The *index* parameter should be a non-negative integer and specifies which
   duplication slot is set.  A given port may implement more than one slot (slot 0
   will always be available) and in that case terminal input and output is
   duplicated on all the slots that are set.

   If ``None`` is passed as the *stream_object* then duplication is cancelled on
   the slot given by *index*.

   The function returns the previous stream-like object in the given slot.

.. function:: dupterm_notify(obj_in, /)

    Notify the MicroPython REPL that input is available on a stream-like object
    previously registered via `os.dupterm()`.

    This function should be called by custom stream implementations (e.g., UART,
    Bluetooth, or other non-USB REPL streams) to inform the REPL that input is
    ready to be read. Proper use ensures that special characters such as
    Ctrl+C (used to trigger KeyboardInterrupt) are processed promptly by the
    REPL, enabling expected interruption behavior for user code.

    The *obj_in* parameter is ignored by `os.dupterm_notify()`, but is required to allow calling
    dupterm_notify from an interrupt handler such as `UART.irq()`.

    Example:

    .. code-block:: python

        from machine import UART
        import os
        uart = UART(0)
        os.dupterm(uart, 0)
        uart.irq(os.dupterm_notify, machine.UART.IRQ_RX)

    .. note::
        If the ``dupterm_notify()`` function is not called, input from the custom stream
        may not be detected or processed until the next REPL poll, potentially delaying
        KeyboardInterrupts or other control signals.
        This is especially important for UART, Bluetooth and other
        non-standard REPL connections, where automatic notification is not guaranteed.

Filesystem mounting
-------------------

The following functions and classes have been moved to the :mod:`vfs` module.
They are provided in this module only for backwards compatibility and will be
removed in version 2 of MicroPython.

.. function:: mount(fsobj, mount_point, *, readonly)

    See `vfs.mount`.

.. function:: umount(mount_point)

    See `vfs.umount`.

.. class:: VfsFat(block_dev)

    See `vfs.VfsFat`.

.. class:: VfsLfs1(block_dev, readsize=32, progsize=32, lookahead=32)

    See `vfs.VfsLfs1`.

.. class:: VfsLfs2(block_dev, readsize=32, progsize=32, lookahead=32, mtime=True)

    See `vfs.VfsLfs2`.

.. class:: VfsPosix(root=None)

    See `vfs.VfsPosix`.
