#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2004
    Posts
    24
    Rep Power
    0

    CreateProcess and '>' redirection of child process stdout


    Hi,

    I've written some code to create a child process and run it off for a certain time interval, then kill it.

    This is mostly done, however I've having trouble getting the output from the child (stdout that is) redirected to a physical log file, before I used popen and did it that way - but using CreateProcess it seems that simply feeding in a string with 'filename > output.txt' does not work. :(

    Does anyone know how I could simply set this up to work? I've seen lots of C++ examples (MSDN etc) and they seem very complicated for what I want, some don't even seem to work even with a C++ compiler.

    I assume it will have to do with pipes but if anyone could provide a simplistic solution I would be mucho appreciative!

    My code is below.

    Thanks,
    Rob

    Code:
    #include <stdio.h>
    #include <string.h>
    #include <time.h>
    #include <sys/types.h>      
    #include <stdlib.h>  
    #include <signal.h> 
    #include <time.h>
    #include <unistd.h>
    
    //#ifdef __WINDOWS__
    #include <windows.h>
    //#endif
    
    void mSleep(unsigned int numseconds);
    char getsTime(char *timestamp);
    void readFile();
    void errorCheck();
    void runCommands();
    void sortstrarr(void *array, unsigned n);
    static int cmpr(const void *a, const void *b);
    static int binsearch(char *str[], int max, char *value);
    void sort_string (char *s);
    void WinCommands();
    void WinCheckCommands();
    
    char *cCommandarray[5000];
    char *cTimearray[5000];
    
    int main() 
    {    
      readFile();   
      //WinCheckCommands(); 
      WinCommands();
    }
    
    void mSleep(unsigned int numseconds) //Sleep function to sleep the main thread
    {
      //#ifdef __WINDOWS__
        Sleep(numseconds * 1000);
      //#endif
    
      /*#ifdef __LINUX__
        sleep(numseconds);
      #endif
      
      #ifdef __UNIX__
        sleep(numseconds);
      #endif*/
    }
    
    void readFile()
    {
      FILE *f;
      char *s;
      char q[1000];
      int arr_counter = 0;
      int arr_counter2 = 0;
      int x2;
      
      f=fopen("config.cfg","r");
      
      for(x2 = 0;x2 < sizeof cCommandarray / sizeof cCommandarray[0];x2++)
      {
        cCommandarray[x2] = '\0';    
        cTimearray[x2] = '\0';  
      }
      
      while ((s = fgets(q,1000,f)) !=NULL)
      {     
        char *tmpptr = (char *)malloc(strlen(s) +1); //Make room in memory
    
        strcpy(tmpptr, s); //Copy string out of memeory   
            
        strtok(tmpptr,"["); //Catch delimeters
              
        cTimearray[arr_counter2++] = strtok (NULL, "]");
            
        cCommandarray[arr_counter++] = tmpptr; //Add it to the array
      }   
      
      #ifdef __WINDOWS__
      unlink("config.cfg");
      #endif
    
      fclose(f);
    }
    
    void WinCheckCommands()
    {
      int x;
      int passcount = 0;
      int failcount = 0;
      char *commandstring;
      char swaparray[256];
      
      PROCESS_INFORMATION pi;
      STARTUPINFO si;
      HANDLE hProcess; 
    
      memset(&si,0,sizeof(si));
      si.cb = sizeof(si);
        
      for(x = 0;x < sizeof cCommandarray / sizeof cCommandarray[0];x++)
      {       
        if(cCommandarray[x] == NULL || cCommandarray[x] == '\0')
        {           
          break;        
        } 
        
        CreateProcess(NULL, cCommandarray[x], 0, 0, 0, 0, 0,0,&si,&pi);
        
        commandstring = strcpy(swaparray, cCommandarray[x]);
        
        strtok(commandstring, " ");
        
        hProcess = pi.hProcess;
        
        printf("\n");
        
        printf("Test %d: Running Test %s:\n", x + 1, commandstring); 
        
        if(pi.dwProcessId == 0)
        {
          printf("Test Failed!\n"); 
          failcount = failcount + 1;                 
        }
        else
        {
          mSleep(atoi(cTimearray[x]));
          TerminateProcess(hProcess, 0);  
          CloseHandle(hProcess); 
          passcount = passcount + 1;
          printf("Test Passed!\n");
        }  
      }  
      
      printf("\n");
      
      printf("File Consistency Check Results:\n");
      printf("Tests Passed: %d\n", passcount);
      printf("Tests Failed: %d\n", failcount);
    
      printf("\n");
      
      printf("Pre-Checks Complete!\n");     
    }
    
    void WinCommands()
    {
      int a;
      int n;
      int x2;
      int passcount = 0;
      int failcount = 0;
      char *commandstring;
      char *plaincommandstring;
      char *whitespaceremoval;
      char *time;
      char swaparray[256];
      char swaparray2[256];
      char swaparray3[256];
      char swaparray4[256];
      char swaparray5[256];
      char swaparray6[256];
      char runningtime[256];
      
      char pipe[] = " > ";
      char text[] =".txt";
      char bracket[] ="[";
      char endbracket[] ="-second-run]";
      
      
      PROCESS_INFORMATION pi;
      STARTUPINFO si;
      HANDLE hProcess; 
     
      memset(&si,0,sizeof(si));
      si.cb = sizeof(si);
        
      for(x2 = 0;x2 < sizeof cCommandarray / sizeof cCommandarray[0];x2++)
      {       
        if(cCommandarray[x2] == NULL || cCommandarray[x2] == '\0')
        {           
          break;        
        } 
        
        getsTime(runningtime);
        
        commandstring = strcpy(swaparray2, cCommandarray[x2]);
        
        strtok(commandstring, " ");
        
        whitespaceremoval = strcpy(swaparray3, cCommandarray[x2]);
        
        strtok(whitespaceremoval, " ");
        
        time = strcpy(swaparray4, cTimearray[x2]);
        
        strncat(commandstring, pipe, strlen(pipe)); 
        
        strncat(whitespaceremoval, runningtime, strlen(runningtime));
          
        strncat(whitespaceremoval, bracket, strlen(bracket));
           
        strncat(whitespaceremoval, time, strlen(time));       
           
        strncat(whitespaceremoval, endbracket, strlen(endbracket));
    
        strncat(whitespaceremoval, text, strlen(text)); 
        
        strncat(commandstring, whitespaceremoval, strlen(whitespaceremoval));
        
        a = 0;
        
        for(n=0;whitespaceremoval[n]!='\0';n++) //Whitespace removal loop
        {       
          if(whitespaceremoval[n] != ' ' && whitespaceremoval[n] != '\t') //Check for whitespace
          {
            swaparray5[a++] = whitespaceremoval[n]; //dest array equals removewhitespace without the spaces
          }
          swaparray5[a]= 0;
        }
          
        HANDLE old = GetStdHandle(STD_OUTPUT_HANDLE);
        SetStdHandle(STD_OUTPUT_HANDLE, "boo.txt");
        CreateProcess(NULL, commandstring, 0, 0, TRUE, 0, 0,0,&si,&pi);
        SetStdHandle(STD_OUTPUT_HANDLE, old);
        
        plaincommandstring = strcpy(swaparray6, cCommandarray[x2]);
        
        strtok(plaincommandstring, " ");
        
        hProcess = pi.hProcess;
        
        printf("\n");
        
        printf("Test %d: Running Test %s:\n", x2 + 1, plaincommandstring); 
        
        printf("%s\n", commandstring);
        
        if(pi.dwProcessId == 0)
        {
          printf("Test Failed!\n"); 
          failcount = failcount + 1;                 
        }
        else
        {
          mSleep(atoi(cTimearray[x2]));
          TerminateProcess(hProcess, 0);  
          CloseHandle(hProcess); 
          passcount = passcount + 1;
          printf("Test Passed!\n");
        }  
      }  
    }
    
    char getsTime(char *timestamp) //Get the localtime so it can be appended to a log
    {
      time_t mytime;   
      struct tm *mytm;   
      mytime=time(NULL);   
      mytm=localtime(&mytime);   
      memset(timestamp, ' ', 100);
      strftime(timestamp,100,"-%d.%b.%Y@%Hh%Mm%Ss",mytm);   
    }
  2. #2
  3. No Profile Picture
    Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Oct 2007
    Posts
    921
    Rep Power
    536
    "filename > output.txt" relies on a command shell being executed, and that command shell running filename and redirecting its output. CreateProcess does not execute a command shell.

    Google, when given the string "createprocess redirect" gave me this as the first hit. There's a lot more in the sample than you need; with a little thought and experimentation, you'll be able to work out what you don't need within this sample.
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2004
    Posts
    24
    Rep Power
    0
    Originally Posted by LittleGrin
    "filename > output.txt" relies on a command shell being executed, and that command shell running filename and redirecting its output. CreateProcess does not execute a command shell.

    Google, when given the string "createprocess redirect" gave me this as the first hit. There's a lot more in the sample than you need; with a little thought and experimentation, you'll be able to work out what you don't need within this sample.
    I have looked over that example, and did try to implement some of it into my program - alas I completely failed and spent till 3 in morning trying to get it to work, in the end I just deleted it all because it was a mess.

    I think I'm probably missing something rather obvious but for the life of me I just can't seem to work out how to get it to work. :(

    Thanks for your reply, I'll have another crack at it and see how far I get. :)
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Oct 2007
    Posts
    921
    Rep Power
    536
    Ah, well. View this as a real-life learning exercise. A lot of examples you find on the net (or from someone else) include some things you need and some you don't. The trick is working out systematically how to extract the bits you need from those you don't. The important thing is to systematically take your time (eg look at things one line at a time) rather than just hacking things at random.

IMN logo majestic logo threadwatch logo seochat tools logo