2016-04-21 14 views
0

Ich möchte globbing für eine benutzerdefinierte Shell implementieren, aber wenn ich versuche, die Funktion zu verwenden, erhalten Sie einen segfault.Wie benutzt man die Glob-Funktion?

#include <stdlib.h> 
#include <string.h> 
#include <glob.h> 

/* Convert a wildcard pattern into a list of blank-separated 
    filenames which match the wildcard. */ 

char * glob_pattern(char *wildcard) 
{ 
    char *gfilename; 
    size_t cnt, length; 
    glob_t glob_results; 
    char **p; 

    glob(wildcard, GLOB_NOCHECK, 0, &glob_results); 

    /* How much space do we need? */ 
    for (p = glob_results.gl_pathv, cnt = glob_results.gl_pathc; 
     cnt; p++, cnt--) 
    length += strlen(*p) + 1; 

    /* Allocate the space and generate the list. */ 
    gfilename = (char *) calloc(length, sizeof(char)); 
    for (p = glob_results.gl_pathv, cnt = glob_results.gl_pathc; 
     cnt; p++, cnt--) 
    { 
     strcat(gfilename, *p); 
     if (cnt > 1) 
     strcat(gfilename, " "); 
    } 

    globfree(&glob_results); 
    return gfilename; 
} 

Wenn ich versuche, den abose-Code zu verwenden, bekomme ich einen segfault. Warum funktioniert es nicht?

+1

Haben Sie mit einigen Druckfunktionen jedes Debuggen versucht, einen Debugger oder einem Speicher-Checker wie valgrind? – Evert

+1

@ v7d8dpo4 Sie haben Glück, denn es gibt ein undefiniertes Verhalten im Code. Welcher Valgrind weist leicht darauf hin. – Evert

+1

'strcat (gfilename, * p);' ist langsam. Es ist besser, 'char * tmp = gfilename;' vor der Schleife und 'tmp = stpcpy (tmp, * p);' und '* (tmp ++) = ''; in der Schleife zu haben. – v7d8dpo4

Antwort

1

Das Problem ist, weil length nicht initialisiert wird, bevor Sie Längen von Pfaden in es ansammeln.

length = 0; <-- should initialize length here 
for (p = glob_results.gl_pathv, cnt = glob_results.gl_pathc; cnt; p++, cnt--) 
    length += strlen(*p) + 1; 

Auch werfen nicht Rückgabewert von calloc und sizeof(char) ist 1 definiert in der Norm zu sein. Also ist es besser, nur tun:

gfilename = calloc(length, 1); 

oder

gfilename = malloc(length);