**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 functions 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()`.

**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.