Page 1 of 2 12 Last
  • Jump to page:
    #1
  1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2003
    Location
    Istanbul, TR
    Posts
    85
    Rep Power
    12

    call perl program within C


    Can we call perl programs within C

    I couldnt write a function in C for my program. But i have successfully write it in perl and it works great. I want to call this function written in perl within my C program..

    is it possible ?

    thanx for any help...
  2. #2
  3. not a fan of fascism (n00b)
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Feb 2003
    Location
    ct
    Posts
    2,756
    Rep Power
    95
    i think you can just go
    Code:
    system("/path/to/script -args");
  4. #3
  5. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,172
    Rep Power
    2222
    Also, if you need to read the output generated by the perl script, you might consider piping stdout with popen. Then whatever the script writes to stdout you can read in your program with fread as if it were from a file.
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2003
    Location
    Istanbul, TR
    Posts
    85
    Rep Power
    12
    thanks for help.. and one more question.. Can i pass a variable in the system function

    in perl you can do for exm;

    my $file = "/var/spool/mail/root";

    system("cat /dev/null > $file");

    in C how can i pass a variable in the system function is it possible?

    Thanks again in advanced for any help...
  8. #5
  9. I'm Baaaaaaack!
    Devshed God 1st Plane (5500 - 5999 posts)

    Join Date
    Jul 2003
    Location
    Maryland
    Posts
    5,538
    Rep Power
    244
    You have to create a buffer and copy the commands into it. C does not expand string variables like Perl does. You can do it with a std::string if you are in C++ or you have to allocate a char buffer (either on the stack or on the heap).

    For instance (C++):

    //presumes that fileName is a string
    std::string strSysCall = "cat /dev/null > " + fileName;
    system(strSysCall .c_str());

    In C:

    #define MAXLINELENGTH 1024 //or whatever, just be sure it is big enough!

    char buf[MAXLINELENGTH];

    strcpy(buf, "cat /dev/null > ");

    //presumes that fileName is a character array
    strcat(buf, fileName);

    system(buf);


    As mentioned before, you probably want to get feedback from your call, you should do a popen so you can read back its stdout.

    My blog, The Fount of Useless Information http://sol-biotech.com/wordpress/
    Free code: http://sol-biotech.com/code/.
    Secure Programming: http://sol-biotech.com/code/SecProgFAQ.html.
    Performance Programming: http://sol-biotech.com/code/PerformanceProgramming.html.
    LinkedIn Profile: http://www.linkedin.com/in/keithoxenrider

    It is not that old programmers are any smarter or code better, it is just that they have made the same stupid mistake so many times that it is second nature to fix it.
    --Me, I just made it up

    The reasonable man adapts himself to the world; the unreasonable one persists in trying to adapt the world to himself. Therefore, all progress depends on the unreasonable man.
    --George Bernard Shaw
  10. #6
  11. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2003
    Location
    Istanbul, TR
    Posts
    85
    Rep Power
    12
    thansk again this will solve my problem..
    .
    Mitakeet, do you remember subdirectory recursion problem we talked.. I solved it in Perl and i will call that function within C :))

    the perl code solution for the problem we talked is;

    Code:
    sub show_dir {
      my $dir = shift;
      my @subdir = ();
      my @files = ();
      
      opendir DIR, $dir || die("Can't open directory $dir");
      @files = grep { !/^\./ && !/^CVS$/} readdir DIR;
      closedir DIR;
      
      foreach my $file (@files) {
            
        if (! -d "$dir/$file" ) {
          push @pathfiles , "$dir/$file";
        }
        if (-d "$dir/$file" ) {
          push @subdir, "$dir/$file";
        }
      } #end of foreeach
      
      foreach (@subdir ) {
                &show_dir("$_");
      } 
      
      return \@pathfiles;
    }
  12. #7
  13. I'm Baaaaaaack!
    Devshed God 1st Plane (5500 - 5999 posts)

    Join Date
    Jul 2003
    Location
    Maryland
    Posts
    5,538
    Rep Power
    244
    If you want to stick with C, look up the source for the 'du' command. It is also traversing directories (correctly). My example code started with someone else's, I guess they have the same bug.

    You can also do a popen on the 'du' command and probably get exactly the same results and not have to deal with the overhead of Perl.

    My blog, The Fount of Useless Information http://sol-biotech.com/wordpress/
    Free code: http://sol-biotech.com/code/.
    Secure Programming: http://sol-biotech.com/code/SecProgFAQ.html.
    Performance Programming: http://sol-biotech.com/code/PerformanceProgramming.html.
    LinkedIn Profile: http://www.linkedin.com/in/keithoxenrider

    It is not that old programmers are any smarter or code better, it is just that they have made the same stupid mistake so many times that it is second nature to fix it.
    --Me, I just made it up

    The reasonable man adapts himself to the world; the unreasonable one persists in trying to adapt the world to himself. Therefore, all progress depends on the unreasonable man.
    --George Bernard Shaw
  14. #8
  15. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2003
    Location
    Istanbul, TR
    Posts
    85
    Rep Power
    12
    du worked great.. instead of perl i can use it..

    with -a (--all )parameter it is traversing dirs..

    [root@null] du -a cfiles

    48 cfiles/install.sh
    12 cfiles/mystat
    99 cfiles/XXX/YYY/which.pl
    4 cfiles/XXX/YYY
    0 cfiles/XXX/deneme
    8 cfiles/XXX
    80 cfiles/scripts/jdrules
    56 cfiles/scripts/cvsget
    ..........

    with a little awk

    [root@null] du -a /dir | awk '{print $2 }'

    cfiles/install.sh
    cfiles/mystat
    cfiles/XXX/YYY/which.pl
    cfiles/XXX/YYY
    cfiles/XXX/deneme
    cfiles/XXX
    cfiles/scripts/jdrules
    cfiles/scripts/cvsget

    thanks all for advices...
  16. #9
  17. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2003
    Location
    Istanbul, TR
    Posts
    85
    Rep Power
    12
    One more question.. I wrote a test program to use popen as you recommended.

    When i use in the below code

    popen("du -a /home/jazzy/cfiles | awk '{print $2}'","w");

    it works great i can see the results with no error but

    when i use in the below code

    popen("ls -l","w");

    it gives an error message at the last line like
    -rw-r--r-- 1 jazzy jazzy 274 Aug 22 17:40 Makefile
    -rw-r--r-- 1 jazzy jazzy 3745 Aug 25 19:33 deploy.c
    -rw-r--r-- 1 jazzy jazzy 183 Aug 25 14:56 deploy.h
    -rw-r--r-- 1 jazzy jazzy 1003 Aug 25 19:41 main.c
    -rwxr-xr-x 1 root root 10541 Aug 26 16:43 test
    -rw-r--r-- 1 root root 436 Aug 26 16:43 test.c
    Broken pipe

    i dont use ls -l in my program but coincidentally i put ls -l there and it gave me broken pipe.. i only wonder what is the problem when i put ls -l there..

    the code is below;

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int main() {
    
            char *c;
            int n,i;
            FILE *stream;
    
            stream = popen("du -a /home/jazzy/cfiles | awk '{print $2}'","w");
    
            if (!stream) {
                    fprintf (stderr, "Error occured.\n");
                    return EXIT_FAILURE;
            }
    
            for (i = 0; i < 4; i++) {
                    fprintf (stream, "%d\n", i);
            }
    
            if (ferror (stream)) {
                    fprintf (stderr, "Output to stream failed.\n");
                    exit(EXIT_FAILURE);
            }
    
    
            pclose (stream);
            return 0;
    }
  18. #10
  19. I'm Baaaaaaack!
    Devshed God 1st Plane (5500 - 5999 posts)

    Join Date
    Jul 2003
    Location
    Maryland
    Posts
    5,538
    Rep Power
    244
    Why are you trying to write to your pipe? Shouldn't they be read(only)? Maybe that is your problem.

    My blog, The Fount of Useless Information http://sol-biotech.com/wordpress/
    Free code: http://sol-biotech.com/code/.
    Secure Programming: http://sol-biotech.com/code/SecProgFAQ.html.
    Performance Programming: http://sol-biotech.com/code/PerformanceProgramming.html.
    LinkedIn Profile: http://www.linkedin.com/in/keithoxenrider

    It is not that old programmers are any smarter or code better, it is just that they have made the same stupid mistake so many times that it is second nature to fix it.
    --Me, I just made it up

    The reasonable man adapts himself to the world; the unreasonable one persists in trying to adapt the world to himself. Therefore, all progress depends on the unreasonable man.
    --George Bernard Shaw
  20. #11
  21. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2003
    Location
    Istanbul, TR
    Posts
    85
    Rep Power
    12
    when i write r no results return.. if i write w then i can see the results..

    [root@null] ./test
    [root@null]
  22. #12
  23. I'm Baaaaaaack!
    Devshed God 1st Plane (5500 - 5999 posts)

    Join Date
    Jul 2003
    Location
    Maryland
    Posts
    5,538
    Rep Power
    244
    Open your pipe with read permissions!

    stream = popen("du -a /home/jazzy/cfiles | awk '{print $2}'","r");

    My blog, The Fount of Useless Information http://sol-biotech.com/wordpress/
    Free code: http://sol-biotech.com/code/.
    Secure Programming: http://sol-biotech.com/code/SecProgFAQ.html.
    Performance Programming: http://sol-biotech.com/code/PerformanceProgramming.html.
    LinkedIn Profile: http://www.linkedin.com/in/keithoxenrider

    It is not that old programmers are any smarter or code better, it is just that they have made the same stupid mistake so many times that it is second nature to fix it.
    --Me, I just made it up

    The reasonable man adapts himself to the world; the unreasonable one persists in trying to adapt the world to himself. Therefore, all progress depends on the unreasonable man.
    --George Bernard Shaw
  24. #13
  25. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2003
    Location
    Istanbul, TR
    Posts
    85
    Rep Power
    12
    yes i made it as you said but when i change it to "r"

    stream = popen("du -a /home/jazzy/cfiles | awk '{print $2}'","r");

    no results return.. interesting!!!

    stream = popen("du -a /home/jazzy/cfiles | awk '{print $2}'","w");

    no problem with this it works great this way. I can see all files dirs and subdirs with no error.

    ----------------

    stream = popen("ls -l","w");
    it shows the result perfect but at the end of the result also an error occurs (Broken pipe)

    when i turned it to "r" then again no results returns

    It is so interesting... Now we have 2 problems

    1)we cant use "r" option.. if we use it there is no result...
    2)why it returns Broken pipe error when we use popen("ls","w") or popen("ls -l","w")
  26. #14
  27. I'm Baaaaaaack!
    Devshed God 1st Plane (5500 - 5999 posts)

    Join Date
    Jul 2003
    Location
    Maryland
    Posts
    5,538
    Rep Power
    244

    Try this...


    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    #include <vector>
    #include <string>
    
    #define MAXLINELENGTH 1024
    
    int main(int argc, char * argv[]) {
        char input[MAXLINELENGTH];
        FILE *stream;
        std::vector < std::string > myVect;
        int len;
    
        if (argc != 2){
            fprintf(stderr, "Usage: %s <type>\n", argv[0]);
            fprintf(stderr, "\tIf type = 1 then 'du .' else 'ls -l'\n");
            exit(1);
        }
        if (atoi(argv[1]) == 1){
            stream = popen("du -a . | awk '{print $2}'","r");
        }else{
            stream = popen("ls -l", "r");
        }
    
        if (!stream) {
            fprintf (stderr, "Error occured.\n");
            return EXIT_FAILURE;
        }
        while (fgets(input, MAXLINELENGTH, stream)){
            len = strlen(input);
            if (input[len-1] == '\n')
                input[len-1] = '\0';
            myVect.push_back(input);
        }
    
        pclose (stream);
    
        std::vector < std::string >::iterator myIterator = myVect.begin();
        while (myIterator != myVect.end()){
            printf("%s\n", myIterator->c_str());
            myIterator++;
        }
        return 0;
    }

    My blog, The Fount of Useless Information http://sol-biotech.com/wordpress/
    Free code: http://sol-biotech.com/code/.
    Secure Programming: http://sol-biotech.com/code/SecProgFAQ.html.
    Performance Programming: http://sol-biotech.com/code/PerformanceProgramming.html.
    LinkedIn Profile: http://www.linkedin.com/in/keithoxenrider

    It is not that old programmers are any smarter or code better, it is just that they have made the same stupid mistake so many times that it is second nature to fix it.
    --Me, I just made it up

    The reasonable man adapts himself to the world; the unreasonable one persists in trying to adapt the world to himself. Therefore, all progress depends on the unreasonable man.
    --George Bernard Shaw
  28. #15
  29. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2003
    Location
    Istanbul, TR
    Posts
    85
    Rep Power
    12
    i am so sorry.. i have found my fault when i looked your c++ code.. stupid me!! augghh..

    look at my code i wrote

    fprintf (stream, "%d\n", i); this is wrong.. %d a very stupid mistake.. Here i am writing to stream here not getting data from stream.. i think i made this mistake cause i am so sleepy

    the real code in C

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int main() {
    
            char *c;
            FILE *stream;
    
            stream = popen("du -a .  | awk '{print $2}'","r");
    
            if (!stream) {
                    fprintf (stderr, "Error occured.\n");
                    return EXIT_FAILURE;
            }
    
           /* i have to use fgets here not fprintf cause i am reading from stream */
            while (fgets(c, 512, stream)){
                    printf("%s",c);
            }
    
            if (ferror (stream)) {
                    fprintf (stderr, "Error reading stream.\n");
                    exit(EXIT_FAILURE);
            }
    
            pclose (stream);
            return 0;
    }
    thanx...
Page 1 of 2 12 Last
  • Jump to page:

IMN logo majestic logo threadwatch logo seochat tools logo