A
ais523
I was just wondering whether there was a portable way to use gets()
safely, and came up with this:
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE* temp;
char buf[L_tmpnam];
char* readin, *tfn;
int len;
tfn = tmpnam(buf);
if(!tfn) abort();
temp = fopen(tfn,"w");
if(!temp) abort();
len = fprintf(temp, "%s %d.\n", "Hello, world!", 42);
fclose(temp);
if(!freopen(tfn, "r", stdin)) {remove(tfn); abort();};
readin = malloc(len+1);
if(readin)
{
gets(readin); /* hopefully safe */
printf("%s contained %s\n", tfn, readin);
free(readin);
}
fclose(stdin);
remove(tfn);
return 0;
}
Here, freopen is used to control the input to stdin, so the string that
will be read in will have to fit in readin (whose length has been
calculated by an earlier printf). The program itself demonstrates one
possible (inefficient) way of writing an asprintf() function: write to
a temporary file, and then read back the data from that file. (Of
course, in real code fgets() would be used, rather than gets(), and
stdin wouldn't be redirected!). I thought something like fclose(stdin)
might cause UB or at best be implementation-defined, but from reading
the standard it seems to be valid.
safely, and came up with this:
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE* temp;
char buf[L_tmpnam];
char* readin, *tfn;
int len;
tfn = tmpnam(buf);
if(!tfn) abort();
temp = fopen(tfn,"w");
if(!temp) abort();
len = fprintf(temp, "%s %d.\n", "Hello, world!", 42);
fclose(temp);
if(!freopen(tfn, "r", stdin)) {remove(tfn); abort();};
readin = malloc(len+1);
if(readin)
{
gets(readin); /* hopefully safe */
printf("%s contained %s\n", tfn, readin);
free(readin);
}
fclose(stdin);
remove(tfn);
return 0;
}
Here, freopen is used to control the input to stdin, so the string that
will be read in will have to fit in readin (whose length has been
calculated by an earlier printf). The program itself demonstrates one
possible (inefficient) way of writing an asprintf() function: write to
a temporary file, and then read back the data from that file. (Of
course, in real code fgets() would be used, rather than gets(), and
stdin wouldn't be redirected!). I thought something like fclose(stdin)
might cause UB or at best be implementation-defined, but from reading
the standard it seems to be valid.