Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com Message-ID: <3F7F77B0.853C8E40@alphalink.com.au> Date: Sun, 05 Oct 2003 11:45:20 +1000 From: Mark Ord X-Accept-Language: en MIME-Version: 1.0 To: cygwin AT cygwin DOT com Subject: Re: cygwin-1.5.4-1 breaks fetchmail on Win9x Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Jason, Jason Tishler 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 #include 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 AT scholars ~] > gcc test.c 11:06pm [ord AT scholars ~] > touch file.txt 11:06pm [ord AT scholars ~] > ls -l file.txt -rw-r--r-- 1 ord all 0 Oct 4 23:06 file.txt 11:06pm [ord AT scholars ~] > ./a 11:07pm [ord AT 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 AT 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 AT chimera ~] > touch file.txt 11:08pm [ord AT chimera ~] > ls -l file.txt -rw-r--r-- 1 ord None 0 Oct 4 23:08 file.txt 11:08pm [ord AT chimera ~] > gcc test.c 11:08pm [ord AT chimera ~] > ./a 11:08pm [ord AT 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 AT alphalink DOT com DOT 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/