From 02636dc511076149fbe1ac854467d3c167f0c6f7 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sat, 25 Apr 2015 16:27:22 +0200 Subject: [PATCH] added readline for file descriptors (from kerrisk) --- session2/readline.c | 71 +++++++++++++++++++++++++++++++++++++++++++++ session2/readline.h | 22 ++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 session2/readline.c create mode 100644 session2/readline.h diff --git a/session2/readline.c b/session2/readline.c new file mode 100644 index 0000000..0cc1bb6 --- /dev/null +++ b/session2/readline.c @@ -0,0 +1,71 @@ +/*************************************************************************\ +* Copyright (C) Michael Kerrisk, 2015. * +* * +* This program is free software. You may use, modify, and redistribute it * +* under the terms of the GNU Lesser General Public License as published * +* by the Free Software Foundation, either version 3 or (at your option) * +* any later version. This program is distributed without any warranty. * +* See the files COPYING.lgpl-v3 and COPYING.gpl-v3 for details. * +\*************************************************************************/ + +/* read_line.c + + Implementation of readLine(). +*/ +#include +#include +#include "readline.h" /* Declaration of readLine() */ + +/* Read characters from 'fd' until a newline is encountered. If a newline + character is not encountered in the first (n - 1) bytes, then the excess + characters are discarded. The returned string placed in 'buf' is + null-terminated and includes the newline character if it was read in the + first (n - 1) bytes. The function return value is the number of bytes + placed in buffer (which includes the newline character if encountered, + but excludes the terminating null byte). */ + +ssize_t +readline(int fd, void *buffer, size_t n) +{ + ssize_t numRead; /* # of bytes fetched by last read() */ + size_t totRead; /* Total bytes read so far */ + char *buf; + char ch; + + if (n <= 0 || buffer == NULL) { + errno = EINVAL; + return -1; + } + + buf = buffer; /* No pointer arithmetic on "void *" */ + + totRead = 0; + for (;;) { + numRead = read(fd, &ch, 1); + + if (numRead == -1) { + if (errno == EINTR) /* Interrupted --> restart read() */ + continue; + else + return -1; /* Some other error */ + + } else if (numRead == 0) { /* EOF */ + if (totRead == 0) /* No bytes read; return 0 */ + return 0; + else /* Some bytes read; add '\0' */ + break; + + } else { /* 'numRead' must be 1 if we get here */ + if (totRead < n - 1) { /* Discard > (n - 1) bytes */ + totRead++; + *buf++ = ch; + } + + if (ch == '\n') + break; + } + } + + *buf = '\0'; + return totRead; +} diff --git a/session2/readline.h b/session2/readline.h new file mode 100644 index 0000000..4121893 --- /dev/null +++ b/session2/readline.h @@ -0,0 +1,22 @@ +/*************************************************************************\ +* Copyright (C) Michael Kerrisk, 2015. * +* * +* This program is free software. You may use, modify, and redistribute it * +* under the terms of the GNU Lesser General Public License as published * +* by the Free Software Foundation, either version 3 or (at your option) * +* any later version. This program is distributed without any warranty. * +* See the files COPYING.lgpl-v3 and COPYING.gpl-v3 for details. * +\*************************************************************************/ + +/* read_line.h + + Header file for read_line.c. +*/ +#ifndef READ_LINE_H +#define READ_LINE_H + +#include + +ssize_t readline(int fd, void *buffer, size_t n); + +#endif