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