-/* Copyright (C) 1985, 1986, 1987, 1993 Free Software Foundation, Inc.
+/* Copyright (C) 1985, 1986, 1987, 1993, 1994 Free Software Foundation, Inc.
This file is part of GNU Emacs.
You should have received a copy of the GNU General Public License
along with GNU Emacs; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
#include <sys/types.h>
#include <sys/stat.h>
-#include "config.h"
+#include <config.h>
#ifdef VMS
#include "vms-pwd.h"
#endif /* USG */
#include "lisp.h"
-#include "paths.h"
+#include <paths.h>
#include "buffer.h"
+#ifdef SYSV_SYSTEM_DIR
+#include <dirent.h>
+#else /* not SYSV_SYSTEM_DIR */
+#ifdef NONSYSTEM_DIR_LIBRARY
+#include "ndir.h"
+#else /* not NONSYSTEM_DIR_LIBRARY */
+#ifdef MSDOS
+#include <dirent.h>
+#else
+#include <sys/dir.h>
+#endif
+#endif /* not NONSYSTEM_DIR_LIBRARY */
+#ifndef MSDOS
+extern DIR *opendir ();
+#endif /* not MSDOS */
+#endif /* not SYSV_SYSTEM_DIR */
+
extern int errno;
extern char *egetenv ();
extern char *strcpy ();
+#ifdef DECLARE_GETPWUID_WITH_UID_T
+extern struct passwd *getpwuid (uid_t);
+#else
+extern struct passwd *getpwuid ();
+#endif
+
#ifdef CLASH_DETECTION
/* If system does not have symbolic links, it does not have lstat.
/* The name of the directory in which we keep lock files, with a '/'
appended. */
-char *lock_path;
+char *lock_dir;
/* The name of the file in the lock directory which is used to
arbitrate access to the entire directory. */
#define SUPERLOCK_NAME "!!!SuperLock!!!"
-/* The path to the superlock file. This is SUPERLOCK_NAME appended to
- lock_path. */
-char *superlock_path;
+/* The name of the superlock file. This is SUPERLOCK_NAME appended to
+ lock_dir. */
+char *superlock_file;
/* Set LOCK to the name of the lock file for the filename FILE.
char *LOCK; Lisp_Object FILE; */
-#ifdef SHORT_FILE_NAMES
+#ifndef HAVE_LONG_FILE_NAMES
-#define MAKE_LOCK_PATH(lock, file) \
- (lock = (char *) alloca (14 + strlen (lock_path) + 1), \
+#define MAKE_LOCK_NAME(lock, file) \
+ (lock = (char *) alloca (14 + strlen (lock_dir) + 1), \
fill_in_lock_short_file_name (lock, (file)))
for (p = XSTRING (fn)->data; new = *p++; )
{
- new += crc.byte[7];
- crc.byte[7] = crc.byte[6];
+ new += crc.byte[6];
crc.byte[6] = crc.byte[5] + new;
crc.byte[5] = crc.byte[4];
crc.byte[4] = crc.byte[3];
crc.byte[1] = crc.byte[0];
crc.byte[0] = new;
}
- sprintf (lockfile, "%s%.2x%.2x%.2x%.2x%.2x%.2x%.2x", lock_path,
+ sprintf (lockfile, "%s%.2x%.2x%.2x%.2x%.2x%.2x%.2x", lock_dir,
crc.byte[0], crc.byte[1], crc.byte[2], crc.byte[3],
crc.byte[4], crc.byte[5], crc.byte[6]);
}
-#else /* !defined SHORT_FILE_NAMES */
+#else /* defined HAVE_LONG_FILE_NAMES */
-#define MAKE_LOCK_PATH(lock, file) \
- (lock = (char *) alloca (XSTRING (file)->size + strlen (lock_path) + 1), \
+#define MAKE_LOCK_NAME(lock, file) \
+ (lock = (char *) alloca (XSTRING (file)->size + strlen (lock_dir) + 1), \
fill_in_lock_file_name (lock, (file)))
{
register char *p;
- strcpy (lockfile, lock_path);
+ strcpy (lockfile, lock_dir);
p = lockfile + strlen (lockfile);
*p = '!';
}
}
-#endif /* SHORT_FILE_NAMES */
+#endif /* !defined HAVE_LONG_FILE_NAMES */
static Lisp_Object
lock_file_owner_name (lfname)
{
struct stat s;
struct passwd *the_pw;
- extern struct passwd *getpwuid ();
if (lstat (lfname, &s) == 0)
the_pw = getpwuid (s.st_uid);
and put in the Emacs lock directory. */
/* (ie., /ka/king/junk.tex -> /!/!ka!king!junk.tex). */
-/* If SHORT_FILE_NAMES is defined, the lock file name is the hex
+/* If HAVE_LONG_FILE_NAMES is not defined, the lock file name is the hex
representation of a 14-bytes CRC generated from the file name
and put in the Emacs lock directory (not very nice, but it works).
- (ie., /ka/king/junk.tex -> /!/ec92d3ed24a8f0). */
+ (ie., /ka/king/junk.tex -> /!/12a82c62f1c6da). */
void
lock_file (fn)
register Lisp_Object fn;
{
- register Lisp_Object attack;
+ register Lisp_Object attack, orig_fn;
register char *lfname;
- MAKE_LOCK_PATH (lfname, fn);
+ orig_fn = fn;
+ fn = Fexpand_file_name (fn, Qnil);
+
+ MAKE_LOCK_NAME (lfname, fn);
/* See if this file is visited and has changed on disk since it was
visited. */
{
- register Lisp_Object subject_buf = Fget_file_buffer (fn);
+ register Lisp_Object subject_buf;
+ subject_buf = get_truename_buffer (orig_fn);
if (!NILP (subject_buf)
&& NILP (Fverify_visited_file_modtime (subject_buf))
&& !NILP (Ffile_exists_p (fn)))
{
lock_superlock (lfname);
lock_file_1 (lfname, O_WRONLY) ;
- unlink (superlock_path);
+ unlink (superlock_file);
return;
}
/* User says ignore the lock */
{
register char *lfname;
- MAKE_LOCK_PATH (lfname, fn);
+ fn = Fexpand_file_name (fn, Qnil);
+
+ MAKE_LOCK_NAME (lfname, fn);
lock_superlock (lfname);
if (current_lock_owner_1 (lfname) == getpid ())
unlink (lfname);
- unlink (superlock_path);
+ unlink (superlock_file);
}
lock_superlock (lfname)
char *lfname;
{
register int i, fd;
+ DIR *lockdir;
- for (i = -20; i < 0 && (fd = open (superlock_path,
+ for (i = -20; i < 0 && (fd = open (superlock_file,
O_WRONLY | O_EXCL | O_CREAT, 0666)) < 0;
i++)
{
if (errno != EEXIST)
return;
+
+ /* This seems to be necessary to prevent Emacs from hanging when the
+ competing process has already deleted the superlock, but it's still
+ in the NFS cache. So we force NFS to synchronize the cache. */
+ if (lockdir = opendir (lock_dir))
+ closedir (lockdir);
+
sleep (1);
}
if (fd >= 0)
{
#ifdef USG
- chmod (superlock_path, 0666);
+ chmod (superlock_file, 0666);
#else
fchmod (fd, 0666);
#endif
register Lisp_Object tail;
register struct buffer *b;
- for (tail = Vbuffer_alist; XGCTYPE (tail) == Lisp_Cons;
- tail = XCONS (tail)->cdr)
+ for (tail = Vbuffer_alist; GC_CONSP (tail); tail = XCONS (tail)->cdr)
{
b = XBUFFER (XCONS (XCONS (tail)->car)->cdr);
- if (XTYPE (b->filename) == Lisp_String &&
- b->save_modified < BUF_MODIFF (b))
- unlock_file (b->filename);
+ if (STRINGP (b->file_truename) && BUF_SAVE_MODIFF (b) < BUF_MODIFF (b))
+ unlock_file (b->file_truename);
}
}
"Lock FILE, if current buffer is modified.\n\
FILE defaults to current buffer's visited file,\n\
or else nothing is done if current buffer isn't visiting a file.")
- (fn)
- Lisp_Object fn;
+ (file)
+ Lisp_Object file;
{
- if (NILP (fn))
- fn = current_buffer->filename;
+ if (NILP (file))
+ file = current_buffer->file_truename;
else
- CHECK_STRING (fn, 0);
- if (current_buffer->save_modified < MODIFF
- && !NILP (fn))
- lock_file (fn);
+ CHECK_STRING (file, 0);
+ if (SAVE_MODIFF < MODIFF
+ && !NILP (file))
+ lock_file (file);
return Qnil;
}
if it should normally be locked.")
()
{
- if (current_buffer->save_modified < MODIFF &&
- XTYPE (current_buffer->filename) == Lisp_String)
- unlock_file (current_buffer->filename);
+ if (SAVE_MODIFF < MODIFF
+ && STRINGP (current_buffer->file_truename))
+ unlock_file (current_buffer->file_truename);
return Qnil;
}
unlock_buffer (buffer)
struct buffer *buffer;
{
- if (buffer->save_modified < BUF_MODIFF (buffer) &&
- XTYPE (buffer->filename) == Lisp_String)
- unlock_file (buffer->filename);
+ if (BUF_SAVE_MODIFF (buffer) < BUF_MODIFF (buffer)
+ && STRINGP (buffer->file_truename))
+ unlock_file (buffer->file_truename);
}
DEFUN ("file-locked-p", Ffile_locked_p, Sfile_locked_p, 0, 1, 0,
"Return nil if the FILENAME is not locked,\n\
t if it is locked by you, else a string of the name of the locker.")
- (fn)
- Lisp_Object fn;
+ (filename)
+ Lisp_Object filename;
{
register char *lfname;
int owner;
- fn = Fexpand_file_name (fn, Qnil);
+ filename = Fexpand_file_name (filename, Qnil);
- MAKE_LOCK_PATH (lfname, fn);
+ MAKE_LOCK_NAME (lfname, filename);
owner = current_lock_owner (lfname);
if (owner <= 0)
init_filelock ()
{
- lock_path = egetenv ("EMACSLOCKDIR");
- if (! lock_path)
- lock_path = PATH_LOCK;
+ char *new_name;
+
+ lock_dir = egetenv ("EMACSLOCKDIR");
+ if (! lock_dir)
+ lock_dir = PATH_LOCK;
+
+ /* Copy the name in case egetenv got it from a Lisp string. */
+ new_name = (char *) xmalloc (strlen (lock_dir) + 2);
+ strcpy (new_name, lock_dir);
+ lock_dir = new_name;
/* Make sure it ends with a slash. */
- if (lock_path[strlen (lock_path) - 1] != '/')
- {
- lock_path = strcpy ((char *) xmalloc (strlen (lock_path) + 2),
- lock_path);
- strcat (lock_path, "/");
- }
+ if (lock_dir[strlen (lock_dir) - 1] != '/')
+ strcat (lock_dir, "/");
- superlock_path = (char *) xmalloc ((strlen (lock_path)
+ superlock_file = (char *) xmalloc ((strlen (lock_dir)
+ sizeof (SUPERLOCK_NAME)));
- strcpy (superlock_path, lock_path);
- strcat (superlock_path, SUPERLOCK_NAME);
+ strcpy (superlock_file, lock_dir);
+ strcat (superlock_file, SUPERLOCK_NAME);
}
syms_of_filelock ()