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

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Francis Avila

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

    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 KeyboardInterru pt, 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(ttyfd in):
    print >> sys.stderr, usage
    print >> sys.stderr, ttyfn + " is not a tty"
    return 1

    stdin = sys.stdin.filen o()
    stdout = sys.stdout.file no()

    # make the above non-blocking
    fcntl.fcntl(std in, fcntl.F_SETFL, os.O_NONBLOCK)
    fcntl.fcntl(std out, fcntl.F_SETFL, os.O_NONBLOCK)

    while 1:
    #read tty, write to stdout
    try:
    ttybuf = os.read(ttyfdou t, 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(ttyfdi n, stdinbuf)


    if __name__ == '__main__':
    main()

    --
    Francis Avila

  • Peter Otten

    #2
    Re: Echo console to a device (and vice-versa)?

    Francis Avila wrote:
    [color=blue]
    > try:
    > ttybuf = os.read(ttyfdou t, 1)
    > except OSError, err:
    > if err == EAGAIN:
    > pass
    > else:
    > os.write(stdout , ttybuf)[/color]

    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(ttyfdou t, 1)
    except OSError, err:
    if err != EAGAIN:
    raise
    else:
    os.write(stdout , ttybuf)

    instead.

    Peter

    Comment

    • Francis Avila

      #3
      Re: Echo console to a device (and vice-versa)?

      "Peter Otten" <__peter__@web. de> wrote in message
      news:bljgqr$995 $06$1@news.t-online.com...[color=blue]
      > Francis Avila wrote:
      >[color=green]
      > > try:
      > > ttybuf = os.read(ttyfdou t, 1)
      > > except OSError, err:
      > > if err == EAGAIN:
      > > pass
      > > else:
      > > os.write(stdout , ttybuf)[/color]
      >
      > 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(ttyfdou t, 1)
      > except OSError, err:
      > if err != EAGAIN:
      > raise
      > else:
      > os.write(stdout , ttybuf)
      >
      > instead.
      >
      > Peter[/color]


      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

      Comment

      Working...