Other than that, LGTM.
> + char *buf = xmalloc (buf_len);
The buf variable is not released after use, I added free (buf)