In select: interrupt

Anyone getting errors like this.... I'm working on a console mode full
screen editor (that Dossy kindly prototyped for me years ago).
Basically, it's reading $STD_IN with a select, thusly:

        if select([@in_io], nil, nil, 1)
        c = @in_io.sysread(1)

{lots of stuff to process the input follows...}

Funny thing is, there seems to be a finite amount of code that can be
below here, in the input loop. After I add a certian amount, I start
getting funny errors while I'm typing in the editor, either in select:
interrupt, or the program simply says "Quit" and abends.

If I take some code out, the behaviour stops. Problem is, I need this
code. I was also having the same issues when i was using
term/ansicolor. I wrote my own ansi module and this went away, until
I started adding code to the select loop.
...
I've used select in this way before, on a TCP/IP socket, with no issues....

Frankly, this is far too little information to come up with any
meaningful reply. You do not even give specific errors or stack
traces.

From what you posted I'd say it is something timing related or mixing
sysread with other IO operations but these are a totally wild guesses.
Personally I start implementing with #read and only switch to
#sysread if there is a particular reason for using this.

Cheers

robert

···

2008/7/1 Mark Firestone <mark@cortex-media.com>:

Anyone getting errors like this.... I'm working on a console mode full
screen editor (that Dossy kindly prototyped for me years ago).
Basically, it's reading $STD_IN with a select, thusly:

       if select([@in_io], nil, nil, 1)
       c = @in_io.sysread(1)

{lots of stuff to process the input follows...}

Funny thing is, there seems to be a finite amount of code that can be
below here, in the input loop. After I add a certian amount, I start
getting funny errors while I'm typing in the editor, either in select:
interrupt, or the program simply says "Quit" and abends.

If I take some code out, the behaviour stops. Problem is, I need this
code. I was also having the same issues when i was using
term/ansicolor. I wrote my own ansi module and this went away, until
I started adding code to the select loop.
...
I've used select in this way before, on a TCP/IP socket, with no issues....

--
use.inject do |as, often| as.you_can - without end

Thanks for the advice. I can provide more of the code, or all the code...

The specific error messages are:

fsed.rb:681:in 'select': Interrupt
from fsed.rb 681:in 'run'
from edit.rb:93

-or-
the application simply reports "Quit", with no error at all

Let me send you the whole loop... it's long and not refactored and a
mess.... so no laughing (out loud...)

I'm not sure what else I could provide. Unix low level io is not one
of my skills...

Appreciate any other advice you guys could give, and I will happily
provide any info you want.

Take Care and thanks!

Mark

       while true

        if select([@in_io], nil, nil, 1)
        c = @in_io.sysread(1)
        #c = @in_io.getc
         $lf.print"c: #{c.bytes.to_a}\n"

         if @supress then # if we are suppressing the mysterious
extra linefeed... we do that here.
          @supress = false
           c = 0.chr if c.bytes.to_a[0] = 10
         end
  
         if @w_mode then #We are in winodw mode, not edit mode...
            $lf.print "in wmode\n"
            $lf.print "c: #{c.upcase}"

          case c
           when "\e" #effectively, esc this is cancel for everything
            @w_mode = false
            @out_io.print @state.screen_clear
          else
           case @w_type
              when ABORT,SAVE
                if c.upcase == "Y" then
                 @state.clear if ABORT
                 @state.clear_screen
                sleep(4)
                 break
                else
                 @out_io.print @state.screen_clear
                 @w_mode = false
               end
            end
          end

    else
      case c
      when "\cX" # exit
         @out_io.print @state.yes_no_window("Post message... Are you sure?")
        @w_type = SAVE
        @w_mode = true
      when "\cG","\eOP"
        @out_io.print @state.help_window
        @w_type = MESSAGE
        @w_mode = true
      when "\cA"
         @out_io.print @state.yes_no_window("Abort message... Are you sure?")
        @w_type = ABORT
        @w_mode = true
       when "\cN" #insert line
         @state.newline
         @out_io.print @state.redraw(true)
        when "\cY" #delete line
         @state.deleteline
         @out_io.print @state.redraw(true)
        when "\cL" # refresh
          @out_io.print @state.redraw(true)
        when "\r","\n"
          $lf.print "i'm at newline\n"
          @state.newline
          @supress = true if @bbs_mode #telnet seems to like to echo
