Both sendfile_before and sendfile_after are confusing to me. First there's sendfile/7 with two clauses, one where we open the file and one with fd, where we read the position. Then there's sendfile_before that's checking that position and only moving if we're not at the expected position. Then things happen. Then sendfile_after may close the file or restore the position.

I'd remove sendfile/8 and do the get/set position in the clauses directly, and the closing of the file in the clause too. Don't keep unneeded state around if we can make it obvious. That does mean two try..after but they're not exactly big, the code will probably still be smaller, and for sure simpler to follow.