svn commit: r186337 - head/usr.sbin/burncd

David E. O'Brien obrien at FreeBSD.org
Fri Dec 19 20:20:14 UTC 2008


Author: obrien
Date: Fri Dec 19 20:20:14 2008
New Revision: 186337
URL: http://svn.freebsd.org/changeset/base/186337

Log:
  burncd(8) doesn't handle signals and interrupting burncd during operation.
  For example, ^C (SIGINT) may leave the drive spinning and locked.
  This may also happen if you try to write a too-large image to a disc
  and burncd(8) exits with an I/O error.
  
  Add signal handling by doing a CDRIOCFLUSH ioctl to attempt to leave
  burner in a sane state when burning is interrupted with SIGHUP, SIGINT,
  SIGTERM, or in case an I/O error occurs during write.
  Note, that blanking will still continue after interrupt but it seems to
  finish correctly even after burncd(8) has quit.
  
  Also, while I'm here bump WARNS to "6".
  
  PR:		48730
  Submitted by:	Jaakko Heinonen <jh at saunalahti.fi>

Modified:
  head/usr.sbin/burncd/Makefile
  head/usr.sbin/burncd/burncd.c

Modified: head/usr.sbin/burncd/Makefile
==============================================================================
--- head/usr.sbin/burncd/Makefile	Fri Dec 19 20:19:59 2008	(r186336)
+++ head/usr.sbin/burncd/Makefile	Fri Dec 19 20:20:14 2008	(r186337)
@@ -3,6 +3,6 @@
 PROG=	burncd
 MAN=	burncd.8
 
-WARNS?=	5
+WARNS?=	6
 
 .include <bsd.prog.mk>

Modified: head/usr.sbin/burncd/burncd.c
==============================================================================
--- head/usr.sbin/burncd/burncd.c	Fri Dec 19 20:19:59 2008	(r186336)
+++ head/usr.sbin/burncd/burncd.c	Fri Dec 19 20:20:14 2008	(r186337)
@@ -29,6 +29,7 @@
  */
 
 #include <unistd.h>
+#include <signal.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -67,6 +68,8 @@ int write_file(int fd, struct track_info
 int roundup_blocks(struct track_info *);
 void cue_ent(struct cdr_cue_entry *, int, int, int, int, int, int, int);
 void cleanup(int);
+void cleanup_flush(void);
+void cleanup_signal(int);
 void usage(void);
 
 int
@@ -157,6 +160,9 @@ main(int argc, char **argv)
 
 	global_fd_for_cleanup = fd;
 	err_set_exit(cleanup);
+	signal(SIGHUP, cleanup_signal);
+	signal(SIGINT, cleanup_signal);
+	signal(SIGTERM, cleanup_signal);
 
 	for (arg = 0; arg < argc; arg++) {
 		if (!strcasecmp(argv[arg], "fixate")) {
@@ -319,6 +325,10 @@ main(int argc, char **argv)
 	if (eject)
 		if (ioctl(fd, CDIOCEJECT) < 0)
 			err(EX_IOERR, "ioctl(CDIOCEJECT)");
+
+	signal(SIGHUP, SIG_DFL);
+	signal(SIGINT, SIG_DFL);
+	signal(SIGTERM, SIG_DFL);
 	close(fd);
 	exit(EX_OK);
 }
@@ -469,8 +479,10 @@ do_DAO(int fd, int test_write, int multi
 		err(EX_IOERR, "ioctl(CDRIOCSENDCUE)");
 
 	for (i = 0; i < notracks; i++) {
-		if (write_file(fd, &tracks[i]))
+		if (write_file(fd, &tracks[i])) {
+			cleanup_flush();
 			err(EX_IOERR, "write_file");
+		}
 	}
 
 	ioctl(fd, CDRIOCFLUSH);
@@ -499,8 +511,10 @@ do_TAO(int fd, int test_write, int preem
 		if (!quiet)
 			fprintf(stderr, "next writeable LBA %d\n",
 				tracks[i].addr);
-		if (write_file(fd, &tracks[i]))
+		if (write_file(fd, &tracks[i])) {
+			cleanup_flush();
 			err(EX_IOERR, "write_file");
+		}
 		if (ioctl(fd, CDRIOCFLUSH) < 0)
 			err(EX_IOERR, "ioctl(CDRIOCFLUSH)");
 	}
@@ -630,9 +644,11 @@ write_file(int fd, struct track_info *tr
 				track_info->block_size;
 		}
 		if ((res = write(fd, buf, count)) != count) {
-			if (res == -1)
-				fprintf(stderr, "\n%s\n", strerror(errno));
-			else
+			if (res == -1) {
+				fprintf(stderr, "\n");
+				close(track_info->file);
+				return errno;
+			} else
 				fprintf(stderr, "\nonly wrote %d of %jd"
 				    " bytes\n", res, (intmax_t)count);
 			break;
@@ -693,6 +709,21 @@ cleanup(int dummy __unused)
 }
 
 void
+cleanup_flush(void)
+{
+	if (ioctl(global_fd_for_cleanup, CDRIOCFLUSH) < 0)
+		err(EX_IOERR, "ioctl(CDRIOCFLUSH)");
+}
+
+void
+cleanup_signal(int sig __unused)
+{
+	cleanup_flush();
+	fprintf(stderr, "\n");
+	errx(EXIT_FAILURE, "Aborted");
+}
+
+void
 usage(void)
 {
 	fprintf(stderr,


More information about the svn-src-all mailing list