diff options
author | Mike Frysinger <vapier@gentoo.org> | 2021-01-15 22:24:38 -0500 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2021-01-30 01:07:58 -0500 |
commit | f4dd74915b2139dbc64eecc38a0acda40408c3b2 (patch) | |
tree | ce630a698206acb88d939985045ec9b1464450b6 /sim/common/sim-hw.c | |
parent | 481fac96bd6e2db034174f534bed885f3e76925a (diff) | |
download | gdb-f4dd74915b2139dbc64eecc38a0acda40408c3b2.zip gdb-f4dd74915b2139dbc64eecc38a0acda40408c3b2.tar.gz gdb-f4dd74915b2139dbc64eecc38a0acda40408c3b2.tar.bz2 |
sim: hw: replace fgets with getline
This avoids fixed sized buffers on the stack.
Diffstat (limited to 'sim/common/sim-hw.c')
-rw-r--r-- | sim/common/sim-hw.c | 67 |
1 files changed, 37 insertions, 30 deletions
diff --git a/sim/common/sim-hw.c b/sim/common/sim-hw.c index 81b4f64..11d3abd 100644 --- a/sim/common/sim-hw.c +++ b/sim/common/sim-hw.c @@ -138,8 +138,9 @@ merge_device_file (struct sim_state *sd, { FILE *description; struct hw *current = STATE_HW (sd)->tree; - int line_nr; - char device_path[1000]; + char *device_path = NULL; + size_t buf_size = 0; + ssize_t device_path_len; /* try opening the file */ description = fopen (file_name, "r"); @@ -149,19 +150,14 @@ merge_device_file (struct sim_state *sd, return SIM_RC_FAIL; } - line_nr = 0; - while (fgets (device_path, sizeof (device_path), description)) + while ((device_path_len = getline (&device_path, &buf_size, description)) > 0) { char *device; - /* check that a complete line was read */ - if (strchr (device_path, '\n') == NULL) - { - fclose (description); - sim_io_eprintf (sd, "%s:%d: line to long", file_name, line_nr); - return SIM_RC_FAIL; - } - *strchr (device_path, '\n') = '\0'; - line_nr++; + char *next_line = NULL; + + if (device_path[device_path_len - 1] == '\n') + device_path[--device_path_len] = '\0'; + /* skip comments ("#" or ";") and blank lines lines */ for (device = device_path; *device != '\0' && isspace (*device); @@ -170,33 +166,44 @@ merge_device_file (struct sim_state *sd, || device[0] == ';' || device[0] == '\0') continue; + /* merge any appended lines */ - while (device_path[strlen (device_path) - 1] == '\\') + while (device_path[device_path_len - 1] == '\\') { - int curlen = strlen (device_path) - 1; + size_t next_buf_size = 0; + ssize_t next_line_len; + /* zap the `\' at the end of the line */ - device_path[curlen] = '\0'; + device_path[--device_path_len] = '\0'; + + /* get the next line */ + next_line_len = getline (&next_line, &next_buf_size, description); + if (next_line_len <= 0) + break; + + if (next_line[next_line_len - 1] == '\n') + next_line[--next_line_len] = '\0'; + /* append the next line */ - if (!fgets (device_path + curlen, - sizeof (device_path) - curlen, - description)) - { - fclose (description); - sim_io_eprintf (sd, "%s:%d: unexpected eof", file_name, line_nr); - return SIM_RC_FAIL; - } - if (strchr (device_path, '\n') == NULL) + if (buf_size - device_path_len <= next_line_len) { - fclose (description); - sim_io_eprintf (sd, "%s:%d: line to long", file_name, line_nr); - return SIM_RC_FAIL; + ptrdiff_t offset = device - device_path; + + buf_size += next_buf_size; + device_path = xrealloc (device_path, buf_size); + device = device_path + offset; } - *strchr (device_path, '\n') = '\0'; - line_nr++; + memcpy (device_path + device_path_len, next_line, + next_line_len + 1); + device_path_len += next_line_len; } + free (next_line); + /* parse this line */ current = hw_tree_parse (current, "%s", device); } + + free (device_path); fclose (description); return SIM_RC_OK; } |