/* 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.
#include <errno.h>
#include "lisp.h"
-#include "buffer.h"
#include "character.h"
+#include "buffer.h"
#include "coding.h"
#include "systime.h"
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];
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;
/* 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))
{
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 ();
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)
err = symlink (lock_info_str, lfname);
}
+ symlink_errno = errno;
+ SAFE_FREE ();
+ errno = symlink_errno;
return err == 0;
}
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;
/* 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;
{
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
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 */
{
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));
}
}
}
return ret;
}
-\f
-/* Initialization functions. */
-
-void
-init_filelock (void)
-{
- boot_time = 0;
- boot_time_initialized = 0;
-}
#endif /* CLASH_DETECTION */
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);