delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2001/08/14/09:32:07

X-Authentication-Warning: new-smtp1.ihug.com.au: Host p56-max18.syd.ihug.com.au [203.173.153.56] claimed to be acceleron
Message-ID: <015401c124c4$d13fbdd0$0a02a8c0@acceleron>
From: "Andrew Cottrell" <acottrel AT ihug DOT com DOT au>
To: <djgpp-workers AT delorie DOT com>, "Eli Zaretskii" <eliz AT is DOT elta DOT co DOT il>
Cc: "Charles Sandmann" <sandmann AT clio DOT rice DOT edu>
References: <00fe01c12311$92957890$0a02a8c0 AT acceleron> <4331-Mon13Aug2001125532+0300-eliz AT is DOT elta DOT co DOT il> <019701c123f9$6febae70$0a02a8c0 AT acceleron> <557-Mon13Aug2001165656+0300-eliz AT is DOT elta DOT co DOT il> <028c01c12405$d1b326e0$0a02a8c0 AT acceleron> <013d01c124bc$b4b1fe60$0a02a8c0 AT acceleron>
Subject: Re: Fw: Fstat.c patch
Date: Tue, 14 Aug 2001 23:27:06 +1000
MIME-Version: 1.0
X-Priority: 3
X-MSMail-Priority: Normal
X-Mailer: Microsoft Outlook Express 5.50.4807.1700
X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4807.1700
Reply-To: djgpp-workers AT delorie DOT com

> The plot thickens....
>
> > > > The link problem is that the existing code fails on the following if
> > > > condition as one of the stat buffers is from stat() and the other is
> > from
> > > > fstat().
> > > >   if (statbuf1.st_dev != statbuf2.st_dev)
> > > >   {
> > > >     (void)close(fd1);
> > > >     (void)close(fd2);
> > > >     (void)unlink(path2);
> > > >     errno = EXDEV;
> > > >     return -1;
> > > >   }
> > >
> > > The st_dev stuff comes from fstat, so the key for the problem is
> > > there.
> > >
> > > I think this happens because, as Charles reported earlier,
> > > _get_dev_info always returns zero for LFN handles, so all files look
> > > as if they were on drive A:.

info from debugging link.c:

statbuf1: stat  => {st_atime = 997793254, st_ctime = 997514192, st_dev = 3,
statbuf2: fstat => {st_atime = 997793324, st_ctime = 997793324, st_dev = 0,
ctd:
statbuf1: st_gid = 42, st_ino = 268435457, st_mode = 420, st_mtime =
997531106
statbuf2: st_gid = 42, st_ino = 268435458, st_mode = 420, st_mtime =
997793324

ctd:
statbuf1: st_nlink = 1, st_size = 279, st_blksize = 16384, st_uid = 42,
st_rdev = 0}
statbuf2: st_nlink = 1, st_size = 0,   st_blksize = 16384, st_uid = 42,
st_rdev = 0}

where
            dev_t    st_dev;       /* The drive number (0 = a:) */

You are correct in that it is exactly what Charles indicated previously that
this is an issue with _get_dev_info().

Why do stat() and lstat()/fstat() use a different methods to get st_dev?
Note that fstat() calles lstat().

The issue below is a different issue.
> > > If I'm right, setting LFN=n should cure this problem (of course, this
> > > is not the solution I propose for the library, just something to
test).
> > No the solution that I found worked was to change the stat() calls to
> > fstat() calls and the code in link.c then works. If this sounds okay
then
> I
> > can produce a patch tomorrow night. It's 12:30 AM at the moment.
> >
> > > > The flaw in the existing fstat() code is that the dos_major vaiable
is
> > > >  not setup on Win 98 with LFN enabled.
> > >
> > > Hmm?  Are you sure?  Could you please step with a debugger into fstat
> > > and see why doesn't dos_major get set?  I've just tried that on my
> > > Windows 98 system, and dos_major's value was 7.
> > I put a printf before the check and it printed 0.  I will do this
tomorrow
> > night.  I suspect that the following code did not call get_sft_entry().
I
> > will check this tomorrow night.
>
> Sorry, but I have verified that the code does work correctly depending on
> what you test. Le me exaplain as best I can and then ask some queries to
> help me resolve some of the issues.
>
> If I recompile the fstat.c code and define TEST then the test function
> included works and sets up the dos_major variable correctly. So if you
test
> the code by itself it works.
>
> If I recompile CP from fileutils using only the relevant files and step
> through the code then the code does NOT set up the dos_major variable,
it's
> set to zero. I have traced this to the djstart.c program which sets the
> _djstat_flags  to 0x34 in the static init_stat_bits() function. The
> definition for _STAT_NEEDS_SFT is 0x23 and as such if I and these together
I
> do NOT get 0 and as such the GNUC compiler does not call the
get_sft_entry()
> which in turn initalises the dos_version function.
>
> >   /* Get pointer to an SFT entry which holds data for our handle. */
> >   if ( (_djstat_flags & _STAT_NEEDS_SFT) == 0 &&
> >        (sft_idx = get_sft_entry(fhandle)) == -1)
> >     {
> >       errno = EBADF;
> >       return -1;
> >     }
>
> Now for the queries to help me try to find a correct solution:
> 1) Is it expected that the get_sft_entry() is not called in the scenario
> above? (I think the answer is no)
> 2) Is it expected that the dos_major is setup even if the get_sft_entry()
is
> not called? (I think the answer is yes)
> 3) Any suggestions as to where to head with this issue? (My gut feel is to
> always ensure that the init_stat() function is always called, once only of
> course. This will ensure that the dos_version and other variables are
setup
> correctly, but I need to look at this if people think this is the way to
go)
>
> I have a potential fix, but I need to double check it and test it on Win
2K
> and it also depends on the answers to the queries above if I am going in
the
> correct direction by calling the init_stat() function once as per quesry
3)
> above.
>
> I grepped the LIBC and found _djstat_flags  variable in the posix\stat
> directory and in the following applications (I don't have all the source
> installed for all of the DJGPP packeges):
>     bash-2.05\shell.c
>     filutil4.0\src\djstart.c
>     filutil4.0\src\ls-msdos.c
>
> I will have a quick look at the other posix\stat files to see if they are
> also potentially affected by similar problems.
>
> > > > The following code is the original code
> > > > and is not executed on Win 98 with LFN enabled, got caught by wrong
> > > > comments. My test app was CP from the file utils.
> > >
> > > I tried this with the simple test program produced from fstat.c if it
> > > is compiled with -DTEST.
> > >
> > > >                   r.x.ax = 0x71a6;      /* file info by handle */
> > > >                   r.x.bx = fhandle;
> > > >                   r.x.ds = __tb >> 4;
> > > >                   r.x.dx = 0;
> > > >                   __dpmi_int(0x21, &r);
> > > >                   if ((r.x.flags & 1) == 0
> > > >                        && (_farpeekl(dos_mem_base, __tb) & 0x07) ==
0)
> > > >                   stat_buf->st_mode |= WRITE_ACCESS; /* no R, S or H
> > bits set */
> > >
> > > It might be a good idea to look into the file attributes returned by
> > > 71A6: perhaps there's some indication of the drive letter there (my
> > > references are silent about all but the low 6 bits of that DWORD.
> >
> > Will look at this tomorrow night.
> The reason I think this failed was that the init_stat()  function was not
> called and as such the dos_mem_base was not setup  and the _farpeekl() asm
> code causes the crash. Traced it to the _farpeek SIGSEGV when dos_mem_base
> is not initialised.
>
>
>

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019