Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add getlinex() #640

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
31 changes: 2 additions & 29 deletions lib/commonio.c
Expand Up @@ -447,7 +447,7 @@ static void add_one_entry_nis (struct commonio_db *db,

int commonio_open (struct commonio_db *db, int mode)
{
char *buf;
char *buf = NULL;
char *cp;
char *line;
struct commonio_entry *p;
Expand Down Expand Up @@ -512,34 +512,7 @@ int commonio_open (struct commonio_db *db, int mode)
/* Do not inherit fd in spawned processes (e.g. nscd) */
fcntl (fileno (db->fp), F_SETFD, FD_CLOEXEC);

buflen = BUFLEN;
buf = (char *) malloc (buflen);
if (NULL == buf) {
goto cleanup_ENOMEM;
}

while (db->ops->fgets (buf, (int) buflen, db->fp) == buf) {
while ( ((cp = strrchr (buf, '\n')) == NULL)
&& (feof (db->fp) == 0)) {
size_t len;

buflen += BUFLEN;
cp = (char *) realloc (buf, buflen);
if (NULL == cp) {
goto cleanup_buf;
}
buf = cp;
len = strlen (buf);
if (db->ops->fgets (buf + len,
(int) (buflen - len),
db->fp) == NULL) {
goto cleanup_buf;
}
}
cp = strrchr (buf, '\n');
if (NULL != cp) {
*cp = '\0';
}
while (db->ops->getline (&buf, &buflen, db->fp) != -1) {

line = strdup (buf);
if (NULL == line) {
Expand Down
3 changes: 2 additions & 1 deletion lib/commonio.h
Expand Up @@ -58,11 +58,12 @@ struct commonio_ops {
int (*put) (const void *, FILE *);

/*
* fgets and fputs (can be replaced by versions that
* fgets, fputs, and getline (can be replaced by versions that
* understand line continuation conventions).
*/
/*@null@*/char *(*fgets) (/*@returned@*/ /*@out@*/char *s, int n, FILE *stream);
int (*fputs) (const char *, FILE *);
ssize_t (*getline) (char **restrict lineptr, size_t *restrict size, FILE *restrict stream);

/*
* open_hook and close_hook.
Expand Down
49 changes: 49 additions & 0 deletions lib/fputsx.c
Expand Up @@ -16,6 +16,55 @@
#ident "$Id$"


/*
* Similar to getline(3), but handle escaped newlines.
* Returns the length of the string, or -1 on error.
*/
ssize_t
getlinex(char **restrict lineptr, size_t *restrict size,
FILE *restrict stream)
{
char *p;
size_t len;

if (*lineptr == NULL || *size < BUFSIZ) {
*size = BUFSIZ;
} else if (*size > INT_MAX) {
*size = INT_MAX;
}

len = 0;
for (size_t sz = *size; sz < INT_MAX; sz <<= 1) {
*size = sz;
*lineptr = reallocf(*lineptr, sz);
if (*lineptr == NULL)
return -1;

p = fgetsnulx(*lineptr + len, sz, stream);
if (p == NULL)
return -1;

len = p - *lineptr;
if (p[-1] == '\n' && p[-2] != '\\')
return len;
if (p[-1] == '\n' && p[-2] == '\\')
len -= 2;
}

return -1;
}


/* Like fgetsx(), but returns a pointer to the terminating NUL byte. */
char *
fgetsnulx(char *buf, int size, FILE *stream)
{
if (fgetsx(buf, size, stream) == NULL)
return NULL;
return buf + strlen(buf);
}


/*@null@*/char *fgetsx (/*@returned@*/ /*@out@*/char *buf, int cnt, FILE * f)
{
char *cp = buf;
Expand Down
1 change: 1 addition & 0 deletions lib/groupio.c
Expand Up @@ -96,6 +96,7 @@ static struct commonio_ops group_ops = {
group_put,
fgetsx,
fputsx,
getlinex, /* getline */
group_open_hook,
group_close_hook
};
Expand Down
36 changes: 2 additions & 34 deletions lib/gshadow.c
Expand Up @@ -192,48 +192,16 @@ void endsgent (void)
static size_t buflen = 0;
static char *buf = NULL;

char *cp;

if (0 == buflen) {
buf = (char *) malloc (BUFSIZ);
if (NULL == buf) {
return NULL;
}
buflen = BUFSIZ;
}

if (NULL == fp) {
return NULL;
}

#ifdef USE_NIS
while (fgetsx (buf, (int) buflen, fp) == buf)
while (getlinex (&buf, &buflen, fp) != -1)
#else
if (fgetsx (buf, (int) buflen, fp) == buf)
if (getlinex (&buf, &buflen, fp) != -1)
#endif
{
while ( ((cp = strrchr (buf, '\n')) == NULL)
&& (feof (fp) == 0)) {
size_t len;

cp = (char *) realloc (buf, buflen*2);
if (NULL == cp) {
return NULL;
}
buf = cp;
buflen *= 2;

len = strlen (buf);
if (fgetsx (&buf[len],
(int) (buflen - len),
fp) != &buf[len]) {
return NULL;
}
}
cp = strrchr (buf, '\n');
if (NULL != cp) {
*cp = '\0';
}
#ifdef USE_NIS
if (nis_ignore && IS_NISCHAR (buf[0])) {
continue;
Expand Down
3 changes: 3 additions & 0 deletions lib/prototypes.h
Expand Up @@ -176,6 +176,9 @@ extern int get_uid (const char *uidstr, uid_t *uid);
extern int getulong (const char *numstr, /*@out@*/unsigned long int *result);

/* fputsx.c */
extern ssize_t getlinex(char **restrict lineptr, size_t *restrict size,
FILE *restrict stream);
extern char * fgetsnulx(char *buf, int size, FILE *stream);
extern /*@null@*/char *fgetsx (/*@returned@*/ /*@out@*/char *, int, FILE *);
extern int fputsx (const char *, FILE *);

Expand Down
1 change: 1 addition & 0 deletions lib/pwio.c
Expand Up @@ -74,6 +74,7 @@ static struct commonio_ops passwd_ops = {
passwd_put,
fgets,
fputs,
getline, /* getline */
NULL, /* open_hook */
NULL /* close_hook */
};
Expand Down
1 change: 1 addition & 0 deletions lib/sgroupio.c
Expand Up @@ -195,6 +195,7 @@ static struct commonio_ops gshadow_ops = {
gshadow_put,
fgetsx,
fputsx,
getlinex, /* getline */
NULL, /* open_hook */
NULL /* close_hook */
};
Expand Down
1 change: 1 addition & 0 deletions lib/shadowio.c
Expand Up @@ -73,6 +73,7 @@ static struct commonio_ops shadow_ops = {
shadow_put,
fgets,
fputs,
getline, /* getline */
NULL, /* open_hook */
NULL /* close_hook */
};
Expand Down
1 change: 1 addition & 0 deletions lib/subordinateio.c
Expand Up @@ -145,6 +145,7 @@ static struct commonio_ops subordinate_ops = {
subordinate_put, /* put */
fgets, /* fgets */
fputs, /* fputs */
getline, /* getline */
NULL, /* open_hook */
NULL, /* close_hook */
};
Expand Down