From: Alastair B. <nye...@li...> - 2008-06-28 02:57:19
|
Julian Stecklina wrote: > Hello, > > I tried to update StumpWMs battery contrib to use Linux' sysfs and hit > the following issue: > >> (with-open-file (in "/sys/class/power_supply/AC/type") > (let ((buf (make-string 32 :initial-element #\Space))) > (read-sequence buf in) > buf)) > > READ-SEQUENCE blocks and does not return. > /sys/class/power_supply/AC/type only contains the null-terminated string > "Mains". Interrupting with C-c gives the following backtrace: [ Backtrace elided ] > Opening the file with :element-type '(unsigned-byte 8) does not work > either. > > This is with SBCL 1.0.16 on Gentoo and I am running Linux 2.6.25.4 on an > x86 box. > > Regards, What I expect is happening here is that the Linux kernel is using the "data ready for reading" notification as a "file contents changed" notification. This, of course, breaks SBCL's assumption of straight POSIX semantics for select() on files. I ran into the same problem with /proc/bus/usb/devices. The following (untested) nasty hack (based on what I ended up doing) might behave approximately the way you want: (with-open-file (in "/sys/class/power_supply/AC/type") (let ((buf (make-array 32 :initial-element (char-code #\Space)))) ;; FIXME: Add error handling here. (sb-unix:unix-read (sb-sys:fd-stream-fd in) (sb-sys:vector-sap buf) 32) (sb-ext:octets-to-string buf))) Note that this would mean that you can hold a stream open to a file that behaves this way, register an fd-handler on it for input, and recieve notification of when the file changes via serve-event. Might be useful for detecting battery level changes and AC adaptor connect/disconnect. The only problem is that you can't use the standard Lisp stream I/O functions to read the file data. The only way that I can think of to have SBCL do "The Right Thing" with files that behave in this manner is for there to be some method whereby it can determine for itself if a file descriptor actually has this particular set of brain-damaged semantics ahead of time, and raise end-of-file instead of entering wait-until-fd-usable on such files. I don't know of such a method, but that's more indicative of my not having looked for one than anything else. --Alastair Bridgewater |
From: Julian S. <der...@we...> - 2008-06-30 21:43:29
|
Alastair Bridgewater <nye...@li...> writes: > What I expect is happening here is that the Linux kernel is using the > "data ready for reading" notification as a "file contents changed" > notification. This, of course, breaks SBCL's assumption of straight > POSIX semantics for select() on files. I ran into the same problem with > /proc/bus/usb/devices. Could that be seen as a Linux kernel bug? I condensed your description in a small C program: http://www1.inf.tu-dresden.de/~s1054849/kernbug.c A sample session: % ./kernbug /proc/cpuinfo Read 512 bytes. Read 512 bytes. Read 126 bytes. Read 0 bytes. EOF % ./kernbug /sys/class/power_supply/BAT0/type Read 8 bytes. Timeout... ^C Is there something that mandates that select returns immediately for a fd that is at the EOF ? I only see the following sentence in the man page: "A file descriptor is considered ready if it is possible to perform the corresponding I/O operation (e.g., read(2)) without blocking." > Note that this would mean that you can hold a stream open to a file that > behaves this way, register an fd-handler on it for input, and recieve > notification of when the file changes via serve-event. This does not seem to work. > The only way that I can think of to have SBCL do "The Right Thing" with > files that behave in this manner is for there to be some method whereby > it can determine for itself if a file descriptor actually has this > particular set of brain-damaged semantics ahead of time, and raise > end-of-file instead of entering wait-until-fd-usable on such files. I > don't know of such a method, but that's more indicative of my not having > looked for one than anything else. IMHO it seems to be Linux' fault. Regards, -- Julian Stecklina Well, take it from an old hand: the only reason it would be easier to program in C is that you can't easily express complex problems in C, so you don't. - Erik Naggum (in comp.lang.lisp) (Spam-Experiment: http://cthulhu.c3d2.de/~astro/badpit.html ) |
From: Paul K. <pk...@gm...> - 2008-06-30 23:56:25
|
On 30-Jun-08, at 5:43 PM, Julian Stecklina wrote: > Alastair Bridgewater <nye...@li...> writes: >> What I expect is happening here is that the Linux kernel is using the >> "data ready for reading" notification as a "file contents changed" >> notification. This, of course, breaks SBCL's assumption of straight >> POSIX semantics for select() on files. I ran into the same problem >> with >> /proc/bus/usb/devices. > > Could that be seen as a Linux kernel bug? Unfortunately, strictly speaking, no. Here's what SUSv3 has to say on the topic (http://www.opengroup.org/onlinepubs/000095399/functions/select.html ): > The pselect() and select() functions shall support regular files, > terminal and pseudo-terminal devices, [XSR] STREAMS-based files, > FIFOs, pipes, and sockets. The behavior of pselect() and select() on > file descriptors that refer to other types of file is unspecified. sysfs 'files' are none of the above, so a compliant *nix can do whatever they want in such a situation. I don't think OS-specific hacks are anything new or surprising to linux users of linux extensions. The current situation, along with the FS-specific approach sketched by Alastair, seems acceptable. Paul Khuong |
From: Julian S. <der...@we...> - 2008-06-30 23:58:37
|
Alastair Bridgewater <nye...@li...> writes: > What I expect is happening here is that the Linux kernel is using the > "data ready for reading" notification as a "file contents changed" > notification. This, of course, breaks SBCL's assumption of straight > POSIX semantics for select() on files. FYI, I opened a Linux kernel bug and it was almost instantly rejected: http://bugzilla.kernel.org/show_bug.cgi?id=11014#c2 Regarding the comment "It is weird that lisp has such a strange file io implementation.": Is there any rationale for doing file I/O this way? Regards, -- Julian Stecklina Well, take it from an old hand: the only reason it would be easier to program in C is that you can't easily express complex problems in C, so you don't. - Erik Naggum (in comp.lang.lisp) (Spam-Experiment: http://cthulhu.c3d2.de/~astro/badpit.html ) |
From: Nathan F. <fr...@gm...> - 2008-07-01 01:22:21
|
On Mon, Jun 30, 2008 at 7:58 PM, Julian Stecklina <der...@we...> wrote: > FYI, I opened a Linux kernel bug and it was almost instantly rejected: > > http://bugzilla.kernel.org/show_bug.cgi?id=11014#c2 > > Regarding the comment "It is weird that lisp has such a strange file io > implementation.": Is there any rationale for doing file I/O this way? I'd be curious as to what other way one would do file I/O if you want to support doing I/O on multiple sockets and files simultaneously. I mean, this has worked for *years*. (And no, whiz-bangy Linux-specific stuff doesn't count at the moment, at least not until something like iolib lands in SBCL.) -Nathan |
From: Julian S. <der...@we...> - 2008-07-01 01:34:29
|
"Nathan Froyd" <fr...@gm...> writes: > On Mon, Jun 30, 2008 at 7:58 PM, Julian Stecklina <der...@we...> wrote: >> FYI, I opened a Linux kernel bug and it was almost instantly rejected: >> >> http://bugzilla.kernel.org/show_bug.cgi?id=11014#c2 >> >> Regarding the comment "It is weird that lisp has such a strange file io >> implementation.": Is there any rationale for doing file I/O this way? > > I'd be curious as to what other way one would do file I/O if you want > to support doing I/O on multiple sockets and files simultaneously. I > mean, this has worked for *years*. (And no, whiz-bangy Linux-specific > stuff doesn't count at the moment, at least not until something like > iolib lands in SBCL.) Btw, I just tried CMUCL 19c suspecting that it would exhibit the same behaviour, but it seems fine with sysfs files: * (with-open-file (in "/sys/class/power_supply/AC/type") (read-line in)) "Mains" NIL Does anyone have a clue what they do differently? Regards, -- Julian Stecklina Well, take it from an old hand: the only reason it would be easier to program in C is that you can't easily express complex problems in C, so you don't. - Erik Naggum (in comp.lang.lisp) (Spam-Experiment: http://cthulhu.c3d2.de/~astro/badpit.html ) |
From: James Y K. <fo...@fu...> - 2008-07-01 02:36:41
|
On Jun 30, 2008, at 9:22 PM, Nathan Froyd wrote: > On Mon, Jun 30, 2008 at 7:58 PM, Julian Stecklina > <der...@we...> wrote: >> FYI, I opened a Linux kernel bug and it was almost instantly >> rejected: >> >> http://bugzilla.kernel.org/show_bug.cgi?id=11014#c2 >> >> Regarding the comment "It is weird that lisp has such a strange >> file io >> implementation.": Is there any rationale for doing file I/O this way? > > I'd be curious as to what other way one would do file I/O if you want > to support doing I/O on multiple sockets and files simultaneously. I > mean, this has worked for *years*. (And no, whiz-bangy Linux-specific > stuff doesn't count at the moment, at least not until something like > iolib lands in SBCL.) Well, I guess I've always found it a bit odd that SBCL enters a serve- event loop in all the places where it does. If you're just trying to read a file, it seems like it should just read the file. I actually find the recursive invocations of serve-event in random places to be irritating, not useful. It makes it hard to reason about how the program is going to execute if arbitrary code can be executed just about anywhere. I'd naively expect the example code to simply translate to the syscalls: open -> fd, read -> "Mains", read -> EOF, close. Basically, *less* whiz-bangy stuff, not more. I expect the kernel developers would also consider it odd. But, as a less world-shattering suggestion, I'll just note that select never does anything useful whatsoever for regular files, so it's basically a waste to ever call bother implicitly calling it in such cases. James |
From: Nathan F. <fr...@gm...> - 2008-07-01 03:09:59
|
On Mon, Jun 30, 2008 at 10:36 PM, James Y Knight <fo...@fu...> wrote: > On Jun 30, 2008, at 9:22 PM, Nathan Froyd wrote: >> I'd be curious as to what other way one would do file I/O if you want >> to support doing I/O on multiple sockets and files simultaneously. I >> mean, this has worked for *years*. (And no, whiz-bangy Linux-specific >> stuff doesn't count at the moment, at least not until something like >> iolib lands in SBCL.) > > Well, I guess I've always found it a bit odd that SBCL enters a serve-event > loop in all the places where it does. If you're just trying to read a file, > it seems like it should just read the file. I actually find the recursive > invocations of serve-event in random places to be irritating, not useful. It > makes it hard to reason about how the program is going to execute if > arbitrary code can be executed just about anywhere. Agreed. But if you're not going to differentiate between "file" fd-streams and "network socket" fd-streams, can you do any better? (Note that some people do this differentiation, probably for reasons like the ones you describe and/or running on strange OSes--not Windows, things like AIX. IBM's Jalapeno, for instance, only does non-blocking I/O on network socket streams, so presumably there's a flag *somewhere* that gets switched on.) One wonders if the I/O subsystem would be any faster if these extra syscalls went away. FD-STREAM does have a FILE member that appears to only be set for files...so some of the bits are there already... -Nathan |