Echo console to a device (and vice-versa)?

Discussion in 'Python' started by Francis Avila, Oct 3, 2003.

  1. This is not really a python question, but a posix question. (If it's too
    little of a python question to be OT, please let me know.)

    I wanted a simple "bi-directional cat", i.e. something that passes stdin to
    a device, and takes the device's output to stdout (Like 'screen
    /dev/ttyS0'). I couldn't find a simple thing like this anywhere, so I
    figured I would just write one.

    However, I can't seem to get it to work: nothing is ever output or input on
    either end (also, if run in emacs it hangs it until I can kill python--it's
    eating stdin and stdout, I suspect). I suspect I have a deep ignorance of
    file descriptors, but I don't understand what it could be. Might it also be
    possible that the interpreter is somehow getting "in the way" of
    stdin/stdout? A C-c still sends KeyboardInterrupt, for example, so I know
    python is still looking at stdin.

    Here's the important code, which went through some revisions:


    import os, sys
    from errno import EAGAIN
    import fcntl


    usage = """usage: scat TTY-DEV"""

    def main():
    try:
    ttyfn = sys.argv[1]
    except IndexError:
    print >> sys.stderr, usage
    return 1

    try:
    ttyfdout = os.open(ttyfn, os.O_RDONLY | os.O_NONBLOCK)
    ttyfdin = os.open(ttyfn, os.O_WRONLY | os.O_NONBLOCK)
    except:
    print >> sys.stderr, usage
    print >> sys.stderr, "invalid filename " + ttyfn
    return 1

    if not os.isatty(ttyfdin):
    print >> sys.stderr, usage
    print >> sys.stderr, ttyfn + " is not a tty"
    return 1

    stdin = sys.stdin.fileno()
    stdout = sys.stdout.fileno()

    # make the above non-blocking
    fcntl.fcntl(stdin, fcntl.F_SETFL, os.O_NONBLOCK)
    fcntl.fcntl(stdout, fcntl.F_SETFL, os.O_NONBLOCK)

    while 1:
    #read tty, write to stdout
    try:
    ttybuf = os.read(ttyfdout, 1)
    except OSError, err:
    if err == EAGAIN:
    pass
    else:
    os.write(stdout, ttybuf)

    #read stdin, write to tty
    try:
    stdinbuf = os.read(stdin, 1)
    except OSError, err:
    if err == EAGAIN:
    pass
    else:
    os.write(ttyfdin, stdinbuf)


    if __name__ == '__main__':
    main()

    --
    Francis Avila
    Francis Avila, Oct 3, 2003
    #1
    1. Advertising

  2. Francis Avila

    Peter Otten Guest

    Francis Avila wrote:

    > try:
    > ttybuf = os.read(ttyfdout, 1)
    > except OSError, err:
    > if err == EAGAIN:
    > pass
    > else:
    > os.write(stdout, ttybuf)


    Well, admitting that I don't have any idea what you want to do, the above
    code silences *any* OSError, i. e.

    if err == EAGAIN:
    pass

    is a NOOP. If you want to catch only EAGAIN, you might consider

    try:
    ttybuf = os.read(ttyfdout, 1)
    except OSError, err:
    if err != EAGAIN:
    raise
    else:
    os.write(stdout, ttybuf)

    instead.

    Peter
    Peter Otten, Oct 3, 2003
    #2
    1. Advertising

  3. "Peter Otten" <> wrote in message
    news:bljgqr$995$06$-online.com...
    > Francis Avila wrote:
    >
    > > try:
    > > ttybuf = os.read(ttyfdout, 1)
    > > except OSError, err:
    > > if err == EAGAIN:
    > > pass
    > > else:
    > > os.write(stdout, ttybuf)

    >
    > Well, admitting that I don't have any idea what you want to do, the above
    > code silences *any* OSError, i. e.
    >
    > if err == EAGAIN:
    > pass
    >
    > is a NOOP. If you want to catch only EAGAIN, you might consider
    >
    > try:
    > ttybuf = os.read(ttyfdout, 1)
    > except OSError, err:
    > if err != EAGAIN:
    > raise
    > else:
    > os.write(stdout, ttybuf)
    >
    > instead.
    >
    > Peter



    That's true, thanks. I was thinking a bit sloppily, catching EAGAIN as
    though it were itself an exception. However, it doesn't effect functioning
    unless some other fatal exception pops up.

    The problem was simply that my tty wasn't raw enough. It wasn't sufficient
    to make the tty raw from the shell (using, in this case, 'stty raw pass8').
    Calling tty.setraw on each of the four fd's solved the problem without
    incident, and the code works exactly as expected.

    Of course, now there are no excape characters, so I can't even ^C to exit,
    but this is all resolvable.
    --
    Francis Avila
    Francis Avila, Oct 5, 2003
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jimmy
    Replies:
    1
    Views:
    3,156
    Eliyahu Goldin
    Jun 14, 2005
  2. carmen
    Replies:
    4
    Views:
    30,707
    ersecchio
    Jan 12, 2010
  3. Sam Hwang

    Java Object to XML and vice versa

    Sam Hwang, Apr 24, 2005, in forum: Java
    Replies:
    5
    Views:
    1,011
    iksrazal
    Apr 25, 2005
  4. -
    Replies:
    8
    Views:
    614
    Antti S. Brax
    Jun 11, 2005
  5. Peter Otten
    Replies:
    1
    Views:
    153
    Andreas Perstinger
    Jun 18, 2013
Loading...

Share This Page