Index: usr.sbin/cron/crontab/crontab.1
===================================================================
RCS file: /usr/home/ncvs/src/usr.sbin/cron/crontab/crontab.1,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- usr.sbin/cron/crontab/crontab.1	1999/08/28 01:15:52	1.7
+++ usr.sbin/cron/crontab/crontab.1	2000/11/06 11:17:37	1.8
@@ -89,7 +89,12 @@
 .Ev VISUAL
 or
 .Ev EDITOR
-environment variables.  After you exit
+environment variables.
+The specified editor
+.Em must
+edit the file in place;
+any editor that unlinks the file and recreates it cannot be used.
+After you exit
 from the editor, the modified crontab will be installed automatically.
 .El
 .Sh SEE ALSO
Index: usr.sbin/cron/crontab/crontab.c
===================================================================
RCS file: /usr/home/ncvs/src/usr.sbin/cron/crontab/crontab.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- usr.sbin/cron/crontab/crontab.c	2000/10/15 00:35:34	1.13
+++ usr.sbin/cron/crontab/crontab.c	2000/11/06 11:17:37	1.14
@@ -285,7 +285,7 @@
 	char		n[MAX_FNAME], q[MAX_TEMPSTR], *editor;
 	FILE		*f;
 	int		ch, t, x;
-	struct stat	statbuf;
+	struct stat	statbuf, fsbuf;
 	time_t		mtime;
 	WAIT_T		waiter;
 	PID_T		pid, xpid;
@@ -317,7 +317,7 @@
 		warn("fchown");
 		goto fatal;
 	}
-	if (!(NewCrontab = fdopen(t, "w"))) {
+	if (!(NewCrontab = fdopen(t, "r+"))) {
 		warn("fdopen");
 		goto fatal;
 	}
@@ -347,14 +347,20 @@
 		while (EOF != (ch = get_char(f)))
 			putc(ch, NewCrontab);
 	fclose(f);
-	if (fclose(NewCrontab))
+	if (fflush(NewCrontab))
 		err(ERROR_EXIT, "%s", Filename);
+	if (fstat(t, &fsbuf) < 0) {
+		warn("unable to fstat temp file");
+		goto fatal;
+	}
  again:
 	if (stat(Filename, &statbuf) < 0) {
 		warn("stat");
  fatal:		unlink(Filename);
 		exit(ERROR_EXIT);
 	}
+	if (statbuf.st_dev != fsbuf.st_dev || statbuf.st_ino != fsbuf.st_ino)
+		errx(ERROR_EXIT, "temp file must be edited in place");
 	mtime = statbuf.st_mtime;
 
 	if ((!(editor = getenv("VISUAL")))
@@ -419,15 +425,13 @@
 		warn("stat");
 		goto fatal;
 	}
+	if (statbuf.st_dev != fsbuf.st_dev || statbuf.st_ino != fsbuf.st_ino)
+		errx(ERROR_EXIT, "temp file must be edited in place");
 	if (mtime == statbuf.st_mtime) {
 		warnx("no changes made to crontab");
 		goto remove;
 	}
 	warnx("installing new crontab");
-	if (!(NewCrontab = fopen(Filename, "r"))) {
-		warn("%s", Filename);
-		goto fatal;
-	}
 	switch (replace_cmd()) {
 	case 0:
 		break;
@@ -497,10 +501,10 @@
 
 	/* copy the crontab to the tmp
 	 */
+	rewind(NewCrontab);
 	Set_LineNum(1)
 	while (EOF != (ch = get_char(NewCrontab)))
 		putc(ch, tmp);
-	fclose(NewCrontab);
 	ftruncate(fileno(tmp), ftell(tmp));
 	fflush(tmp);  rewind(tmp);
 
