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)
This commit is contained in:
Po Lu 2024-06-11 10:04:16 +08:00
parent 5a576069fc
commit 9e96fbfd85

View 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)