Hi,

Here's a quick and dirty patch to retry replacing in-use files.  Unless
setup is running in unattended mode, it will show an Abort/Retry/Ignore
dialog warning the user that a particular file was in-use.  The user can
"Retry" indefinitely, though the second and subsequent messages are going
to be a bit more stringent.  "Ignore" will prevent any further pop-ups
(the logic being that if even one file was set to be replaced on reboot,
might as well do all of them).

This worked for me in some limited testing, but is obviously not complete
(e.g., "Abort" doesn't work -- do we even need it?).

I'd like some comments from people on both the behavior and my
assumptions.  The patch was intentionally done in whitespace-indifferent
mode to make the actual changes easier to see, so please don't mention the
sloppy indentation. :-)  Just in case this gets passed with flying colors
and accepted into the codebase, I've included the ChangeLog below.
        Igor
==============================================================================
2006-02-14  Igor Peshansky  <[EMAIL PROTECTED]>

        * install.cc (Installer::installOne): If file is in use, ask the user
        to stop processes and retry.

-- 
                                http://cs.nyu.edu/~pechtcha/
      |\      _,,,---,,_            [EMAIL PROTECTED] | [EMAIL PROTECTED]
ZZZzz /,`.-'`'    -.  ;-;;,_            Igor Peshansky, Ph.D. (name changed!)
     |,4-  ) )-,_. ,\ (  `'-'           old name: Igor Pechtchanski
    '---''(_/--'  `-'\_) fL     a.k.a JaguaR-R-R-r-r-r-.-.-.  Meow!

"Las! je suis sot... -Mais non, tu ne l'es pas, puisque tu t'en rends compte."
"But no -- you are no fool; you call yourself a fool, there's proof enough in
that!" -- Rostand, "Cyrano de Bergerac"
Index: install.cc
===================================================================
RCS file: /cvs/cygwin-apps/setup/install.cc,v
retrieving revision 2.77
diff -u -p -w -r2.77 install.cc
--- install.cc  1 Sep 2005 16:39:27 -0000       2.77
+++ install.cc  15 Feb 2006 02:44:52 -0000
@@ -206,6 +206,7 @@ Installer::installOne (packagemeta &pkgm
   io_stream *tmp = io_stream::open (source.Cached (), "rb");
   io_stream *tmp2 = 0;
   archive *thefile = 0;
+  bool ignoreExtractErrors = unattended_mode;
   if (tmp)
     {
       tmp2 = compress::decompress (tmp);
@@ -253,8 +254,38 @@ Installer::installOne (packagemeta &pkgm
          Progress.SetText3 (canonicalfn.c_str());
          log (LOG_BABBLE) << "Installing file " << prefixURL << prefixPath 
             << fn << endLog;
-         if (archive::extract_file (thefile, prefixURL, prefixPath) != 0)
+         bool firstIteration = true;
+         while (archive::extract_file (thefile, prefixURL, prefixPath) != 0)
            {
+             if (!ignoreExtractErrors)
+               {
+                 char msg[fn.size() + 300];
+                 sprintf (msg,
+                          "%snable to extract %s -- the file is in use.\r\n"
+                          "Please stop %s Cygwin processes and select 
\"Retry\",\r\n"
+                          "or select \"Ignore\" to go on anyway (you will need 
to reboot).\r\n"
+                          "Select \"Abort\" to stop the installation\r\n",
+                          firstIteration?"U":"Still u", fn.c_str(), 
firstIteration?"all":"ALL");
+                 switch (MessageBox
+                         (NULL, msg, "In-use files detected",
+                          MB_ABORTRETRYIGNORE | MB_ICONWARNING | MB_TASKMODAL))
+                   {
+                   case IDRETRY:
+                     // retry
+                     firstIteration = false;
+                     continue;
+                   case IDABORT:
+                     MessageBox(NULL, "This option is ignored for now",
+                                "Option ignored", MB_OK | MB_ICONINFORMATION | 
MB_TASKMODAL);
+                     break;
+                   case IDIGNORE:
+                     ignoreExtractErrors = true;
+                     break;
+                   default:
+                     break;
+                   }
+                 // fall through to previous functionality
+               }
              if (NoReplaceOnReboot)
                {
                  ++errors;
@@ -324,6 +355,8 @@ Installer::installOne (packagemeta &pkgm
                        }
                    }
                }
+             // We're done with this file
+             break;
            }
          progress (tmp->tell ());
          num_installs++;

Reply via email to