linefeeds. lets supress this ...
          @out_io.print @state.redraw(true)
         when "\010", "\177"
           redraw = @state.backspace
           @out_io.print "\e[#{@state.current_y + @state.header_height};1H\e[K"
           @out_io.print @state.buffer.line(@state.current_y)
           @out_io.print @state.update_cursor_position
           @out_io.print @state.redraw(true) if redraw
         when "\e" # escape
           buf = c
           else
              if buf.nil?
                chr = c.unpack("c")[0]
                if (chr >= 32 && chr <= 127)
                 out_c,redraw = @state.input_char_at_cursor(c)
                 @out_io.putc(out_c) if !out_c.nil?
                 @out_io.print @state.redraw(true) if redraw
                end
              else
                buf << c
                $lf.print "buf: #{buf}\n"
                case buf
                 when "\e[H","\e[1"
                  @state.home_cursor
                  @out_io.print @state.update_cursor_position
                 when "\e[F","\e[4"
                  @state.end_cursor
                  @out_io.print @state.update_cursor_position
                 when "\e[6"
                  redraw = @state.page_down
                  @out_io.print @state.redraw(true) if redraw
                 when "\e[5"
                  redraw = @state.page_up
                 @out_io.print @state.redraw(true) if redraw
                 when "\e[2"
                  @state.toggle_ins
                  @out_io.print @state.redraw(true)
                 when "\e[A"
                   redraw = @state.move_cursor_up(1)
                   if redraw
                    @out_io.print @state.redraw(true)
                   else
                    @out_io.print @state.update_cursor_position
                   end
                   buf = nil
                  when "\e[B"
       redraw = @state.move_cursor_down(1)
       if redraw
                    @out_io.print @state.redraw(true)
                   else
                    @out_io.print @state.update_cursor_position
       end
                   buf = nil
                  when "\e[D"
                   @state.move_cursor_left(1)
                   @out_io.print @state.update_cursor_position
                   buf = nil
                  when "\e[C"
                  @state.move_cursor_right(1)
                  @out_io.print @state.update_cursor_position
                  buf = nil
                else
                  if buf.size >= 3
                    buf = nil
      end
      end
                end
              end
            end
          end
        end
        @state.buffer
      end
    end

···

On Tue, Jul 1, 2008 at 12:53 PM, Robert Klemme <shortcutter@googlemail.com> wrote:

2008/7/1 Mark Firestone <mark@cortex-media.com>:

Anyone getting errors like this.... I'm working on a console mode full
screen editor (that Dossy kindly prototyped for me years ago).
Basically, it's reading $STD_IN with a select, thusly:

       if select([@in_io], nil, nil, 1)
       c = @in_io.sysread(1)

{lots of stuff to process the input follows...}

Funny thing is, there seems to be a finite amount of code that can be
below here, in the input loop. After I add a certian amount, I start
getting funny errors while I'm typing in the editor, either in select:
interrupt, or the program simply says "Quit" and abends.

If I take some code out, the behaviour stops. Problem is, I need this
code. I was also having the same issues when i was using
term/ansicolor. I wrote my own ansi module and this went away, until
I started adding code to the select loop.
...
I've used select in this way before, on a TCP/IP socket, with no issues....

Frankly, this is far too little information to come up with any
meaningful reply. You do not even give specific errors or stack
traces.

From what you posted I'd say it is something timing related or mixing
sysread with other IO operations but these are a totally wild guesses.
Personally I start implementing with #read and only switch to
#sysread if there is a particular reason for using this.

Cheers

robert

--
use.inject do |as, often| as.you_can - without end

--
001100010010011110100001101101110011

Thanks for the advice. I can provide more of the code, or all the code...

The specific error messages are:

fsed.rb:681:in 'select': Interrupt
from fsed.rb 681:in 'run'
from edit.rb:93

