reading from a unix pipe and then from the user

Hello, I'm trying to write a program that first reads input from a pipe and then reads keyboard input from the user (like fzf, the fuzzy finder). Under different circumstances I could open a handle to `/dev/tty` and use the `hGet...` functions from `System.IO` to get the user's keyboard input, but I'm constructing the text user interface with the brick library, which doesn't seem to give my any way to sneak in alternative handles through its application entry point functions. So, what I'm looking for is a function which takes an `IO ()` function like the usual `main` and a `Handle` and turns it into an `IO ()` function that reads from the provided handle instead of `stdin`. Does that make sense? I might be looking for something that doesn't exist. Or I'm lacking the language to get results from a search engine. To illustrate the problem further, here is a condensed brick application: import qualified Brick.Main as Main import qualified Brick.Types as Types import qualified Graphics.Vty as Vty import Brick.AttrMap ( attrMap ) import Brick.Widgets.Core ( str ) type Event = Types.EventM () ( Types.Next () ) main = let app = Main.App { Main.appChooseCursor = Main.neverShowCursor , Main.appHandleEvent = \ _ _ -> Main.halt () :: Event , Main.appStartEvent = pure , Main.appAttrMap = \ _ -> attrMap Vty.currentAttr [] , Main.appDraw = \ _ -> [ str Hit any key to exit. ] } in Main.defaultMain app () How do I get this `main` function to read from a custom handle intead of stdin?

If brick really doesn't provide a way to override the input handle, your
best bet is to use System.Posix.IO.dup to "copy" the original stdInput pipe
to a new file descriptor, fdClose stdInput, openFd /dev/tty, dupTo the
handle to stdInput (== 0) if necessary (POSIX says it is, actual Unixes
will have opened /dev/tty on to fd 0 already if you closed it first), then
use fdToHandle to get a handle for the new pipe. Don't do any IO on the
pipe before doing this, or there will be no safe way to synchronize the
existing Handle with its new fd. The mappings between the things in
System.Posix.IO and the underlying Unix / POSIX syscalls is fairly obvious
if you already know the latter; the only new ones are fdToHandle and
handleToFd which correspond to C stdio's openfd() and fileno().
On Sat, Oct 26, 2019 at 9:17 AM Aramís Concepción Durán
Hello,
I'm trying to write a program that first reads input from a pipe and then reads keyboard input from the user (like fzf, the fuzzy finder).
Under different circumstances I could open a handle to `/dev/tty` and use the `hGet...` functions from `System.IO` to get the user's keyboard input, but I'm constructing the text user interface with the brick library, which doesn't seem to give my any way to sneak in alternative handles through its application entry point functions.
So, what I'm looking for is a function which takes an `IO ()` function like the usual `main` and a `Handle` and turns it into an `IO ()` function that reads from the provided handle instead of `stdin`.
Does that make sense? I might be looking for something that doesn't exist. Or I'm lacking the language to get results from a search engine.
To illustrate the problem further, here is a condensed brick application:
import qualified Brick.Main as Main import qualified Brick.Types as Types import qualified Graphics.Vty as Vty
import Brick.AttrMap ( attrMap ) import Brick.Widgets.Core ( str )
type Event = Types.EventM () ( Types.Next () )
main = let app = Main.App { Main.appChooseCursor = Main.neverShowCursor , Main.appHandleEvent = \ _ _ -> Main.halt () :: Event , Main.appStartEvent = pure , Main.appAttrMap = \ _ -> attrMap Vty.currentAttr [] , Main.appDraw = \ _ -> [ str Hit any key to exit. ] } in Main.defaultMain app ()
How do I get this `main` function to read from a custom handle intead of stdin? _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.
-- brandon s allbery kf8nh allbery.b@gmail.com

It depends on what you're doing, to. For passwords, /dev/tty is almost always best. If you have reason to expect that someone might want to redirect the user's input for some reason, stderr would be a better choice. But also consider that someone might want to capture a fatal error from stderr (not all programs are well behaved, and in particular ghc's runtime panics would still go to stderr ignoring brick; also consider any FFI callouts to C that might assume stderr is a dedicated error channel) which would again suggest /dev/tty. There's no one right answer here, in short. On Sun, Oct 27, 2019 at 9:31 AM Neil Mayhew < neil_mayhew@users.sourceforge.net> wrote:
On 2019-10-26 2:27 a.m., Aramís Concepción Durán wrote:
I could open a handle to `/dev/tty`
It's also worth noting that many similar programs use stderr instead of /dev/tty. Each approach has its advocates. vim -i uses stderr, for example, and sudo uses /dev/tty. _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.
-- brandon s allbery kf8nh allbery.b@gmail.com
participants (3)
-
Aramís Concepción Durán
-
Brandon Allbery
-
Neil Mayhew