A bullet-proof fgets wrapper?
I have been working on a wrapper for fgets that will return all input even if the destination buffer length is exceeded. This is what I came up with, tear it apart.
Code:
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <malloc.h>
char *sgets(char *buf, int bufsize);
size_t strlcpy(char *d, const char *s, size_t bufsize);
size_t strlcat(char *d, const char *s, size_t bufsize);
int main(void)
{
char buf1[6];
char *pbuf1;
char buf2[6];
char *pbuf2;
printf("Enter String 1: ");
pbuf1 = sgets(buf1, sizeof(buf1));
if(pbuf1 == NULL)
{
printf("Input error: String 1\n");
return(1);
}
printf("Enter String 2: ");
pbuf2 = sgets(buf2, sizeof(buf2));
if(pbuf2 == NULL)
{
printf("Input error: String 2\n");
return(2);
}
printf("\n");
printf("String 1 = %s \n", pbuf1);
printf("String 2 = %s \n", pbuf2);
printf("\nPress any key to continue...");
getch();
return(0);
}
char *sgets(char *buf, int bufsize)
{
char *newbuf;
char tempbuf[BUFSIZ];
size_t newsize;
if(fgets(buf, bufsize, stdin) == NULL)
{
return(NULL);
}
else
{
if( strchr(buf, '\n') == NULL )
{
newbuf = malloc(bufsize);
strlcpy(newbuf, buf, bufsize);
newsize = bufsize;
}
else
{
return(buf);
}
while( strchr(newbuf, '\n') == NULL )
{
newsize += (BUFSIZ * sizeof(char));
newbuf = realloc(newbuf, newsize);
if( newbuf == NULL )
{
return(NULL);
}
else
{
if(fgets(tempbuf, sizeof(tempbuf), stdin) == NULL)
{
return(NULL);
}
else
{
strlcat(newbuf, tempbuf, newsize);
}
}
}
return(newbuf);
}
}
size_t strlcpy(char *d, const char *s, size_t bufsize)
{
size_t len;
size_t ret;
if (!d || !s)
{
return(0);
}
len = strlen(s);
ret = len;
if (bufsize <= 0)
{
return(0);
}
if (len >= bufsize)
{
len = bufsize-1;
}
memcpy(d, s, len);
d[len] = 0;
return(ret);
}
size_t strlcat(char *d, const char *s, size_t bufsize)
{
size_t len1;
size_t len2;
size_t ret;
if (!d || !s || bufsize <= 0)
{
return(0);
}
len1 = strlen(d);
len2 = strlen(s);
ret = len1 + len2;
if (len1+len2 >= bufsize)
{
len2 = bufsize - (len1+1);
}
if (len2 > 0)
{
memcpy(d+len1, s, len2);
d[len1+len2] = 0;
}
return(ret);
}