Re: bug: :if-exists :append

Sam Steingold <[email protected]>
Newsgroups gmane.lisp.clisp.general
Message-ID <m1inodzzz5.fsf@clr-sds>
Hi Jean,

> * Jean Louis <[email protected]> [2017-02-13 07:45:29 +0300]:
>
> I cannot file bug on Sourceforge for some reason, so maybe someone
> else may do it. I hope this bug will be corrected at least in the
> development version.

When I click on "Create Ticket" on https://sourceforge.net/p/clisp/bugs/,
I am redirected to https://sourceforge.net/p/clisp/bugs/new/
What happens to you?

> When file is chattr-ed +a (append only) on GNU/Linux system, CLISP is
> reporting: *** - OS-FILE-ERROR(EPERM): Operation not permitted
> and is not appending to the file.

To be honest, I am not surprised.
CLISP was written before chattr came around, so, with `:if-exists
:append` it opens the file the usual way and fseek()s to the end.

Moreover, a comment in clisp/src/stream.d says:

--8<---------------cut here---------------start------------->8---
  /* treat Mode :APPEND:
   CLHS says that :APPEND implies that "the file pointer is _initially_
   positioned at the end of the file". Note that this is different from
   the Unix O_APPEND semantics. */
--8<---------------cut here---------------end--------------->8---

for the reference (http://pubs.opengroup.org/onlinepubs/7908799/xsh/open.html):
--8<---------------cut here---------------start------------->8---
O_APPEND
  If set, the file offset will be set to the end of the file prior to each write.
--8<---------------cut here---------------end--------------->8---

IOW, to open your `chattr +a` file, we need to pass `O_APPEND` to `open(2)`.
However, this will break this code:

--8<---------------cut here---------------start------------->8---
(with-open-file (s "my-append-only-file" :direction :output :if-exists :append)
  (let ((pos (file-position s)))
    (write-string "foo" s)
    (file-position s (- pos 3))
    (write-string "bar" s)))
--8<---------------cut here---------------end--------------->8---

ANSI CL mandates that this appends 3 chars "bar" to
"my-append-only-file".
However, if "my-append-only-file" was opened with `O_APPEND`, it will
actually append 6 chars "foobar".

It is not clear to me what to do here:

* `file-position' can detect that the file is O_APPEND and return nil -
  this is a functionality loss in many ways - e.g., we cannot scroll
  back and read an O_RDWR|O_APPEND file.

* Accept that the code above will not do what the user expects for
  ___SOME___ streams.

* Add another `:direction' option -- `:unix-append' which will use
  `O_APPEND'.

I think the best course of action if the last one - it will be backwards
compatible and will not violate too many expectations.

For now the only course of action is to use FFI or syscall (not sure if
it can do that) to get a raw file descriptor and then wrap it into a
Lisp stream using [`make-stream`](http://clisp.org/impnotes/make-stream.html).

> To reproduce, touch my-append-only-file and:
> sudo chattr +a my-append-only-file
>
> and try:
>
> (with-open-file
>    (str "my-append-only-file" :direction :output :if-exists :append :if-does-not-exist :error)
>       (format str "~a~%" "Hello"))

-- 
Sam Steingold (http://sds.podval.org/) on darwin Ns 10.3.1504
http://steingoldpsychology.com http://www.childpsy.net http://think-israel.org
http://www.memritv.org http://jij.org http://no2bds.org
Those who can't write, write manuals.

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
clisp-list mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/clisp-list
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.