summaryrefslogtreecommitdiffstats
path: root/usr.sbin/burncd
diff options
context:
space:
mode:
authorobrien <obrien@FreeBSD.org>2008-12-19 20:20:14 +0000
committerobrien <obrien@FreeBSD.org>2008-12-19 20:20:14 +0000
commit9cb8693afe328ae55dc576c27633f512b5da9020 (patch)
tree9781a965909e7361155101b3e8909cb9a0bb6076 /usr.sbin/burncd
parent04b1d503e162172ac1f99cab401b24577008d8a5 (diff)
downloadFreeBSD-src-9cb8693afe328ae55dc576c27633f512b5da9020.zip
FreeBSD-src-9cb8693afe328ae55dc576c27633f512b5da9020.tar.gz
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@saunalahti.fi>
Diffstat (limited to 'usr.sbin/burncd')
-rw-r--r--usr.sbin/burncd/Makefile2
-rw-r--r--usr.sbin/burncd/burncd.c41
2 files changed, 37 insertions, 6 deletions
diff --git a/usr.sbin/burncd/Makefile b/usr.sbin/burncd/Makefile
index 6f03273..bd4f285 100644
--- a/usr.sbin/burncd/Makefile
+++ b/usr.sbin/burncd/Makefile
@@ -3,6 +3,6 @@
PROG= burncd
MAN= burncd.8
-WARNS?= 5
+WARNS?= 6
.include <bsd.prog.mk>
diff --git a/usr.sbin/burncd/burncd.c b/usr.sbin/burncd/burncd.c
index 2800f52..5be73e0f 100644
--- a/usr.sbin/burncd/burncd.c
+++ b/usr.sbin/burncd/burncd.c
@@ -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 preemp, int dvdrw)
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 *track_info)
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,
OpenPOWER on IntegriCloud