mirror of
https://gitlab.com/sortix/sortix.git
synced 2023-02-13 20:55:38 -05:00
Fix getdelim(3).
This commit is contained in:
parent
86c5bc52b3
commit
f3e4be0d83
8 changed files with 48 additions and 39 deletions
|
@ -53,7 +53,10 @@ char* read_single_line(FILE* fp)
|
|||
size_t ret_size = 0;
|
||||
ssize_t ret_length = getline(&ret, &ret_size, fp);
|
||||
if ( ret_length < 0 )
|
||||
{
|
||||
free(ret);
|
||||
return NULL;
|
||||
}
|
||||
if ( ret_length && ret[ret_length-1] == '\n' )
|
||||
ret[--ret_length] = '\0';
|
||||
return ret;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*******************************************************************************
|
||||
|
||||
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2014.
|
||||
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2014, 2015.
|
||||
|
||||
This file is part of the Sortix C Library.
|
||||
|
||||
|
@ -22,58 +22,55 @@
|
|||
|
||||
*******************************************************************************/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static const size_t DEFAULT_BUFSIZE = 32UL;
|
||||
|
||||
extern "C" ssize_t getdelim(char** lineptr, size_t* n, int delim, FILE* fp)
|
||||
{
|
||||
if ( !lineptr || (*lineptr && !n) || !fp )
|
||||
return errno = EINVAL, -1;
|
||||
const size_t DEFAULT_BUFSIZE = 32UL;
|
||||
bool malloced = !*lineptr;
|
||||
if ( malloced )
|
||||
*lineptr = (char*) malloc(DEFAULT_BUFSIZE);
|
||||
if ( !*lineptr )
|
||||
return -1;
|
||||
size_t bufsize = malloced ? DEFAULT_BUFSIZE : *n;
|
||||
if ( n )
|
||||
*n = bufsize;
|
||||
ssize_t written = 0;
|
||||
int c;
|
||||
int err = EINVAL;
|
||||
flockfile(fp);
|
||||
if ( !lineptr || !n )
|
||||
{
|
||||
failure:
|
||||
fp->flags |= _FILE_STATUS_ERROR;
|
||||
funlockfile(fp);
|
||||
return errno = err, -1;
|
||||
}
|
||||
err = ENOMEM;
|
||||
if ( !*lineptr )
|
||||
*n = 0;
|
||||
size_t written = 0;
|
||||
int c;
|
||||
do
|
||||
{
|
||||
if ( (c = getc_unlocked(fp)) == EOF )
|
||||
if ( written == (size_t) SSIZE_MAX )
|
||||
goto failure;
|
||||
if ( *n <= (size_t) written + 1UL )
|
||||
{
|
||||
if ( written )
|
||||
break;
|
||||
else
|
||||
goto cleanup;
|
||||
}
|
||||
if ( bufsize <= (size_t) written + 1UL )
|
||||
{
|
||||
size_t newbufsize = 2UL * bufsize;
|
||||
size_t newbufsize = *n ? 2UL * *n : DEFAULT_BUFSIZE;
|
||||
char* newbuf = (char*) realloc(*lineptr, newbufsize);
|
||||
if ( !newbuf )
|
||||
goto cleanup;
|
||||
bufsize = newbufsize;
|
||||
if ( n )
|
||||
*n = bufsize;
|
||||
goto failure;
|
||||
*lineptr = newbuf;
|
||||
*n = newbufsize;
|
||||
}
|
||||
if ( (c = getc_unlocked(fp)) == EOF )
|
||||
{
|
||||
if ( !written || feof_unlocked(fp) )
|
||||
{
|
||||
funlockfile(fp);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
(*lineptr)[written++] = c;
|
||||
} while ( c != delim );
|
||||
funlockfile(fp);
|
||||
(*lineptr)[written] = 0;
|
||||
return written;
|
||||
|
||||
cleanup:
|
||||
funlockfile(fp);
|
||||
if ( malloced )
|
||||
{
|
||||
free(*lineptr);
|
||||
*lineptr = NULL;
|
||||
}
|
||||
return -1;
|
||||
return (ssize_t) written;
|
||||
}
|
||||
|
|
|
@ -270,6 +270,7 @@ void string_array_append_file(string_array_t* sa, FILE* fp)
|
|||
entry[entry_length-1] = '\0';
|
||||
string_array_append(sa, entry);
|
||||
}
|
||||
free(entry);
|
||||
}
|
||||
|
||||
bool string_array_append_file_path(string_array_t* sa, const char* path)
|
||||
|
@ -355,6 +356,7 @@ void dictionary_append_file(string_array_t* sa, FILE* fp)
|
|||
continue;
|
||||
string_array_append(sa, entry);
|
||||
}
|
||||
free(entry);
|
||||
}
|
||||
|
||||
bool dictionary_append_file_path(string_array_t* sa, const char* path)
|
||||
|
@ -384,7 +386,10 @@ char* read_single_line(FILE* fp)
|
|||
size_t ret_size = 0;
|
||||
ssize_t ret_len = getline(&ret, &ret_size, fp);
|
||||
if ( ret_len < 0 )
|
||||
{
|
||||
free(ret);
|
||||
return NULL;
|
||||
}
|
||||
if ( ret_len && ret[ret_len-1] == '\n' )
|
||||
ret[ret_len-1] = '\0';
|
||||
return ret;
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <errno.h>
|
||||
#include <error.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
@ -96,6 +97,7 @@ int main(int /*argc*/, char* argv[])
|
|||
fflush(stdout);
|
||||
mode = next_mode;
|
||||
}
|
||||
free(line);
|
||||
int status;
|
||||
waitpid(child_pid, &status, 0);
|
||||
return WEXITSTATUS(status);
|
||||
|
|
|
@ -100,10 +100,9 @@ bool append_lines_from_file(FILE* fp,
|
|||
ssize_t string_length = getline(&string, &string_size, fp);
|
||||
if ( string_length < 0 )
|
||||
{
|
||||
free(string);
|
||||
if ( feof(stdin) )
|
||||
return true;
|
||||
// TODO: HACK: Unfortunately feof(stdin) isn't always true in the
|
||||
// normal EOF case due to a getline/getdelim bug.
|
||||
if ( errno == 0 )
|
||||
return true;
|
||||
error(0, errno, "getline: `%s'", fpname);
|
||||
|
|
|
@ -102,6 +102,7 @@ char* read_line(FILE* fp, const char* fpname, int delim)
|
|||
ssize_t amount = getdelim(&line, &line_size, delim, fp);
|
||||
if ( amount < 0 )
|
||||
{
|
||||
free(line);
|
||||
if ( ferror(fp) )
|
||||
error(0, errno, "read: `%s'", fpname);
|
||||
return NULL;
|
||||
|
|
|
@ -67,6 +67,7 @@ bool processfp(const char* inputname, FILE* fp)
|
|||
ssize_t linelen = getline(&line, &linesize, fp);
|
||||
if ( linelen < 0 )
|
||||
{
|
||||
free(line);
|
||||
if ( feof(fp) ) { break; }
|
||||
error(1, errno, "error reading line: %s", inputname);
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@ char* read_line(FILE* fp, const char* fpname, int delim)
|
|||
ssize_t amount = getdelim(&line, &line_size, delim, fp);
|
||||
if ( amount < 0 )
|
||||
{
|
||||
free(line);
|
||||
if ( ferror(fp) )
|
||||
error(0, errno, "read: `%s'", fpname);
|
||||
return NULL;
|
||||
|
|
Loading…
Add table
Reference in a new issue