There are several ways to go about this in general. The best choice is likely dependant on what type of data you are looking when you read the serial port and how you want to go about dealing with errors in that data.
The fist way would be to open the serial file for blocking IO and do:
while (question) {
write(ser_fd, question.data, question.len);
sleep(1);
ioctl(ser_fd, FIONREAD, &answer.len);
answer.data = realloc(answer.data, answer.len);
read(ser_fd, question.answer, question.answer_len);
question = next(question);
answer = next(answer);
}
Though I didn't do any error handling in this.
If you want to be able to timeout waiting for a reply to come in the serial port then that changes things a lot. You should look into using either select, pselect, poll, ppoll, or the epoll family of system calls. These allow your program to block (sleep) until there is data ready to be read in. Then you can loop around a poll and read until you have either completed your answer or run out of time.
Another option is to try to use SIGIO, but I don't recommend this. It's not easy to get this right and difficult to debug.
Additionally you may be able to use SIGALRM to knock you out of your read call to act as a timeout for that.
If you are trying to use the stdio input and output routines then this is much more difficult. You will be stuck with something like the first method without being able to ask about how much data is ready.