diff --git a/cgminer.c b/cgminer.c index 58c939fa..99c5dd3d 100644 --- a/cgminer.c +++ b/cgminer.c @@ -1944,15 +1944,6 @@ static bool curses_active_locked(void) } #endif -void tailsprintf(char *f, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - vsprintf(f + strlen(f), fmt, ap); - va_end(ap); -} - /* Convert a uint64_t value into a truncated string for displaying with its * associated suitable for Mega, Giga etc. Buf array needs to be long enough */ static void suffix_string(uint64_t val, char *buf, int sigdigits) @@ -2010,7 +2001,7 @@ static void suffix_string(uint64_t val, char *buf, int sigdigits) } } -static void get_statline(char *buf, struct cgpu_info *cgpu) +static void get_statline(char *buf, size_t bufsiz, struct cgpu_info *cgpu) { char displayed_hashes[16], displayed_rolling[16]; uint64_t dh64, dr64; @@ -2035,8 +2026,8 @@ static void get_statline(char *buf, struct cgpu_info *cgpu) suffix_string(dr64, displayed_rolling, 4); sprintf(buf, "%s%d ", cgpu->drv->name, cgpu->device_id); - cgpu->drv->get_statline_before(buf, cgpu); - tailsprintf(buf, "(%ds):%s (avg):%sh/s | A:%.0f R:%.0f HW:%d WU:%.1f/m", + cgpu->drv->get_statline_before(buf, bufsiz, cgpu); + tailsprintf(buf, bufsiz, "(%ds):%s (avg):%sh/s | A:%.0f R:%.0f HW:%d WU:%.1f/m", opt_log_interval, displayed_rolling, displayed_hashes, @@ -2044,7 +2035,7 @@ static void get_statline(char *buf, struct cgpu_info *cgpu) cgpu->diff_rejected, cgpu->hw_errors, wu); - cgpu->drv->get_statline(buf, cgpu); + cgpu->drv->get_statline(buf, bufsiz, cgpu); } static void text_print_status(int thr_id) @@ -2054,7 +2045,7 @@ static void text_print_status(int thr_id) cgpu = get_thr_cgpu(thr_id); if (cgpu) { - get_statline(logline, cgpu); + get_statline(logline, sizeof(logline), cgpu); printf("%s\n", logline); } } @@ -2143,7 +2134,7 @@ static void curses_print_devstatus(struct cgpu_info *cgpu, int count) wmove(statuswin,devcursor + count, 0); wprintw(statuswin, " %s %*d: ", cgpu->drv->name, dev_width, cgpu->device_id); logline[0] = '\0'; - cgpu->drv->get_statline_before(logline, cgpu); + cgpu->drv->get_statline_before(logline, sizeof(logline), cgpu); wprintw(statuswin, "%s", logline); dh64 = (double)cgpu->total_mhashes / dev_runtime * 1000000ull; @@ -2179,7 +2170,7 @@ static void curses_print_devstatus(struct cgpu_info *cgpu, int count) wuwidth + 2, wu); logline[0] = '\0'; - cgpu->drv->get_statline(logline, cgpu); + cgpu->drv->get_statline(logline, sizeof(logline), cgpu); wprintw(statuswin, "%s", logline); wclrtoeol(statuswin); @@ -2642,7 +2633,7 @@ static bool submit_upstream_work(struct work *work, CURL *curl, bool resubmit) if (!want_per_device_stats) { char logline[256]; - get_statline(logline, cgpu); + get_statline(logline, sizeof(logline), cgpu); applog(LOG_INFO, "%s", logline); } @@ -4693,7 +4684,7 @@ static void hashmeter(int thr_id, struct timeval *diff, cgpu->last_message_tv = now; - get_statline(logline, cgpu); + get_statline(logline, sizeof(logline), cgpu); if (!curses_active) { printf("%s \r", logline); fflush(stdout); @@ -6643,7 +6634,7 @@ static void log_print_status(struct cgpu_info *cgpu) { char logline[255]; - get_statline(logline, cgpu); + get_statline(logline, sizeof(logline), cgpu); applog(LOG_WARNING, "%s", logline); } @@ -7023,12 +7014,12 @@ static void noop_reinit_device(struct cgpu_info __maybe_unused *cgpu) { } -void blank_get_statline_before(char *buf, struct cgpu_info __maybe_unused *cgpu) +void blank_get_statline_before(char *buf, size_t bufsiz, struct cgpu_info __maybe_unused *cgpu) { - tailsprintf(buf, " | "); + tailsprintf(buf, bufsiz, " | "); } -static void noop_get_statline(char __maybe_unused *buf, struct cgpu_info __maybe_unused *cgpu) +static void noop_get_statline(char __maybe_unused *buf, size_t __maybe_unused bufsiz, struct cgpu_info __maybe_unused *cgpu) { } diff --git a/driver-avalon.c b/driver-avalon.c index d6aaa4dd..d9606ac9 100644 --- a/driver-avalon.c +++ b/driver-avalon.c @@ -1146,7 +1146,7 @@ static void avalon_update_temps(struct cgpu_info *avalon, struct avalon_info *in } } -static void get_avalon_statline_before(char *buf, struct cgpu_info *avalon) +static void get_avalon_statline_before(char *buf, size_t bufsiz, struct cgpu_info *avalon) { struct avalon_info *info = avalon->device_data; int lowfan = 10000; @@ -1157,7 +1157,7 @@ static void get_avalon_statline_before(char *buf, struct cgpu_info *avalon) if (info->fan2 >= 0 && info->fan2 < lowfan) lowfan = info->fan2; - tailsprintf(buf, "%2d/%3dC %04dR | ", info->temp0, info->temp2, lowfan); + tailsprintf(buf, bufsiz, "%2d/%3dC %04dR | ", info->temp0, info->temp2, lowfan); } /* We use a replacement algorithm to only remove references to work done from diff --git a/driver-bflsc.c b/driver-bflsc.c index 2c239781..f3800c08 100644 --- a/driver-bflsc.c +++ b/driver-bflsc.c @@ -1235,7 +1235,7 @@ static void bflsc_detect(void) usb_detect(&bflsc_drv, bflsc_detect_one); } -static void get_bflsc_statline_before(char *buf, struct cgpu_info *bflsc) +static void get_bflsc_statline_before(char *buf, size_t bufsiz, struct cgpu_info *bflsc) { struct bflsc_info *sc_info = (struct bflsc_info *)(bflsc->device_data); float temp = 0; @@ -1253,7 +1253,7 @@ static void get_bflsc_statline_before(char *buf, struct cgpu_info *bflsc) } rd_unlock(&(sc_info->stat_lock)); - tailsprintf(buf, " max%3.0fC %4.2fV | ", temp, vcc1); + tailsprintf(buf, bufsiz, " max%3.0fC %4.2fV | ", temp, vcc1); } static void flush_one_dev(struct cgpu_info *bflsc, int dev) diff --git a/driver-bitforce.c b/driver-bitforce.c index 33061701..a2d19b58 100644 --- a/driver-bitforce.c +++ b/driver-bitforce.c @@ -294,15 +294,16 @@ static void bitforce_detect(void) usb_detect(&bitforce_drv, bitforce_detect_one); } -static void get_bitforce_statline_before(char *buf, struct cgpu_info *bitforce) +static void get_bitforce_statline_before(char *buf, size_t bufsiz, struct cgpu_info *bitforce) { float gt = bitforce->temp; if (gt > 0) - tailsprintf(buf, "%5.1fC ", gt); + tailsprintf(buf, bufsiz, "%5.1fC ", gt); else - tailsprintf(buf, " ", gt); - tailsprintf(buf, " | "); + tailsprintf(buf, bufsiz, " "); + + tailsprintf(buf, bufsiz, " | "); } static bool bitforce_thread_prepare(struct thr_info *thr) diff --git a/driver-modminer.c b/driver-modminer.c index 50488e8a..37cb02e2 100644 --- a/driver-modminer.c +++ b/driver-modminer.c @@ -741,16 +741,12 @@ static bool modminer_fpga_init(struct thr_info *thr) return true; } -static void get_modminer_statline_before(char *buf, struct cgpu_info *modminer) +static void get_modminer_statline_before(char *buf, size_t bufsiz, struct cgpu_info *modminer) { - char info[64]; - - sprintf(info, " %s%.1fC %3uMHz | ", + tailsprintf(buf, bufsiz, " %s%.1fC %3uMHz | ", (modminer->temp < 10) ? " " : "", modminer->temp, (unsigned int)(modminer->clock)); - - strcat(buf, info); } static bool modminer_start_work(struct thr_info *thr, struct work *work) diff --git a/driver-opencl.c b/driver-opencl.c index 9bb7b1fc..4f5ee698 100644 --- a/driver-opencl.c +++ b/driver-opencl.c @@ -52,7 +52,6 @@ extern bool have_opencl; extern void *miner_thread(void *userdata); extern int dev_from_id(int thr_id); -extern void tailsprintf(char *f, const char *fmt, ...); extern void decay_time(double *f, double fadd); /**********************************************/ @@ -667,24 +666,24 @@ retry: if (temp != -1) sprintf(logline, "%.1f C ", temp); if (fanspeed != -1 || fanpercent != -1) { - tailsprintf(logline, "F: "); + tailsprintf(logline, sizeof(logline), "F: "); if (fanpercent != -1) - tailsprintf(logline, "%d%% ", fanpercent); + tailsprintf(logline, sizeof(logline), "%d%% ", fanpercent); if (fanspeed != -1) - tailsprintf(logline, "(%d RPM) ", fanspeed); - tailsprintf(logline, " "); + tailsprintf(logline, sizeof(logline), "(%d RPM) ", fanspeed); + tailsprintf(logline, sizeof(logline), " "); } if (engineclock != -1) - tailsprintf(logline, "E: %d MHz ", engineclock); + tailsprintf(logline, sizeof(logline), "E: %d MHz ", engineclock); if (memclock != -1) - tailsprintf(logline, "M: %d Mhz ", memclock); + tailsprintf(logline, sizeof(logline), "M: %d Mhz ", memclock); if (vddc != -1) - tailsprintf(logline, "V: %.3fV ", vddc); + tailsprintf(logline, sizeof(logline), "V: %.3fV ", vddc); if (activity != -1) - tailsprintf(logline, "A: %d%% ", activity); + tailsprintf(logline, sizeof(logline), "A: %d%% ", activity); if (powertune != -1) - tailsprintf(logline, "P: %d%%", powertune); - tailsprintf(logline, "\n"); + tailsprintf(logline, sizeof(logline), "P: %d%%", powertune); + tailsprintf(logline, sizeof(logline), "\n"); _wlog(logline); } } @@ -1271,7 +1270,7 @@ static void reinit_opencl_device(struct cgpu_info *gpu) } #ifdef HAVE_ADL -static void get_opencl_statline_before(char *buf, struct cgpu_info *gpu) +static void get_opencl_statline_before(char *buf, size_t bufsiz, struct cgpu_info *gpu) { if (gpu->has_adl) { int gpuid = gpu->device_id; @@ -1280,25 +1279,25 @@ static void get_opencl_statline_before(char *buf, struct cgpu_info *gpu) int gp; if (gt != -1) - tailsprintf(buf, "%5.1fC ", gt); + tailsprintf(buf, bufsiz, "%5.1fC ", gt); else - tailsprintf(buf, " ", gt); + tailsprintf(buf, bufsiz, " ", gt); if (gf != -1) // show invalid as 9999 - tailsprintf(buf, "%4dRPM ", gf > 9999 ? 9999 : gf); + tailsprintf(buf, bufsiz, "%4dRPM ", gf > 9999 ? 9999 : gf); else if ((gp = gpu_fanpercent(gpuid)) != -1) - tailsprintf(buf, "%3d%% ", gp); + tailsprintf(buf, bufsiz, "%3d%% ", gp); else - tailsprintf(buf, " "); - tailsprintf(buf, "| "); + tailsprintf(buf, bufsiz, " "); + tailsprintf(buf, bufsiz, "| "); } else gpu->drv->get_statline_before = &blank_get_statline_before; } #endif -static void get_opencl_statline(char *buf, struct cgpu_info *gpu) +static void get_opencl_statline(char *buf, size_t bufsiz, struct cgpu_info *gpu) { - tailsprintf(buf, " I:%2d", gpu->intensity); + tailsprintf(buf, bufsiz, " I:%2d", gpu->intensity); } struct opencl_thread_data { diff --git a/driver-ztex.c b/driver-ztex.c index 09387267..ba6d8cf0 100644 --- a/driver-ztex.c +++ b/driver-ztex.c @@ -362,11 +362,11 @@ static int64_t ztex_scanhash(struct thr_info *thr, struct work *work, return noncecnt; } -static void ztex_statline_before(char *buf, struct cgpu_info *cgpu) +static void ztex_statline_before(char *buf, size_t bufsiz, struct cgpu_info *cgpu) { if (cgpu->deven == DEV_ENABLED) { - tailsprintf(buf, "%s-%d | ", cgpu->device_ztex->snString, cgpu->device_ztex->fpgaNum+1); - tailsprintf(buf, "%0.1fMHz | ", cgpu->device_ztex->freqM1 * (cgpu->device_ztex->freqM + 1)); + tailsprintf(buf, bufsiz, "%s-%d | ", cgpu->device_ztex->snString, cgpu->device_ztex->fpgaNum+1); + tailsprintf(buf, bufsiz, "%0.1fMHz | ", cgpu->device_ztex->freqM1 * (cgpu->device_ztex->freqM + 1)); } } diff --git a/miner.h b/miner.h index 68577f99..c0543259 100644 --- a/miner.h +++ b/miner.h @@ -294,7 +294,7 @@ struct gpu_adl { }; #endif -extern void blank_get_statline_before(char *buf, struct cgpu_info __maybe_unused *cgpu); +extern void blank_get_statline_before(char *buf, size_t bufsiz, struct cgpu_info __maybe_unused *cgpu); struct api_data; struct thr_info; @@ -311,8 +311,8 @@ struct device_drv { // Device-specific functions void (*reinit_device)(struct cgpu_info *); - void (*get_statline_before)(char *, struct cgpu_info *); - void (*get_statline)(char *, struct cgpu_info *); + void (*get_statline_before)(char *, size_t, struct cgpu_info *); + void (*get_statline)(char *, size_t, struct cgpu_info *); struct api_data *(*get_api_stats)(struct cgpu_info *); bool (*get_stats)(struct cgpu_info *); void (*identify_device)(struct cgpu_info *); // e.g. to flash a led @@ -1272,6 +1272,18 @@ struct modminer_fpga_state { }; #endif +#define TAILBUFSIZ 64 + +#define tailsprintf(buf, bufsiz, fmt, ...) do { \ + char tmp13[TAILBUFSIZ]; \ + size_t len13, buflen = strlen(buf); \ + snprintf(tmp13, sizeof(tmp13), fmt, ##__VA_ARGS__); \ + len13 = strlen(tmp13); \ + if ((buflen + len13) >= bufsiz) \ + quit(1, "tailsprintf buffer overflow in %s %s line %d", __FILE__, __func__, __LINE__); \ + strcat(buf, tmp13); \ +} while (0) + extern void get_datestamp(char *, struct timeval *); extern void inc_hw_errors(struct thr_info *thr); extern bool submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce); @@ -1280,7 +1292,6 @@ extern struct work *__find_work_bymidstate(struct work *que, char *midstate, siz extern struct work *find_queued_work_bymidstate(struct cgpu_info *cgpu, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen); extern void work_completed(struct cgpu_info *cgpu, struct work *work); extern void hash_queued_work(struct thr_info *mythr); -extern void tailsprintf(char *f, const char *fmt, ...); extern void _wlog(const char *str); extern void _wlogprint(const char *str); extern int curses_int(const char *query);