aboutsummaryrefslogtreecommitdiff
path: root/sim/common/sim-hw.c
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2021-01-15 22:24:38 -0500
committerMike Frysinger <vapier@gentoo.org>2021-01-30 01:07:58 -0500
commitf4dd74915b2139dbc64eecc38a0acda40408c3b2 (patch)
treece630a698206acb88d939985045ec9b1464450b6 /sim/common/sim-hw.c
parent481fac96bd6e2db034174f534bed885f3e76925a (diff)
downloadgdb-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.c67
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;
}