Subject: Re: bug#71477: 30.0.50; Lock files are not deleted on Windows 98

From: Eli Zaretskii <[email-masked]>
Date: Wed, 12 Jun 2024 11:25:44 +0300

> From: Po Lu <[email-masked]>
> Cc: [email-masked]
> Date: Tue, 11 Jun 2024 16:43:06 +0800
> 
> Eli Zaretskii <[email-masked]> writes:
> 
> > What inconsistencies, specifically?
> 
> Any older Emacs binary that encounters a lock file produced under
> Windows 9X will report an "Invalid argument" error until the user
> intervenes to delete this lock file.

I don't see how we can fix such problems retroactively.

> > The only possible issue I see with allowing a negative PID is that the
> > code checks for "pid > 0" or "pid < 0" somewhere; if that is the case,
> > we should replace those with comparisons with -1 instead.
> >
> > Can you test the above on Windows 9X when you have a chance?  Then we
> > could install it.
> 
> If it doesn't produce any adverse effect on modern Windows, and what I
> raised is not important, let's install it now, and I will test it as
> soon as may be, or it might fall by the wayside.

OK.  (It turns out we already knew about this issue, see the comments
in w32proc.c, search for "Hack for Windows 95".)

Paul, do you see any problems with the change below?  It worked for me
in some limited testing.  I intend to install it on the master branch
unless there are objections.

diff --git a/src/filelock.c b/src/filelock.c
index 050cac5..59fb47e 100644
--- a/src/filelock.c
+++ b/src/filelock.c
@@ -393,7 +393,9 @@ current_lock_owner (lock_info_type *owner, Lisp_Object lfname)
     return EINVAL;
 
   /* The PID is everything from the last '.' to the ':' or equivalent.  */
-  if (! c_isdigit (dot[1]))
+  if (! (c_isdigit (dot[1])
+	 /* Windows 9X report negative PID values.  */
+	 || (dot[1] == '-' && c_isdigit (dot[2]))))
     return EINVAL;
   errno = 0;
   pid = strtoimax (dot + 1, &owner->colon, 10);
@@ -451,7 +453,7 @@ current_lock_owner (lock_info_type *owner, Lisp_Object lfname)
     {
       if (pid == getpid ())
         return I_OWN_IT;
-      else if (0 < pid && pid <= TYPE_MAXIMUM (pid_t)
+      else if (pid != -1 && pid <= TYPE_MAXIMUM (pid_t)
                && (kill (pid, 0) >= 0 || errno == EPERM)
 	       && (boot_time == 0
 		   || (boot_time <= TYPE_MAXIMUM (time_t)