do_read implementation (step 18)