From 973d2011a7165e9790ed645d6b286c0803f847f7 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Tue, 11 Jun 2024 10:04:16 +0800 Subject: [PATCH] Provide for negative PIDs on MS Windows * 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 | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/src/filelock.c b/src/filelock.c index 050cac565c9..f625b594d93 100644 --- a/src/filelock.c +++ b/src/filelock.c @@ -47,7 +47,21 @@ along with GNU Emacs. If not, see . */ #ifdef WINDOWSNT #include #include /* 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) -- 2.39.2