You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
50 lines
1.8 KiB
50 lines
1.8 KiB
// https://man7.org/tlpi/code/online/dist/sockets/read_line.c.html |
|
#include "readline.h" |
|
|
|
/* 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 fdReadLine(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; |
|
} |
|
|
|
|