Thread: Handling I/O redirections in my shell.

  1. #16
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by CornedBee View Post
    That's where "SignalHandler" comes from. Bottom line: don't cast at all. Unless you really need to store the old handler, don't use this type explicitly at all.
    Or just use the type void (*)(int)

  2. #17
    Registered User
    Join Date
    Apr 2006
    Location
    Beirut, Lebanon
    Posts
    20
    Quote Originally Posted by CornedBee View Post
    That's where "SignalHandler" comes from. Bottom line: don't cast at all. Unless you really need to store the old handler, don't use this type explicitly at all.
    But then i get this:
    warning: assignment makes integer from pointer without a cast
    My handler returns void and takes an int parameter.

  3. #18
    C++ Developer XSquared's Avatar
    Join Date
    Jun 2002
    Location
    Ontario, Canada
    Posts
    2,718
    Which compiler are you using?
    Naturally I didn't feel inspired enough to read all the links for you, since I already slaved away for long hours under a blistering sun pressing the search button after typing four whole words! - Quzah

    You. Fetch me my copy of the Wall Street Journal. You two, fight to the death - Stewie

  4. #19
    Registered User
    Join Date
    Apr 2006
    Location
    Beirut, Lebanon
    Posts
    20
    gcc 3.4.2

  5. #20
    C++ Developer XSquared's Avatar
    Join Date
    Jun 2002
    Location
    Ontario, Canada
    Posts
    2,718
    For me, removing the explicit cast and changing the signature of handle_ctl_c to be "void handle_ctl_c()" let your sample code compile fine on gcc 4.1.2.
    Naturally I didn't feel inspired enough to read all the links for you, since I already slaved away for long hours under a blistering sun pressing the search button after typing four whole words! - Quzah

    You. Fetch me my copy of the Wall Street Journal. You two, fight to the death - Stewie

  6. #21
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by sbho View Post
    But then i get this:
    warning: assignment makes integer from pointer without a cast
    My handler returns void and takes an int parameter.
    Assignment? What assignment is the compiler referring to? We can't see the code through clairvoyance.

  7. #22
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by XSquared View Post
    For me, removing the explicit cast and changing the signature of handle_ctl_c to be "void handle_ctl_c()" let your sample code compile fine on gcc 4.1.2.
    I don't think the sample code is the same code he's having problems with.

  8. #23
    C++ Developer XSquared's Avatar
    Join Date
    Jun 2002
    Location
    Ontario, Canada
    Posts
    2,718
    I'm starting to get that impression too.
    Naturally I didn't feel inspired enough to read all the links for you, since I already slaved away for long hours under a blistering sun pressing the search button after typing four whole words! - Quzah

    You. Fetch me my copy of the Wall Street Journal. You two, fight to the death - Stewie

  9. #24
    Registered User
    Join Date
    Apr 2006
    Location
    Beirut, Lebanon
    Posts
    20
    It's simple. My code is similar to that one.
    I can't show it since it's huge, but it's the same thing.
    My handler is this:
    Code:
    void handle_INT ()
    {
    	printf ("An interrupt has occured...\n");
    	printf ("\n\n\n\n\n\n\n\n\n");
    	longjmp (jmp, 1);
    }
    and i call
    Code:
    signal (SIGINT, handle_INT)
    in main.
    I don't think ther eis anything else affecting this. I am getting the error message at the above line.

  10. #25
    Registered User
    Join Date
    Apr 2006
    Location
    Beirut, Lebanon
    Posts
    20
    Crap!
    I'm sorry guys, but i'm assigning the returned value of signal to an integer. I had not noticed that.
    But i should assign it to a sighandler_t type right?
    I do this: sighandler_t sig;
    where sig is the assigned the return value but i get syntax error before sig.

  11. #26
    C++ Developer XSquared's Avatar
    Join Date
    Jun 2002
    Location
    Ontario, Canada
    Posts
    2,718
    It sounds like you should be using the SignalHandler type for the return value (the return value is the same type as the second parameter):

    RETURN VALUE
    The signal() function returns the previous value of the signal handler, or SIG_ERR on error.
    Naturally I didn't feel inspired enough to read all the links for you, since I already slaved away for long hours under a blistering sun pressing the search button after typing four whole words! - Quzah

    You. Fetch me my copy of the Wall Street Journal. You two, fight to the death - Stewie

  12. #27
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by sbho View Post
    Crap!
    I'm sorry guys, but i'm assigning the returned value of signal to an integer. I had not noticed that.
    But i should assign it to a sighandler_t type right?
    Unless you're actually going to USE the old handler (like, setting it back after you're done), there's no need to assign it to anything at all.

  13. #28
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > It's simple. My code is similar to that one.
    > I can't show it since it's huge, but it's the same thing.
    It doesn't matter how similar you think it is, if it doesn't produce the stated error messages "as posted", you're just wasting everyones time on pointless guessing.

    > longjmp (jmp, 1);
    This seems to be an exceedingly dodgy thing to be doing inside a signal handler.
    Read your manual pages to find out what is "Async-Safe" and stick to those only.
    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.

  14. #29
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by sbho View Post
    It's simple. My code is similar to that one.
    I can't show it since it's huge, but it's the same thing.
    My handler is this:
    Code:
    void handle_INT ()
    {
    	printf ("An interrupt has occured...\n");
    	printf ("\n\n\n\n\n\n\n\n\n");
    	longjmp (jmp, 1);
    }
    Ohhh boy. longjmp'ing out of a signal handler. You're getting a bit arcane now. I assume the corresponding setjmp() is located somewhere outside of a main loop of some kind? Are you SURE this is the only way to escape the loop?

    Almost all blocking system calls will return early when a signal is caught, with the error code EINTR. The reason they do this is for exactly this reason -- you don't have to rely on longjmp() in order to escape out of a potentially forever-blocking call when a signal comes in. Just set a flag inside the signal handler, and check the flag after every potentially blocking call:

    Code:
    int ctrl_c_hit = 0;
    
    void handle_ctrl_c()
    {
        ctrl_c_hit = 1;
    }
    
    void the_main_loop()
    {
        /* Loop forever */
        for(;;)
        {
            /* A potentially blocking call */
            read(1, buff, 1024);
            if(ctrl_c_hit)
            {
                /* The user hit Ctrl-C. */
                ctrl_c_hit = 0;
                break;
            }
        }
     }
    I every only encountered ONE case where the only solution to a problem with a longjmp() out of a signal handler, and that case is too horrifying to describe.

    EDIT: There are all kinds of fun race conditions to contend with, too. For the SIGINT signal, which is usually only delivered by Ctrl-C, the probability of running into problems is low. But in general you need to understand the principles of concurrent programming to write PROPER signal handlers.
    Last edited by brewbuck; 04-11-2007 at 03:19 PM.

  15. #30
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by Salem View Post
    > longjmp (jmp, 1);
    This seems to be an exceedingly dodgy thing to be doing inside a signal handler.
    Read your manual pages to find out what is "Async-Safe" and stick to those only.
    longjmp out of a signal handler is valid POSIX. Sad to say. It requires all kinds of insanity in the C library as well as the kernel just to make it possible. I'm baffled why the capability is included.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. event handling is serialized in MS Visual Studio C++ 2005 ??
    By mynickmynick in forum Windows Programming
    Replies: 3
    Last Post: 08-07-2008, 04:47 AM
  2. why page based I/O can improve performance?
    By George2 in forum C Programming
    Replies: 1
    Last Post: 06-12-2006, 07:42 AM
  3. File I/O both ASCII and binary handling in C++
    By random in forum C++ Programming
    Replies: 6
    Last Post: 08-16-2005, 04:53 AM
  4. What shell is more powerful?
    By xddxogm3 in forum Tech Board
    Replies: 10
    Last Post: 07-24-2004, 10:47 PM
  5. Overlapped I/O and Completion Port :: Winsock
    By kuphryn in forum Windows Programming
    Replies: 0
    Last Post: 10-30-2002, 05:14 PM