This is the mail archive of the cygwin@cygwin.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: cygwin-1.5.4-1 breaks fetchmail on Win9x


Jason,

Jason Tishler <jason@tishler.net> wrote:

> I do not have access to 9x so you will have to debug this further
> yourself.  Can you run fetchmail under strace or gdb?  If so, can you
> determine why the attempt to delete the lock file fails?

Actually, on a further look, I think I have - the problem is
one of two things, depending on how ulink() is supposed to function.

I've always been under the impression that files need to be closed before
unlink() - which I guess is from my DOS days. If this still holds true,
it's a simple case of lock_state() in lock.c (fetchmail) calling unlink
on the lockfile while it still has the file pointer opened. (Explicitly
doing fclose() before unlink() sees the stale lock file being removed
correctly). -If- that's how unlink is supposed to behave, that's
obviously why.

However, I was curious as to why the same fetchmail binary worked fine
with cygwin-1.3.22, and looked up the unlink() man page on linux and came
across:

   If the name was the last link to a file but any  processes 
   still have the file open the file will remain in existence
   until the last file descriptor referring to it is  closed.

Which seems to imply that unlinking a file while a process has it open is
fine, and it is deleted when fclose() is called. If I am correct in this
assumption, fetchmail's code is okay, but cygwin-1.5.5 on Win9x doesn't do
it:

#include <stdlib.h>
#include <stdio.h>

int main(void)
{
   FILE* fp;

   if( (fp = fopen("file.txt", "r")) != NULL){
      unlink("file.txt");
      fclose(fp);
   }
   return(0);
}

11:06pm uname -a
CYGWIN_98-4.10 scholars 1.5.5(0.94/3/2) 2003-09-20 16:31 i686 unknown unknown
Cygwin
11:06pm [ord@scholars ~] > gcc test.c
11:06pm [ord@scholars ~] > touch file.txt
11:06pm [ord@scholars ~] > ls -l file.txt
-rw-r--r--    1 ord      all             0 Oct  4 23:06 file.txt
11:06pm [ord@scholars ~] > ./a
11:07pm [ord@scholars ~] > ls -l file.txt
-rw-r--r--    1 ord      all             0 Oct  4 23:06 file.txt

> > As far as I can tell, this is a Win9x (Win98SE) issue. Testing
> > fetchmail on XP with cygwin-1.5.5-1 doesn't seem to suffer from this
> > problem
> 
> Could this be a FAT/FAT32 vs. NTFS issue instead?

Maybe, though it seems like a unlink() on 9x vs. a unlink() on NT issue
with cygwin-1.5.5.

11:08pm [ord@chimera ~] > uname -a
CYGWIN_NT-5.1 chimera 1.5.5(0.94/3/2) 2003-09-20 16:31 i686 unknown unknown
Cygwin
11:08pm [ord@chimera ~] > touch file.txt
11:08pm [ord@chimera ~] > ls -l file.txt
-rw-r--r--    1 ord      None            0 Oct  4 23:08 file.txt
11:08pm [ord@chimera ~] > gcc test.c
11:08pm [ord@chimera ~] > ./a
11:08pm [ord@chimera ~] > ls -l file.txt
/bin/ls: file.txt: No such file or directory

I realise this still could be a FAT vs. NTFS issue with unlink(), or more
approprately, probably the code that is responsible for deleting an
unlinked file when the handle is closed. But FWIW, that's where the
problem seems to lie.

I've done a strace, which I can post if it's helpful, but personally I couldn't
find anything useful in it.

But wait... :)

Okay, I could be wrong, but I've been going through the code for unlink() and
I might be onto something. Note, I've never looked at any code from winsup
before, but hopefully I'm not far from the mark.

The source for cygwin-1.3.22 has the line code segment
(winsup/cygwin/syscalls.cc - unlink() ):

if (GetFileAttributes (win32_name) == INVALID_FILE_ATTRIBUTES
    || (!win32_name.isremote () && wincap.has_delete_on_close ()))
{
  syscall_printf ("CreateFile (FILE_FLAG_DELETE_ON_CLOSE) succeeded");
  goto ok;
}
else
{
  syscall_printf ("CreateFile (FILE_FLAG_DELETE_ON_CLOSE) failed");
  SetFileAttributes (win32_name, (DWORD) win32_name & ~(FILE_ATTRIBUTE_READONLY
| FILE_ATTRIBUTE_SYSTEM));
}

The source for cygwin-1.5.5 has the line code segment:
(winsup/cygwin/syscalls.cc - unlink() - line 177):

if (GetFileAttributes (win32_name) == INVALID_FILE_ATTRIBUTES
    || !win32_name.isremote ())
{ 
   syscall_printf ("CreateFile (FILE_FLAG_DELETE_ON_CLOSE) succeeded");
   goto ok;
}
else
{ 
   syscall_printf ("CreateFile (FILE_FLAG_DELETE_ON_CLOSE) failed");
   if (setattrs)
      SetFileAttributes (win32_name, (DWORD) win32_name &
~(FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM));
   }
}

Notible is that wincap.has_delete_on_close() *isn't* called/checked
in the 1.5.5 code.

Looking in winsup/cygwin/wincap.cc (1.5.5), all the wincaps 'entries' (sorry,
the syntax of those is a bit foriegn) for win9x has
has_delete_on_close:false, (while all for NT is true). I assume that
the effect is that wincap.has_delete_on_close() returns false on win9x.

Personally, I've never noticed the WinAPI docs specifying that
FILE_FLAG_DELETE_ON_CLOSE doesn't work on win9x, but at the same time, I've
never used the flag before. Based on what I found in wincaps.cc,
I'm guess it doesn't. In which case, if it's required as part of the if
statement for correct behaviour on win9x, 1.5.5 is actually it's going into
the true part of the if (which it *is* according to strace) and not falling
into the DeleteFile() code later on when (if) FILE_FLAG_DELETE_ON_CLOSE is
failing, hence the file not being deleted.

It seems to make sense, because if FILE_FLAG_DELETE_ON_CLOSE doesn't
delete on win9x (and doesn't cause CreateFile() to return an error),
GetFileAttributes() will succeed on the still existing file after
CloseHandle(), indicating unlink() was successful (or will be successful
when every handle to the file is closed), even when the file isn't
deleted.

In short, I'm assuming that DeleteFile() is required for correct behaviour
of unlink() under Win9x, and it's simply not happening in cygwin-1.5.5,
where it was in cygwin-1.3.22. I can't see why any other code in unlink()
would be responsible for the problem.

That's my educated WAG at what is happening. Maybe someone who is more
familar with the code in question/cygwin1.dll code in general can look
into whether this assessment is correct or not.

Mark.

-- 
Mark Ord                               | Take an eye for an eye and make the
Melbourne, Australia                   | whole world blind.
mailto://ord@alphalink.com.au          |                  'God Gave Me A Gun'
http://www.alphalink.com.au/~ord/home/ |    - Roger Clyne & The Peacemakers -

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]