ChangeLog, e2fsck.8.in, e2fsck.h, pass5.c, unix.c:
  unix.c (PRS): Added new option -C, which causes e2fsck to print
  	progress updates so that callers can keep track of the completion
  	progress of e2fsck.  Designed for use by progress, except for -C 0,
  	which prints a spinning report which may be useful for some users.
  pass5.c (e2fsck_pass5): Use a finer-grained progress reporting scheme
  	(useful for larger filesystems).
  e2fsck.h: Add progress_fd and progress_pos, for use by the Unix
  	progress reporting functions.

diff --git a/e2fsck/ChangeLog b/e2fsck/ChangeLog
index e0a8e00..645bea0 100644
--- a/e2fsck/ChangeLog
+++ b/e2fsck/ChangeLog
@@ -1,3 +1,17 @@
+1998-05-07  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+	* unix.c (PRS): Added new option -C, which causes e2fsck to print
+		progress updates so that callers can keep track of the
+		completion progress of e2fsck.  Designed for use by
+		progress, except for -C 0, which prints a spinning report
+		which may be useful for some users.
+
+	* pass5.c (e2fsck_pass5): Use a finer-grained progress reporting
+		scheme (useful for larger filesystems).
+
+	* e2fsck.h: Add progress_fd and progress_pos, for use by the Unix
+		progress reporting functions.
+
 1998-04-28  Theodore Ts'o  <tytso@rsts-11.mit.edu>
 
 	* pass1.c (process_inode_cmp): Use EXT2_QSORT_TYPE to define the
diff --git a/e2fsck/e2fsck.8.in b/e2fsck/e2fsck.8.in
index 62e7bae..41e6dc8 100644
--- a/e2fsck/e2fsck.8.in
+++ b/e2fsck/e2fsck.8.in
@@ -22,6 +22,10 @@
 .B \-l|-L
 .I bad_blocks_file
 ]
+[
+.B \-C
+.I fd
+]
 .I device
 .SH DESCRIPTION
 .B e2fsck
@@ -69,6 +73,20 @@
 program to find any blocks which are bad on the filesystem, 
 and then marks them as bad by adding them to the bad block inode.
 .TP
+.I -C
+This option causes
+.B e2fsck
+to write completion information to the specified file descriptor 
+so that the progress of the filesystem 
+check can be monitored.  This option is typically used by programs which are
+executing 
+.BR e2fsck ,
+although -C 0 is a special case which will output a spinning
+character which can be useful for users who want to have something to watch
+while 
+.B e2fsck
+goes about its business.
+.TP
 .I -d
 Print debugging output (useless unless you are debugging
 .BR e2fsck ).
diff --git a/e2fsck/e2fsck.h b/e2fsck/e2fsck.h
index a3e3e58..12c5971 100644
--- a/e2fsck/e2fsck.h
+++ b/e2fsck/e2fsck.h
@@ -191,6 +191,12 @@
 	struct resource_track	global_rtrack;
 #endif
 
+	/*
+	 * How we display the progress update (for unix)
+	 */
+	int progress_fd;
+	int progress_pos;
+
 	/* File counts */
 	int fs_directory_count;
 	int fs_regular_count;
diff --git a/e2fsck/pass5.c b/e2fsck/pass5.c
index 7561e79..0dccb02 100644
--- a/e2fsck/pass5.c
+++ b/e2fsck/pass5.c
@@ -39,15 +39,11 @@
 		fix_problem(ctx, PR_5_PASS_HEADER, &pctx);
 
 	if (ctx->progress)
-		if ((ctx->progress)(ctx, 5, 0, 3))
+		if ((ctx->progress)(ctx, 5, 0, ctx->fs->group_desc_count*2))
 			return;
 
 	e2fsck_read_bitmaps(ctx);
 
-	if (ctx->progress)
-		if ((ctx->progress)(ctx, 5, 2, 3))
-			return;
-
 	check_block_bitmaps(ctx);
 	if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
 		return;
@@ -61,10 +57,6 @@
 	if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
 		return;
 
-	if (ctx->progress)
-		if ((ctx->progress)(ctx, 5, 3, 3))
-			return;
-
 	ext2fs_free_inode_bitmap(ctx->inode_used_map);
 	ctx->inode_used_map = 0;
 	ext2fs_free_inode_bitmap(ctx->inode_dir_map);
@@ -164,6 +156,10 @@
 			group ++;
 			blocks = 0;
 			group_free = 0;
+			if (ctx->progress)
+				if ((ctx->progress)(ctx, 5, group,
+						    fs->group_desc_count*2))
+					return;
 		}
 	}
 	if (had_problem)
@@ -305,6 +301,11 @@
 			inodes = 0;
 			group_free = 0;
 			dirs_count = 0;
+			if (ctx->progress)
+				if ((ctx->progress)(ctx, 5,
+					    group + fs->group_desc_count,
+					    fs->group_desc_count*2))
+					return;
 		}
 	}
 	if (had_problem)
diff --git a/e2fsck/unix.c b/e2fsck/unix.c
index 855ab74..e674b71 100644
--- a/e2fsck/unix.c
+++ b/e2fsck/unix.c
@@ -220,6 +220,28 @@
 	exit(FSCK_OK);
 }
 
+/*
+ * For completion notice
+ */
+static int e2fsck_update_progress(e2fsck_t ctx, int pass,
+				  unsigned long cur, unsigned long max)
+{
+	const char spinner[] = "\\|/-";
+	int percent;
+	struct e2_progress_struct *prog_struct;
+	char buf[80];
+	
+	if (ctx->progress_fd) {
+		sprintf(buf, "%d %lu %lu\n", pass, cur, max);
+		write(ctx->progress_fd, buf, strlen(buf));
+	} else {
+		ctx->progress_pos = (ctx->progress_pos+1) & 3;
+		fputc(spinner[ctx->progress_pos], stdout);
+		fputc('\b', stdout);
+		fflush(stdout);
+	}
+	return 0;
+}
 
 #define PATH_SET "PATH=/sbin"
 
@@ -263,8 +285,12 @@
 		ctx->program_name = *argv;
 	else
 		ctx->program_name = "e2fsck";
-	while ((c = getopt (argc, argv, "panyrcB:dfvtFVM:b:I:P:l:L:N:Ss")) != EOF)
+	while ((c = getopt (argc, argv, "panyrcC:B:dfvtFVM:b:I:P:l:L:N:Ss")) != EOF)
 		switch (c) {
+		case 'C':
+			ctx->progress = e2fsck_update_progress;
+			ctx->progress_fd = atoi(optarg);
+			break;
 		case 'p':
 		case 'a':
 			ctx->options |= E2F_OPT_PREEN;