Doing a re_sub in C using pcre
You were so close! So close to having re-entrant code. You declare buffer as a global, but also pass it into a function. It should be easy enough to just move it to main and keep your functions as-is.
You have two different pointer offset styles (right next to each other) that accomplish the exact same thing:
&amp;tmp[tmp_offset], 
buffer+buffer_offset

I prefer the latter, but pick one and stick with it.
This:
size_t buffer_size = strlen(buffer);
char tmp[buffer_size * 2];

leverages a feature of C, variable-length stack arrays, not offered until C99. It's not wrong, but it occupies the stack and I find that for any non-trivial amount of memory the heap is a safer bet.
re_sub and exit_with_error should be marked static.
I don't find this statement:
while ((rc = pcre_exec(re_compiled, NULL, buffer, strlen(buffer), buffer_offset, 0, offsets, OFFSETS_SIZE)) &gt; 0) {

particularly nice to read; you'd be better-off avoiding combined assignment-predicate statements like this, and just separating it out. It will have no impact on your compiled code.