I thought I had this done, but if I try to run with multiple files (mygrep print *.c) I get a double free or corruption runtime error. Any suggestions.
Code:
/*
*CS306 Lab 1 lab1.c
*Author: Chris Wiegman
*Will search through file or
*standard input for a given string
*
*Call as:
* mygrep STRING [FILE...]
*
*Based on:
* Solution to Lab #1 in CS 306, Fall 2008
* Author: Norman Carver
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#define FILE_BUFFER_SIZE 1024
#define INIT_BUFF_SIZE 50
#define INC_BUFF_SIZE 10
char *get_next_line(int fd);
int get_next_char(int fd);
int grep_open_file (char *search_string,int fd,char *file_pathname, int print_file);
int main(int argc, char *argv[]) {
char *needle, *file_pathname;
int i, fd, status = EXIT_SUCCESS;
if (argc < 2) {
fprintf(stderr,"Usage: mygrep STRING [FILE...]\n");
return EXIT_FAILURE;
}
needle = argv[1];
if(argc == 2) {
file_pathname = "stdin";
fd = 0;
grep_open_file(needle,fd,file_pathname,0);
} else {
for (i=2; i<argc; i++) {
file_pathname = argv[i];
fd = open(file_pathname,O_RDONLY);
if (errno > 0) {
fprintf(stderr,"%s: Error opening file %s: %s\n", argv[0], file_pathname, strerror(errno));
status = EXIT_FAILURE;
} else {
grep_open_file(needle,fd,file_pathname,argc>3);
//close(fd);
}
}
}
return status;
}
/*open the file or read the standard input and search for our string */
int grep_open_file(char *needle, int fd, char *file_pathname, int print_file) {
char *haystack;
while ((haystack = get_next_line(fd)) != NULL) {
if (strstr(haystack,needle) != NULL) {
if (print_file) {
printf("%s:%s\n",file_pathname,haystack);
} else {
printf("%s\n",haystack);
}
}
}
if (errno > 0) {
fprintf(stderr,"Error reading from file %s: %s\n", file_pathname, strerror(errno));
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
/*Get the next line and return it as a valid string */
char *get_next_line(int fd) {
static char *line_buff;
char *temp_buff;
int buff_pos, next_char, chars_left, buff_size;
buff_size = INIT_BUFF_SIZE;
chars_left = buff_size;
if (line_buff != NULL) {
free(line_buff);
}
line_buff = malloc(buff_size);
buff_pos = 0;
while ((next_char = get_next_char(fd)) != '\n' && next_char != EOF) {
if (chars_left > 0) {
chars_left--;
} else {
buff_size = buff_size + INC_BUFF_SIZE;
temp_buff = line_buff;
line_buff = realloc(line_buff,buff_size);
if (line_buff == NULL) {
line_buff = temp_buff;
}
}
line_buff[buff_pos++] = next_char;
}
if (chars_left == 0) {
buff_size = buff_size + 1;
temp_buff = line_buff;
line_buff = realloc(line_buff,buff_size);
if (line_buff == NULL) {
line_buff = temp_buff;
}
}
line_buff[buff_pos] = '\0';
if (next_char == EOF && (buff_pos == 0 || (errno > 0))) {
free(line_buff);
return NULL;
} else {
return line_buff;
}
}
/*Get the next character in the file. Make sure to read more than 1 character in per execution*/
int get_next_char(int fd) {
static char char_buff[FILE_BUFFER_SIZE];
static int char_count, bytes_left,pos;
if (bytes_left == 0) {
char_count = read(fd, char_buff, FILE_BUFFER_SIZE);
bytes_left = char_count;
pos = 0;
}
if (bytes_left != 0) {
bytes_left--;
return char_buff[pos++];
} else {
return EOF;
}
}