-/* Copyright (C) 1985, 1986, 1987, 1992 Free Software Foundation, Inc.
+/* Copyright (C) 1985, 1986, 1987, 1993, 1994 Free Software Foundation, Inc.
This file is part of GNU Emacs.
#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 ();
+
+#if defined (__bsdi__) || defined (DECLARE_GETPWUID_WITH_UID_T)
+extern struct passwd *getpwuid (uid_t);
+#else
+extern struct passwd *getpwuid ();
+#endif
#ifdef CLASH_DETECTION
/* Set LOCK to the name of the lock file for the filename FILE.
char *LOCK; Lisp_Object FILE; */
+
+#ifndef HAVE_LONG_FILE_NAMES
+
+#define MAKE_LOCK_PATH(lock, file) \
+ (lock = (char *) alloca (14 + strlen (lock_path) + 1), \
+ fill_in_lock_short_file_name (lock, (file)))
+
+
+fill_in_lock_short_file_name (lockfile, fn)
+ register char *lockfile;
+ register Lisp_Object fn;
+{
+ register union
+ {
+ unsigned int word [2];
+ unsigned char byte [8];
+ } crc;
+ register unsigned char *p, new;
+
+ /* 7-bytes cyclic code for burst correction on byte-by-byte basis.
+ the used polynomial is D^7 + D^6 + D^3 +1. pot@cnuce.cnr.it */
+
+ crc.word[0] = crc.word[1] = 0;
+
+ for (p = XSTRING (fn)->data; new = *p++; )
+ {
+ 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[3] = crc.byte[2] + new;
+ crc.byte[2] = crc.byte[1];
+ crc.byte[1] = crc.byte[0];
+ crc.byte[0] = new;
+ }
+ sprintf (lockfile, "%s%.2x%.2x%.2x%.2x%.2x%.2x%.2x", lock_path,
+ crc.byte[0], crc.byte[1], crc.byte[2], crc.byte[3],
+ crc.byte[4], crc.byte[5], crc.byte[6]);
+}
+
+#else /* defined HAVE_LONG_FILE_NAMES */
+
#define MAKE_LOCK_PATH(lock, file) \
(lock = (char *) alloca (XSTRING (file)->size + strlen (lock_path) + 1), \
fill_in_lock_file_name (lock, (file)))
+
fill_in_lock_file_name (lockfile, fn)
register char *lockfile;
register Lisp_Object fn;
*p = '!';
}
}
+#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 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 -> /!/12a82c62f1c6da). */
+
void
lock_file (fn)
register Lisp_Object 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 = Fget_file_buffer (fn);
if (!NILP (subject_buf)
&& NILP (Fverify_visited_file_modtime (subject_buf))
&& !NILP (Ffile_exists_p (fn)))
char *lfname;
{
register int i, fd;
+ DIR *lockdir;
for (i = -20; i < 0 && (fd = open (superlock_path,
O_WRONLY | O_EXCL | O_CREAT, 0666)) < 0;
{
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_path))
+ closedir (lockdir);
+
sleep (1);
}
if (fd >= 0)
/* 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);
+ char *new_path = (char *) xmalloc (strlen (lock_path) + 2);
+ strcpy (new_path, lock_path);
+ lock_path = new_path;
strcat (lock_path, "/");
}