glcpp: Make standalone preprocessor work with a tty as stdin
Previously glcpp would silently abort if it couldn't fstat the file being read, (so it would work with stdin redirected from a file, but would not work with stdin as a tty). The stat was so that glcpp could allocate a buffer for the file content in a single call. We now use talloc_realloc instead, (even if the fstat is possible). This is theoretically less efficient, but quite irrelevant, (particularly because the standalone preprocessor is used only for testing).
This commit is contained in:
@@ -31,35 +31,32 @@
|
||||
|
||||
extern int yydebug;
|
||||
|
||||
/* Read from fd until EOF and return a string of everything read.
|
||||
*/
|
||||
static char *
|
||||
load_text_file(void *ctx, const char *file_name)
|
||||
load_text_fd (void *ctx, int fd)
|
||||
{
|
||||
#define CHUNK 4096
|
||||
char *text = NULL;
|
||||
struct stat st;
|
||||
ssize_t text_size = 0;
|
||||
ssize_t total_read = 0;
|
||||
int fd;
|
||||
ssize_t bytes;
|
||||
|
||||
if (file_name == NULL || strcmp(file_name, "-") == 0) {
|
||||
fd = STDIN_FILENO;
|
||||
} else {
|
||||
fd = open (file_name, O_RDONLY);
|
||||
|
||||
if (fd < 0) {
|
||||
fprintf (stderr, "Failed to open file %s: %s\n",
|
||||
file_name, strerror (errno));
|
||||
while (1) {
|
||||
if (total_read + CHUNK + 1 > text_size) {
|
||||
text_size = text_size ? text_size * 2 : CHUNK + 1;
|
||||
text = talloc_realloc_size (ctx, text, text_size);
|
||||
if (text == NULL) {
|
||||
fprintf (stderr, "Out of memory\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (fstat(fd, & st) == 0) {
|
||||
text = (char *) talloc_size(ctx, st.st_size + 1);
|
||||
if (text != NULL) {
|
||||
do {
|
||||
ssize_t bytes = read(fd, text + total_read,
|
||||
st.st_size - total_read);
|
||||
bytes = read (fd, text + total_read, CHUNK);
|
||||
if (bytes < 0) {
|
||||
text = NULL;
|
||||
break;
|
||||
fprintf (stderr, "Error while reading: %s\n",
|
||||
strerror (errno));
|
||||
talloc_free (text);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (bytes == 0) {
|
||||
@@ -67,12 +64,31 @@ load_text_file(void *ctx, const char *file_name)
|
||||
}
|
||||
|
||||
total_read += bytes;
|
||||
} while (total_read < st.st_size);
|
||||
}
|
||||
|
||||
text[total_read] = '\0';
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
static char *
|
||||
load_text_file(void *ctx, const char *filename)
|
||||
{
|
||||
char *text;
|
||||
int fd;
|
||||
|
||||
if (filename == NULL || strcmp (filename, "-") == 0)
|
||||
return load_text_fd (ctx, STDIN_FILENO);
|
||||
|
||||
fd = open (filename, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
fprintf (stderr, "Failed to open file %s: %s\n",
|
||||
filename, strerror (errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
text = load_text_fd (ctx, fd);
|
||||
|
||||
close(fd);
|
||||
|
||||
return text;
|
||||
|
Reference in New Issue
Block a user