I am currently writing a small dummy program to try and get the hang of properly using the read in c. I made a small function called readdata to read from the file descriptor and store in a buffer then return the number of bytes read. My problem is I am trying to correctly error handle and trap things so that there is no buffer overflow but I keep doing something from.
Here is the tester:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#define BUFSIZE 10
int readdata(int fd, char *buf, int bsize);
int main(void) {
char buf[BUFSIZE];
int returnval;
int length;
returnval = readdata(STDIN_FILENO, buf, BUFSIZE);
printf("%s",buf);
length = strlen(buf);
fprintf(stderr,"The return value is %d\n", returnval);
fprintf(stderr,"The string is %s\n",buf);
fprintf(stderr,"The length of the string is %d\n",length);
return 0;
}
Here is the small function:
#include <stdio.h>
#include <stdlib.h>
int readdata(int fd, char *buf, int bufsize){
int n = 0;
if(fd < 0){
return 1;
}
while((n=read(fd,buf,(bufsize-1)))>0){
if(n == -1) {
perror( "Read failed" );
return 1;
}
else{
buf[bufsize] = 0;
return n;
}
}
}
If I run
cc -o test test.c readdata.c
And then put
echo "Hello" | ./test
It works fine. But if I pass the bufsize limit like this:
echo "1234567891" | ./getdatatest
It gives me this weird output where it says "the string is 123456789[some weird symbol]" . So I am not sure where to handle this error or why it is still incorrectly putting in the buffer when reading.
You do know that
read()
can return less characters than you requested? Also,buf[bufsize]
is just past the end ofbuf
. Yourreaddata
function should also return something like-1
on error instead of1
so you can distinguish the condition “one byte read” from “IO error.”Consider something like this: