expect
and proc_open()
are both going to use a pipe to provide stdin
, so that won't make any difference. Since stdin
is just a file handle, regardless of whether it's interactive or redirected, you need to cause isatty
to think that the handle is a TTY when it's a pipe.
The only way I can think of to do this, without going and looking at the source for multiple implementations of the C standard library is to use LD_PRELOAD
to override the default implementation of isatty
with a special version that returns 1 for the particular handle that you're using as stdin
.
Update:
Looks like implementations of the C standard library use ioctl
to store a handle or pointer to terminal information with the file handle, and if you fake a TTY by setting a fake pointer using an ioctl
code, anyone who tries to do TTY-specific stuff with that handle will likely crash.
e.g., libc uses tcgetattr
which uses ioctl(TCGETS)
to store a termios
structure, where libbc uses gtty
which uses ioctl(TIOCGETP)
to store a sgttyb
structure.
So I think you could trick libc by doing this:
ioctl(p, TCSETS, 42);
You might be able to trick one or two implementations, but it won't be portable, and you'll have to be sure the program that's using the handle doesn't do anything TTY-related other than isatty
.