{
   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");
       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);
          || 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;
 }