]> git.eshelyaron.com Git - emacs.git/commitdiff
Provide for negative PIDs on MS Windows
authorPo Lu <luangruo@yahoo.com>
Tue, 11 Jun 2024 02:04:16 +0000 (10:04 +0800)
committerEshel Yaron <me@eshelyaron.com>
Wed, 12 Jun 2024 09:27:29 +0000 (11:27 +0200)
* src/filelock.c (pid_t, getpid_for_lock, pidintmax, EPRIdMAX):
New macros; define to unsigned long or corresponding values if
WINDOWSNT.
(lock_file_1, current_lock_owner): Replace intmax_t, getpid,
pid_t and the like with the aforementioned macros.  (bug#71477)

(cherry picked from commit 9e96fbfd855bf0acc005b2b0973c2a9aef7cdcd2)

src/filelock.c

index 050cac565c9c9454a4d93b45c739274b378c622c..f625b594d93da39ba88d96108feafde2977e5a7a 100644 (file)
@@ -47,7 +47,21 @@ along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.  */
 #ifdef WINDOWSNT
 #include <share.h>
 #include <sys/socket.h>        /* for fcntl */
-#endif
+
+/* getpid is liable to return negative values, which the lock string
+   parser cannot grok, but Windows process IDs are DWORDS, i.e.,
+   representable as unsigned longs.  (bug#71477) */
+#define pid_t unsigned long
+#define getpid_for_lock() ((unsigned long) getpid ())
+#define pidintmax unsigned long
+#define EPRIdMAX "lu"
+#define pid_strtoimax strtoul
+#else /* !WINDOWSNT */
+#define pidintmax intmax_t
+#define EPRIdMAX PRIdMAX
+#define getpid_for_lock() getpid ()
+#define strtoimax strtoimax
+#endif /* WIDNOWSNT */
 
 #ifndef MSDOS
 
@@ -281,11 +295,11 @@ lock_file_1 (Lisp_Object lfname, bool force)
   char const *user_name = STRINGP (luser_name) ? SSDATA (luser_name) : "";
   char const *host_name = STRINGP (lhost_name) ? SSDATA (lhost_name) : "";
   char lock_info_str[MAX_LFINFO + 1];
-  intmax_t pid = getpid ();
+  pidintmax pid = getpid_for_lock ();
 
   char const *lock_info_fmt = (boot
-                              ? "%s@%s.%"PRIdMAX":%"PRIdMAX
-                              : "%s@%s.%"PRIdMAX);
+                              ? "%s@%s.%"EPRIdMAX":%"PRIdMAX
+                              : "%s@%s.%"EPRIdMAX);
   int len = snprintf (lock_info_str, sizeof lock_info_str,
                      lock_info_fmt, user_name, host_name, pid, boot);
   if (! (0 <= len && len < sizeof lock_info_str))
@@ -367,7 +381,8 @@ current_lock_owner (lock_info_type *owner, Lisp_Object lfname)
 {
   lock_info_type local_owner;
   ptrdiff_t lfinfolen;
-  intmax_t pid, boot_time;
+  intmax_t boot_time;
+  pidintmax pid;
   char *at, *dot, *lfinfo_end;
 
   /* Even if the caller doesn't want the owner info, we still have to
@@ -396,7 +411,7 @@ current_lock_owner (lock_info_type *owner, Lisp_Object lfname)
   if (! c_isdigit (dot[1]))
     return EINVAL;
   errno = 0;
-  pid = strtoimax (dot + 1, &owner->colon, 10);
+  pid = pid_strtoimax (dot + 1, &owner->colon, 10);
   if (errno == ERANGE)
     pid = -1;
 
@@ -441,7 +456,7 @@ current_lock_owner (lock_info_type *owner, Lisp_Object lfname)
   /* Protect against the extremely unlikely case of the host name
      containing an @ character.  */
   else if (strchr (SSDATA (system_name), '@'))
-    system_name = CALLN (Ffuncall, intern ("string-replace"),
+    system_name = CALLN (Ffuncall, Qstring_replace,
                         build_string ("@"), build_string ("-"),
                         system_name);
   /* On current host?  */
@@ -449,7 +464,7 @@ current_lock_owner (lock_info_type *owner, Lisp_Object lfname)
       && dot - (at + 1) == SBYTES (system_name)
       && memcmp (at + 1, SSDATA (system_name), SBYTES (system_name)) == 0)
     {
-      if (pid == getpid ())
+      if (pid == getpid_for_lock ())
         return I_OWN_IT;
       else if (0 < pid && pid <= TYPE_MAXIMUM (pid_t)
                && (kill (pid, 0) >= 0 || errno == EPERM)