Christopher Faylor wrote: > > I've built findutils from CVS and made it available as a test/experimental > version. > > This version is reputed to fix the problem the '-printf "%P"'. I don't > know if it also solves the mind-bogglingly awful problem of spurious > floppy access but if anyone is still functional after suffering from > this terrible affliction, it would be useful to know if this solves the > problem or not. > > This will be available at a mirror near you soon.
Okay. I just upgraded my findutils and now am facing the dreaded floppy seek problem as well. :-) I tried the above test version, but it does not solve the problem. Aside: I think I hit Yet Anoter Setup Bug (YASB) in that setup seems in capable to install the "prev" version of findutils, given the current version situation. It seems to be confused by the fact that Prev and Curr differ from Test in the format of the version number, i.e. x.y.z-n vs yyyymmdd-n. When I had the Curr version installed and cycle the selection to 4.1.7-4 to install the Prev version, it does not actually install anything. The Curr version remains installed on disk and when I rerun setup it still thinks that Curr is what is installed, despite having selected Prev previously. (No pun intended...) Anyway. Having not used a floppy disk in months, I immediately ruled out the MRU theory. This was annoying enough that I built a debug version of findutils from the 20041219-1 source and stepped through it with gdb. The floppy seek occurs in the following section of code in mountlist.c, starting at line 324: while ((mnt = getmntent (fp))) { me = xmalloc (sizeof *me); me->me_devname = xstrdup (mnt->mnt_fsname); me->me_mountdir = xstrdup (mnt->mnt_dir); me->me_type = xstrdup (mnt->mnt_type); me->me_type_malloced = 1; me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); me->me_remote = ME_REMOTE (me->me_devname, me->me_type); devopt = strstr (mnt->mnt_opts, "dev="); if (devopt) me->me_dev = strtoul (devopt + 4, NULL, 16); else me->me_dev = (dev_t) -1; /* Magic; means not known yet. */ /* Add to the linked list. */ *mtail = me; mtail = &me->me_next; } if (endmntent (fp) == 0) goto free_then_fail; This is a simple enumeration of the mounts. The following test case duplicates the code in find and also demonstrates the unwanted floppy seek. It is essentially the same as running "mount" with no options, which also results in a floppy seek.[1] #include <stdio.h> #include <errno.h> #include <unistd.h> #include <mntent.h> int main(int argc, char **argv) { struct mntent *mnt; char *table = MOUNTED; FILE *fp; fp = setmntent (table, "r"); if (fp == NULL) { perror("setmntent"); return 1; } while ((mnt = getmntent (fp))) { printf("fsname = %s, dir = %s, type = %s, opts = %s\n", mnt->mnt_fsname, mnt->mnt_dir, mnt->mnt_type, mnt->mnt_opts); } return 0; } Looking further, it seems that the seek occurs at the point when all the actual mounts have been enumerated and mount_info::getmntent() calls cygdrive_getmntent() to enumerate any drive letters not already represented by a mount. cygdrive_getmntent() contains the following code to search starting at "a:" and iterate through the letters: while (_my_tls.locals.available_drives) { for (/* nothing */; drive <= 'z'; mask <<= 1, drive++) if (_my_tls.locals.available_drives & mask) break; __small_sprintf (native_path, "%c:\\", drive); if (GetFileAttributes (native_path) == INVALID_FILE_ATTRIBUTES) { _my_tls.locals.available_drives &= ~mask; continue; } native_path[2] = '\0'; __small_sprintf (posix_path, "%s%c", mount_table->cygdrive, drive); ret = fillout_mntent (native_path, posix_path, mount_table->cygdrive_flags); break; } return ret; It is the call to GetFileAttributes("a:\\") which is causing the floppy seek, as the following testcase will demonstrate: #include <windows.h> int main(int argc, char **argv) { long res; res = GetFileAttributes("a:\\"); printf("res = %li", res); return 0; } If you compile this as a Cygwin app you get a floppy seek and res = -1 if there's no disk in the drive. If you compile it with -mno-cygwin you get a popup window that says "There is no disk in the drive. Please insert a disk into drive A:" with the all-so-familiar options Cancel, Try Again, Continue. (...flashback to "Abort, Retry, Fail?" from DOS v3.3!) So, the root cause here seems to be the fact that available_drives is populated by the following in setmntent(): _my_tls.locals.available_drives = GetLogicalDrives (); ...which means that bit 0 of available_drives is set since drive A: exists - but that means that it is later tested in the above cygdrive_getmntent() code which causes the seek. Possible solutions: - Find an API call to determine if a floppy is in the drive that does not cause a seek, and special case this for A: and B: checks in cygdrive_getmntent() instead of using GetFileAttributes(). - Filter the return value of GetLogicalDrives() so that bit 0 and bit 1 (A: and B:) are never set. - Initialize 'mask' and 'drive' to '1<<2' and 'c:' respectively in cygdrive_getmntent() to avoid checking the first two drives. Brian [1] I had always wondered why running "mount" to list the mount table caused a floppy seek. This has been the case for as long as I can remember, and certainly has nothing to do with findutils et al. -- 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/