1

is there a simple way to directly use the find command and get the path as a return
rather than something like this

            sprintf(inputPath, "find -name %s",fileNameList[i]);
            fpop=popen(inputPath, "r");
            fgets(inputPath, sizeof(inputPath)-1, fpop) ;
            pclose(fpop);

or some similar command which when executed through c returns the path ?

Aditya P
  • 1,862
  • 5
  • 28
  • 39
  • 1
    No, the return value is the exit value from the invocation of find(1); you're stuck parsing the output. – tbert Feb 10 '12 at 11:52
  • I found: http://stackoverflow.com/questions/671461/how-can-i-execute-external-commands-in-c-linux – Peter Feb 10 '12 at 11:53

2 Answers2

2

I suggest using nftw() to do the find yourself, it's not that much to code in C. Simple proof of concept (compile with gcc test.c -o test)

#define _XOPEN_SOURCE 500
#include <ftw.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>

static int    s_argc;
static char** s_argv;

static int
display_info(const char *fpath, const struct stat *sb,
             int tflag, struct FTW *ftwbuf)
{
    int matched = 0, i;
    for (i=0; i<s_argc; i++)
    {
        const char* match = strstr(fpath, s_argv[i]);
        matched |= (match && *match 
                && (strlen(match) == strlen(s_argv[i]))           // matches at end
                && ((match == s_argv[i]) || (match[-1] == '/'))); // is full basename
    }

    if (matched)
    {
        printf("%-3s %2d %7jd   %-40s %d %s\n",
                (tflag == FTW_D) ?   "d"   : (tflag == FTW_DNR) ? "dnr" :
                (tflag == FTW_DP) ?  "dp"  : (tflag == FTW_F) ?   "f" :
                (tflag == FTW_NS) ?  "ns"  : (tflag == FTW_SL) ?  "sl" :
                (tflag == FTW_SLN) ? "sln" : "???",
                ftwbuf->level, (intmax_t) sb->st_size,
                fpath, ftwbuf->base, fpath + ftwbuf->base);
    }

    return 0;           /* To tell nftw() to continue */
}

int
main(int argc, char *argv[])
{
    s_argc = argc-1;
    s_argv = argv+1;

    int flags = FTW_DEPTH | FTW_PHYS;

    if (nftw(".", display_info, 20, flags) == -1)
    {
        perror("nftw");
        exit(EXIT_FAILURE);
    }
    exit(EXIT_SUCCESS);
}

For simplicity I start the search from the current working directory ("."). Used like this:

./test target.txt b c

prints nothing (assuming you don't have such files existing)

mkdir -pv a/b/c/{d,e,f,g}/subdir
touch a/b/c/{e,g}/subdir/target.txt
./test target.txt b c

now prints:

f    6       0   ./a/b/c/e/subdir/target.txt              17 target.txt
f    6       0   ./a/b/c/g/subdir/target.txt              17 target.txt
dp   3       0   ./a/b/c                                  6 c
dp   2       0   ./a/b                                    4 b

You can see the ordering is depth-first but that is easily changed by tweaking the flags to nftw

sehe
  • 374,641
  • 47
  • 450
  • 633
  • +1 this is pretty neat, i am afraid i was asking something simpler in terms of some command /syntax i missed out that returns the path as string when called. it was clarified by tbert . – Aditya P Feb 10 '12 at 12:30
0

Can you try dup or dup2 calls to achieve this ?