Subject: bin/7662: crontab(1) does not always save changed crontab file
To: None <gnats-bugs@gnats.netbsd.org>
From: TheMan <andrew@untraceable.net>
List: netbsd-bugs
Date: 05/29/1999 11:05:47
>Number:         7662
>Category:       bin
>Synopsis:       crontab(1) does not always save changed crontab file
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    bin-bug-people (Utility Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat May 29 11:05:00 1999
>Last-Modified:
>Originator:     TheMan
>Organization:
nothing important
>Release:        1.3.3
>Environment:
System: NetBSD noc 1.3.3 NetBSD 1.3.3 (LINGAM) #1: Tue Apr 13 12:33:49 EDT 1999 andrew@noc:/usr/src/sys/arch/i386/compile/LINGAM i386


>Description:

whilst editing my crontab file from a shell script, i noticed that i
was apparently not editing my crontab file.  at least...crontab(1)
didn't think so.  i was trying to use ed(1) in a pipeline to do some
changes, and, of course, the file gets saved almost instantly after
it's opened.  so...unless you can arrange to edit the file right on
the cusp of a new second (so that the mtime will actually get changed
to something different from ctime), your changes are not noticed.

>How-To-Repeat:

attempt to comment out the newsyslog command from the root crontab via
ed in a pipeline:

	# setenv EDITOR ed
	# printf "/^[^#].*newsyslog/s/^/#/\nwq\n" | crontab -e
	881
	882
	crontab: no changes made to crontab
	# 

>Fix:

this looks right to me.  just check the size of the new file vs. the
size of the old file.  of course...you will still lose if the changes
you make (a) take less than a second to perform, and (b) result in a
same-sized file.

--- crontab.c-orig	Tue May 18 12:16:36 1999
+++ crontab.c	Sat May 29 13:49:37 1999
@@ -319,6 +319,7 @@
 	int		ch, t, x;
 	struct stat	statbuf;
 	time_t		mtime;
+	off_t		size;
 	WAIT_T		waiter;
 	PID_T		pid, xpid;
 
@@ -397,6 +398,7 @@
 		goto fatal;
 	}
 	mtime = statbuf.st_mtime;
+	size = statbuf.st_size;
 
 	if ((!(editor = getenv("VISUAL")))
 	 && (!(editor = getenv("EDITOR")))
@@ -464,7 +466,7 @@
 		perror("fstat");
 		goto fatal;
 	}
-	if (mtime == statbuf.st_mtime) {
+	if (mtime == statbuf.st_mtime && size == statbuf.st_size) {
 		fprintf(stderr, "%s: no changes made to crontab\n",
 			ProgramName);
 		goto remove;


>Audit-Trail:
>Unformatted: