Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>If I understand you correctly, you want to know how to handle the signal as well as what to do once you get it.</p> <p>The way you establish a signal handler is with <a href="http://man7.org/linux/man-pages/man2/sigaction.2.html" rel="nofollow"><code>sigaction()</code></a>. You didn't state the platform you're on so I'm assuming Linux, although <code>sigaction()</code> is defined by the POSIX standards and should be available on most other platforms.</p> <p>There are various ways you can do this. One way is to establish a signal handler which simply sets a global variable to 1, denoting that the signal was caught. Then in your <code>getline()</code> function you establish a check to see if <code>SIGINT</code> was caught and if it was then return <code>NULL</code> and allow <code>run_interactive()</code> to run again.</p> <p>Here's how you would catch the signal:</p> <pre><code>#include &lt;signal.h&gt; static int sigint_caught = 0; static void sigint_handler(int sig) { sigint_caught = 1; } struct sigaction sa; sigemptyset(&amp;sa.sa_mask); sa.sa_flags = 0; // or SA_RESTART if you want to automatically restart system calls interrupted by the signal sa.sa_handler = sigint_handler; if (sigaction(SIGINT, &amp;sa, NULL) == -1) { printf("could not establish handler\n"); exit(-1); // or something } </code></pre> <p>And then perhaps in <code>getline()</code>, in the infinite loop, you would establish the check to see if <code>SIGINT</code> has been caught:</p> <pre><code>for (;;) { if (sigint_caught) { return NULL; } // ... </code></pre> <p>And then in your <code>run_interactive()</code> call you can check the return value <em>with</em> the check to see if <code>SIGINT</code> was caught:</p> <pre><code>// ... get_line(&amp;line); if (line == NULL &amp;&amp; sigint_caught) { sigint_caught = 0; // allow it to be caught again free(line); continue; // or something; basically go to the next iteration of this loop } else if (line[0] == '\0') { free(line); break; } else { // rest of code </code></pre> <p>Didn't test it so I can't guarantee it'll work, since your question is pretty broad (having to look through more of your code etc.), but hopefully it gives you enough of an idea as to what you can do you in your situation. This is perhaps a pretty naive solution but it might meet your needs. For something more robust perhaps look into the source code for popular shells like bash or zsh.</p> <p>For example, one thing that can happen is that <code>fgetc()</code> might block since there is no new data in stdin, and that might be when the signal is sent. <code>fgetc()</code> would be interrupted and <code>errno</code> would be <code>EINTR</code>, so you could add a check for this in <code>getline()</code>:</p> <pre><code>c = fgetc(stdin); // make sure to #include &lt;errno.h&gt; if (errno == EINTR &amp;&amp; sigint_caught) return NULL; </code></pre> <p>This would only happen if you <em>don't</em> set <code>sa_flags</code> to <code>SA_RESTART</code>. If you do, then <code>fgetc</code> should automatically restart and continue blocking until new input is received, which may or may not be what you want.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload