summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2013-03-02 13:05:52 -0800
committerPaul Eggert <eggert@cs.ucla.edu>2013-03-02 13:05:52 -0800
commit2db41375423b6a48a55df2c5922bb2813319f06f (patch)
tree50c68274acb327e04705554b5828201ed63732f9
parentb5029e230d10ea412e4ff1d4867a0c884d130039 (diff)
downloademacs-2db41375423b6a48a55df2c5922bb2813319f06f.tar.gz
* filelock.c (lock_file): Don't access freed storage.
-rw-r--r--src/ChangeLog1
-rw-r--r--src/filelock.c49
2 files changed, 23 insertions, 27 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 7afae3df6f5..adff00f7189 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -27,6 +27,7 @@
that's not portable.
(lock_file): Document that this function can return if lock
creation fails.
+ (lock_file): Don't access freed storage.
2013-03-02 Andreas Schwab <schwab@linux-m68k.org>
diff --git a/src/filelock.c b/src/filelock.c
index d52e9faeb44..14b9d4aaca5 100644
--- a/src/filelock.c
+++ b/src/filelock.c
@@ -597,11 +597,9 @@ lock_if_free (lock_info_type *clasher, register char *lfname)
void
lock_file (Lisp_Object fn)
{
- register Lisp_Object attack, orig_fn, encoded_fn;
- register char *lfname, *locker;
- ptrdiff_t locker_size;
+ Lisp_Object orig_fn, encoded_fn;
+ char *lfname;
lock_info_type lock_info;
- printmax_t pid;
struct gcpro gcpro1;
USE_SAFE_ALLOCA;
@@ -642,32 +640,29 @@ lock_file (Lisp_Object fn)
call1 (intern ("ask-user-about-supersession-threat"), fn);
}
- UNGCPRO;
-
- /* Try to lock the lock. */
- if (lock_if_free (&lock_info, lfname) <= 0)
- /* Return now if we have locked it, or if lock creation failed */
- return;
- /* Else consider breaking the lock */
- locker_size = (strlen (lock_info.user) + strlen (lock_info.host)
- + INT_STRLEN_BOUND (printmax_t)
- + sizeof "@ (pid )");
- locker = SAFE_ALLOCA (locker_size);
- pid = lock_info.pid;
- esprintf (locker, "%s@%s (pid %"pMd")",
- lock_info.user, lock_info.host, pid);
- FREE_LOCK_INFO (lock_info);
-
- attack = call2 (intern ("ask-user-about-lock"), fn, build_string (locker));
- SAFE_FREE ();
- if (!NILP (attack))
- /* User says take the lock */
+ /* Try to lock the lock. */
+ if (0 < lock_if_free (&lock_info, lfname))
{
- lock_file_1 (lfname, 1);
- return;
+ /* Someone else has the lock. Consider breaking it. */
+ ptrdiff_t locker_size = (strlen (lock_info.user) + strlen (lock_info.host)
+ + INT_STRLEN_BOUND (printmax_t)
+ + sizeof "@ (pid )");
+ char *locker = SAFE_ALLOCA (locker_size);
+ printmax_t pid = lock_info.pid;
+ Lisp_Object attack;
+ esprintf (locker, "%s@%s (pid %"pMd")",
+ lock_info.user, lock_info.host, pid);
+ FREE_LOCK_INFO (lock_info);
+
+ attack = call2 (intern ("ask-user-about-lock"), fn, build_string (locker));
+ /* Take the lock if the user said so. */
+ if (!NILP (attack))
+ lock_file_1 (lfname, 1);
}
- /* User says ignore the lock */
+
+ UNGCPRO;
+ SAFE_FREE ();
}
void