From 90e9748dc9f6bb9962969ce1067cb50c7467fb8b Mon Sep 17 00:00:00 2001 From: Luis Pedro Coelho Date: Tue, 13 Mar 2018 17:08:33 +0100 Subject: [PATCH] Check for whether output is correctly written If `puts()` returns an error (e.g., writing to a full disk), then immediately `exit(1)`. Also, flush the output at the end and check if that operation was successful before exiting with a zero error code. fixes #103 --- format.c | 6 ++++-- main.c | 15 +++++++++++++-- map.c | 7 +++++-- mmpriv.h | 2 +- 4 files changed, 23 insertions(+), 7 deletions(-) diff --git a/format.c b/format.c index 89a93b69..49cadd32 100644 --- a/format.c +++ b/format.c @@ -112,8 +112,9 @@ static void sam_write_rg_line(kstring_t *str, const char *s) free(rg_line); } -void mm_write_sam_hdr(const mm_idx_t *idx, const char *rg, const char *ver, int argc, char *argv[]) +int mm_write_sam_hdr(const mm_idx_t *idx, const char *rg, const char *ver, int argc, char *argv[]) { + int err; kstring_t str = {0,0,0}; if (idx) { uint32_t i; @@ -130,8 +131,9 @@ void mm_write_sam_hdr(const mm_idx_t *idx, const char *rg, const char *ver, int mm_sprintf_lite(&str, " %s", argv[i]); } mm_sprintf_lite(&str, "\n"); - fputs(str.s, stdout); + err = fputs(str.s, stdout); free(str.s); + return err; } static void write_cs(void *km, kstring_t *s, const mm_idx_t *mi, const mm_bseq1_t *t, const mm_reg1_t *r, int no_iden) diff --git a/main.c b/main.c index 0a3eaad7..db313591 100644 --- a/main.c +++ b/main.c @@ -309,13 +309,18 @@ int main(int argc, char *argv[]) return 1; } if ((opt.flag & MM_F_OUT_SAM) && idx_rdr->n_parts == 1) { + int err; if (mm_idx_reader_eof(idx_rdr)) { - mm_write_sam_hdr(mi, rg, MM_VERSION, argc, argv); + err = mm_write_sam_hdr(mi, rg, MM_VERSION, argc, argv); } else { - mm_write_sam_hdr(0, rg, MM_VERSION, argc, argv); + err = mm_write_sam_hdr(0, rg, MM_VERSION, argc, argv); if (mm_verbose >= 2) fprintf(stderr, "[WARNING]\033[1;31m For a multi-part index, no @SQ lines will be outputted.\033[0m\n"); } + if (err == EOF) { + fprintf(stderr, "[ERROR] error writing output header\n"); + return 1; + } } if (mm_verbose >= 3) fprintf(stderr, "[M::%s::%.3f*%.2f] loaded/built the index for %d target sequence(s)\n", @@ -337,5 +342,11 @@ int main(int argc, char *argv[]) for (i = 0; i < argc; ++i) fprintf(stderr, " %s", argv[i]); fprintf(stderr, "\n[M::%s] Real time: %.3f sec; CPU: %.3f sec\n", __func__, realtime() - mm_realtime0, cputime()); + + int err = fflush(stdout); + if (err == EOF) { + fprintf(stderr, "[ERROR]: Could not flush output\n"); + return 1; + } return 0; } diff --git a/map.c b/map.c index 4dcff71c..b77db93d 100644 --- a/map.c +++ b/map.c @@ -478,6 +478,7 @@ static void *worker_pipeline(void *shared, int step, void *in) if ((p->opt->flag & MM_F_OUT_CS) && !(mm_dbg_flag & MM_DBG_NO_KALLOC)) km = km_init(); for (k = 0; k < s->n_frag; ++k) { int seg_st = s->seg_off[k], seg_en = s->seg_off[k] + s->n_seg[k]; + int err; for (i = seg_st; i < seg_en; ++i) { mm_bseq1_t *t = &s->seq[i]; for (j = 0; j < s->n_reg[i]; ++j) { @@ -489,11 +490,13 @@ static void *worker_pipeline(void *shared, int step, void *in) mm_write_sam2(&p->str, mi, t, i - seg_st, j, s->n_seg[k], &s->n_reg[seg_st], (const mm_reg1_t*const*)&s->reg[seg_st], km, p->opt->flag); else mm_write_paf(&p->str, mi, t, r, km, p->opt->flag); - puts(p->str.s); + err = puts(p->str.s); + if (err == EOF) exit(1); } if (s->n_reg[i] == 0 && (p->opt->flag & MM_F_OUT_SAM)) { mm_write_sam2(&p->str, mi, t, i - seg_st, -1, s->n_seg[k], &s->n_reg[seg_st], (const mm_reg1_t*const*)&s->reg[seg_st], km, p->opt->flag); - puts(p->str.s); + err = puts(p->str.s); + if (err == EOF) exit(1); } } for (i = seg_st; i < seg_en; ++i) { diff --git a/mmpriv.h b/mmpriv.h index 4a1ae2b4..54a4a576 100644 --- a/mmpriv.h +++ b/mmpriv.h @@ -56,7 +56,7 @@ uint32_t ks_ksmall_uint32_t(size_t n, uint32_t arr[], size_t kk); void mm_sketch(void *km, const char *str, int len, int w, int k, uint32_t rid, int is_hpc, mm128_v *p); -void mm_write_sam_hdr(const mm_idx_t *mi, const char *rg, const char *ver, int argc, char *argv[]); +int mm_write_sam_hdr(const mm_idx_t *mi, const char *rg, const char *ver, int argc, char *argv[]); void mm_write_paf(kstring_t *s, const mm_idx_t *mi, const mm_bseq1_t *t, const mm_reg1_t *r, void *km, int opt_flag); void mm_write_sam(kstring_t *s, const mm_idx_t *mi, const mm_bseq1_t *t, const mm_reg1_t *r, int n_regs, const mm_reg1_t *regs); void mm_write_sam2(kstring_t *s, const mm_idx_t *mi, const mm_bseq1_t *t, int seg_idx, int reg_idx, int n_seg, const int *n_regs, const mm_reg1_t *const* regs, void *km, int opt_flag);