On Sun, 17 Jun 2001, Nadav Har'El wrote:
> On Sun, Jun 17, 2001, guy keren wrote about "Re: Background process I\O redirection":
> >...
> > 3. on a shell attached to '/dev/tty5' i run a debugger:
> > gdb /usr/bin/ncftp 7787
> >
> > in the debugger:
> >
> > (gdb) print open("/dev/tty4", 0) /* '0' stands for O_RDONLY */
> > $ = 4
> > (gdb) print dup2(4, 0);
> >...
> > it'll be interesting to check this method on the shell itself. if it'll
> > work, it'll give a screen-like behaviour without having to run screen in
> > advance, or having it installed on the system. any system with a debugger
> > on it will work...
>
> This is very interesting, but screen has another important capability, which
> is to remember the previous output that the program generated. In your
> method, whatever output the program generated while it wasn't "attached"
> is lost (unless it was originally saved to a file, like your nohup example).
we already heard enough about screen. the problem is that it works only if
you thinkof using it in advance - which is not always the case. its also
not always installed, while installing a pair of small scripts that allow
you to attach to a program as an afterthought is very easy.
in fact, i don't see why screen cannot be enhanced to support "taking
over" an existing program in the same manner described here. the only
problem is it will not get CHLD signals when the program exits.
as for the output being lost - actually, this is mostly true for screen as
well, as i remember from using it back in 90 - it just lets the data
scroll over, and that eventually gets flushed (if it did store all the
data, then for some outputs, screen's memoery footprint might grow
significantly. i assume, however, that you have some mechanism to define
some scrollback buffer size for every screen session?).
> Screen is a very useful utility to get aquainted with, for many reasons. If
> you always run screen in advance, you can always attach back to your processes
> and see what output they generated while you were away. This is extremely
> useful, for example, in modem connections which tend to disconnect at the
> exact moment you are running an important command and forgot to "nohup" it.
ok. still no reason not to complement it with such a small utility, for
the reasons i mentioned earlier.
> P.S. why did you have to do these 'fdopen' stuff? Since the file descriptors
> remained the same, the previous definitions of 'stdin', 'stdout', etc., should
> work just the same, so these calls are redundant.
cause they _might_ have been closed somehow earlier? or they contain old
buffers (that 512 bytes block each FILE structure is holding) which could
lead to confusing input or output? so i did that in order to tidy up.
> If you were thinking that
> this wouldflush the old buffers, etc., then there are few problems with that
> thinking:
> 1. I don't think it would, since you are just overwriting the 'stdin'
> variable. stdouts's old buffers may be completely lost, rather then
> flushed to the old (or new) output file or terminal.
losing them was exactly my intention. starting afresh, rather then having
unknown values in those buffers.
> 2. Are you sure stdin, etc., are variables? I remember in old versions of
> AT&T unix that these were macros, pointing to some internal stuff in the
> stdio library. You weren't supposed to set them. Does ANSI C guarantee
> that they are standard variables?
> BTW, in Linux, stdin is defined as "extern FILE *stdin;", and then they
> do "#define stdin stdin", commenting about that:
> /* C89/C99 say they're macros.Make them happy. */
> So I guess you shouldn't go around redifining stdin, etc.
indeed, they could be macros. in the old implementations i once looked at
(i think it was a BSD 4.3 system), they were pointers to a global array of
FILE structures.
my other option would have been to make a structure copy, as in:
(*stdin) = (*new_stdin);
however, that'd require declaring the 'new_stdin' variable, which can't be
done via gdb. i'd have to do something more compliaction, such as:
(gdb) print malloc(sizeof(FILE));
$ = 0x46705a
(gdb) print memcpy((void*)stdin, (void*)0x46705a, 148); /* 148 =
sizeof(FILE) */
$ = 0
(gdb)
and now i have to rely both on sizeof(FILE) - which is architecture
dependant, and on thassumption that a shallow copy would work. on the
other hand, i don't know which method is worse - i'll simply have to
experiment with them.
> 3. Why just stdin - how can you assume that this program uses stdio? What
> about C++'s "cin"?
good point. i'll have to check if its a C++ program. on the other hand -
most terminal programs are written in C, so i'll concentrate on C for now.
> What if the program uses its own IO library?
then i can't help it - but then again, they would still do that on top of
descriptors 0, 1 and 2, so i might get lucky, and this will actually
work.
--
guy
"For world domination - press 1,
or dial 0, and please hold, for the creator." -- nob o. dy
=================================================================
To unsubscribe, send mail to [EMAIL PROTECTED] with
the word "unsubscribe" in the message body, e.g., run the command
echo unsubscribe | mail [EMAIL PROTECTED]