Hm, maybe your process receives a signal or the thread is somehow interrupted.

-or-
the application simply reports "Quit", with no error at all

Then you're probably catch an exception somewhere without rethrowing
or reporting it.

Let me send you the whole loop... it's long and not refactored and a
mess.... so no laughing (out loud...)

Laughing is usually not my reaction to this kind of mess...

I'm not sure what else I could provide. Unix low level io is not one
of my skills...

You are doing at least one mistake: you #select with a timeout but do
not check return values. With a timeout #select might return without
anything to read - simply because time has passed.

Also, as I said, I'd start with the regular #read and not use #sysread.

Cheers

robert

···

2008/7/1 Mark Firestone <mark@cortex-media.com>:

--
use.inject do |as, often| as.you_can - without end

Hm, maybe your process receives a signal or the thread is somehow interrupted.

Then you're probably catch an exception somewhere without rethrowing
or reporting it.

Laughing is usually not my reaction to this kind of mess...

Heh. So, what is your usual reaction? Tears? Dispair? It's a mess
I intend to clean up, I assure you... (;

You are doing at least one mistake: you #select with a timeout but do
not check return values. With a timeout #select might return without
anything to read - simply because time has passed.

Shouldn't it return nil in that case?

Also, as I said, I'd start with the regular #read and not use #sysread.

Ok. What's the difference?

···

On Tue, Jul 1, 2008 at 4:18 PM, Robert Klemme <shortcutter@googlemail.com> wrote:

--
001100010010011110100001101101110011

Downgraded Ruby from 1.8.7 to 1.8.6 and the problem went away. Hmmm....

···

On Tue, Jul 1, 2008 at 4:25 PM, Mark Firestone <mark@cortex-media.com> wrote:

On Tue, Jul 1, 2008 at 4:18 PM, Robert Klemme > <shortcutter@googlemail.com> wrote:

Hm, maybe your process receives a signal or the thread is somehow interrupted.

Then you're probably catch an exception somewhere without rethrowing
or reporting it.

Laughing is usually not my reaction to this kind of mess...

Heh. So, what is your usual reaction? Tears? Dispair? It's a mess
I intend to clean up, I assure you... (;

You are doing at least one mistake: you #select with a timeout but do
not check return values. With a timeout #select might return without
anything to read - simply because time has passed.

Shouldn't it return nil in that case?

Also, as I said, I'd start with the regular #read and not use #sysread.

Ok. What's the difference?

--
001100010010011110100001101101110011

--
001100010010011110100001101101110011

Laughing is usually not my reaction to this kind of mess...

Heh. So, what is your usual reaction? Tears? Dispair?

You don't want to know.

It's a mess
I intend to clean up, I assure you... (;

That's good to hear. <rant>There are too many around creating even worse messes and not caring. Usually other have to clean up after them and remove all the bugs. Worst of all initially they have to spend numerous hours understanding what the poorly written code was supposed to do in the first place. Often it's just lack of experience but even more often it seems that it's just carelessness - probably because they do not take pride in what they do or just don't like their work and are just in SE for the money.</rant>

You are doing at least one mistake: you #select with a timeout but do
not check return values. With a timeout #select might return without
anything to read - simply because time has passed.

Shouldn't it return nil in that case?

Yep, I think you are right. Sorry for that. But given the fact that you are reading from a single stream only why do you use select at all - especially since you do an endless loop anyway? I mean, you could just do blocking reads, couldn't you?

Also, as I said, I'd start with the regular #read and not use #sysread.

Ok. What's the difference?

http://www.ruby-doc.org/core/classes/IO.html#M000484

I believe it will at least circumvent Ruby's buffering. Rdocs are not very exhaustive and I don't have my copy of the Pickaxe handy but I'd always first use the "regular" methods #read and #write.

Kind regards

  robert

···

On 01.07.2008 17:25, Mark Firestone wrote:

On Tue, Jul 1, 2008 at 4:18 PM, Robert Klemme > <shortcutter@googlemail.com> wrote: