All of the real world examples you described above involve I/O. There are various approaches for this, the most popular being the IO monad.
A function using the IO Monad looks like regular imperative code except for the type signature of the function which indicates that the function side effects and thus can only be called by other functions that side effect. Pure functions cannot call a side effecting function. This helps in isolating side effects and capturing it in the type signature of functions.
Plenty of examples here
https://www.haskell.org/tutorial/io.html
Functional programming is not stateless programming. Rather it captures any state changes in the type signature. An explicit example of it would be the state monad.