X-Git-Url: https://git.kernel.dk/?a=blobdiff_plain;ds=sidebyside;f=init.c;h=4c5a8dd8ebab33bd28bb6c1a6b12864910cb7aff;hb=b29c813fc632d486d8c9c7858c26ab31e0b89e8d;hp=a0ec914130934ba52626aad25f2b60b15c93c4a3;hpb=4af7c007e120a3fd75cdbbb50d1cf1fd79e67732;p=fio.git diff --git a/init.c b/init.c index a0ec9141..4c5a8dd8 100644 --- a/init.c +++ b/init.c @@ -364,7 +364,7 @@ static struct thread_data *get_new_job(int global, struct thread_data *parent, td->thread_number = thread_number; - if (!parent || !parent->o.group_reporting) + if (!parent->o.group_reporting) stat_number++; set_cmd_options(td); @@ -937,11 +937,12 @@ static struct fpre_keyword { { .keyword = NULL, }, }; -static char *make_filename(char *buf, struct thread_options *o, +static char *make_filename(char *buf, size_t buf_size,struct thread_options *o, const char *jobname, int jobnum, int filenum) { struct fpre_keyword *f; char copy[PATH_MAX]; + size_t dst_left = PATH_MAX - 1; if (!o->filename_format || !strlen(o->filename_format)) { sprintf(buf, "%s.%d.%d", jobname, jobnum, filenum); @@ -951,7 +952,9 @@ static char *make_filename(char *buf, struct thread_options *o, for (f = &fpre_keywords[0]; f->keyword; f++) f->strlen = strlen(f->keyword); - strcpy(buf, o->filename_format); + buf[buf_size - 1] = '\0'; + strncpy(buf, o->filename_format, buf_size - 1); + memset(copy, 0, sizeof(copy)); for (f = &fpre_keywords[0]; f->keyword; f++) { do { @@ -969,27 +972,49 @@ static char *make_filename(char *buf, struct thread_options *o, if (pre_len) { strncpy(dst, buf, pre_len); dst += pre_len; + dst_left -= pre_len; } switch (f->key) { - case FPRE_JOBNAME: - dst += sprintf(dst, "%s", jobname); + case FPRE_JOBNAME: { + int ret; + + ret = snprintf(dst, dst_left, "%s", jobname); + if (ret < 0) + break; + dst += ret; + dst_left -= ret; break; - case FPRE_JOBNUM: - dst += sprintf(dst, "%d", jobnum); + } + case FPRE_JOBNUM: { + int ret; + + ret = snprintf(dst, dst_left, "%d", jobnum); + if (ret < 0) + break; + dst += ret; + dst_left -= ret; break; - case FPRE_FILENUM: - dst += sprintf(dst, "%d", filenum); + } + case FPRE_FILENUM: { + int ret; + + ret = snprintf(dst, dst_left, "%d", filenum); + if (ret < 0) + break; + dst += ret; + dst_left -= ret; break; + } default: assert(0); break; } if (post_start) - strcpy(dst, buf + post_start); + strncpy(dst, buf + post_start, dst_left); - strcpy(buf, copy); + strncpy(buf, copy, buf_size - 1); } while (1); } @@ -1049,7 +1074,7 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num, add_file(td, jobname, job_add_num, 0); else { for (i = 0; i < o->nr_files; i++) - add_file(td, make_filename(fname, o, jobname, job_add_num, i), job_add_num, 0); + add_file(td, make_filename(fname, sizeof(fname), o, jobname, job_add_num, i), job_add_num, 0); } } @@ -1435,9 +1460,6 @@ int parse_jobs_ini(char *file, int is_buf, int stonewall_flag, int type) i++; } - for (i = 0; i < num_opts; i++) - free(opts[i]); - free(string); free(name); free(opts); @@ -1694,8 +1716,6 @@ int parse_cmd_line(int argc, char *argv[], int client_type) optind = 1; while ((c = getopt_long_only(argc, argv, ostr, l_opts, &lidx)) != -1) { - did_arg = 1; - if ((c & FIO_CLIENT_FLAG) || client_flag_set(c)) { parse_cmd_client(cur_client, argv[optind - 1]); c &= ~FIO_CLIENT_FLAG; @@ -1719,6 +1739,9 @@ int parse_cmd_line(int argc, char *argv[], int client_type) write_bw_log = 1; break; case 'o': + if (f_out) + fclose(f_out); + f_out = fopen(optarg, "w+"); if (!f_out) { perror("fopen output"); @@ -1749,30 +1772,35 @@ int parse_cmd_line(int argc, char *argv[], int client_type) append_terse_output = 1; break; case 'h': + did_arg = 1; if (!cur_client) { usage(argv[0]); do_exit++; } break; case 'c': + did_arg = 1; if (!cur_client) { fio_show_option_help(optarg); do_exit++; } break; case 'i': + did_arg = 1; if (!cur_client) { fio_show_ioengine_help(optarg); do_exit++; } break; case 's': + did_arg = 1; dump_cmdline = 1; break; case 'r': read_only = 1; break; case 'v': + did_arg = 1; if (!cur_client) { log_info("%s\n", fio_version_string); do_exit++; @@ -1809,6 +1837,7 @@ int parse_cmd_line(int argc, char *argv[], int client_type) do_exit++; break; case 'P': + did_arg = 1; parse_only = 1; break; case 'x': { @@ -1828,6 +1857,7 @@ int parse_cmd_line(int argc, char *argv[], int client_type) break; } case 'p': + did_arg = 1; if (exec_profile) free(exec_profile); exec_profile = strdup(optarg); @@ -1839,8 +1869,9 @@ int parse_cmd_line(int argc, char *argv[], int client_type) if (!strncmp(opt, "name", 4) && td) { ret = add_job(td, td->o.name ?: "fio", 0, 0, client_type); if (ret) - return 0; + goto out_free; td = NULL; + did_arg = 1; } if (!td) { int is_section = !strncmp(opt, "name", 4); @@ -1854,7 +1885,7 @@ int parse_cmd_line(int argc, char *argv[], int client_type) td = get_new_job(global, &def_thread, 1); if (!td || ioengine_load(td)) - return 0; + goto out_free; fio_options_set_ioengine_opts(l_opts, td); } @@ -1876,7 +1907,7 @@ int parse_cmd_line(int argc, char *argv[], int client_type) if (!ret && !strcmp(opt, "ioengine")) { free_ioengine(td); if (ioengine_load(td)) - return 0; + goto out_free; fio_options_set_ioengine_opts(l_opts, td); } break; @@ -1884,6 +1915,10 @@ int parse_cmd_line(int argc, char *argv[], int client_type) case FIO_GETOPT_IOENGINE: { const char *opt = l_opts[lidx].name; char *val = optarg; + + if (!td) + break; + ret = fio_cmd_ioengine_option_parse(td, opt, val); break; } @@ -1899,6 +1934,7 @@ int parse_cmd_line(int argc, char *argv[], int client_type) } break; case 'S': + did_arg = 1; if (nr_clients) { log_err("fio: can't be both client and server\n"); do_exit++; @@ -1911,17 +1947,21 @@ int parse_cmd_line(int argc, char *argv[], int client_type) backend = 1; break; case 'D': + if (pid_file) + free(pid_file); pid_file = strdup(optarg); break; case 'I': if ((ret = fio_idle_prof_parse_opt(optarg))) { /* exit on error and calibration only */ + did_arg = 1; do_exit++; - if (ret == -1) + if (ret == -1) exit_val = 1; } break; case 'C': + did_arg = 1; if (is_backend) { log_err("fio: can't be both client and server\n"); do_exit++; @@ -1948,10 +1988,12 @@ int parse_cmd_line(int argc, char *argv[], int client_type) } break; case 'T': + did_arg = 1; do_exit++; exit_val = fio_monotonic_clocktest(); break; case 'G': + did_arg = 1; do_exit++; exit_val = fio_crctest(optarg); break; @@ -1991,8 +2033,11 @@ int parse_cmd_line(int argc, char *argv[], int client_type) free(pid_file); if (td) { - if (!ret) + if (!ret) { ret = add_job(td, td->o.name ?: "fio", 0, 0, client_type); + if (ret) + did_arg = 1; + } } while (!ret && optind < argc) { @@ -2002,6 +2047,10 @@ int parse_cmd_line(int argc, char *argv[], int client_type) optind++; } +out_free: + if (pid_file) + free(pid_file); + return ini_idx; }