Thread: Need help with piping and signals

  1. #1
    Registered User
    Join Date
    Dec 2009
    Posts
    11

    Need help with piping and signals

    My program has two child processes and a parent. Every time the first child program gets a SIGINT signal, it's supposed to pipe the message "Record created" to it's parent, and then the parent is supposed to write that message into a specific file.

    My problem is that it only does it the first time and doesn't do it anymore afterwards, so when it gets the first SIGINT, it pipes and writes properly, but every SIGINT afterwards, it doesn't write the message for some reason.

    Here's the main for my program.

    Code:
    void main(void)
    {
            sigignore(SIGINT);
            sigignore(SIGQUIT);
            sigset(SIGTSTP);
            int child1, child2;     //the two forked processes
            int fd[2];              //
            char reader[150];      //buffer for the pipe
            FILE *logfile;
    
            int bytes;
            pipe(fd);
    
            child1 = fork();        //forking for the first child
    
            if (child1 > 0)         //checking to fork a parent and not a child
            {
                    child2 = fork();        //second child is created
            }
    
            pid_t pid;
            int status;
    
            if (child1 == 0)
            {
                    sigset(SIGINT, got_int);
                    write(fd[1], "Record created", (strlen("Record created")+1));
                    for(;;);
                    _exit(1);
            }
    
            if (child2 == 0)
            {
                    if(sigset(SIGQUIT, got_quit) == 1) {
                    write(fd[1], "Record found", (strlen("Record found")+1));
                    }
                    else
                    write(fd[1], "Record not found", (strlen("Record not found")+1));
                    for(;;);
                    _exit(2);
            }
    
            else {
                    logfile = fopen("a1.log", "a+b");
                    bytes = read(fd[0], reader, sizeof(reader));
    
                    fprintf(logfile, "%s\n", reader);
                    fclose(logfile);                                        //writing to the logfile
            }
                    pid = wait(&status);    //two waits since there's two child processes
                    pid = wait(&status);
    }
    The important code is the child1 and the parent program which is this part

    Code:
     else {
                    logfile = fopen("a1.log", "a+b");
                    bytes = read(fd[0], reader, sizeof(reader));
    
                    fprintf(logfile, "%s\n", reader);
                    fclose(logfile);                                        //writing to the logfile
            }
    Any suggestions on how I should modify it?

  2. #2
    Registered User
    Join Date
    Oct 2006
    Location
    Canada
    Posts
    1,243
    but every SIGINT afterwards, it doesn't write the message for some reason.
    I imagine your signal handle functions are "got_int", etc., which you haven't given so we can only guess they're contents. If I remember correctly, if you set the action to some custom function, and the signal occurs, and the function is called, subsequent actions of the same type will result in the default behaviour. So, in short, "re-install" the signal handler in the signal handler function itself, probably the last line in the function.

    I haven't really gone through all of your code, but the quote above is what caught my attention so that's what I've focused on.

  3. #3
    Registered User
    Join Date
    Dec 2009
    Posts
    11
    Quote Originally Posted by nadroj View Post
    I imagine your signal handle functions are "got_int", etc., which you haven't given so we can only guess they're contents. If I remember correctly, if you set the action to some custom function, and the signal occurs, and the function is called, subsequent actions of the same type will result in the default behaviour. So, in short, "re-install" the signal handler in the signal handler function itself, probably the last line in the function.

    I haven't really gone through all of your code, but the quote above is what caught my attention so that's what I've focused on.

    I don't think the signal handle functions are relevant to this problem, but anyway I had the 're-install' in there but it was the first line of the function, I changed it to the last line, and I don't think it did anything, it still only prints it one time.

  4. #4
    Registered User
    Join Date
    Oct 2006
    Location
    Canada
    Posts
    1,243
    As I said, I only looked at that statement, which immediately raised flags with me and since, as I said, you didn't post that code we could only guess what those functions do. Post your complete code and I'll try it out.

  5. #5
    Registered User
    Join Date
    Dec 2009
    Posts
    11
    Code:
    void got_int(int sig_num) //SIGINT handler function to add to the database
    {
            char name[20];  //items for the database
            int number;
            char address[30];
    
            printf("Enter a name for the database\n");
            scanf("%s", &name);
    
            FILE *file;             //the database file
            file = fopen("a1.db", "a+b");   //opening the file
            fprintf(file, "%s\n", name);    //writing the items to the database
            fclose(file);
            sigset(SIGINT, got_int);
    }
    This one writes to a file.

    Code:
    int got_quit(int sig_num)       //SIGQUIT handler function to search the database
    {
    
            char searchName[20];
            FILE *datafile = fopen("a1.db", "r");
    
            printf("Enter the name to be searched for in the database.");
            scanf("%s", searchName);
            int found = 0;
       
            char tmp[256] = {0x0};
            while (datafile != NULL && fgets(tmp, sizeof(tmp), datafile) !=NULL)
            {
                    if (strstr(tmp, searchName))
                    {
                            found++;
                    }
            }
     
            if (datafile!=NULL)
            fclose(datafile);
    
    if (found > 0)
    {
    printf("yes");
    return 1;
    }
    else
    printf("no");
    return 0;
    sigset(SIGQUIT, got_quit);
    }
    that one searches from a file
    Last edited by busdude; 03-05-2010 at 04:41 PM.

  6. #6
    Registered User
    Join Date
    Oct 2006
    Location
    Canada
    Posts
    1,243
    First, that isn't the complete code! We would have to take your 3 blocks of code, merge them, add all of the "#include"s, where you could have just posted the "complete" code. This is why I emphasized "complete" in my previous post. Remember we are here to help for free, so you probably want us to do least work as possible. Otherwise we won't help, this just makes sense.

    Every time the first child program gets a SIGINT signal, it's supposed to pipe the message "Record created" to it's parent, and then the parent is supposed to write that message into a specific file.

    My problem is that it only does it the first time and doesn't do it anymore afterwards, so when it gets the first SIGINT, it pipes and writes properly, but every SIGINT afterwards, it doesn't write the message for some reason.
    There is one write in each of the 2 children, and one read in the parent. So, say child1 executes, it writes to the pipe, and the parent reads it. Then child2 writes to the pipe, which is useless because it is never read from again.

    Maybe you want the 2 child "write" stuff in the function handlers? Also, you probably want the parent to loop the "read" stuff, because, again, it only reads from the pipe once.

    If you want something to happen each time the given interrupt happens, you, of course, have to write that logic in the function handler. This is, again, why we needed to see the function handlers themselves.
    Last edited by nadroj; 03-05-2010 at 05:38 PM.

  7. #7
    Registered User
    Join Date
    Dec 2009
    Posts
    11
    so what kind of loop should I try, an infinite one like for (;; or some sort of while loop?

  8. #8
    Registered User
    Join Date
    Oct 2006
    Location
    Canada
    Posts
    1,243
    The child1, child2 blocks should probably just have the for loop that does nothing. Actually, you should probably put a "sleep" or other similar call in each of the for loops, otherwise you're hogging up the CPU and wasting a lot of cycles, making the program run slower. If you want to write to the pipe each time signal X is received, then simply put that code in the function handler for that signal. You may be overthinking this, and confusing yourself.

    Also, if you want to write to the pipe in any function besides main you have to pass around the fd. You probably have to make it global, since those function handlers don't accept other arguments.

Popular pages Recent additions subscribe to a feed