**Error: Mishandles input errors** When `fgets()` returns `NULL` due to input error, this function might return 0 (for EOF). **Lack of in code documentation** A _declaration_ like `int fgets_line(char **line, size_t *capacity, size_t *length, FILE *stream);` deserves to exist with documentation describing the goals and function limitations. (e.g. a .h file.) Do not assume users want to dissect the function source code. **Minimum work** "minimal work as possible" --> User I/O is a sink-hole of time. A linear extra call to `strlen()` will not be noticed. **Pedantic: Reliance on not reading a _null character_** Code performs incorrectly with `*length = position - *line + strlen(position);` should `fgets()` read a _null character_. Either adjust code to detect reading a _null character_ (not easy) or consider dropping the `length` parameter. Calling code can use `strlen()` if desired. **Pedantic: `*capacity` not validated** If `fgets_line()` called with a wee `*capacity` (like 0 or 1), `(*line)[various]` risks accessing the array out of bounds. Take care in assuming what how the caller set up the buffer pointer and size. It may have been _right-sized_ after a prior read. **Pedantic: Out of `int` range** `fgets()` uses an `int` for the size, so `*line + *capacity - position` risks out-of-range conversion. ---- **Design** I am not a fan of giving the user the ability to overwhelm memory resources and prefer a sane upper bound to allocation size.