File 90_report_recording_errors.dpatch of Package gramofile

# Report errors during recording to the user. [dk]
#PATCHOPTIONS: -p0

--- bplaysrc/shmbuf.c.orig
+++ bplaysrc/shmbuf.c
@@ -80,10 +80,12 @@ static char *bigbuff;
 static char **buffarr;
 static int numbuffs, numsemblks;
 static blockinf_t *buffinf;
+static volatile int stoprecording;
 
 /* prototypes */
 void cleanupsems(void);
 static void sighandler(int i);
+static void childerrhandler(int i);
 
 /* Extern globals */
 extern int abuf_size;
@@ -194,6 +196,8 @@ void init_shm(void)
     }
     /* Catch some signals, so we clean up semaphores */
     signal(SIGINT, sighandler);
+    /* Out of disk space errors are handled explicitly already. */
+    signal(SIGXFSZ, SIG_IGN);
 }
 
 
@@ -240,6 +244,7 @@ void shmrec(int outfd, long totalcount,
     {
 	int cbuff = 0;
 	long totalrd = 0; /* we need it here too... */
+	int err = 0;
 
 #ifdef VUMETER
 	signed short *ssptr;
@@ -276,6 +281,13 @@ void shmrec(int outfd, long totalcount,
                 totalrd += count;
 	    }
 
+	    if (count == -1 && errno != EINTR) {
+		    err = errno;
+		    for (i = 0; i < numbuffs; i++)
+			    up(sndsemid, i);
+		    break;
+	    }
+
 #ifdef VUMETER
 	    maxleft = 0;
 	    maxright = 0;
@@ -342,19 +354,27 @@ void shmrec(int outfd, long totalcount,
 
 	printw("\n\n");
 	printw("      Recording information:\n\n\n");
-	fsec2hmsf ( (double) totalrd / (4 * 44100) , timestring);
-	printw("    Recorded time    : %s\n", timestring);
-	printw("    Recorded samples : %11ld\n", totalrd / 4);
-	printw("    Recorded bytes   : %11ld  (excl. header)\n", totalrd);
-	printw("\n");
-	printw("    Samples above 50%% of max. volume  : %9ld  (%5.1f%%)\n",
-          samplesabove50pct, samplesabove50pct * 100. / (totalrd/4));
-	printw("    Samples above 90%% of max. volume  : %9ld  (%5.1f%%)\n",
-          samplesabove90pct, samplesabove90pct * 100. / (totalrd/4));
-	printw("    Samples above 99%% of max. volume  : %9ld  (%5.1f%%)\n",
-          samplesabove99pct, samplesabove99pct * 100. / (totalrd/4));
-	printw("    Really too loud (clipped) samples : %9ld  (%5.1f%%)\n",
-          samplestooloud, samplestooloud * 100. / (totalrd/4));
+
+	if (!err) {
+		
+	  fsec2hmsf ( (double) totalrd / (4 * 44100) , timestring);
+	  printw("    Recorded time    : %s\n", timestring);
+	  printw("    Recorded samples : %11ld\n", totalrd / 4);
+	  printw("    Recorded bytes   : %11ld  (excl. header)\n", totalrd);
+	  printw("\n");
+	  printw("    Samples above 50%% of max. volume  : %9ld  (%5.1f%%)\n",
+            samplesabove50pct, samplesabove50pct * 100. / (totalrd/4));
+	  printw("    Samples above 90%% of max. volume  : %9ld  (%5.1f%%)\n",
+            samplesabove90pct, samplesabove90pct * 100. / (totalrd/4));
+	  printw("    Samples above 99%% of max. volume  : %9ld  (%5.1f%%)\n",
+            samplesabove99pct, samplesabove99pct * 100. / (totalrd/4));
+	  printw("    Really too loud (clipped) samples : %9ld  (%5.1f%%)\n",
+            samplestooloud, samplestooloud * 100. / (totalrd/4));
+
+	} else {
+		printw("    Recording has terminated due to an error.\n");
+		printw("    Operating system reports: %s\n", strerror(err));
+	}
 
 #if 0
 	/* The computation of the avg volume is not simple. One approach
@@ -379,6 +399,11 @@ void shmrec(int outfd, long totalcount,
                3, strlen (ok_button.text) + 2);
 	move (0, 79);
 	refresh();
+
+	/* Tell parent to stop recording */
+	if (err)
+		kill(getppid(), SIGUSR1);
+	
 #endif
 
 	exit(0);
@@ -389,9 +414,10 @@ void shmrec(int outfd, long totalcount,
 	int cbuff = 0;
 	long totalrd = 0;
 
-	int stoprecording=0;
 	int in_ch;
 
+	signal(SIGUSR1, childerrhandler);
+
 	while (totalrd < totalcount && !stoprecording)
 	{
 	    long trgt, count, numrd;
@@ -401,11 +427,15 @@ void shmrec(int outfd, long totalcount,
 		trgt = abuf_size;
 	    /* Get the buffer. Blocks until OK to do so */
 	    down(sndsemid, cbuff);
+	    if (stoprecording)
+		    break;
+	    
 	    /* Read a block of data */
 	    numrd = 0;
 	    tmpptr = buffarr[cbuff];
 	    while( (numrd < trgt) &&
-		((count = read(audio, tmpptr, trgt - numrd)) > 0) )
+		((count = read(audio, tmpptr, trgt - numrd)) > 0) &&
+		!stoprecording)
 	    {
 		numrd += count;
 		tmpptr += count;
@@ -674,3 +704,8 @@ static void sighandler(int i)
     finish_curses(1);
     exit(1);
 }
+
+static void childerrhandler(int i)
+{
+	stoprecording = 1;
+}