diff options
Diffstat (limited to 'src/filelock.c')
| -rw-r--r-- | src/filelock.c | 42 |
1 files changed, 25 insertions, 17 deletions
diff --git a/src/filelock.c b/src/filelock.c index 18483b6f3f3..2613eec4aca 100644 --- a/src/filelock.c +++ b/src/filelock.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Lock files for editing. | 1 | /* Lock files for editing. |
| 2 | Copyright (C) 1985-1987, 1993-1994, 1996, 1998-2011 | 2 | Copyright (C) 1985-1987, 1993-1994, 1996, 1998-2012 |
| 3 | Free Software Foundation, Inc. | 3 | Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| @@ -337,10 +337,13 @@ static int | |||
| 337 | lock_file_1 (char *lfname, int force) | 337 | lock_file_1 (char *lfname, int force) |
| 338 | { | 338 | { |
| 339 | register int err; | 339 | register int err; |
| 340 | intmax_t boot, pid; | 340 | printmax_t boot, pid; |
| 341 | const char *user_name; | 341 | const char *user_name; |
| 342 | const char *host_name; | 342 | const char *host_name; |
| 343 | char *lock_info_str; | 343 | char *lock_info_str; |
| 344 | ptrdiff_t lock_info_size; | ||
| 345 | int symlink_errno; | ||
| 346 | USE_SAFE_ALLOCA; | ||
| 344 | 347 | ||
| 345 | /* Call this first because it can GC. */ | 348 | /* Call this first because it can GC. */ |
| 346 | boot = get_boot_time (); | 349 | boot = get_boot_time (); |
| @@ -353,17 +356,14 @@ lock_file_1 (char *lfname, int force) | |||
| 353 | host_name = SSDATA (Fsystem_name ()); | 356 | host_name = SSDATA (Fsystem_name ()); |
| 354 | else | 357 | else |
| 355 | host_name = ""; | 358 | host_name = ""; |
| 356 | lock_info_str = (char *)alloca (strlen (user_name) + strlen (host_name) | 359 | lock_info_size = (strlen (user_name) + strlen (host_name) |
| 357 | + 2 * INT_STRLEN_BOUND (intmax_t) | 360 | + 2 * INT_STRLEN_BOUND (printmax_t) |
| 358 | + sizeof "@.:"); | 361 | + sizeof "@.:"); |
| 362 | SAFE_ALLOCA (lock_info_str, char *, lock_info_size); | ||
| 359 | pid = getpid (); | 363 | pid = getpid (); |
| 360 | 364 | ||
| 361 | if (boot) | 365 | esprintf (lock_info_str, boot ? "%s@%s.%"pMd":%"pMd : "%s@%s.%"pMd, |
| 362 | sprintf (lock_info_str, "%s@%s.%"PRIdMAX":%"PRIdMAX, | 366 | user_name, host_name, pid, boot); |
| 363 | user_name, host_name, pid, boot); | ||
| 364 | else | ||
| 365 | sprintf (lock_info_str, "%s@%s.%"PRIdMAX, | ||
| 366 | user_name, host_name, pid); | ||
| 367 | 367 | ||
| 368 | err = symlink (lock_info_str, lfname); | 368 | err = symlink (lock_info_str, lfname); |
| 369 | if (errno == EEXIST && force) | 369 | if (errno == EEXIST && force) |
| @@ -372,6 +372,9 @@ lock_file_1 (char *lfname, int force) | |||
| 372 | err = symlink (lock_info_str, lfname); | 372 | err = symlink (lock_info_str, lfname); |
| 373 | } | 373 | } |
| 374 | 374 | ||
| 375 | symlink_errno = errno; | ||
| 376 | SAFE_FREE (); | ||
| 377 | errno = symlink_errno; | ||
| 375 | return err == 0; | 378 | return err == 0; |
| 376 | } | 379 | } |
| 377 | 380 | ||
| @@ -541,9 +544,11 @@ lock_file (Lisp_Object fn) | |||
| 541 | { | 544 | { |
| 542 | register Lisp_Object attack, orig_fn, encoded_fn; | 545 | register Lisp_Object attack, orig_fn, encoded_fn; |
| 543 | register char *lfname, *locker; | 546 | register char *lfname, *locker; |
| 547 | ptrdiff_t locker_size; | ||
| 544 | lock_info_type lock_info; | 548 | lock_info_type lock_info; |
| 545 | intmax_t pid; | 549 | printmax_t pid; |
| 546 | struct gcpro gcpro1; | 550 | struct gcpro gcpro1; |
| 551 | USE_SAFE_ALLOCA; | ||
| 547 | 552 | ||
| 548 | /* Don't do locking while dumping Emacs. | 553 | /* Don't do locking while dumping Emacs. |
| 549 | Uncompressing wtmp files uses call-process, which does not work | 554 | Uncompressing wtmp files uses call-process, which does not work |
| @@ -580,14 +585,17 @@ lock_file (Lisp_Object fn) | |||
| 580 | return; | 585 | return; |
| 581 | 586 | ||
| 582 | /* Else consider breaking the lock */ | 587 | /* Else consider breaking the lock */ |
| 583 | locker = (char *) alloca (strlen (lock_info.user) + strlen (lock_info.host) | 588 | locker_size = (strlen (lock_info.user) + strlen (lock_info.host) |
| 584 | + INT_STRLEN_BOUND (intmax_t) + sizeof "@ (pid )"); | 589 | + INT_STRLEN_BOUND (printmax_t) |
| 590 | + sizeof "@ (pid )"); | ||
| 591 | SAFE_ALLOCA (locker, char *, locker_size); | ||
| 585 | pid = lock_info.pid; | 592 | pid = lock_info.pid; |
| 586 | sprintf (locker, "%s@%s (pid %"PRIdMAX")", | 593 | esprintf (locker, "%s@%s (pid %"pMd")", |
| 587 | lock_info.user, lock_info.host, pid); | 594 | lock_info.user, lock_info.host, pid); |
| 588 | FREE_LOCK_INFO (lock_info); | 595 | FREE_LOCK_INFO (lock_info); |
| 589 | 596 | ||
| 590 | attack = call2 (intern ("ask-user-about-lock"), fn, build_string (locker)); | 597 | attack = call2 (intern ("ask-user-about-lock"), fn, build_string (locker)); |
| 598 | SAFE_FREE (); | ||
| 591 | if (!NILP (attack)) | 599 | if (!NILP (attack)) |
| 592 | /* User says take the lock */ | 600 | /* User says take the lock */ |
| 593 | { | 601 | { |
| @@ -622,7 +630,7 @@ unlock_all_files (void) | |||
| 622 | b = XBUFFER (XCDR (XCAR (tail))); | 630 | b = XBUFFER (XCDR (XCAR (tail))); |
| 623 | if (STRINGP (BVAR (b, file_truename)) && BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)) | 631 | if (STRINGP (BVAR (b, file_truename)) && BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)) |
| 624 | { | 632 | { |
| 625 | unlock_file(BVAR (b, file_truename)); | 633 | unlock_file (BVAR (b, file_truename)); |
| 626 | } | 634 | } |
| 627 | } | 635 | } |
| 628 | } | 636 | } |