added readline for file descriptors (from kerrisk)
This commit is contained in:
parent
e2d6d4cf9d
commit
02636dc511
2 changed files with 93 additions and 0 deletions
71
session2/readline.c
Normal file
71
session2/readline.c
Normal file
|
@ -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 <unistd.h>
|
||||
#include <errno.h>
|
||||
#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;
|
||||
}
|
22
session2/readline.h
Normal file
22
session2/readline.h
Normal file
|
@ -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 <sys/types.h>
|
||||
|
||||
ssize_t readline(int fd, void *buffer, size_t n);
|
||||
|
||||
#endif
|
Loading…
Add table
Reference in a new issue