When I run my program with ./a.out and name of directory as arguments I get a segmentation fault after the first time I print "made it" to the terminal and when I try to read from the directory (I know this because the second "made it" never gets printed). I'm assuming it's a pointer problem but unsure as to why. Some of the issues have been fixed thanks to the advice of commenters below. I have updated this post since.
Why am I receiving this? I've tried valgrind to fix the issue but I'm completely new to it and the messages it gave me didn't make sense to me. Here's perhaps the most useful snippets from running valgrind and from my code below :
==26237== Invalid read of size 1
==26237== at 0x4F1B940: invalid_name (opendir.c:91)
==26237== by 0x4F1B940: opendir (opendir.c:172)
==26237== by 0x108DF2: main (DirectorySearch.c:63)
==26237== Address 0x522d2c0 is 0 bytes inside a block of size 250 free'd
==26237== at 0x4C30D3B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==26237== by 0x108D7A: main (DirectorySearch.c:52)
==26237== Block was alloc'd at
==26237== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==26237== by 0x108C8B: main (DirectorySearch.c:36)
==26237==
==26237== Syscall param openat(filename) points to unaddressable byte(s)
==26237== at 0x4F4BDB1: __open_nocancel (open64.c:69)
==26237== by 0x4F1B952: opendir (opendir.c:190)
==26237== by 0x108DF2: main (DirectorySearch.c:63)
==26237== Address 0x522d2c0 is 0 bytes inside a block of size 250 free'd
==26237== at 0x4C30D3B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==26237== by 0x108D7A: main (DirectorySearch.c:52)
==26237== Block was alloc'd at
==26237== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==26237== by 0x108C8B: main (DirectorySearch.c:36)
/*
Lists directory contents recursively, breadth first.
*/
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/stat.h>
#include <dirent.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
typedef struct {
char* name;
char* abs;
struct node* next;
struct node* prev;
} node;
node* append(node*, char*, char*);
int print_list(node*);
int main(int argc, char** argv) {
if(argc != 2){
printf("You must provide 2 arguments: <./filename> <directory>\n");
return 0;
}
DIR* dp;
struct dirent* dirp;
struct stat buff;
char* name = malloc(250 * sizeof(char));
char* abs = malloc(250 * sizeof(char));
char* tmp = malloc(250 * sizeof(char));
node* head = malloc(sizeof(node));
if((chdir(argv[1])) == -1) {
fprintf(stderr, "%s\n", strerror(errno));
exit(errno);
}
head->name = argv[1];
head->abs = getcwd(tmp, 250);
head->next = NULL;
printf("%s\n", tmp);
free(name);
free(abs);
free(tmp);
int firstDir = 0;
do {
if(firstDir > 0) {
if (chdir(head->abs) == -1) {
fprintf(stderr, "%s\n", strerror(errno));
exit(errno);
}
}
dp = opendir(head->abs);
printf("%s\n", "made it");
while((dirp = readdir(dp)) != NULL)
{
printf("%s\n", "made it");
lstat(dirp->d_name, &buff);
if(S_ISREG(buff.st_mode))
printf("regular file: %s\n", dirp->d_name);
else if(S_ISDIR(buff.st_mode) && !S_ISLNK(buff.st_mode)) {
if (((strcmp(dirp->d_name, "..")) != 0) && ((strcmp(dirp->d_name, ".")) != 0)) {
printf("directory: %s\n", dirp->d_name);
name = calloc(250, sizeof(char));
abs = calloc(250, sizeof(char));
tmp = calloc(250, sizeof(char));
strncpy(name, dirp->d_name, strlen(dirp->d_name));
abs = getcwd(tmp, 250);
tmp = abs;
asprintf(&abs, "%s/%s", tmp, dirp->d_name);
head = append(head, name, abs);
free(name);
free(tmp);
}else
printf("directory: %s\n", dirp->d_name);
}
else if (S_ISLNK(buff.st_mode))
printf("%s %s\n", "LINK: ", dirp->d_name);
else if (S_ISFIFO(buff.st_mode))
printf("%s %s\n", "FIFO: ", dirp->d_name);
else if (S_ISCHR(buff.st_mode))
printf("%s %s\n", "CHAR DEV: ", dirp->d_name);
else if (S_ISBLK(buff.st_mode))
printf("%s %s\n", "BLOCK DEV: ", dirp->d_name);
else if (S_ISSOCK(buff.st_mode))
printf("%s %s\n", "SOCKET: ", dirp->d_name);
else
printf("%s\n", "Unknown file type.");
}
head = head->next;
if (head != NULL) {free(head->prev);}
printf("\n");
firstDir++;
} while (head != NULL);
free(abs);
return 0;
}
node* append(node* head, char *name, char *abs)
{
node* new = malloc(sizeof(node));
node* cursor = head;
while(cursor->next != NULL)
cursor = cursor->next;
node* prev = cursor;
new->name = name;
new->abs = abs;
new->next = NULL;
new->prev = prev;
cursor->next = new;
return head;
}
You're using node *head=malloc( sizeof( node*))'
when you probably want to use sizeof( node)
for that last allocation. After that point, assigning to head->abs invokes undefined behavior.