Thread: waitpid behaving strange...

  1. #1
    Registered User
    Join Date
    Nov 2011
    Posts
    19

    waitpid behaving strange...

    hi, my waitpid is behaving really strange can u see what im dooing wrong?
    (when my background processes are finished it prints out pid as 1 instead of the real pid and it never does the else part)

    Code:
        while(pid = waitpid(-1, &status, WNOHANG) > 0){ 
            if (WIFEXITED(status)){
                printf("bakgrundsprocess med pid: %i har avslutats!\n", pid);
            }
            else {
                printf("bakgrundsprocess med pid: %i lever!\n", pid);
            }
            
        }
    ps. do you need to see my whole program?
    ps2. thanks for helping me I really appreciate it!
    Last edited by mattholm; 11-28-2011 at 12:36 PM.

  2. #2
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Your whole program would be helpful so I can compile and test myself. It would also be helpful if you told us what compiler and OS you're using (and version). It could be caused by pid_t not working properly with the %i format in printf. Do you get any errors/warnings? Are you compiling with the warning level turned up to the max.

  3. #3
    Registered User
    Join Date
    Nov 2011
    Posts
    19
    ok, this is all of my code, im working in ubuntu and compiling by writing "gcc -o 23 23.c" in the shell. i dont get any warnings but i dont know how to turn up the warning lvl.

    thanks for helping me!

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #define MAXSIZE 70
    #include <sys/types.h>
    #include <unistd.h>
    #include <string.h>
    #include <signal.h>
    #include <sys/wait.h>
    
    int main()
    {
    char *inputString;        /*strängen som användaren matar in*/
    inputString = malloc(MAXSIZE);    
    int pid;
    char word2[20] = {"exit"};    /*för att kolla om man matade in kommandot exit*/
    char word1[20] = {"cd"};    /*för att kolla om man matade in kommandot cd*/
    int i = 0;
    int status;
    int x = 1;
    int count;            /*används för att hacka upp strängen som användaren matar in*/                
    char * argv[5];
    int return_value;            /*returvärde för systemanrop*/
    char * home_d = malloc(MAXSIZE);    /*hemkatalogen*/
    char * work_d = getenv("HOME");        /*arbetskatalogen*/
    char * endcheck;            /*Variabel för att få reda på adress för möjligt &-tecken som anger om det är en bakgrundsprocess*/
    int bgpro;                /*sätts till 1 om det är en bakgrundsprocess (annars 0)*/
    struct timeval tv1, tv2; /*gettimeofday, så att man kan så hur länge en process har jobbat*/
    int time;
    
    home_d = strcpy(home_d, work_d);    /*sparar home directory så att den ej ändras när man ändrar working directory*/
    return_value = chdir(work_d);    /*börjar med att gå till home_d*/
    if(return_value==-1){
        perror("Error in changing to home directory");}    /*om det inte funkade*/                    
    
    /*sigignore(SIGINT);*/    /*så att man ej kan avsluta med det klassiska control+c*/                    
    pid = 0;
    while (1){
        bgpro = 1;
           printf("%s>",work_d);
        printf("$ ");
          fgets(inputString, MAXSIZE, stdin);
           int len = strlen(inputString);
           if (inputString[len-1] == '\n') {
                  inputString[len-1] = '\0';
           }
    
    /*hacka upp strängen*/   
           argv[0] = (char *)strtok (inputString," \n");        /*det första värdet i listan av parametrar*/
           count = 0;                            /*en variabel som räknar antalet...*/
    
    /*WHAT IS WRONG WITH THIS ONE???*/    
        if(pid = waitpid(-1, &status, WNOHANG) > 0){ 
            if (WIFEXITED(status)){
                printf("bakgrundsprocess med pid: %i har avslutats!\n", pid);
            }
        }
    /*hacka upp strängen forts...*/
           while (argv[count] != NULL){                    /*hackar upp strängen*/
                count++;
                argv[count] = (char *)strtok (NULL, " \n");
           }
           argv[count] = 0;                         /*Den sista parametern blir noll för att signalera att listan är slut*/
           if (argv[0] == NULL){                    /*om man inte skriver något så startar whileloopen om igen*/
            continue; 
        }
    /* exit */
           if(strcmp(argv[0],word2) == 0){
            printf("exiting\n");     
            exit(0);
           }
    
    /* cd */
           else if(strcmp(argv[0],word1) == 0){ 
            return_value = chdir(argv[1]);            /*byter dir*/
            if (return_value==0){                /*om det gick bra*/
                if (strcmp(argv[1],"..") == 0){
                    printf("du backar ett steg\n"); 
                    endcheck = (char *) strrchr(work_d,'/');
                        *endcheck = '\0';
                }        
                else {
                    printf("du vill till: %s\n", argv[1]);
                    work_d = strcat(work_d,"/");
                        work_d = strcat(work_d,argv[1]);
                }
            }    
            else{
            /*om man angett en ogiltig sökväg*/
                printf("Mappen finns inte eller så har du stavat fel.\n");
                    return_value = chdir(home_d);
                work_d = strcpy(work_d,home_d);
            }    
           }
    
    /*skapar en barnprocess*/
           else{
            endcheck = (char *) strrchr(argv[0],'&');
            if (endcheck==NULL){
                bgpro = 0;
                }
            else{
                bgpro = 1;
                *endcheck='\0';    
                            
            }
            pid = fork();          
               if ( pid == 0 ){ 
            /* child-process code */
                sleep(5);
                     return_value = execvp(argv[0], argv);
                printf("har gjort execvp/barnet\n");
                if(return_value == -1){
                    printf("Kommandot finns ej\n");
                }
            exit(0);
            }
               else if ( pid > 0){ 
            /* parent-process code */                
                if (bgpro==0){
                    printf("skapar en förgrundsprocess med pid: %i\n", pid);
                    return_value = gettimeofday(&tv1, NULL);
                    if( -1 == return_value ){        /* felkontroll */
                           perror( "gettimeofday() misslyckades" );
                        exit( 1 ); 
                    }
                    waitpid(-1, &status, 0);
                    return_value = gettimeofday(&tv2, NULL);
                    if( -1 == return_value ){        /* felkontroll */
                           perror( "gettimeofday() misslyckades" );
                        exit( 1 ); 
                    }
                    time = tv2.tv_usec - tv1.tv_usec;
                    printf("Processen med pid: %i är nu död, den levde i %d microsekunder.\n", pid,time);
                }            
                else{
                    printf("skapar en bakgrundsprocess med pid: %i\n", pid);                        
                }
            }
    
            else /* if (pid < 0) */
            { /* SYSTEM ERROR */}
        }    
    }
    return 0;
    }
    
    /* 
    Frågor:
    - statistikutskrifter är vilka processer som terminerats med processid och hur länge de har arbetat.
    plan 8 c hissen 2 svata brevlådor, elektronik
    */

  4. #4
    Registered User
    Join Date
    Nov 2011
    Posts
    19
    forgot to say I did a minor change to it but it just keeps printing out the number 1.

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > while(pid = waitpid(-1, &status, WNOHANG) > 0)
    Look up your precedence table - you have a boolean expression returning 0 or 1

    ie
    while(pid = (waitpid(-1, &status, WNOHANG) > 0))

    You want this
    while((pid = waitpid(-1, &status, WNOHANG)) > 0)
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  6. #6
    Registered User
    Join Date
    Nov 2011
    Posts
    19
    Thank you!

  7. #7
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    For gcc, use the -Wall flag to enable all warnings:

    Code:
    $ gcc -Wall -o waitpid waitpid.c
    waitpid.c: In function ‘main’:
    waitpid.c:52: warning: suggest parentheses around assignment used as truth value
    waitpid.c:121: warning: implicit declaration of function ‘gettimeofday’
    waitpid.c:19: warning: unused variable ‘x’
    waitpid.c:17: warning: unused variable ‘i’
    That error on line 52 is your problem.
    Code:
    if(pid = waitpid(-1, &status, WNOHANG) > 0){
    Read this link C Operator Precedence Table. Note that the > has higher precedence, so it happens first. You can imagine parentheses around the (waitpid > 0) part, so you assign the truth value of that to pid, and since it's positive in this case, the expression is true, and thus you get a 1. I prefer putting the assignment outside the if, in part to prevent such errors:
    Code:
    pid = waitpid(-1, &status, WNOHANG);
    if(pid > 0){

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. waitpid() non-blocking fork
    By codevyper in forum C Programming
    Replies: 5
    Last Post: 06-21-2011, 04:05 PM
  2. help with waitpid()
    By kotoko in forum C Programming
    Replies: 1
    Last Post: 09-28-2008, 01:23 PM
  3. fprintf behaving strangely
    By cwmccart in forum C++ Programming
    Replies: 6
    Last Post: 07-17-2008, 09:56 AM
  4. Printf... behaving Strange...
    By vsriharsha in forum C Programming
    Replies: 3
    Last Post: 04-02-2002, 02:38 AM
  5. while loop not behaving properly.
    By Dreamerv3 in forum C++ Programming
    Replies: 20
    Last Post: 01-08-2002, 05:51 PM