getting error from open

Started by conan, December 22, 2011, 04:15:32 AM

Previous topic - Next topic

conan

I'm using http://i3wm.org/">i3 with https://sites.google.com/site/gotmor/dzen">dzen bar and I'm using newlisp to build me a pretty customized bar.



I have this code to check for cpuload:

(define (read-proc-stat)
    (setq procStat (open "/proc/stat" "read"))

    (do-while (regex {cpud?} (read-line procStat))
        (parse-stat-line (current-line)))
    (close procStat))  

Script runs ok for a while, with a (sleep 1000) between calls, and then spits this:

ERR: value expected in function read-line : procStat
called from user defined function read-proc-stat
called from user defined function draw-cpu-load

I added a (println procStat) and found script stopped when procStat would take value 1024, so it sounded like I was hitting an OS limit there. So I wrote a new script to test that:

(define (read-proc-stat)
    (setq proc-stat (open "/proc/stat" "read"))
    (println "open handle: " proc-stat)                                                                                                                                  

    (do-while (regex {cpud?} (read-line proc-stat))
        (println (current-line)))
    (close proc-stat))

(while true
    (read-proc-stat)
    (sleep 1000))

With this script the opening handle remains constant (at value 4 in my test).



The difference with the "real" script is that I have a status script that loads a cpuload module which contains read-proc-stat function definition.



I wonder why same function gets a constant handle when I call it one way and an incremented one (in steps of 4) when I call it the other way.



I modified read-proc-stat like this:

(define (read-proc-stat:read-proc-stat)
    (if (nil? read-proc-stat:procStat)
        (setq read-proc-stat:procStat (open "/proc/stat" "read")))

    (do-while (regex {cpud?} (read-line read-proc-stat:procStat))
        (parse-stat-line (current-line)))
    (seek read-proc-stat:procStat 0))


Which fixed the issue. But now I wonder: since I'm not closing the file ever, does newlisp close opened file handles when script finishes? What if it finishes with ctrl-c or what if it explodes on some other part? Does it do a proper cleaning?

Lutz

#1
On this simpler program:



(define (read-stat)
 (setq handle (open "foo.txt" "read")) ; foo contains 10 lines with: abcdefg
 (while (read-line handle) (println (current-line)))
 (println handle) (close handle))


I cannot repeat the behavior, you are seeing (incrementing of file handles). Also when exiting newLISP with Ctl-C or exists otherwise, a new newLISP session will not increment the file handle, but always create the same file handle.



ps: also - unrelated - why are you using 'do-while' instead of 'while'. Shouldn't the regex test take place always after reading a line from the file?

conan

#2
Quote from: "Lutz"On this simpler program:

...

I cannot repeat the behavior, you are seeing (incrementing of file handles).


Yes, called directly it behaves fine. So I rolled back my git repo and uploaded the bogus version with some additions to denote the bug.



I put it here: https://gitorious.org/bogus-stuff/dzenbar-bogus">//https://gitorious.org/bogus-stuff/dzenbar-bogus



(I realized just now, when replying this message, that I could have attached the code to the message)



Run status and you'll get increasing file handles. Run try.it.alone.lsp and you'll see the (almost) same code (parse-stat-line replaced with a println) behaving ok, like in your simpler script.



Also I included an error.log which is a full run of status until it blows up.


Quote from: "Lutz"
ps: also - unrelated - why are you using 'do-while' instead of 'while'. Shouldn't the regex test take place always after reading a line from the file?


Because I'm a moron! :P



In fact I had a while before, but had what I thought was a convoluted exit condition, you can check it out with

git log -p 48317b302b67e820e8d0a9816267d5a42c68f16e

The thing is that in theory is wrong, but in practice it seems I'm setting something somewhere that avoids parse-stat-line from exploding. And since it doesn't blow up, it's unseen since this runs once per second.