The getdelim function has a bad interface.

It works like this: You give it a buffer to fill and sometimes grow. You give it a file pointer. You give it a delimiter. The function responds with either

Going back a little, a stream using a file descriptor consists of a sequence of chunks of bytes, each such chunk read by a single call to read. End-of-file is the name of a special case—an empty chunk.

Now, getdelim doesn’t use a file descriptor; it uses a file pointer. A file pointer is a different model: It consists of a sequence of either single bytes or end-of-file conditions. You read a stream using repeated calls to fgetc. Each call returns either the next single byte or EOF. After an EOF you need to clear the stream’s end-of-file bit to continue reading.

The getdelim function uses different model still: A sequence of either lines or end-of-file conditions. A line is a sequence of bytes, terminated by a “delimiter.” A line that occurs directly before an end-of-file condition may be a partial line; that is, missing its terminating delimiter.

Terminals interface with read syscalls like so: The user can decide how the chunks look, but the easiest thing to do is to type lines terminated by newlines, with each chunk containing exactly one line (or one line being split into multiple chunks if it doesn’t fit in a single one). To have a chunk contain multiple line terminators, the user can escape them (usually using ^V). To have a chunk both smaller than the reading process’s buffer size and not terminated by a newline, the user can use another special byte (usually ^D). The special bytes for terminating a line, escaping a byte, and sending off a chunk without a line terminator can be configured in the kernel’s structure for a terminal using stty.

Anyway, I find it strange that getdelim special-cases end-of-file in such a way. While fitting the standard i/o stream model, it is quite different from the conventions used by terminals—which is the main use of it for me (as getline). But now that I think about it, I hadn’t had any reason to use getdelim in the first place. Takeaway: You don’t need to both start processing partial lines and use getdelim. The getdelim function is a workaround for not being able to process partial lines.