Subject: Re: AW: [clisp-list] with-open-file bug on linux

From: Peter Wood <[email-masked]>
Date: Tue Mar 19 11:01:09 2002

On Tue, Mar 19, 2002 at 10:51:04AM -0500, Sam Steingold wrote:
> CLISP has to open with O_RDWR to use buffering, so :DIRECTION :OUTPUT
> means O_RDWR too.  This breaks write-only files, like Peter's /proc
> file.
> 
> I guess we should document "the obvious" - that one cannot use
> buffering on write-only files - and use O_WRONLY with :BUFFERED NIL
> :DIRECTION :OUTPUT.
> 

But the file isn't write only!  You *can* read from it.

ls -l /proc/sys/fs/binfmt_misc/PY ==>
-rw-r--r--   1 root     root            0 Mar 19 18:32 /proc/sys/fs/binfmt_misc/PY

cat /proc/sys/fs/binfmt_misc/PY ==>
enabled

interpreter /usr/bin/python
extension .py

I *speculate* as follows:

You can write() to it, but you have to do it all in one go (I think).
I believe full_write() [unixaux.d:301] is causing EINVAL, because it
tries to write() several times. The kernel which is generating the
content of the file, won't let you write anything but "-1" or "1" or
"0".  You can't write "-" then "1".  And you can't write "+1" either. 

This test results in the following output:
{
  int retv;
  int fd;
  char* msg1 = "11";

  fd = open("/proc/sys/fs/binfmt_misc/PY", 66, 420);
  retv = write (fd, msg1, 2);
  printf ("retv = %d\n", retv);
  printf ("errno is %d\n", errno);
  printf ("fsync returns %d - errno = %d\n", fsync (fd), errno);
  return(0);
} ==>

retv = -1
errno is 22
fsync returns -1 - errno = 22

Changing msg1="11" to msg1="-1" results in this output:

retv = 2
errno is 0
fsync returns -1 - errno = 0

Which works. Obviously fsync is superfluous, here, but I'm surprised
it doesn't also set EINVAL in the second example.

Regards,
Peter

---

From: Peter Wood <[email-masked]>
Date: Tue Mar 19 11:14:06 2002

On Tue, Mar 19, 2002 at 09:42:36AM +0100, Hoehle, Joerg-Cyril wrote:
> Hi,
> 
> > I didn't know Clisp took a :buffered nil keyword for open.  It seems
> > this is the way to write to peculiar files like some of the ones under
> > /proc.  It fixes the problem I described in the last post.
> 
> Do you know enough about Linux to enhance the heuristics that CLISP uses to discover whether to use buffering? There already was a changelog years ago saying something like "works better on /proc now".
> 
> Another solution (hack?) would be to special-case /proc completely on Linux?? Not clean, though. Special case /dev as well? And what next?
> 
> Regards,
> 	Jorg Hohle.

Hi

There are already a few special-cases for /proc in pathname.d,
including one with a comment about  /proc being a zoo filled with
strange animals :-)

I don't know if its possible to test a file for wether it will support
buffering io.  Also, there's nothing to stop the kernel developers
from dreaming up some new bizarre file in /proc which allows x but not
y.

It might be fun to try write an ffi definition for sysctl, but they
warn that it changes between kernels, and shouldn't be used by
applications :-(

Regards,
Peter