# In select: interrupt

**URL:** <https://www.ruby-forum.com/t/in-select-interrupt/141884>\
**Category:** Ruby\
**Created:** [July 1, 2008, 12:09pm UTC](https://www.ruby-forum.com/t/in-select-interrupt/141884 "2008-07-01T12:09:00Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![mfaine](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b3f665/32.png) [@mfaine](https://www.ruby-forum.com/u/mfaine)\
**Post date:** [July 1, 2008, 12:09pm UTC](https://www.ruby-forum.com/t/in-select-interrupt/141884/1 "2008-07-01T12:09:00Z")

</div>

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…

---

<div class="post-metadata">

**Author:** ![mfaine](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b3f665/32.png) [@mfaine](https://www.ruby-forum.com/u/mfaine)\
**Post date:** [July 1, 2008, 1:56pm UTC](https://www.ruby-forum.com/t/in-select-interrupt/141884/2 "2008-07-01T13:56:56Z")

</div>

2008/7/1 Mark F. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> 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

---

<div class="post-metadata">

**Author:** ![mfaine](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b3f665/32.png) [@mfaine](https://www.ruby-forum.com/u/mfaine)\
**Post date:** [July 1, 2008, 5:22pm UTC](https://www.ruby-forum.com/t/in-select-interrupt/141884/3 "2008-07-01T17:22:36Z")

</div>

2008/7/1 Mark F. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> 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

---

<div class="post-metadata">

**Author:** ![mfaine](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b3f665/32.png) [@mfaine](https://www.ruby-forum.com/u/mfaine)\
**Post date:** [July 1, 2008, 2:29pm UTC](https://www.ruby-forum.com/t/in-select-interrupt/141884/4 "2008-07-01T14:29:14Z")

</div>

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©  
@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 K.

---

<div class="post-metadata">

**Author:** ![mfaine](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b3f665/32.png) [@mfaine](https://www.ruby-forum.com/u/mfaine)\
**Post date:** [July 1, 2008, 11:56pm UTC](https://www.ruby-forum.com/t/in-select-interrupt/141884/5 "2008-07-01T23:56:46Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![mfaine](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b3f665/32.png) [@mfaine](https://www.ruby-forum.com/u/mfaine)\
**Post date:** [July 1, 2008, 5:30pm UTC](https://www.ruby-forum.com/t/in-select-interrupt/141884/6 "2008-07-01T17:30:13Z")

</div>

On Tue, Jul 1, 2008 at 4:18 PM, Robert K.  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) 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?

---

<div class="post-metadata">

**Author:** ![mfaine](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b3f665/32.png) [@mfaine](https://www.ruby-forum.com/u/mfaine)\
**Post date:** [July 1, 2008, 11:58pm UTC](https://www.ruby-forum.com/t/in-select-interrupt/141884/7 "2008-07-01T23:58:31Z")

</div>

On 01.07.2008 17:25, Mark F. wrote:

> On Tue, Jul 1, 2008 at 4:18 PM, Robert K.  
> [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > 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. 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.

> > 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](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
