Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 23 Aug 2017 13:09:38 +0100
From:      Martin Simmons <martin@lispworks.com>
To:        freebsd-fs@freebsd.org
Subject:   Re: Can telldir() == 0 value be made special?
Message-ID:  <201708231209.v7NC9cYk008393@higson.cam.lispworks.com>
In-Reply-To: <CAG6CVpWf33CxbVJLtr-2-NESdoiPUWQHfcL_qaYrCUR2kQFS4g@mail.gmail.com> (message from Conrad Meyer on Tue, 22 Aug 2017 12:05:29 -0700)
References:  <87bmn7kf3b.fsf@vostro.rath.org> <CAG6CVpVViqnbGuVn_JETBC5Q0NoYfC4VJK7iWjEfA7tFurQ2ag@mail.gmail.com> <87lgmbfob2.fsf@vostro.rath.org> <CAF6rxg=J7TYQQtG4%2B9TzEPPAb7LTReAm6U3A19Aq24PWrnK4vw@mail.gmail.com> <CAG6CVpWf33CxbVJLtr-2-NESdoiPUWQHfcL_qaYrCUR2kQFS4g@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
Does this solution (and the previous one) need to check for dd_seek == 0 as
well?  It looks like dd_loc == 0 is also true after readdir has returned NULL
for eof.

__Martin


>>>>> On Tue, 22 Aug 2017 12:05:29 -0700, Conrad Meyer said:
> 
> One could also make it reserve the zero slot for the loc == 0 entry,
> but not create it dynamically.  Just set loccnt=1 at initialization
> and then special-case dd_loc==0.  Like this:
> 
> --- a/lib/libc/gen/opendir.c
> +++ b/lib/libc/gen/opendir.c
> @@ -295,7 +295,7 @@ __opendir_common(int fd, int flags, bool use_current_pos)
>         dirp->dd_lock = NULL;
>         dirp->dd_td = (struct _telldir *)((char *)dirp + sizeof(DIR));
>         LIST_INIT(&dirp->dd_td->td_locq);
> -       dirp->dd_td->td_loccnt = 0;
> +       dirp->dd_td->td_loccnt = 1;
>         dirp->dd_compat_de = NULL;
> 
>         /*
> --- a/lib/libc/gen/telldir.c
> +++ b/lib/libc/gen/telldir.c
> @@ -76,7 +76,10 @@ telldir(DIR *dirp)
>                                 _pthread_mutex_unlock(&dirp->dd_lock);
>                         return (-1);
>                 }
> -               lp->loc_index = dirp->dd_td->td_loccnt++;
> +               if (dirp->dd_loc == 0)
> +                       lp->loc_index = 0;
> +               else
> +                       lp->loc_index = dirp->dd_td->td_loccnt++;
>                 lp->loc_seek = dirp->dd_seek;
>                 lp->loc_loc = dirp->dd_loc;
>                 if (flp != NULL)
> 
> Best,
> Conrad
> 
> 
> On Tue, Aug 22, 2017 at 11:35 AM, Eitan Adler <lists@eitanadler.com> wrote:
> > On 22 August 2017 at 14:30, Nikolaus Rath <Nikolaus@rath.org> wrote:
> >> On Aug 22 2017, Conrad Meyer <cem@freebsd.org> wrote:
> >>> Hi Nikolaus,
> >>>
> >>> As you have surmised, DIR* seekpoints are created dynamically whenever
> >>> requested by user's telldir() call:
> >>
> >> Good to know, thanks!
> >>
> >>> I believe we could special case zero without breaking ABI
> >>> compatibility of correct programs.  Something like this:
> >>>
> >>> --- a/lib/libc/gen/telldir.c
> >>> +++ b/lib/libc/gen/telldir.c
> >>> @@ -70,6 +70,20 @@ telldir(DIR *dirp)
> >>>                 }
> >>>         }
> >>>         if (lp == NULL) {
> >>> +               /* Create special zero telldir entry, similar to Linux */
> >>> +               if (dirp->dd_td->td_loccnt == 0 && dirp->dd_loc != 0) {
> >>> +                       lp = malloc(sizeof(struct ddloc));
> >>> +                       if (lp == NULL) {
> >>> +                               if (__isthreaded)
> >>> +                                       _pthread_mutex_unlock(&dirp->dd_lock);
> >>> +                               return (-1);
> >>> +                       }
> >>> +                       lp->loc_index = dirp->dd_td->td_loccnt++;
> >>> +                       lp->loc_seek = 0;
> >>> +                       lp->loc_loc = 0;
> >>> +                       LIST_INSERT_HEAD(&dirp->dd_td->td_locq, lp, loc_lqe);
> >>> +               }
> >>> +
> >>>                 lp = malloc(sizeof(struct ddloc));
> >>>                 if (lp == NULL) {
> >>>                         if (__isthreaded)
> >>>
> >>> I don't know if there are any downsides to special-casing zero like
> >>> this, other than additional code complexity.
> >>
> >> This seems a little more complex than I would have expected.
> >
> >> Is this
> >> maybe turning zero into a valid argument for seekdir() even if telldir()
> >> has never been called?
> >
> > No, this code is called inside of telldir. I'd be against adding that
> > behavior by contract since it complicates the contract of seekdir. No
> > objection to this behavior by implementation though if it is simpler
> > than modifying telldir (doubtful).
> >
> > What this is doing is ensuring that there will always be a 0 entry
> > *after* telldir is called, and that seekdir(0) will return to the
> > start of the directory if called with an argument of 0.
> >
> >
> >> That would be even better, but the minimal change that I need is just to
> >> ensure that telldir() either (a) never returns zero, or (b) only returns
> >> zero if called at the beginning of the stream.
> _______________________________________________
> freebsd-fs@freebsd.org mailing list
> https://lists.freebsd.org/mailman/listinfo/freebsd-fs
> To unsubscribe, send any mail to "freebsd-fs-unsubscribe@freebsd.org"
> 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201708231209.v7NC9cYk008393>