Thread: command line wildcard question

  1. #1
    Registered User
    Join Date
    Apr 2004
    Posts
    28

    command line wildcard question

    Hi

    Before i start i just wanted to say that i know there is a linux programming board, but it seems like not many people post there, and seeing as this is mostly a C question too i thought it would be ok for me to try it here, sorry if I made a mistake.

    Im in the process of making a command line parser and im stuck handling wildcards... I know that i need to use the glob() function and i gave it my best shot but im getting segmentation faults at runtime.

    The function in question accepts the argument list, number of args, and offs (which is the amount of tokens containing * in them, that were found during string processing). Basically i thought i would be able to check if there were offs in the string, if so then use glob() and send it to execvp, or if there wasnt any offs, then just send the string to execvp as per normal.

    The problem is in the logic used to glob in the string, and i would really like any help at all, my current attempt is below and ive marked where i think the faults are occuring, thanks.

    Code:
    void childProcess(char **arglist, int args, int extra_proc, int offs)
    {
         int init, i, first_glob = TRUE;
         id_t pid;
         glob_t globbuf;
    
         if(offs > 0)
         {
              globbuf.gl_offs = offs;
    
              for(i=0; i<args; i++)
              {
                   if(strstr(arglist[i], "*") != NULL)
                   {
                        if(first_glob)
                        {
                             glob(arglist[i], GLOB_DOOFFS, NULL, &globbuf);
                             first_glob = FALSE;
                        }
                        else
                        {
                             glob(arglist[i], GLOB_DOOFFS | GLOB_APPEND, NULL, &globbuf);
                        }
                   }
                   else
                   {
                        globbuf.gl_pathv[i] = arglist[i];                //here
                   }
              } 
         }
    
         pid = fork();
    
         if(pid == -1)
         {
              printf("\n[ERROR_FORK]");
         }
         else
         {
              if(pid > 0)
              {
                   if(extra_proc != BACKGROUND)
                   {
                        wait(&init);
                   }
              }
              else
              {
                   if(offs > 0)
                   {
                        if((init = execvp(arglist[0], &globbuf.gl_pathv[0])) == -1)          //here                
                        {
                             printf("\nUnknown command");
                        }
                   }
                   else
                   {
                        if((init = execvp(arglist[0], arglist)) == -1)
                        {
                             printf("\nUnknown command");
                        }
                   }
                   exit(0);
              }
         }
    }

  2. #2
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Code:
    globbuf.gl_pathv[i] = arglist[i];
    You pass glob() a pattern, and it returns a glob_t with the filenames that matched. That's how it's supposed to work.

    But you can't just add a string to gl_pathv[]. First of all, a pattern likely matches more than one filename, so gl_pathv[i] is probably already taken. Secondly, you'd need to increase the amount of memory allocated for gl_pathv[] if you wanted to add an item to it. This could be difficult and unportable.

    I recommend that you just pass every string to glob, even if it's just a filename. If it's just a filename and contains no '?'s or '*'s, glob will still work properly and add only that one filename (assuming it exists) to the glob_t structure.

    This is a better idea than just adding the filename into the glob_t yourself for two reasons:
    • glob() will make sure that that file actually exists, rather than blindly assuming it does;
    • and your code will be more portable, because you have no way of knowing how glob() allocates the members of glob_t(), and assuming it uses malloc()/realloc() might not work.


    In short, this code should work:
    Code:
              for(i=0; i<args; i++)
              {
                   if(first_glob)
                   {
                        glob(arglist[i], GLOB_DOOFFS, NULL, &globbuf);
                        first_glob = FALSE;
                   }
                   else
                   {
                        glob(arglist[i], GLOB_DOOFFS | GLOB_APPEND, NULL, &globbuf);
                   }
              }
    (Sorry about the indentation, but you know what I mean.)

    Also see:
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Alice....
    By Lurker in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 06-20-2005, 02:51 PM
  2. Debugging question
    By o_0 in forum C Programming
    Replies: 9
    Last Post: 10-10-2004, 05:51 PM
  3. Question about pointers #2
    By maxhavoc in forum C++ Programming
    Replies: 28
    Last Post: 06-21-2004, 12:52 PM
  4. Question...
    By TechWins in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 07-28-2003, 09:47 PM
  5. Question, question!
    By oskilian in forum A Brief History of Cprogramming.com
    Replies: 5
    Last Post: 12-24-2001, 01:47 AM