libinn_qio(3)

πŸ’… libinn_qio(3) β€” the InterNetNews docs, bestie edition ✨

okay so real talk, this is a libinn(3) page, and it's about reading files fast. no cap. πŸ¦‹


✨ NAME ✨

qio β€” Quick I/O routines for reading files. that's it, that's the whole vibe check. πŸ’–


🌸 SYNOPSIS 🌸

like, here's the whole cast of characters, presented verbatim because i would never mess with your includes:

#include <inn/qio.h>

QIOSTATE *QIOopen(const char *name);

QIOSTATE *QIOfdopen(int fd);

void QIOclose(QIOSTATE *qp);

char *QIOread(QIOSTATE *qp);

int QIOfileno(QIOSTATE *qp);

size_t QIOlength(QIOSTATE *qp);

int QIOrewind(QIOSTATE *qp);

off_t QIOtell(QIOSTATE *qp);

bool QIOerror(QIOSTATE *qp);

bool QIOtoolong(QIOSTATE *qp);

πŸŽ€ DESCRIPTION πŸŽ€

so these routines live inside libinn(3), and their whole job is giving you quick read access to files. the QIO routines do buffering adapted to the block size of the device β€” think stdio energy β€” but with a way more convenient syntax for reading newline-terminated lines. and yeah, "QIO" is short for "Quick I/O", which is honestly a bit of a misnomer because QIO only gives you read-only access to files. πŸ™ˆ iconic of it to oversell, honestly.

the QIOSTATE structure you get back from QIOopen and QIOfdopen is the analog to stdio's FILE structure, and bestie, treat it like a black box. literally every user of these routines should only ever touch the API listed above. the way that's the whole rule. πŸ”₯

  • QIOopen β€” opens the given file for reading with a buffer size of 32KiB. returns a pointer for you to use in subsequent calls, or NULL on error. 😭
  • QIOfdopen β€” does the exact same thing except it works on an already-open file descriptor (fd must designate a file open for reading).
  • QIOclose β€” closes the open file and releases any resources used by the QIOSTATE structure. 🫢 the QIOSTATE pointer should not be used again after you've passed it to this function. like, it's done. move on. periodt.
  • QIOread β€” reads the next newline-terminated line in the file and returns a pointer to it, with the trailing newline replaced by nul. the returned pointer points into a buffer inside the QIOSTATE object, so it stays valid until QIOclose is called on that object. but heads up: if EOF is reached, an error occurs, or the line is longer than the buffer size (32KiB), NULL is returned instead. to tell those cases apart, use QIOerror and QIOtoolong. 🧚
  • QIOfileno β€” returns the descriptor of the open file. simple, slay.
  • QIOlength β€” returns the length in bytes of the last line returned by QIOread. ⚠️ its return value is only defined after a successful call to QIOread, so don't come for it before then.
  • QIOrewind β€” sets the read pointer back to the beginning of the file and reads the first block of the file in anticipation of future reads. returns 0 if successful and -1 on error.
  • QIOtell β€” returns the current value of the read pointer (the lseek(2) offset at which the next line will start). πŸ‘‘
  • QIOerror β€” returns true if there was an error in the last call to QIOread, false otherwise.
  • QIOtoolong β€” returns true if there was an error and the error was that the line was too long.
okay so here's the detective work: if QIOread returns NULL, you should call these functions to figure out what actually happened. if QIOread returned NULL and QIOerror is false, that means EOF was reached. πŸ’€ and ngl, note this one carefully: if QIOtoolong returns true, the next call to QIOread will try to read the remainder of the line and will likely return a partial line. users of this library should in general treat long lines as fatal errors. fr fr, don't sleep on that.

🌈 EXAMPLES 🌈

this block of code opens /etc/motd and reads it a line at a time, printing out each line preceded by its offset in the file. look at it go, main character code:

QIOSTATE *qp;
off_t offset;
char *p;

qp = QIOopen("/etc/motd");
if (qp == NULL) {
    perror("Open error");
    exit(1);
}
for (p = QIOread(qp); p != NULL; p = QIOread(qp))
    printf("%ld: %s\n", (unsigned long) QIOtell(qp), p);
if (QIOerror(qp)) {
    perror("Read error");
    exit(1);
}
QIOclose(qp);

πŸ¦‹ HISTORY πŸ¦‹

written by Rich $alz <rsalz@uunet.uu.net> for InterNetNews. updated by Russ Allbery <eagle@eyrie.org>. we love a credited origin story. πŸ’œ


and that's the whole page, bestie β€” this was libinn_qio(3) from INN 2.7.4, dated 2025-03-29. go forth and read your files quickly πŸ’…βœ¨πŸŽ€

πŸ“¦ where this page comes from
  • arch rolling: inn 2.7.4-4 Β· ISC
  • epel 10: inn-devel 2.7.4-5.el10_3 Β· ISC AND BSD-3-Clause AND BSD-4-Clause AND FSFAP AND (GPL-1.0-or-later OR Artistic-1.0-Perl) AND GPL-3.0-or-later WITH Bison-exception-2.2 AND LicenseRef-Fedora-Public-Domain AND MIT AND NTP
  • πŸ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms