From: "Юрий Соколов" Date: 2014-09-03T08:54:11+04:00 Subject: [ruby-core:64723] Re: [ruby-trunk - Feature #10181] [Open] New method File.openat() --bcaec53d5acbe6def60502220687 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable If you can reuse result of `opendir(dirname)` why you couldn't reuse result of `Dir.at(dirname)` ? 29.08.2014 11:55 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D0= =B5=D0=BB=D1=8C "Eric Wong" =D0=BD=D0=B0=D0=BF=D0= =B8=D1=81=D0=B0=D0=BB: > Joel VanderWerf wrote: > > On 08/28/2014 02:53 PM, Eric Wong wrote: > > >I like this feature. > > > > > >If matz approves, I assume you also want to add other *at functions? > > >e.g. fstatat, renameat, unlinkat, mkdirat, etc. > > > > Hm, that suggests... > > > > Dir.at(...).open(...) > > Dir.at(...).fstat(...) > > How would that be implemented? > > I don't see it working... > > The reason for *at functions is the file descriptor points to the > same file (directory) handle across multiple functions; in other words > it's a way to avoid race conditions by creating a private reference > to a container object (an FS directory) > > The file descriptor points to the same directory regardless of whether > it's renamed (moved) or not. > > One can think of FS operations as operations on Ruby hashes. > In your example, it might be like the following, assuming > "fs" is a giant hash protected by OS-wide locks: > > # Dir.at(dirname).open("foo") > fs[dirname]["foo"] # open("/dirname/foo", ...) > # another thread may replace/remove > # root[dirname] here > # Dir.at(dirname).open("bar") > fs[dirname]["bar"] # open("/dirname/bar", ...) > > We cannot guarantee Dir.at(dirname) / fs[dirname] returns > the same value twice when called in succession. > > openat lets you work like this: > > dh =3D fs[dirname] # dh =3D opendir(dirname) > dh["foo"] # openat(fileno(dh), "foo", ...) > dh["bar"] # openat(fileno(dh), "bar", ...) > ... > > Other threads can remove/replace/rename fs[dirname] with another > directory, but the directory handle from the initial lookup > remains valid to the thread which opened it. > --bcaec53d5acbe6def60502220687 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable

If you can reuse result of `opendir(dirname)` why you couldn= 't reuse result of `Dir.at(dirname)` ?

29.08.2014 11:55 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7= =D0=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8C "Eric Wong" <normalperson@yhbt.net> =D0=BD=D0= =B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:
Joel VanderWerf <joelvanderw= erf@gmail.com> wrote:
> On 08/28/2014 02:53 PM, Eric Wong wrote:
> >I like this feature.
> >
> >If matz approves, I assume you also want to add other *at function= s?
> >e.g. fstatat, renameat, unlinkat, mkdirat, etc.
>
> Hm, that suggests...
>
> Dir.at(...).open(...)
> Dir.at(...).fstat(...)

How would that be implemented?

I don't see it working...

The reason for *at functions is the file descriptor points to the
same file (directory) handle across multiple functions; in other words
it's a way to avoid race conditions by creating a private reference
to a container object (an FS directory)

The file descriptor points to the same directory regardless of whether
it's renamed (moved) or not.

One can think of FS operations as operations on Ruby hashes.
In your example, it might be like the following, assuming
"fs" is a giant hash protected by OS-wide locks:

=C2=A0 =C2=A0 # Dir.at(dirname).open("foo")
=C2=A0 =C2=A0 fs[dirname]["foo"]=C2=A0 # open("/dirname/foo&= quot;, ...)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0# another thread may replace/remove =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0# root[dirname] here
=C2=A0 =C2=A0 # Dir.at(dirname).open("bar")
=C2=A0 =C2=A0 fs[dirname]["bar"]=C2=A0 # open("/dirname/bar&= quot;, ...)

We cannot guarantee Dir.at(dirname) / fs[dirname] returns
the same value twice when called in succession.

openat lets you work like this:

=C2=A0 =C2=A0 dh =3D fs[dirname] # dh =3D opendir(dirname)
=C2=A0 =C2=A0 dh["foo"] # openat(fileno(dh), "foo", ...= )
=C2=A0 =C2=A0 dh["bar"] # openat(fileno(dh), "bar", ...= )
=C2=A0 =C2=A0 ...

Other threads can remove/replace/rename fs[dirname] with another
directory, but the directory handle from the initial lookup
remains valid to the thread which opened it.
--bcaec53d5acbe6def60502220687--