Two cross-platform implementations of getline in C
exit(1) is probably a bad idea, so is fprintf to stderr.  We don't know how big the string can be, therefore running out of memory could be valid, and if stderr is redirected to somewhere a client can see. realloc should already set errno to ENOMEM, so you could probably just return NULL, and modify comment that upon returning NULL, caller should check errno. Or maybe you should return empty string if there's no data, and use NULL to indicate error.

change calloc to malloc, as you anyway NULL terminate the string in your fgetc implementation.

Instead of having this code duplicated for error message (which I vote against), and actual calculation: chunk_size*(j+1)*sizeof*line+1, you could create a variable and use it in both places, therefore you know you print exactly what you did, and there wasn't a mistake if you had to change the calculation slightly.

Try this on windows (as it claims to be a cross platform implementation), but from memory fgetc will return '\r', which you'll put right into the line, whereas I'm pretty sure fgets won't return '\r', when the line terminator is "\r\n"; I believe fgets returns "\n", not "\r\n" on windows, even if "\r\n" is in the input stream.

You don't need to assign data to tmp like this: char* tmp=realloc(line,chunk_size*(i+2)*sizeof*line+1); as upon success you always do: line=tmp, and upon failure, line will no longer point to valid memory. So you could just assign to line.

Notice how you're calling malloc/calloc/realloc, I would add a freeline function to your code in order to free any memory allocated by this code.  The caller may not be using the same malloc/calloc/realloc you're using, and their free may not be compatible.

Finally I'm not really sure about this: chunk_size*(j+1)*sizeof*line+1
I think you want: chunk_size*(j+1)*sizeof*char+1, as I think line is of size 4 or maybe even 8?, print it out in the debugger, and see, I think you're allocating a lot more memory then you end up putting into the array.