diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2022-04-17 01:44:30 -0700 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2022-04-17 01:44:30 -0700 |
commit | ff7bc018307681564235583722675997dc309915 (patch) | |
tree | 3b1f9350e91a17d7048c3e82e0d99fc2f84256ed /src/filelock.c | |
parent | 5bc3ed492bffa962ef326387f2476b66442a006c (diff) | |
parent | 4641bc1c550a81c71798c0176a6bfc34c8947c74 (diff) | |
download | emacs-ff7bc018307681564235583722675997dc309915.tar.gz |
Merge from origin/emacs-28
4641bc1c55 Fix GC bug in filelock.c
Diffstat (limited to 'src/filelock.c')
-rw-r--r-- | src/filelock.c | 50 |
1 files changed, 24 insertions, 26 deletions
diff --git a/src/filelock.c b/src/filelock.c index 4fdad8d8560..8fa86e64eb8 100644 --- a/src/filelock.c +++ b/src/filelock.c @@ -413,14 +413,13 @@ create_lock_file (char *lfname, char *lock_info_str, bool force) Return 0 if successful, an error number on failure. */ static int -lock_file_1 (char *lfname, bool force) +lock_file_1 (Lisp_Object lfname, bool force) { - /* Call this first because it can GC. */ intmax_t boot = get_boot_time (); - Lisp_Object luser_name = Fuser_login_name (Qnil); - char const *user_name = STRINGP (luser_name) ? SSDATA (luser_name) : ""; Lisp_Object lhost_name = Fsystem_name (); + + 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 (); @@ -439,7 +438,7 @@ lock_file_1 (char *lfname, bool force) user_name, host_name, pid)) return ENAMETOOLONG; - return create_lock_file (lfname, lock_info_str, force); + return create_lock_file (SSDATA (lfname), lock_info_str, force); } /* Return true if times A and B are no more than one second apart. */ @@ -511,7 +510,7 @@ enum or an errno value if something is wrong with the locking mechanism. */ static int -current_lock_owner (lock_info_type *owner, char *lfname) +current_lock_owner (lock_info_type *owner, Lisp_Object lfname) { lock_info_type local_owner; ptrdiff_t lfinfolen; @@ -524,7 +523,7 @@ current_lock_owner (lock_info_type *owner, char *lfname) owner = &local_owner; /* If nonexistent lock file, all is well; otherwise, got strange error. */ - lfinfolen = read_lock_data (lfname, owner->user); + lfinfolen = read_lock_data (SSDATA (lfname), owner->user); if (lfinfolen < 0) return errno == ENOENT || errno == ENOTDIR ? 0 : errno; if (MAX_LFINFO < lfinfolen) @@ -600,7 +599,7 @@ current_lock_owner (lock_info_type *owner, char *lfname) /* The owner process is dead or has a strange pid, so try to zap the lockfile. */ else - return unlink (lfname) < 0 ? errno : 0; + return unlink (SSDATA (lfname)) < 0 ? errno : 0; } else { /* If we wanted to support the check for stale locks on remote machines, @@ -617,7 +616,7 @@ current_lock_owner (lock_info_type *owner, char *lfname) Return errno value if cannot lock for any other reason. */ static int -lock_if_free (lock_info_type *clasher, char *lfname) +lock_if_free (lock_info_type *clasher, Lisp_Object lfname) { int err; while ((err = lock_file_1 (lfname, 0)) == EEXIST) @@ -636,10 +635,14 @@ lock_if_free (lock_info_type *clasher, char *lfname) return err; } +/* Return the encoded name of the lock file for FN, or nil if none. */ + static Lisp_Object make_lock_file_name (Lisp_Object fn) { - return call1 (Qmake_lock_file_name, Fexpand_file_name (fn, Qnil)); + Lisp_Object lock_file_name = call1 (Qmake_lock_file_name, + Fexpand_file_name (fn, Qnil)); + return !NILP (lock_file_name) ? ENCODE_FILE (lock_file_name) : Qnil; } /* lock_file locks file FN, @@ -663,7 +666,6 @@ make_lock_file_name (Lisp_Object fn) static Lisp_Object lock_file (Lisp_Object fn) { - char *lfname = NULL; lock_info_type lock_info; /* Don't do locking while dumping Emacs. @@ -672,13 +674,13 @@ lock_file (Lisp_Object fn) if (will_dump_p ()) return Qnil; + Lisp_Object lfname = Qnil; if (create_lockfiles) { /* Create the name of the lock-file for file fn */ - Lisp_Object lock_filename = make_lock_file_name (fn); - if (NILP (lock_filename)) + lfname = make_lock_file_name (fn); + if (NILP (lfname)) return Qnil; - lfname = SSDATA (ENCODE_FILE (lock_filename)); } /* See if this file is visited and has changed on disk since it was @@ -687,14 +689,14 @@ lock_file (Lisp_Object fn) if (!NILP (subject_buf) && NILP (Fverify_visited_file_modtime (subject_buf)) && !NILP (Ffile_exists_p (fn)) - && !(lfname && (current_lock_owner (NULL, lfname) == I_OWN_IT))) + && !(!NILP (lfname) && current_lock_owner (NULL, lfname) == I_OWN_IT)) call1 (intern ("userlock--ask-user-about-supersession-threat"), fn); /* Don't do locking if the user has opted out. */ - if (lfname) + if (!NILP (lfname)) { /* Try to lock the lock. FIXME: This ignores errors when - lock_if_free returns a positive errno value. */ + lock_if_free returns an errno value. */ if (lock_if_free (&lock_info, lfname) == ANOTHER_OWNS_IT) { /* Someone else has the lock. Consider breaking it. */ @@ -719,17 +721,14 @@ lock_file (Lisp_Object fn) static Lisp_Object unlock_file (Lisp_Object fn) { - char *lfname; - - Lisp_Object lock_filename = make_lock_file_name (fn); - if (NILP (lock_filename)) + Lisp_Object lfname = make_lock_file_name (fn); + if (NILP (lfname)) return Qnil; - lfname = SSDATA (ENCODE_FILE (lock_filename)); int err = current_lock_owner (0, lfname); if (! (err == 0 || err == ANOTHER_OWNS_IT || (err == I_OWN_IT - && (unlink (lfname) == 0 || (err = errno) == ENOENT)))) + && (unlink (SSDATA (lfname)) == 0 || (err = errno) == ENOENT)))) report_file_errno ("Unlocking file", fn, err); return Qnil; @@ -871,10 +870,9 @@ t if it is locked by you, else a string saying which user has locked it. */) return call2 (handler, Qfile_locked_p, filename); } - Lisp_Object lock_filename = make_lock_file_name (filename); - if (NILP (lock_filename)) + Lisp_Object lfname = make_lock_file_name (filename); + if (NILP (lfname)) return Qnil; - char *lfname = SSDATA (ENCODE_FILE (lock_filename)); owner = current_lock_owner (&locker, lfname); switch (owner) |