diff options
author | Douglas Gilbert <dgilbert@interlog.com> | 2021-07-29 02:49:07 +0000 |
---|---|---|
committer | Douglas Gilbert <dgilbert@interlog.com> | 2021-07-29 02:49:07 +0000 |
commit | c2a103b26a80218c8c2ee9a8ddb7122e36a69331 (patch) | |
tree | 7d82843bcf1064edafd518280ede8d0e5149292e /testing | |
parent | 303f8c98ee28150285d69bd213970144fe224da3 (diff) | |
download | sg3_utils-c2a103b26a80218c8c2ee9a8ddb7122e36a69331.tar.gz |
sg_zones: finish initial support for REPORT ZONE DOMAINS and REPORT REALMS
Lots of clean-up based on Coverity and other code checkers. Add some new
inhex folder entries to testing those new ZBC-2 commands.
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@906 6180dd3e-e324-4e3e-922d-17de1ae2f315
Diffstat (limited to 'testing')
-rw-r--r-- | testing/sg_mrq_dd.cpp | 73 | ||||
-rw-r--r-- | testing/sgh_dd.cpp | 58 | ||||
-rw-r--r-- | testing/sgs_dd.c | 47 |
3 files changed, 109 insertions, 69 deletions
diff --git a/testing/sg_mrq_dd.cpp b/testing/sg_mrq_dd.cpp index 5f906028..2f1aff94 100644 --- a/testing/sg_mrq_dd.cpp +++ b/testing/sg_mrq_dd.cpp @@ -30,7 +30,7 @@ * */ -static const char * version_str = "1.31 20210620"; +static const char * version_str = "1.32 20210627"; #define _XOPEN_SOURCE 600 #ifndef _GNU_SOURCE @@ -386,6 +386,7 @@ static atomic<int> num_miscompare(0); static atomic<bool> vb_first_time(true); static sigset_t signal_set; +static sigset_t orig_signal_set; static const char * proc_allow_dio = "/proc/scsi/sg/allow_dio"; @@ -1272,8 +1273,10 @@ sg_in_open(struct global_collection *clp, const string & inf, uint8_t **mmpp, return -sg_convert_errno(err); } n = sg_prepare_resbuf(fd, clp, true, mmpp); - if (n <= 0) + if (n <= 0) { + close(fd); return -SG_LIB_FILE_ERROR; + } if (mmap_lenp) *mmap_lenp = n; return fd; @@ -1303,8 +1306,10 @@ sg_out_open(struct global_collection *clp, const string & outf, return -sg_convert_errno(err); } n = sg_prepare_resbuf(fd, clp, false, mmpp); - if (n <= 0) + if (n <= 0) { + close(fd); return -SG_LIB_FILE_ERROR; + } if (mmap_lenp) *mmap_lenp = n; return fd; @@ -1447,10 +1452,10 @@ flag_all_stop(struct global_collection * clp) } } -/* Has an infinite loop doing a timed wait for any signals in sig_set. After - * each timeout (300 ms) checks if the most_recent_pack_id atomic integer - * has changed. If not after another two timeouts announces a stall has - * been detected. If shutting down atomic is true breaks out of loop and +/* Has an infinite loop doing a timed wait for any signals in signal_set. + * After each timeout (300 ms) checks if the most_recent_pack_id atomic + * integer has changed. If not after another two timeouts announces a stall + * has been detected. If shutting down atomic is true breaks out of loop and * shuts down this thread. Other than that, this thread is normally cancelled * by the main thread, after other threads have exited. */ static void @@ -1467,8 +1472,6 @@ sig_listen_thread(struct global_collection * clp) tsp->tv_nsec = (ict_ms % 1000) * 1000 * 1000; /* DEF_SDT_ICT_MS */ while (1) { sig_number = sigtimedwait(&signal_set, NULL, tsp); - if (shutting_down) - break; if (sig_number < 0) { int err = errno; @@ -1484,7 +1487,7 @@ sig_listen_thread(struct global_collection * clp) __func__, pack_id); } else pr2serr_lk("%s: subsequent stall at pack_id=%d\n", - __func__, pack_id); + __func__, pack_id); system_wrapper("/usr/bin/cat /proc/scsi/sg/debug\n"); } else prev_pack_id = pack_id; @@ -1495,7 +1498,12 @@ sig_listen_thread(struct global_collection * clp) pr2serr_lk("%sinterrupted by SIGINT\n", my_name); flag_all_stop(clp); shutting_down.store(true); + sigprocmask(SIG_SETMASK, &orig_signal_set, NULL); + raise(SIGINT); + break; } + if (shutting_down) + break; } /* end of while loop */ if (clp->verbose > 1) pr2serr_lk("%s: exiting\n", __func__); @@ -2968,7 +2976,8 @@ do_both_sg_segment(Rq_elem * rep, scat_gath_iter & i_sg_it, int num_mrq, k, res, fd, mrq_pack_id_base, id, b_len, iflags, oflags; int num, kk, i_lin_blks, o_lin_blks, cdbsz, num_good, err; int o_seg_blks = seg_blks; - uint32_t in_fin_blks, out_fin_blks; + uint32_t in_fin_blks = 0; + uint32_t out_fin_blks = 0;; uint32_t in_mrq_q_blks = 0; uint32_t out_mrq_q_blks = 0; const int max_cdb_sz = MAX_SCSI_CDB_SZ; @@ -3473,6 +3482,7 @@ parse_cmdline_sanity(int argc, char * argv[], struct global_collection * clp, bool bpt_given = false; int ibs = 0; int obs = 0; + int ret = 0; int k, keylen, n, res; char str[STR_SZ]; char * key; @@ -3513,7 +3523,7 @@ parse_cmdline_sanity(int argc, char * argv[], struct global_collection * clp, if ((n < 0) || (n > 32)) { pr2serr("%s: bad argument to 'cdbsz=', expect 6, 10, 12 or " "16\n", my_name); - return SG_LIB_SYNTAX_ERROR; + goto syn_err; } clp->cdbsz_in = n; if (ccp) { @@ -3521,7 +3531,7 @@ parse_cmdline_sanity(int argc, char * argv[], struct global_collection * clp, if ((n < 0) || (n > 32)) { pr2serr("%s: bad second argument to 'cdbsz=', expect 6, " "10, 12 or 16\n", my_name); - return SG_LIB_SYNTAX_ERROR; + goto syn_err; } } clp->cdbsz_out = n; @@ -3532,7 +3542,7 @@ parse_cmdline_sanity(int argc, char * argv[], struct global_collection * clp, if ((n < 0) || (n > 7)) { pr2serr("%s: bad argument to 'cdl=', expect 0 to 7\n", my_name); - return SG_LIB_SYNTAX_ERROR; + goto syn_err; } clp->in_flags.cdl = n; if (ccp) { @@ -3540,7 +3550,7 @@ parse_cmdline_sanity(int argc, char * argv[], struct global_collection * clp, if ((n < 0) || (n > 7)) { pr2serr("%s: bad second argument to 'cdl=', expect 0 " "to 7\n", my_name); - return SG_LIB_SYNTAX_ERROR; + goto syn_err; } } clp->out_flags.cdl = n; @@ -3552,7 +3562,7 @@ parse_cmdline_sanity(int argc, char * argv[], struct global_collection * clp, } else if (0 == strcmp(key, "conv")) { if (process_conv(buf, &clp->in_flags, &clp->out_flags)) { pr2serr("%s: bad argument to 'conv='\n", my_name); - return SG_LIB_SYNTAX_ERROR; + goto syn_err; } } else if (0 == strcmp(key, "count")) { if (clp->count_given) { @@ -3706,6 +3716,8 @@ parse_cmdline_sanity(int argc, char * argv[], struct global_collection * clp, goto syn_err; } seek_buf = (char *)calloc(n + 16, 1); + if (NULL == seek_buf) + goto syn_err; memcpy(seek_buf, buf, n + 1); } else if (0 == strcmp(key, "skip")) { n = strlen(buf); @@ -3714,6 +3726,8 @@ parse_cmdline_sanity(int argc, char * argv[], struct global_collection * clp, goto syn_err; } skip_buf = (char *)calloc(n + 16, 1); + if (NULL == skip_buf) + goto syn_err; memcpy(skip_buf, buf, n + 1); } else if (0 == strcmp(key, "sync")) do_sync = !! sg_get_num(buf); @@ -3828,11 +3842,13 @@ parse_cmdline_sanity(int argc, char * argv[], struct global_collection * clp, #endif if (version_given) { pr2serr("%s%s\n", my_name, version_str); - return SG_LIB_OK_FALSE; + ret = SG_LIB_OK_FALSE; + goto oth_err; } if (clp->help > 0) { usage(clp->help); - return SG_LIB_OK_FALSE; + ret = SG_LIB_OK_FALSE; + goto oth_err; } if (clp->bs <= 0) { clp->bs = DEF_BLOCK_SIZE; @@ -3846,26 +3862,26 @@ parse_cmdline_sanity(int argc, char * argv[], struct global_collection * clp, if ((ibs && (ibs != clp->bs)) || (obs && (obs != clp->bs))) { pr2serr("If 'ibs' or 'obs' given must be same as 'bs'\n"); usage(0); - return SG_LIB_SYNTAX_ERROR; + goto syn_err; } if (clp->out_flags.append) { if ((clp->o_sgl.lowest_lba > 0) || (clp->o_sgl.linearity != SGL_LINEAR)) { pr2serr("Can't use both append and seek switches\n"); - return SG_LIB_SYNTAX_ERROR; + goto syn_err; } if (verify_given) { pr2serr("Can't use both append and verify switches\n"); - return SG_LIB_SYNTAX_ERROR; + goto syn_err; } } if (clp->bpt < 1) { pr2serr("bpt must be greater than 0\n"); - return SG_LIB_SYNTAX_ERROR; + goto syn_err; } if (clp->in_flags.mmap && clp->out_flags.mmap) { pr2serr("mmap flag on both IFILE and OFILE doesn't work\n"); - return SG_LIB_SYNTAX_ERROR; + goto syn_err; } /* defaulting transfer size to 128*2048 for CD/DVDs is too large * for the block layer in lk 2.6 and results in an EIO on the @@ -3877,7 +3893,7 @@ parse_cmdline_sanity(int argc, char * argv[], struct global_collection * clp, if ((num_threads < 1) || (num_threads > MAX_NUM_THREADS)) { pr2serr("too few or too many threads requested\n"); usage(1); - return SG_LIB_SYNTAX_ERROR; + goto syn_err; } clp->unit_nanosec = (do_time > 1) || !!getenv("SG3_UTILS_LINUX_NANO"); return 0; @@ -3888,6 +3904,12 @@ syn_err: if (skip_buf) free(skip_buf); return contra ? SG_LIB_CONTRADICT : SG_LIB_SYNTAX_ERROR; +oth_err: + if (seek_buf) + free(seek_buf); + if (skip_buf) + free(skip_buf); + return ret; } static int @@ -4443,7 +4465,7 @@ main(int argc, char * argv[]) sigemptyset(&signal_set); sigaddset(&signal_set, SIGINT); - res = sigprocmask(SIG_BLOCK, &signal_set, NULL); + res = sigprocmask(SIG_BLOCK, &signal_set, &orig_signal_set); if (res < 0) { pr2serr("sigprocmask failed: %s\n", safe_strerror(errno)); goto fini; @@ -4566,5 +4588,6 @@ fini: pr2serr("Verify/compare failed due to miscompare\n"); if (0 == res) res = clp->reason_res.load(); + sigprocmask(SIG_SETMASK, &orig_signal_set, NULL); return (res >= 0) ? res : SG_LIB_CAT_OTHER; } diff --git a/testing/sgh_dd.cpp b/testing/sgh_dd.cpp index a8fcd56e..4610caef 100644 --- a/testing/sgh_dd.cpp +++ b/testing/sgh_dd.cpp @@ -36,7 +36,7 @@ * renamed [20181221] */ -static const char * version_str = "2.10 20210621"; +static const char * version_str = "2.12 20210727"; #define _XOPEN_SOURCE 600 #ifndef _GNU_SOURCE @@ -375,8 +375,10 @@ static atomic<int> num_mrq_abort_req_success(0); static atomic<int> num_miscompare(0); static atomic<long> num_waiting_calls(0); static atomic<bool> vb_first_time(true); +static atomic<bool> shutting_down(false); static sigset_t signal_set; +static sigset_t orig_signal_set; static pthread_t sig_listen_thread_id; static const char * proc_allow_dio = "/proc/scsi/sg/allow_dio"; @@ -405,7 +407,6 @@ static bool have_sg_version = false; static int sg_version = 0; static bool sg_version_lt_4 = false; static bool sg_version_ge_40045 = false; -static bool shutting_down = false; static bool do_sync = false; static int do_time = 1; static struct global_collection gcoll; @@ -1227,8 +1228,6 @@ sig_listen_thread(void * v_clp) tsp->tv_nsec = (ict_ms % 1000) * 1000 * 1000; /* DEF_SDT_ICT_MS */ while (1) { sig_number = sigtimedwait(&signal_set, NULL, tsp); - if (shutting_down) - break; if (sig_number < 0) { int err = errno; @@ -1255,7 +1254,12 @@ sig_listen_thread(void * v_clp) pr2serr_lk("%sinterrupted by SIGINT\n", my_name); stop_both(clp); pthread_cond_broadcast(&clp->out_sync_cv); + sigprocmask(SIG_SETMASK, &orig_signal_set, NULL); + raise(SIGINT); + break; } + if (shutting_down) + break; } /* end of while loop */ if (clp->verbose > 1) pr2serr_lk("%s: exiting\n", __func__); @@ -1361,6 +1365,7 @@ mrq_abort_thread(void * v_maip) "%d, success\n", __func__, l_mai.from_tid, l_mai.mrq_id); } + delete ruip; return NULL; } @@ -1785,8 +1790,6 @@ skip_force_out_sequence: if (0 != status) err_exit(status, "unlock in_mutex"); fini: - if ((rep->mmap_active == 0) && rep->alloc_bp) - free(rep->alloc_bp); if ((1 == rep->mmap_active) && (rep->mmap_len > 0)) { if (munmap(rep->buffp, rep->mmap_len) < 0) { int err = errno; @@ -1800,6 +1803,11 @@ fini: rep->mmap_len); rep->mmap_active = 0; } + if (rep->alloc_bp) { + free(rep->alloc_bp); + rep->alloc_bp = NULL; + rep->buffp = NULL; + } if (sg_version_ge_40045) { if (clp->noshare) { @@ -2871,7 +2879,7 @@ sgh_do_deferred_mrq(Rq_elem * rep, mrq_arr_t & def_arr) ctl_v4.flags = SGV4_FLAG_MULTIPLE_REQS; if (! clp->mrq_async) { ctl_v4.flags |= SGV4_FLAG_STOP_IF; - if (clp->in_flags.mrq_svb || clp->in_flags.mrq_svb) + if (clp->in_flags.mrq_svb || clp->out_flags.mrq_svb) ctl_v4.flags |= SGV4_FLAG_SHARE; } ctl_v4.dout_xferp = (uint64_t)a_v4p; /* request array */ @@ -2993,7 +3001,7 @@ try_again: pr2serr_lk("%s: %s\n", __func__, mrq_vb_s); } res = ioctl(fd, SG_IOSUBMIT, &ctl_v4); - } else if (clp->in_flags.mrq_svb || clp->in_flags.mrq_svb) { + } else if (clp->in_flags.mrq_svb || clp->out_flags.mrq_svb) { iosub_str = "SG_IOSUBMIT(shared_variable_blocking)"; if (!after1 && (clp->verbose > 1)) { after1 = true; @@ -3598,7 +3606,8 @@ sg_prepare_resbuf(int fd, bool is_in, struct global_collection *clp, bool wq_excl = is_in ? clp->in_flags.wq_excl : clp->out_flags.wq_excl; bool skip_thresh = is_in ? clp->in_flags.no_thresh : clp->out_flags.no_thresh; - int res, t, num; + int res, t; + int num = 0; uint8_t *mmp; struct sg_extended_info sei {}; struct sg_extended_info * seip = &sei; @@ -3703,7 +3712,6 @@ bypass: seip->ctl_flags_wr_mask |= SG_CTL_FLAGM_TIME_IN_NS; seip->ctl_flags |= SG_CTL_FLAGM_TIME_IN_NS; if (ioctl(fd, SG_SET_GET_EXTENDED, seip) < 0) { - res = -1; pr2serr_lk("ioctl(EXTENDED(TIME_IN_NS)) failed, errno=%d %s\n", errno, strerror(errno)); } @@ -3864,8 +3872,10 @@ sg_in_open(struct global_collection *clp, const char *inf, uint8_t **mmpp, return -sg_convert_errno(err); } n = sg_prepare_resbuf(fd, true, clp, mmpp); - if (n <= 0) + if (n <= 0) { + close(fd); return -SG_LIB_FILE_ERROR; + } if (clp->noshare) sg_noshare_enlarge(fd, clp->verbose > 3); if (mmap_lenp) @@ -3896,8 +3906,10 @@ sg_out_open(struct global_collection *clp, const char *outf, uint8_t **mmpp, return -sg_convert_errno(err); } n = sg_prepare_resbuf(fd, false, clp, mmpp); - if (n <= 0) + if (n <= 0) { + close(fd); return -SG_LIB_FILE_ERROR; + } if (clp->noshare) sg_noshare_enlarge(fd, clp->verbose > 3); if (mmap_lenp) @@ -4319,7 +4331,7 @@ parse_cmdline_sanity(int argc, char * argv[], struct global_collection * clp, return SG_LIB_SYNTAX_ERROR; } if ((clp->in_flags.mmap || clp->out_flags.mmap) && - (clp->in_flags.same_fds || clp->in_flags.same_fds)) { + (clp->in_flags.same_fds || clp->out_flags.same_fds)) { pr2serr("can't have both 'mmap' and 'same_fds' flags\n"); return SG_LIB_SYNTAX_ERROR; } @@ -4628,12 +4640,14 @@ main(int argc, char * argv[]) if (0 != (clp->nmrqs % 3)) { pr2serr("When both IFILE+OFILE sg devices and OSP>0, " "mrq=NRQS must be divisible by 3\n"); - return SG_LIB_SYNTAX_ERROR; + pr2serr(" triple NRQS to avoid error\n"); + clp->nmrqs *= 3; } } else if (0 != (clp->nmrqs % 2)) { pr2serr("When both IFILE+OFILE sg devices (and OSP=0), " "mrq=NRQS must be even\n"); - return SG_LIB_SYNTAX_ERROR; + pr2serr(" double NRQS to avoid error\n"); + clp->nmrqs *= 2; } } if (clp->is_mrq_i && clp->is_mrq_o) @@ -4845,7 +4859,7 @@ main(int argc, char * argv[]) sigemptyset(&signal_set); sigaddset(&signal_set, SIGINT); - status = pthread_sigmask(SIG_BLOCK, &signal_set, NULL); + status = pthread_sigmask(SIG_BLOCK, &signal_set, &orig_signal_set); if (0 != status) err_exit(status, "pthread_sigmask"); status = pthread_create(&sig_listen_thread_id, NULL, sig_listen_thread, (void *)clp); @@ -4899,6 +4913,11 @@ main(int argc, char * argv[]) } } /* started worker threads and here after they have all exited */ + shutting_down = true; + /* pthread_cancel() has issues and is not supported in Android */ + status = pthread_kill(sig_listen_thread_id, SIGINT); + if (0 != status) err_exit(status, "pthread_kill"); + if (do_time && (start_tm.tv_sec || start_tm.tv_usec)) calc_duration_throughput(0); @@ -4927,14 +4946,7 @@ main(int argc, char * argv[]) } } - shutting_down = true; - status = pthread_kill(sig_listen_thread_id, SIGINT); - if (0 != status) err_exit(status, "pthread_kill"); - /* valgrind says the above _kill() leaks; web says it needs a following - * _join() to clear heap taken by associated _create() */ - fini: - if ((STDIN_FILENO != clp->infd) && (clp->infd >= 0)) close(clp->infd); if ((STDOUT_FILENO != clp->outfd) && (FT_DEV_NULL != clp->out_type) && diff --git a/testing/sgs_dd.c b/testing/sgs_dd.c index 64ff86cf..8af8612b 100644 --- a/testing/sgs_dd.c +++ b/testing/sgs_dd.c @@ -84,7 +84,7 @@ #include "sg_unaligned.h" -static const char * version_str = "4.19 20210406"; +static const char * version_str = "4.20 20210727"; static const char * my_name = "sgs_dd"; #ifndef SGV4_FLAG_HIPRI @@ -478,11 +478,11 @@ sg_finish_io(Rq_coll * clp, bool wr, Rq_elem ** repp) return res; } if (n > 0) { - if ( ((res = ioctl(fd, SG_GET_PACK_ID, &id))) < 0) { - res = -errno; + if ( (ioctl(fd, SG_GET_PACK_ID, &id)) < 0) { + res = errno; pr2serr("%s: ioctl(SG_GET_PACK_ID): %s [%d]\n", - __func__, strerror(errno), errno); - return res; + __func__, strerror(res), res); + return -res; } /* got pack_id or tag of first waiting */ break; @@ -553,11 +553,11 @@ do_v4: return res; } if (n > 0) { - if ( ((res = ioctl(fd, SG_GET_PACK_ID, &id))) < 0) { - res = -errno; + if ( (ioctl(fd, SG_GET_PACK_ID, &id)) < 0) { + res = errno; pr2serr("%s: ioctl(SG_GET_PACK_ID): %s [%d]\n", - __func__, strerror(errno), errno); - return res; + __func__, strerror(res), res); + return -res; } /* got pack_id or tag of first waiting */ break; @@ -664,7 +664,6 @@ sz_reserve(Rq_coll * clp, bool is_in) sgs_full_v4_sg_driver = false; } else sgs_full_v4_sg_driver = true; - res = 0; t = clp->bs * clp->bpt; res = ioctl(fd, SG_SET_RESERVED_SIZE, &t); if (res < 0) @@ -721,7 +720,7 @@ sz_reserve(Rq_coll * clp, bool is_in) if (ioctl(fd, SG_SET_GET_EXTENDED, seip) < 0) { err = errno; pr2serr("ioctl(EXTENDED(SG_SEIM_EVENTFD)) failed, " - "errno=%d %s\n", errno, strerror(errno)); + "errno=%d %s\n", err, strerror(err)); return 1; } } @@ -830,7 +829,7 @@ start_read(Rq_coll * clp) if (clp->in_is_sg) { res = sg_start_io(clp, rep); if (1 == res) { /* ENOMEM, find what's available+try that */ - if ((res = ioctl(clp->infd, SG_GET_RESERVED_SIZE, &buf_sz)) < 0) { + if (ioctl(clp->infd, SG_GET_RESERVED_SIZE, &buf_sz) < 0) { res = -errno; perror("RESERVED_SIZE ioctls failed"); return res; @@ -843,7 +842,7 @@ start_read(Rq_coll * clp) if (1 == res) res = -ENOMEM; } - else if (res < 0) { + if (res < 0) { pr2serr("%s: inputting from sg failed, blk=%d\n", my_name, rep->blk); rep->state = SGQ_IO_ERR; @@ -987,7 +986,7 @@ do_sigwait(Rq_coll * clp, bool inc1_clear0) static int do_num_poll_in(Rq_coll * clp, int fd, bool is_evfd) { - int err; + int err, res; struct pollfd a_pollfd = {0, POLLIN | POLLOUT, 0}; if (! clp->no_sig) { @@ -1009,13 +1008,13 @@ do_num_poll_in(Rq_coll * clp, int fd, bool is_evfd) if (is_evfd) { uint64_t count; - if (read(fd, &count, sizeof(count)) < 0) { + if ((res = read(fd, &count, sizeof(count))) < 0) { err = errno; pr2serr("%s: read(): %s [%d]\n", __func__, strerror(err), err); return -err; } - return (int)count; + return (res < (int)sizeof(uint64_t)) ? 0 : (int)count; } else return 1; /* could be more but don't know without evfd */ } else if (a_pollfd.revents & POLLERR) @@ -1100,7 +1099,7 @@ can_read_write(Rq_coll * clp) } for (rep = clp->wr_posp, res = 1; - rep != clp->rd_posp; rep = rep->nextp) { + rep && (rep != clp->rd_posp); rep = rep->nextp) { if (SGQ_IO_STARTED == rep->state) { if (rep->wr) ++writing; @@ -1148,7 +1147,8 @@ can_read_write(Rq_coll * clp) return res; /* wasn't timeout */ } /* Now check the _whole_ buffer for pending requests */ - for (rep = clp->rd_posp->nextp; rep != clp->rd_posp; rep = rep->nextp) { + for (rep = clp->rd_posp->nextp; rep && (rep != clp->rd_posp); + rep = rep->nextp) { if (SGQ_IO_WAIT == rep->state) { res = sg_start_io(clp, rep); if (res < 0) @@ -1441,6 +1441,7 @@ main(int argc, char * argv[]) if (ioctl(clp->outfd, SG_GET_TIMEOUT, 0) < 0) { /* not a scsi generic device so now try and open RDONLY */ close(clp->outfd); + clp->outfd = -1; } else { clp->out_is_sg = true; @@ -1454,8 +1455,10 @@ main(int argc, char * argv[]) } } if (! clp->out_is_sg) { - if (clp->outfd >= 0) + if (clp->outfd >= 0) { close(clp->outfd); + clp->outfd = -1; + } open_fl = clp->oflag.excl ? O_EXCL : 0; open_fl |= (O_WRONLY | O_CREAT); if ((clp->outfd = open(outf, open_fl, 0666)) < 0) { @@ -1560,6 +1563,8 @@ main(int argc, char * argv[]) clp->out_done_count = count; clp->out_blk = seek; res = init_elems(clp); + if (res < 0) + pr2serr("init_elems() failed, res=%d\n", res); res = 0; /* vvvvvvvvvvvvvvvvv Main Loop vvvvvvvvvvvvvvvvvvvvvvvv */ @@ -1585,9 +1590,9 @@ main(int argc, char * argv[]) } } - if (STDIN_FILENO != clp->infd) + if ((STDIN_FILENO != clp->infd) && (clp->infd >= 0)) close(clp->infd); - if (STDOUT_FILENO != clp->outfd) + if ((STDOUT_FILENO != clp->outfd) && (clp->outfd >= 0)) close(clp->outfd); if (0 != clp->out_count) { pr2serr("Some error occurred, remaining blocks=%d\n", clp->out_count); |