aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2024-08-15 12:58:19 -0700
committerPaul Eggert2024-08-15 13:31:31 -0700
commit4b6b9a7acdc4f7d0594caaaa382e2e633f8f1225 (patch)
tree6b522f0bca6835c62d10692b89be22638d27f185 /src
parentcbacdca9e3f6dcf9b88704391f06daf7301608b0 (diff)
downloademacs-4b6b9a7acdc4f7d0594caaaa382e2e633f8f1225.tar.gz
emacs-4b6b9a7acdc4f7d0594caaaa382e2e633f8f1225.zip
Avoid some GC when locking/unlocking files
* src/filelock.c (lock_file_1, current_lock_owner): Don’t possibly invoke the garbage collector when comparing lock file contents to host names.
Diffstat (limited to 'src')
-rw-r--r--src/filelock.c62
1 files changed, 37 insertions, 25 deletions
diff --git a/src/filelock.c b/src/filelock.c
index 55ab15feb8d..cdf9e6f0ffc 100644
--- a/src/filelock.c
+++ b/src/filelock.c
@@ -271,27 +271,29 @@ lock_file_1 (Lisp_Object lfname, bool force)
271 intmax_t boot = get_boot_sec (); 271 intmax_t boot = get_boot_sec ();
272 Lisp_Object luser_name = Fuser_login_name (Qnil); 272 Lisp_Object luser_name = Fuser_login_name (Qnil);
273 Lisp_Object lhost_name = Fsystem_name (); 273 Lisp_Object lhost_name = Fsystem_name ();
274
275 /* Protect against the extremely unlikely case of the host name
276 containing an @ character. */
277 if (!NILP (lhost_name) && strchr (SSDATA (lhost_name), '@'))
278 lhost_name = CALLN (Ffuncall, Qstring_replace,
279 build_string ("@"), build_string ("-"),
280 lhost_name);
281
282 char const *user_name = STRINGP (luser_name) ? SSDATA (luser_name) : ""; 274 char const *user_name = STRINGP (luser_name) ? SSDATA (luser_name) : "";
283 char const *host_name = STRINGP (lhost_name) ? SSDATA (lhost_name) : ""; 275 char const *host_name = STRINGP (lhost_name) ? SSDATA (lhost_name) : "";
284 char lock_info_str[MAX_LFINFO + 1]; 276 char lock_info_str[MAX_LFINFO + 1];
285 intmax_t pid = getpid (); 277 intmax_t pid = getpid ();
286 278
287 char const *lock_info_fmt = (boot 279 int room = sizeof lock_info_str;
288 ? "%s@%s.%"PRIdMAX":%"PRIdMAX 280 int len = snprintf (lock_info_str, room, "%s@", user_name);
289 : "%s@%s.%"PRIdMAX);
290 int len = snprintf (lock_info_str, sizeof lock_info_str,
291 lock_info_fmt, user_name, host_name, pid, boot);
292 if (! (0 <= len && len < sizeof lock_info_str)) 281 if (! (0 <= len && len < sizeof lock_info_str))
293 return ENAMETOOLONG; 282 return ENAMETOOLONG;
294 283 /* Protect against the extremely unlikely case of the host name
284 containing an @ character. */
285 for (; *host_name; len++, host_name++)
286 {
287 if (! (len < sizeof lock_info_str - 1))
288 return ENAMETOOLONG;
289 lock_info_str[len] = *host_name == '@' ? '-' : *host_name;
290 }
291 char const *lock_info_fmt = boot ? ".%"PRIdMAX":%"PRIdMAX : ".%"PRIdMAX;
292 room = sizeof lock_info_str - len;
293 int suffixlen = snprintf (lock_info_str + len, room,
294 lock_info_fmt, pid, boot);
295 if (! (0 <= suffixlen && suffixlen < room))
296 return ENAMETOOLONG;
295 return create_lock_file (SSDATA (lfname), lock_info_str, force); 297 return create_lock_file (SSDATA (lfname), lock_info_str, force);
296} 298}
297 299
@@ -448,22 +450,32 @@ current_lock_owner (lock_info_type *owner, Lisp_Object lfname)
448 if (lfinfo_end != owner->user + lfinfolen) 450 if (lfinfo_end != owner->user + lfinfolen)
449 return EINVAL; 451 return EINVAL;
450 452
453 char *linkhost = at + 1;
454 ptrdiff_t linkhostlen = dot - linkhost;
451 Lisp_Object system_name = Fsystem_name (); 455 Lisp_Object system_name = Fsystem_name ();
452 /* If `system-name' returns nil, that means we're in a 456 /* If `system-name' returns nil, that means we're in a
453 --no-build-details Emacs, and the name part of the link (e.g., 457 --no-build-details Emacs, and the name part of the link (e.g.,
454 .#test.txt -> larsi@.118961:1646577954) is an empty string. */ 458 .#test.txt -> larsi@.118961:1646577954) is an empty string. */
459 bool on_current_host;
455 if (NILP (system_name)) 460 if (NILP (system_name))
456 system_name = build_string (""); 461 on_current_host = linkhostlen == 0;
457 /* Protect against the extremely unlikely case of the host name 462 else
458 containing an @ character. */ 463 {
459 else if (strchr (SSDATA (system_name), '@')) 464 on_current_host = linkhostlen == SBYTES (system_name);
460 system_name = CALLN (Ffuncall, intern ("string-replace"), 465 if (on_current_host)
461 build_string ("@"), build_string ("-"), 466 {
462 system_name); 467 /* Protect against the extremely unlikely case of the host
463 /* On current host? */ 468 name containing '@'. */
464 if (STRINGP (system_name) 469 char *sysname = SSDATA (system_name);
465 && dot - (at + 1) == SBYTES (system_name) 470 for (ptrdiff_t i = 0; i < linkhostlen; i++)
466 && memcmp (at + 1, SSDATA (system_name), SBYTES (system_name)) == 0) 471 if (linkhost[i] != (sysname[i] == '@' ? '-' : sysname[i]))
472 {
473 on_current_host = false;
474 break;
475 }
476 }
477 }
478 if (on_current_host)
467 { 479 {
468 if (pid == getpid ()) 480 if (pid == getpid ())
469 return I_OWN_IT; 481 return I_OWN_IT;