Rocksolid Light

Welcome to RetroBBS

mail  files  register  newsreader  groups  login

Message-ID:  

In computing, the mean time to failure keeps getting shorter.


devel / comp.lang.lisp / how to portably and atomically write a file?

SubjectAuthor
* how to portably and atomically write a file?Julieta Shem
+* Re: how to portably and atomically write a file?Spiros Bousbouras
|`* Re: how to portably and atomically write a file?Julieta Shem
| `* Re: how to portably and atomically write a file?Lawrence D'Oliveiro
|  `* Re: how to portably and atomically write a file?Julieta Shem
|   `* Re: how to portably and atomically write a file?Alan Bawden
|    +- Re: how to portably and atomically write a file?Lawrence D'Oliveiro
|    `* Re: how to portably and atomically write a file?Julieta Shem
|     `* Re: how to portably and atomically write a file?Alan Bawden
|      +- Re: how to portably and atomically write a file?Lawrence D'Oliveiro
|      `- Re: how to portably and atomically write a file?Julieta Shem
`* Re: how to portably and atomically write a file?Joerg Mertens
 `- Re: how to portably and atomically write a file?Julieta Shem

1
how to portably and atomically write a file?

<875xzojosa.fsf@yaxenu.org>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=17879&group=comp.lang.lisp#17879

  copy link   Newsgroups: comp.lang.lisp
Path: i2pn2.org!i2pn.org!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: jshem@yaxenu.org (Julieta Shem)
Newsgroups: comp.lang.lisp
Subject: how to portably and atomically write a file?
Date: Sat, 20 Jan 2024 07:13:25 -0300
Organization: A noiseless patient Spider
Lines: 19
Message-ID: <875xzojosa.fsf@yaxenu.org>
MIME-Version: 1.0
Content-Type: text/plain
Injection-Info: dont-email.me; posting-host="62ee3c425ded30f299d326f65aa702e0";
logging-data="3821277"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+M9Uz9yzWXh8nE9ijmuCG19ca3Ll1gvOI="
Cancel-Lock: sha1:kBkwauln0pH0OOr6To8xjDYrMEo=
sha1:CSSCsgYo/FUzeKVt6gzDml9vq3g=
 by: Julieta Shem - Sat, 20 Jan 2024 10:13 UTC

I need multiple processes to write files to the same directory, so I
need to atomically write. I found uiop's call-with-temporary-file and I
wrote the following.

(defun save-file (data)
(let ((tmp (uiop:call-with-temporary-file
(lambda (s p)
(write-sequence data s)
p)
:directory (merge-pathnames ".")
:keep t)))
(rename-file tmp "final-name.txt")))

That's just a prototype. The final-name will be calculated at run time.
The problem I have is that rename-file overwrites an existing file. I
need it not to do that so I can try again with a different name if the
choice of final name was already taken.

How do you guys do this? Thank you.

Re: how to portably and atomically write a file?

<hbPtaGxgbJvVZtP67@bongo-ra.co>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=17885&group=comp.lang.lisp#17885

  copy link   Newsgroups: comp.lang.lisp
Path: i2pn2.org!rocksolid2!news.neodome.net!news.mixmin.net!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: spibou@gmail.com (Spiros Bousbouras)
Newsgroups: comp.lang.lisp
Subject: Re: how to portably and atomically write a file?
Date: Sat, 20 Jan 2024 15:57:24 -0000 (UTC)
Organization: A noiseless patient Spider
Lines: 55
Message-ID: <hbPtaGxgbJvVZtP67@bongo-ra.co>
References: <875xzojosa.fsf@yaxenu.org>
MIME-Version: 1.0
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8bit
Injection-Date: Sat, 20 Jan 2024 15:57:24 -0000 (UTC)
Injection-Info: dont-email.me; posting-host="03400f2503c3eaaff6a9af6839acac68";
logging-data="3929687"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19KHykIySNxZBTOJM39Z2pI"
Cancel-Lock: sha1:Xt3KsmTSCH+qMmml/8nf6Gox8aY=
X-Server-Commands: nowebcancel
In-Reply-To: <875xzojosa.fsf@yaxenu.org>
X-Organisation: Weyland-Yutani
 by: Spiros Bousbouras - Sat, 20 Jan 2024 15:57 UTC

On Sat, 20 Jan 2024 07:13:25 -0300
Julieta Shem <jshem@yaxenu.org> wrote:
> I need multiple processes to write files to the same directory, so I
> need to atomically write. I found uiop's call-with-temporary-file and I
> wrote the following.
>
> (defun save-file (data)
> (let ((tmp (uiop:call-with-temporary-file
> (lambda (s p)
> (write-sequence data s)
> p)
> :directory (merge-pathnames ".")
> :keep t)))
> (rename-file tmp "final-name.txt")))
>
> That's just a prototype. The final-name will be calculated at run time.
> The problem I have is that rename-file overwrites an existing file.

I couldn't see anything in the CLHS which covers what happens if the file
already exists.

> I
> need it not to do that so I can try again with a different name if the
> choice of final name was already taken.
>
> How do you guys do this? Thank you.

Does "portably" mean without using anything outside Common Lisp ? If yes ,
then the only way I can think of is to get from somewhere a source of
random bytes (/dev/urandom on Linux) and each process will use this to
calculate a unique file name. It is not 100% certain that you will get
a unique file name but if you read enough bytes , then the probability
of getting twice the same sequence of bytes is so small that for practical
reasons you can treat it as 0.

If you are willing to use the FFI then you do it in the same way(s) you would
do it using C for your operating system.

On Linux/Unix I can think of 2 ways :

1. Each process atomically creates a lock file with a fixed name under the
directory , then calculates a file name , verifies that the directory does
not already have a file with this name , creates the file and then removes
the lock file.

2. Append to some fixed file name (pattern) the process ID which the
operating system guarantees is unique.

A possible 3rd way depends on how the processes get launched. If they all get
launched by the same process then that process first calculates a unique file
name for each process it launches and then passes it as a command line
argument or an environment variable or something.

--
vlaho.ninja/menu

Re: how to portably and atomically write a file?

<87le8jgbk3.fsf@yaxenu.org>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=17887&group=comp.lang.lisp#17887

  copy link   Newsgroups: comp.lang.lisp
Path: i2pn2.org!i2pn.org!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: jshem@yaxenu.org (Julieta Shem)
Newsgroups: comp.lang.lisp
Subject: Re: how to portably and atomically write a file?
Date: Sat, 20 Jan 2024 14:27:24 -0300
Organization: A noiseless patient Spider
Lines: 50
Message-ID: <87le8jgbk3.fsf@yaxenu.org>
References: <875xzojosa.fsf@yaxenu.org> <hbPtaGxgbJvVZtP67@bongo-ra.co>
MIME-Version: 1.0
Content-Type: text/plain
Injection-Info: dont-email.me; posting-host="62ee3c425ded30f299d326f65aa702e0";
logging-data="3960143"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18AXTOGzFkVsF67fSXbEY3soTD5jmOHO5E="
Cancel-Lock: sha1:qIqw9rWpko//7ZJ8MEVhLMNoKYA=
sha1:E7E2Z/yPf23kBLatOfheHd9k2r0=
 by: Julieta Shem - Sat, 20 Jan 2024 17:27 UTC

Spiros Bousbouras <spibou@gmail.com> writes:

> On Sat, 20 Jan 2024 07:13:25 -0300
> Julieta Shem <jshem@yaxenu.org> wrote:
>> I need multiple processes to write files to the same directory, so I
>> need to atomically write. I found uiop's call-with-temporary-file and I
>> wrote the following.
>>
>> (defun save-file (data)
>> (let ((tmp (uiop:call-with-temporary-file
>> (lambda (s p)
>> (write-sequence data s)
>> p)
>> :directory (merge-pathnames ".")
>> :keep t)))
>> (rename-file tmp "final-name.txt")))
>>
>> That's just a prototype. The final-name will be calculated at run time.
>> The problem I have is that rename-file overwrites an existing file.
>
> I couldn't see anything in the CLHS which covers what happens if the file
> already exists.
>
>> I need it not to do that so I can try again with a different name if
>> the choice of final name was already taken.
>>
>> How do you guys do this? Thank you.
>
> Does "portably" mean without using anything outside Common Lisp ?

I just meant that ideally it would work on typical Unix systems
including Windows. I'm okay with a solution that only works on the
typical Unix system.

> If yes , then the only way I can think of is to get from somewhere a
> source of random bytes (/dev/urandom on Linux) and each process will
> use this to calculate a unique file name.

[...]

I didn't express myself properly. What I need is an atomic operation to
let me know if a certain name is already taken and, if it is not taken,
take it. As far as I know on Unix sytems, this operation is rename. It
is atomic, but it must be stopped if it's already taken. (I'm afraid
rename is not atomic on Windows. But I'm totally willing to let Windows
go.)

I'm glad to know I can write a replacement for rename-file, but it
sounds strange to me that nobody writing Common Lisp ever needed this
before. Perhaps I'm writing C in Common Lisp.

Re: how to portably and atomically write a file?

<uohdia$3r4em$2@dont-email.me>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=17889&group=comp.lang.lisp#17889

  copy link   Newsgroups: comp.lang.lisp
Path: i2pn2.org!i2pn.org!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: ldo@nz.invalid (Lawrence D'Oliveiro)
Newsgroups: comp.lang.lisp
Subject: Re: how to portably and atomically write a file?
Date: Sat, 20 Jan 2024 21:22:18 -0000 (UTC)
Organization: A noiseless patient Spider
Lines: 7
Message-ID: <uohdia$3r4em$2@dont-email.me>
References: <875xzojosa.fsf@yaxenu.org> <hbPtaGxgbJvVZtP67@bongo-ra.co>
<87le8jgbk3.fsf@yaxenu.org>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Injection-Date: Sat, 20 Jan 2024 21:22:18 -0000 (UTC)
Injection-Info: dont-email.me; posting-host="e15dac640a9167fb7bc10933baa543b0";
logging-data="4035030"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19t7Tgoq2pzHTB97gLxdyHi"
User-Agent: Pan/0.155 (Kherson; fc5a80b8)
Cancel-Lock: sha1:S6RP5jdrld2rWpVhX4vM86cOgIs=
 by: Lawrence D'Oliv - Sat, 20 Jan 2024 21:22 UTC

On Sat, 20 Jan 2024 14:27:24 -0300, Julieta Shem wrote:

> What I need is an atomic operation to
> let me know if a certain name is already taken and, if it is not taken,
> take it.

Open with O_EXCL <https://manpages.debian.org/2/open.2.html>.

Re: how to portably and atomically write a file?

<87msszlllt.fsf@jmertens.eternal-september.org>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=17891&group=comp.lang.lisp#17891

  copy link   Newsgroups: comp.lang.lisp
Path: i2pn2.org!i2pn.org!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!jmertens.eternal-september.org!.POSTED!not-for-mail
From: joerg-mertens@t-online.de (Joerg Mertens)
Newsgroups: comp.lang.lisp
Subject: Re: how to portably and atomically write a file?
Date: Sat, 20 Jan 2024 22:51:26 +0100
Organization: privat
Lines: 9
Message-ID: <87msszlllt.fsf@jmertens.eternal-september.org>
References: <875xzojosa.fsf@yaxenu.org>
MIME-Version: 1.0
Content-Type: text/plain
Injection-Info: jmertens.eternal-september.org; posting-host="56d8661a124eac12c841904e7e930679";
logging-data="4044652"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/aFD2IlgheS7z7Kuv0QWfwhDTkh+1eFw0="
User-Agent: Gnus/5.13 (Gnus v5.13)
Cancel-Lock: sha1:3GR5W/DuLgSgmpLGqBDpllG5WLY=
sha1:ePaLsXPaMKT1hlnR985IGydcR6U=
 by: Joerg Mertens - Sat, 20 Jan 2024 21:51 UTC

Julieta Shem <jshem@yaxenu.org> writes:

> That's just a prototype. The final-name will be calculated at run time.
> The problem I have is that rename-file overwrites an existing file. I
> need it not to do that so I can try again with a different name if the
> choice of final name was already taken.

Don't know if this helps but GNU clisp throws an error if the target
file already exists.

Re: how to portably and atomically write a file?

<8734urfyag.fsf@yaxenu.org>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=17892&group=comp.lang.lisp#17892

  copy link   Newsgroups: comp.lang.lisp
Path: i2pn2.org!i2pn.org!news.hispagatos.org!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: jshem@yaxenu.org (Julieta Shem)
Newsgroups: comp.lang.lisp
Subject: Re: how to portably and atomically write a file?
Date: Sat, 20 Jan 2024 19:13:59 -0300
Organization: A noiseless patient Spider
Lines: 11
Message-ID: <8734urfyag.fsf@yaxenu.org>
References: <875xzojosa.fsf@yaxenu.org> <hbPtaGxgbJvVZtP67@bongo-ra.co>
<87le8jgbk3.fsf@yaxenu.org> <uohdia$3r4em$2@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain
Injection-Info: dont-email.me; posting-host="62ee3c425ded30f299d326f65aa702e0";
logging-data="4051307"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+1/tGO72qT5a2fHvhRD5SkJRLNhCRGiF8="
Cancel-Lock: sha1:rEX1W07FkWQxQDkRDqiA/B+n6Es=
sha1:lv+HyoZGhuxPqMaPKPtPLrx+XUA=
 by: Julieta Shem - Sat, 20 Jan 2024 22:13 UTC

Lawrence D'Oliveiro <ldo@nz.invalid> writes:

> On Sat, 20 Jan 2024 14:27:24 -0300, Julieta Shem wrote:
>
>> What I need is an atomic operation to
>> let me know if a certain name is already taken and, if it is not taken,
>> take it.
>
> Open with O_EXCL <https://manpages.debian.org/2/open.2.html>.

I don't understand. You mean I should write it in C?

Re: how to portably and atomically write a file?

<87wms3ejou.fsf@yaxenu.org>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=17893&group=comp.lang.lisp#17893

  copy link   Newsgroups: comp.lang.lisp
Path: i2pn2.org!i2pn.org!weretis.net!feeder6.news.weretis.net!feeder8.news.weretis.net!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: jshem@yaxenu.org (Julieta Shem)
Newsgroups: comp.lang.lisp
Subject: Re: how to portably and atomically write a file?
Date: Sat, 20 Jan 2024 19:14:41 -0300
Organization: A noiseless patient Spider
Lines: 13
Message-ID: <87wms3ejou.fsf@yaxenu.org>
References: <875xzojosa.fsf@yaxenu.org>
<87msszlllt.fsf@jmertens.eternal-september.org>
MIME-Version: 1.0
Content-Type: text/plain
Injection-Info: dont-email.me; posting-host="62ee3c425ded30f299d326f65aa702e0";
logging-data="4051307"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+OWCWQrzcld4UaLh/RvEzq7Yrh2qr0EOQ="
Cancel-Lock: sha1:GsgvxzzY4ia6qkeq48Jr0pXKJlk=
sha1:V0mcL8Gg/AYr+lIaSDu2w1MooEE=
 by: Julieta Shem - Sat, 20 Jan 2024 22:14 UTC

Joerg Mertens <joerg-mertens@t-online.de> writes:

> Julieta Shem <jshem@yaxenu.org> writes:
>
>> That's just a prototype. The final-name will be calculated at run time.
>> The problem I have is that rename-file overwrites an existing file. I
>> need it not to do that so I can try again with a different name if the
>> choice of final name was already taken.
>
> Don't know if this helps but GNU clisp throws an error if the target
> file already exists.

Interesting. It's one implementation where this would be possible.

Re: how to portably and atomically write a file?

<867ck3sjt5.fsf@williamsburg.bawden.org>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=17894&group=comp.lang.lisp#17894

  copy link   Newsgroups: comp.lang.lisp
Path: i2pn2.org!i2pn.org!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!bawden.eternal-september.org!.POSTED!not-for-mail
From: alan@csail.mit.edu (Alan Bawden)
Newsgroups: comp.lang.lisp
Subject: Re: how to portably and atomically write a file?
Date: Sat, 20 Jan 2024 17:48:22 -0500
Organization: ITS Preservation Society
Lines: 28
Message-ID: <867ck3sjt5.fsf@williamsburg.bawden.org>
References: <875xzojosa.fsf@yaxenu.org> <hbPtaGxgbJvVZtP67@bongo-ra.co>
<87le8jgbk3.fsf@yaxenu.org> <uohdia$3r4em$2@dont-email.me>
<8734urfyag.fsf@yaxenu.org>
MIME-Version: 1.0
Content-Type: text/plain
Injection-Info: bawden.eternal-september.org; posting-host="2b77ae6a2e844608cc7920e56cac7af0";
logging-data="4061375"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18/tEz2HdbeOy+Qnu1We6b3"
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.4 (gnu/linux)
Cancel-Lock: sha1:k1EOG9dW6aJms2u5vVBZWi+zg74=
sha1:hIxUQ7VrcEtLg2nqtJ/bh/plcts=
 by: Alan Bawden - Sat, 20 Jan 2024 22:48 UTC

Julieta Shem <jshem@yaxenu.org> writes:

Lawrence D'Oliveiro <ldo@nz.invalid> writes:

> On Sat, 20 Jan 2024 14:27:24 -0300, Julieta Shem wrote:
>
>> What I need is an atomic operation to
>> let me know if a certain name is already taken and, if it is not taken,
>> take it.
>
> Open with O_EXCL <https://manpages.debian.org/2/open.2.html>.

I don't understand. You mean I should write it in C?

If POSIX open() with O_EXCL really is a solution to your problem, then
you can do the same thing in pure Common Lisp by calling OPEN with
:IF-EXISTS :ERROR.

But you originally asked for a version of RENAME-FILE that renames
atomically but fails if the target already exists. If that's _really_
what you want, then even POSIX won't help you since POSIX rename()
always deletes the target if it exists.

If we knew what problem you were really trying to solve, then we might
be able to help you, but as it is, we're all just throwing ideas at you
in the hopes that something will stick.

- Alan

Re: how to portably and atomically write a file?

<uohj9i$3rub4$2@dont-email.me>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=17895&group=comp.lang.lisp#17895

  copy link   Newsgroups: comp.lang.lisp
Path: i2pn2.org!i2pn.org!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: ldo@nz.invalid (Lawrence D'Oliveiro)
Newsgroups: comp.lang.lisp
Subject: Re: how to portably and atomically write a file?
Date: Sat, 20 Jan 2024 23:00:02 -0000 (UTC)
Organization: A noiseless patient Spider
Lines: 11
Message-ID: <uohj9i$3rub4$2@dont-email.me>
References: <875xzojosa.fsf@yaxenu.org> <hbPtaGxgbJvVZtP67@bongo-ra.co>
<87le8jgbk3.fsf@yaxenu.org> <uohdia$3r4em$2@dont-email.me>
<8734urfyag.fsf@yaxenu.org> <867ck3sjt5.fsf@williamsburg.bawden.org>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Injection-Date: Sat, 20 Jan 2024 23:00:02 -0000 (UTC)
Injection-Info: dont-email.me; posting-host="942a1f970482f2e4dbf1b31185d2ff4b";
logging-data="4061540"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19/dVk3t8yqavba729A4VV1"
User-Agent: Pan/0.155 (Kherson; fc5a80b8)
Cancel-Lock: sha1:J7ULJmsM3mhAkwuN88zNkJUaSJE=
 by: Lawrence D'Oliv - Sat, 20 Jan 2024 23:00 UTC

On Sat, 20 Jan 2024 17:48:22 -0500, Alan Bawden wrote:

> ... even POSIX won't help you since POSIX rename()
> always deletes the target if it exists.

Notice also the new POSIX calls openat, renameat etc, which help to guard
against certain kinds of TOCTOU attacks using symlinks.

Linux also adds renameat2 <https://manpages.debian.org/2/rename.2.html>,
which lets you do some extra clever things, like exchanging file names,
and returning an error if a file with the new name already exists.

Re: how to portably and atomically write a file?

<87sf2rd1tm.fsf@yaxenu.org>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=17896&group=comp.lang.lisp#17896

  copy link   Newsgroups: comp.lang.lisp
Path: i2pn2.org!i2pn.org!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: jshem@yaxenu.org (Julieta Shem)
Newsgroups: comp.lang.lisp
Subject: Re: how to portably and atomically write a file?
Date: Sat, 20 Jan 2024 20:25:57 -0300
Organization: A noiseless patient Spider
Lines: 53
Message-ID: <87sf2rd1tm.fsf@yaxenu.org>
References: <875xzojosa.fsf@yaxenu.org> <hbPtaGxgbJvVZtP67@bongo-ra.co>
<87le8jgbk3.fsf@yaxenu.org> <uohdia$3r4em$2@dont-email.me>
<8734urfyag.fsf@yaxenu.org> <867ck3sjt5.fsf@williamsburg.bawden.org>
MIME-Version: 1.0
Content-Type: text/plain
Injection-Info: dont-email.me; posting-host="ea401732b71920533530d92eaf2a164d";
logging-data="4071787"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+gTcuf42NSe5zfU7GMrKBrEjLwOAltsOw="
Cancel-Lock: sha1:ONBzo3eh2CgltT/hB15ojCrJ494=
sha1:KPJGfjM5qcTy8H8/3jY/lei+r1k=
 by: Julieta Shem - Sat, 20 Jan 2024 23:25 UTC

Alan Bawden <alan@csail.mit.edu> writes:

> Julieta Shem <jshem@yaxenu.org> writes:
>
> Lawrence D'Oliveiro <ldo@nz.invalid> writes:
>
> > On Sat, 20 Jan 2024 14:27:24 -0300, Julieta Shem wrote:
> >
> >> What I need is an atomic operation to
> >> let me know if a certain name is already taken and, if it is not taken,
> >> take it.
> >
> > Open with O_EXCL <https://manpages.debian.org/2/open.2.html>.
>
> I don't understand. You mean I should write it in C?
>
> If POSIX open() with O_EXCL really is a solution to your problem, then
> you can do the same thing in pure Common Lisp by calling OPEN with
> :IF-EXISTS :ERROR.
>
> But you originally asked for a version of RENAME-FILE that renames
> atomically but fails if the target already exists. If that's _really_
> what you want, then even POSIX won't help you since POSIX rename()
> always deletes the target if it exists.
>
> If we knew what problem you were really trying to solve, then we might
> be able to help you, but as it is, we're all just throwing ideas at you
> in the hopes that something will stick.

I'm sorry if I didn't express myself properly. I'm writing an NNTP
service that stores articles in a directory. Each user is served by a
different service-process. When a user POSTs an article (POST is a verb
in the NNTP protocol), the service will write a new file in a directory
relative to the group. Two or more users could be posting at the same
time, so the strategy I came up with is to atomically write the article
by way of using a temporary file and renaming to the final name.

The final name is a string-integer that reflects the internal id of the
article---it's the greatest article number currently present plus one.
If two posts happen near in time, one will take the next id ahead of the
other, so the renaming of the second one would fail (or so I wished)
because a file with that name already exists, so the process can react
by increasing the file number once again, repeating that how many times
is necessary until it finds a free greatest id available. (I suppose
this might not be called an /algorithm/, but I guess in practice it
would work.)

I'm interested in any solution. Thank you.

I think the open-with-:IF-EXISTS-:ERROR strategy would not be good: that
implies I'd create the file with its final name, but then the service
could end up serving that not-yet-written article to another user who is
reading the group.

Re: how to portably and atomically write a file?

<8634ursewp.fsf@williamsburg.bawden.org>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=17899&group=comp.lang.lisp#17899

  copy link   Newsgroups: comp.lang.lisp
Path: i2pn2.org!i2pn.org!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!bawden.eternal-september.org!.POSTED!not-for-mail
From: alan@csail.mit.edu (Alan Bawden)
Newsgroups: comp.lang.lisp
Subject: Re: how to portably and atomically write a file?
Date: Sat, 20 Jan 2024 19:34:14 -0500
Organization: ITS Preservation Society
Lines: 16
Message-ID: <8634ursewp.fsf@williamsburg.bawden.org>
References: <875xzojosa.fsf@yaxenu.org> <hbPtaGxgbJvVZtP67@bongo-ra.co>
<87le8jgbk3.fsf@yaxenu.org> <uohdia$3r4em$2@dont-email.me>
<8734urfyag.fsf@yaxenu.org> <867ck3sjt5.fsf@williamsburg.bawden.org>
<87sf2rd1tm.fsf@yaxenu.org>
MIME-Version: 1.0
Content-Type: text/plain
Injection-Info: bawden.eternal-september.org; posting-host="ddef6e23bd7d59c42d69d72840f409cd";
logging-data="4088728"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18C7LlPKcZsNIx/AOjO5bYx"
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.4 (gnu/linux)
Cancel-Lock: sha1:puKOYyXt8BaU4IwvVvjq9XTjf0E=
sha1:UEucgKRAz2+AyB16H/001mmEm30=
 by: Alan Bawden - Sun, 21 Jan 2024 00:34 UTC

Sounds like you're trying to get the file system to solve too many
problems for you at the same time. I'd try separating the assignment of
sequential article numbers from the problem of choosing file names.

I've seen many systems that use file system directories as queues like
this, and I _think_ that I've never seen one that doesn't eventially
wind up using some kind of locking scheme to make something work.
Perhaps the presence of a magic file named "LOCK" means that the
directory is write-locked while some sensitive operation takes place.
Or perhaps something using POSIX's lockf().

Also don't write off the possibility that an actual database like SQLite
can help you out. SQLite is so ubiquitous so there is probably an
interface for it from whatever Common Lisp implementation you are using.

- Alan

Re: how to portably and atomically write a file?

<uohosn$3snct$1@dont-email.me>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=17900&group=comp.lang.lisp#17900

  copy link   Newsgroups: comp.lang.lisp
Path: i2pn2.org!i2pn.org!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: ldo@nz.invalid (Lawrence D'Oliveiro)
Newsgroups: comp.lang.lisp
Subject: Re: how to portably and atomically write a file?
Date: Sun, 21 Jan 2024 00:35:35 -0000 (UTC)
Organization: A noiseless patient Spider
Lines: 7
Message-ID: <uohosn$3snct$1@dont-email.me>
References: <875xzojosa.fsf@yaxenu.org> <hbPtaGxgbJvVZtP67@bongo-ra.co>
<87le8jgbk3.fsf@yaxenu.org> <uohdia$3r4em$2@dont-email.me>
<8734urfyag.fsf@yaxenu.org> <867ck3sjt5.fsf@williamsburg.bawden.org>
<87sf2rd1tm.fsf@yaxenu.org> <8634ursewp.fsf@williamsburg.bawden.org>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Injection-Date: Sun, 21 Jan 2024 00:35:35 -0000 (UTC)
Injection-Info: dont-email.me; posting-host="942a1f970482f2e4dbf1b31185d2ff4b";
logging-data="4087197"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19H7TsrjNYMCZZhXL67SCoa"
User-Agent: Pan/0.155 (Kherson; fc5a80b8)
Cancel-Lock: sha1:hLSMtNdMflK5YGdO8uCYfPiDibQ=
 by: Lawrence D'Oliv - Sun, 21 Jan 2024 00:35 UTC

On Sat, 20 Jan 2024 19:34:14 -0500, Alan Bawden wrote:

> Also don't write off the possibility that an actual database like SQLite
> can help you out.

I was going to suggest a DBMS, too. But I think a multi-user one might be
more appropriate in this case.

Re: how to portably and atomically write a file?

<87fryqbwnv.fsf@yaxenu.org>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=17911&group=comp.lang.lisp#17911

  copy link   Newsgroups: comp.lang.lisp
Path: i2pn2.org!rocksolid2!news.neodome.net!news.mixmin.net!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: jshem@yaxenu.org (Julieta Shem)
Newsgroups: comp.lang.lisp
Subject: Re: how to portably and atomically write a file?
Date: Sun, 21 Jan 2024 11:15:00 -0300
Organization: A noiseless patient Spider
Lines: 32
Message-ID: <87fryqbwnv.fsf@yaxenu.org>
References: <875xzojosa.fsf@yaxenu.org> <hbPtaGxgbJvVZtP67@bongo-ra.co>
<87le8jgbk3.fsf@yaxenu.org> <uohdia$3r4em$2@dont-email.me>
<8734urfyag.fsf@yaxenu.org> <867ck3sjt5.fsf@williamsburg.bawden.org>
<87sf2rd1tm.fsf@yaxenu.org> <8634ursewp.fsf@williamsburg.bawden.org>
MIME-Version: 1.0
Content-Type: text/plain
Injection-Info: dont-email.me; posting-host="e215d5c8f1e30e817a6586ce13ae5a25";
logging-data="231880"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+0nhlO93l0h58Gx2zqfzHpZ5x/g2MEkgM="
Cancel-Lock: sha1:1ZmI3XAMPHPc7i0xszSSO/QglM0=
sha1:4/XsDxbtZWnPZ989HJ8jehDmgrY=
 by: Julieta Shem - Sun, 21 Jan 2024 14:15 UTC

Alan Bawden <alan@csail.mit.edu> writes:

> Sounds like you're trying to get the file system to solve too many
> problems for you at the same time. I'd try separating the assignment of
> sequential article numbers from the problem of choosing file names.
>
> I've seen many systems that use file system directories as queues like
> this, and I _think_ that I've never seen one that doesn't eventially
> wind up using some kind of locking scheme to make something work.
> Perhaps the presence of a magic file named "LOCK" means that the
> directory is write-locked while some sensitive operation takes place.
> Or perhaps something using POSIX's lockf().

I think there's no escape from some locking because we have multiple
processes that need to write to a central database. I did not think
much when I decided for this---I'm writing this mainly for learning
Common Lisp. Initially I thought the atomic-via-rename would just do
it. I did not see that the serial-numbering of articles would be a
further obstacle.

But you gave me the following idea that I think will work. Let's use
open with :IF-EXISTS :ERROR with the addition that when the server
delivers articles to a client, it ignores files whose names end with
..tmp. Those are articles not completely written.

> Also don't write off the possibility that an actual database like SQLite
> can help you out. SQLite is so ubiquitous so there is probably an
> interface for it from whatever Common Lisp implementation you are using.

I'm using SBCL. There's /sqlite/ in Quicklisp. As a second
version---or even a first if I end up facing more obstacles---, it's
probably a very good idea to use SQLite.

1
server_pubkey.txt

rocksolid light 0.9.8
clearnet tor