2

I'm writing a collection of scripts to talk to an external program. My problem is that the scripts are only "alive" for a short time (triggered by a keypress in a larger program) but the external program needs to stay running between calls, and was originally designed for interactive use (think debugger).

  • If I just wanted to write a single script to run the program, I'd open a PTY to it and send/receive data on that. This works (my scripts are in LUA and lpty can deal with the PTY) but it can't keep the program running when the script terminates.

  • If the external program offered me a socket to connect on (like gdb does), I could just save the name somewhere and have each script connect to that socket. But it was only meant to be used interactively.

I could write a daemon that starts the external program, opens a PTY to it and then listens on a socket itself. The scripts could then connect to the daemon's socket and send data, which the daemon would forward to the program over the PTY and send the results back.

The format of the data I'm exchanging with the external program is line-based, but I don't know in advance how many lines I'm going to get back from a single command. Not a problem with a PTY, but a bit more work with luasocket.

I'm wondering if there isn't a better way to do this. Can I somehow open a PTY to a program and get its "address", from which I can later connect and disconnect multiple times from my scripts? (Only one script can ever run at a time so concurrency is not a problem.) That would avoid using sockets at all.

Or is there some combination of options in socat that does exactly this already?

  • Have you looked at man openvt? – goldilocks May 15 '15 at 9:25
  • openvt seems to require sudo on this machine (Ubuntu trusty; without root I get: Couldn't get a file descriptor referring to the console) so this isn't an option. – Bristol May 15 '15 at 9:35
  • Actually it doesn't look like it works with ptys anyway -- but you can write to any pty you own pretty simply. Find the node with tty and then try, e.g. ls -l > /dev/pts/8 from another terminal. – goldilocks May 15 '15 at 9:41
2

You can't “open a PTY to a program”. A PTY is a pseudo-terminal; it requires a terminal end. If you want to communicate with a program directly via a terminal, the program would need to create a terminal (i.e. to behave like a terminal emulator).

Instead, you can run the program in a terminal, such as screen. Screen makes it easy to inject input and read output from programs.

However, for what you're doing, a terminal would introduce useless complications. A socket is exactly the right tool for what you want to do — direct bidirectional communication between two programs. (For unidirectional communication, a pipe would be the right tool.) The only advantage of using a terminal is if you don't control one of the ends and it insists on buffering output by block rather than by line if the output isn't on a terminal.

  • I've tried opening a pair of read/write pipes to the target program. My problem here is that if I want to check whether there's any new data available (with a lua read(0)), it blocks if there is no data to read from the pipe. This isn't very useful for a "have I read everything" check, that's why I was using lpty. – Bristol May 18 '15 at 10:28
  • @Bristol At the system call level, you can make reading non-blocking in exactly the same way for a terminal as for a pipe. Maybe Lua doesn't expose this and has a different API that works only for terminals? I'm not familiar with Lua's API. In any case, the normal way to read from multiple sources is not with a non-blocking read, but with select or poll to find out in advance which sources have data available. – Gilles May 18 '15 at 12:48
  • Ok, thanks. It seems like I may need to dig further into the libraries I'm using. – Bristol May 18 '15 at 13:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.