X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/2b64ccd2b5916083a421b0263a5bc1d3d075d82b..dac616ff9f51b77e399a06863a79446958c4f840:/src/filelock.c diff --git a/src/filelock.c b/src/filelock.c index c28ee7837f..e840d3c5c3 100644 --- a/src/filelock.c +++ b/src/filelock.c @@ -1,5 +1,5 @@ /* Lock files for editing. - Copyright (C) 1985-1987, 1993-1994, 1996, 1998-2011 + Copyright (C) 1985-1987, 1993-1994, 1996, 1998-2012 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -40,8 +40,8 @@ along with GNU Emacs. If not, see . */ #include #include "lisp.h" -#include "buffer.h" #include "character.h" +#include "buffer.h" #include "coding.h" #include "systime.h" @@ -174,14 +174,14 @@ get_boot_time (void) filename = Qnil; - sprintf (cmd_string, "%s.%d", WTMP_FILE, counter); - tempname = build_string (cmd_string); + tempname = make_formatted_string + (cmd_string, "%s.%d", WTMP_FILE, counter); if (! NILP (Ffile_exists_p (tempname))) filename = tempname; else { - sprintf (cmd_string, "%s.%d.gz", WTMP_FILE, counter); - tempname = build_string (cmd_string); + tempname = make_formatted_string (cmd_string, "%s.%d.gz", + WTMP_FILE, counter); if (! NILP (Ffile_exists_p (tempname))) { Lisp_Object args[6]; @@ -294,12 +294,13 @@ typedef struct trailing period plus one for the digit after it plus one for the null. */ #define MAKE_LOCK_NAME(lock, file) \ - (lock = (char *) alloca (SBYTES (file) + 2 + 1 + 1 + 1), \ + (lock = alloca (SBYTES (file) + 2 + 1 + 1 + 1), \ fill_in_lock_file_name (lock, (file))) static void fill_in_lock_file_name (register char *lockfile, register Lisp_Object fn) { + ptrdiff_t length = SBYTES (fn); register char *p; struct stat st; int count = 0; @@ -309,14 +310,14 @@ fill_in_lock_file_name (register char *lockfile, register Lisp_Object fn) /* Shift the nondirectory part of the file name (including the null) right two characters. Here is one of the places where we'd have to do something to support 14-character-max file names. */ - for (p = lockfile + strlen (lockfile); p != lockfile && *p != '/'; p--) + for (p = lockfile + length; p != lockfile && *p != '/'; p--) p[2] = *p; /* Insert the `.#'. */ p[1] = '.'; p[2] = '#'; - p = p + strlen (p); + p = p + length + 2; while (lstat (lockfile, &st) == 0 && !S_ISLNK (st.st_mode)) { @@ -341,6 +342,9 @@ lock_file_1 (char *lfname, int force) const char *user_name; const char *host_name; char *lock_info_str; + ptrdiff_t lock_info_size; + int symlink_errno; + USE_SAFE_ALLOCA; /* Call this first because it can GC. */ boot = get_boot_time (); @@ -353,17 +357,14 @@ lock_file_1 (char *lfname, int force) host_name = SSDATA (Fsystem_name ()); else host_name = ""; - lock_info_str = (char *)alloca (strlen (user_name) + strlen (host_name) - + 2 * INT_STRLEN_BOUND (printmax_t) - + sizeof "@.:"); + lock_info_size = (strlen (user_name) + strlen (host_name) + + 2 * INT_STRLEN_BOUND (printmax_t) + + sizeof "@.:"); + SAFE_ALLOCA (lock_info_str, char *, lock_info_size); pid = getpid (); - if (boot) - sprintf (lock_info_str, "%s@%s.%"pMd":%"pMd, - user_name, host_name, pid, boot); - else - sprintf (lock_info_str, "%s@%s.%"pMd, - user_name, host_name, pid); + esprintf (lock_info_str, boot ? "%s@%s.%"pMd":%"pMd : "%s@%s.%"pMd, + user_name, host_name, pid, boot); err = symlink (lock_info_str, lfname); if (errno == EEXIST && force) @@ -372,6 +373,9 @@ lock_file_1 (char *lfname, int force) err = symlink (lock_info_str, lfname); } + symlink_errno = errno; + SAFE_FREE (); + errno = symlink_errno; return err == 0; } @@ -419,7 +423,7 @@ current_lock_owner (lock_info_type *owner, char *lfname) return -1; } len = at - lfinfo; - owner->user = (char *) xmalloc (len + 1); + owner->user = xmalloc (len + 1); memcpy (owner->user, lfinfo, len); owner->user[len] = 0; @@ -446,7 +450,7 @@ current_lock_owner (lock_info_type *owner, char *lfname) /* The host is everything in between. */ len = dot - at - 1; - owner->host = (char *) xmalloc (len + 1); + owner->host = xmalloc (len + 1); memcpy (owner->host, at + 1, len); owner->host[len] = 0; @@ -541,9 +545,15 @@ lock_file (Lisp_Object fn) { register Lisp_Object attack, orig_fn, encoded_fn; register char *lfname, *locker; + ptrdiff_t locker_size; lock_info_type lock_info; printmax_t pid; struct gcpro gcpro1; + USE_SAFE_ALLOCA; + + /* Don't do locking if the user has opted out. */ + if (! create_lockfiles) + return; /* Don't do locking while dumping Emacs. Uncompressing wtmp files uses call-process, which does not work @@ -580,15 +590,17 @@ lock_file (Lisp_Object fn) return; /* Else consider breaking the lock */ - locker = (char *) alloca (strlen (lock_info.user) + strlen (lock_info.host) - + INT_STRLEN_BOUND (printmax_t) - + sizeof "@ (pid )"); + locker_size = (strlen (lock_info.user) + strlen (lock_info.host) + + INT_STRLEN_BOUND (printmax_t) + + sizeof "@ (pid )"); + SAFE_ALLOCA (locker, char *, locker_size); pid = lock_info.pid; - sprintf (locker, "%s@%s (pid %"pMd")", - lock_info.user, lock_info.host, 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 */ { @@ -623,7 +635,7 @@ unlock_all_files (void) b = XBUFFER (XCDR (XCAR (tail))); if (STRINGP (BVAR (b, file_truename)) && BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)) { - unlock_file(BVAR (b, file_truename)); + unlock_file (BVAR (b, file_truename)); } } } @@ -696,15 +708,6 @@ t if it is locked by you, else a string saying which user has locked it. */) return ret; } - -/* Initialization functions. */ - -void -init_filelock (void) -{ - boot_time = 0; - boot_time_initialized = 0; -} #endif /* CLASH_DETECTION */ @@ -715,6 +718,10 @@ syms_of_filelock (void) doc: /* The directory for writing temporary files. */); Vtemporary_file_directory = Qnil; + DEFVAR_BOOL ("create-lockfiles", create_lockfiles, + doc: /* Non-nil means use lockfiles to avoid editing collisions. */); + create_lockfiles = 1; + #ifdef CLASH_DETECTION defsubr (&Sunlock_buffer); defsubr (&Slock_buffer);