diff options
| author | Po Lu | 2024-06-11 10:04:16 +0800 |
|---|---|---|
| committer | Po Lu | 2024-06-11 10:05:14 +0800 |
| commit | 9e96fbfd855bf0acc005b2b0973c2a9aef7cdcd2 (patch) | |
| tree | 32dd8d123af586683cec9636028c637f26eaaa3c | |
| parent | 5a576069fcd803a6a5260a2da8ce0862be982eb4 (diff) | |
| download | emacs-9e96fbfd855bf0acc005b2b0973c2a9aef7cdcd2.tar.gz emacs-9e96fbfd855bf0acc005b2b0973c2a9aef7cdcd2.zip | |
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)
| -rw-r--r-- | src/filelock.c | 31 |
1 files 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 <https://www.gnu.org/licenses/>. */ | |||
| 47 | #ifdef WINDOWSNT | 47 | #ifdef WINDOWSNT |
| 48 | #include <share.h> | 48 | #include <share.h> |
| 49 | #include <sys/socket.h> /* for fcntl */ | 49 | #include <sys/socket.h> /* for fcntl */ |
| 50 | #endif | 50 | |
| 51 | /* getpid is liable to return negative values, which the lock string | ||
| 52 | parser cannot grok, but Windows process IDs are DWORDS, i.e., | ||
| 53 | representable as unsigned longs. (bug#71477) */ | ||
| 54 | #define pid_t unsigned long | ||
| 55 | #define getpid_for_lock() ((unsigned long) getpid ()) | ||
| 56 | #define pidintmax unsigned long | ||
| 57 | #define EPRIdMAX "lu" | ||
| 58 | #define pid_strtoimax strtoul | ||
| 59 | #else /* !WINDOWSNT */ | ||
| 60 | #define pidintmax intmax_t | ||
| 61 | #define EPRIdMAX PRIdMAX | ||
| 62 | #define getpid_for_lock() getpid () | ||
| 63 | #define strtoimax strtoimax | ||
| 64 | #endif /* WIDNOWSNT */ | ||
| 51 | 65 | ||
| 52 | #ifndef MSDOS | 66 | #ifndef MSDOS |
| 53 | 67 | ||
| @@ -281,11 +295,11 @@ lock_file_1 (Lisp_Object lfname, bool force) | |||
| 281 | char const *user_name = STRINGP (luser_name) ? SSDATA (luser_name) : ""; | 295 | char const *user_name = STRINGP (luser_name) ? SSDATA (luser_name) : ""; |
| 282 | char const *host_name = STRINGP (lhost_name) ? SSDATA (lhost_name) : ""; | 296 | char const *host_name = STRINGP (lhost_name) ? SSDATA (lhost_name) : ""; |
| 283 | char lock_info_str[MAX_LFINFO + 1]; | 297 | char lock_info_str[MAX_LFINFO + 1]; |
| 284 | intmax_t pid = getpid (); | 298 | pidintmax pid = getpid_for_lock (); |
| 285 | 299 | ||
| 286 | char const *lock_info_fmt = (boot | 300 | char const *lock_info_fmt = (boot |
| 287 | ? "%s@%s.%"PRIdMAX":%"PRIdMAX | 301 | ? "%s@%s.%"EPRIdMAX":%"PRIdMAX |
| 288 | : "%s@%s.%"PRIdMAX); | 302 | : "%s@%s.%"EPRIdMAX); |
| 289 | int len = snprintf (lock_info_str, sizeof lock_info_str, | 303 | int len = snprintf (lock_info_str, sizeof lock_info_str, |
| 290 | lock_info_fmt, user_name, host_name, pid, boot); | 304 | lock_info_fmt, user_name, host_name, pid, boot); |
| 291 | if (! (0 <= len && len < sizeof lock_info_str)) | 305 | if (! (0 <= len && len < sizeof lock_info_str)) |
| @@ -367,7 +381,8 @@ current_lock_owner (lock_info_type *owner, Lisp_Object lfname) | |||
| 367 | { | 381 | { |
| 368 | lock_info_type local_owner; | 382 | lock_info_type local_owner; |
| 369 | ptrdiff_t lfinfolen; | 383 | ptrdiff_t lfinfolen; |
| 370 | intmax_t pid, boot_time; | 384 | intmax_t boot_time; |
| 385 | pidintmax pid; | ||
| 371 | char *at, *dot, *lfinfo_end; | 386 | char *at, *dot, *lfinfo_end; |
| 372 | 387 | ||
| 373 | /* Even if the caller doesn't want the owner info, we still have to | 388 | /* 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) | |||
| 396 | if (! c_isdigit (dot[1])) | 411 | if (! c_isdigit (dot[1])) |
| 397 | return EINVAL; | 412 | return EINVAL; |
| 398 | errno = 0; | 413 | errno = 0; |
| 399 | pid = strtoimax (dot + 1, &owner->colon, 10); | 414 | pid = pid_strtoimax (dot + 1, &owner->colon, 10); |
| 400 | if (errno == ERANGE) | 415 | if (errno == ERANGE) |
| 401 | pid = -1; | 416 | pid = -1; |
| 402 | 417 | ||
| @@ -441,7 +456,7 @@ current_lock_owner (lock_info_type *owner, Lisp_Object lfname) | |||
| 441 | /* Protect against the extremely unlikely case of the host name | 456 | /* Protect against the extremely unlikely case of the host name |
| 442 | containing an @ character. */ | 457 | containing an @ character. */ |
| 443 | else if (strchr (SSDATA (system_name), '@')) | 458 | else if (strchr (SSDATA (system_name), '@')) |
| 444 | system_name = CALLN (Ffuncall, intern ("string-replace"), | 459 | system_name = CALLN (Ffuncall, Qstring_replace, |
| 445 | build_string ("@"), build_string ("-"), | 460 | build_string ("@"), build_string ("-"), |
| 446 | system_name); | 461 | system_name); |
| 447 | /* On current host? */ | 462 | /* On current host? */ |
| @@ -449,7 +464,7 @@ current_lock_owner (lock_info_type *owner, Lisp_Object lfname) | |||
| 449 | && dot - (at + 1) == SBYTES (system_name) | 464 | && dot - (at + 1) == SBYTES (system_name) |
| 450 | && memcmp (at + 1, SSDATA (system_name), SBYTES (system_name)) == 0) | 465 | && memcmp (at + 1, SSDATA (system_name), SBYTES (system_name)) == 0) |
| 451 | { | 466 | { |
| 452 | if (pid == getpid ()) | 467 | if (pid == getpid_for_lock ()) |
| 453 | return I_OWN_IT; | 468 | return I_OWN_IT; |
| 454 | else if (0 < pid && pid <= TYPE_MAXIMUM (pid_t) | 469 | else if (0 < pid && pid <= TYPE_MAXIMUM (pid_t) |
| 455 | && (kill (pid, 0) >= 0 || errno == EPERM) | 470 | && (kill (pid, 0) >= 0 || errno == EPERM) |