Week 23 contribution of SDK documentation content. See release notes for details. Fixes bugs Bug 2714, Bug 462.
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. -->
<!-- This component and the accompanying materials are made available under the terms of the License
"Eclipse Public License v1.0" which accompanies this distribution,
and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". -->
<!-- Initial Contributors:
Nokia Corporation - initial contribution.
Contributors:
-->
<!DOCTYPE concept
PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
<concept id="GUID-66C1493D-5B85-558A-9A39-454E6EBA307B" xml:lang="en"><title>Signal
Emulation on the Symbian Platform</title><prolog><metadata><keywords/></metadata></prolog><conbody>
<p>The <codeph>libc</codeph> library of P.I.P.S. provides support for POSIX
signals, thereby facilitating the porting of applications that use signals
for exception handling and as control IPC. </p>
<p>P.I.P.S. supports POSIX signals by emulating them in user-side code. This
is different from the UNIX architecture, where the kernel manages the generation
and delivery of signals, and has important implications. </p>
<ul>
<li id="GUID-22658912-1F1E-5C77-9DE1-5210B898CFF0"><p>Signals are always handled
in the context of a signal-handler thread created by the P.I.P.S. backend.
For this reason, signals cannot be directed to a particular thread. </p> </li>
<li id="GUID-4EFC9E19-4031-553B-AF88-546665FA37DB"><p>Before the handler function
of a signal is invoked in the signal-handler thread, all other threads are
suspended. When the handler function returns, the other threads resume. This
is done to mirror the UNIX behaviour of process execution being suspended
when a signal is being handled. </p> </li>
<li id="GUID-177E6544-106B-5E8B-94C6-B0AAD6437C4C"><p>There might be a considerable
amount of latency when you send or receive signals. </p> </li>
</ul>
<section id="GUID-BD44C679-553C-402B-AF78-8922E15884E4"><title>Sending signals</title> <p>Signals can be sent between P.I.P.S.
processes using <xref href="GUID-16DC4A9D-44BC-36E2-AB97-5E9E7521937D.dita"><apiname>kill()</apiname></xref>, <xref href="GUID-EB7F74AE-091B-32C3-9D73-18B82F8D3D73.dita"><apiname>raise()</apiname></xref> or <xref href="GUID-3C70BF0B-CD6E-3A30-A9E6-4CCF11D47EEC.dita"><apiname>sigqueue()</apiname></xref>. </p> <p>You
can use these functions to send any of the supported signals (refer to the
following table). </p> <p>The P.I.P.S. runtime sends the following signals
to P.I.P.S. processes: </p> <ul>
<li id="GUID-6F1D5A0A-4562-55B4-8E70-BAFF45F3EFA9"><p> <b>SIGPIPE:</b> This
signal is sent to a process which attempts to write to a broken <xref href="GUID-EC7F85FF-FD4E-324C-8D01-EF6F7E7A79FE.dita"><apiname>pipe()</apiname></xref>. </p> </li>
<li id="GUID-99788FD7-4E26-5979-8E39-BA12F24D1DA9"><p> <b>SIGCHLD:</b> This
signal is sent to a parent process when a child process exits. </p> </li>
<li id="GUID-D41E5F22-0893-5F61-A4F6-E72239205928"><p> <b> SIGALRM:</b> This
signal is sent to a process when an alarm registered by the process times
out. </p> </li>
</ul> <p> <b>Note:</b> Always ensure that you handle <codeph>SIGPIPE</codeph>, <codeph>SIGCHLD</codeph> or <codeph>SIGALRM</codeph> using
a signal handler to avoid the termination of the process receiving these signals.
For more information about handling signals, see the following section. </p> </section>
<section id="GUID-E244317F-3B69-4B10-8156-03F4A807E663"><title>Handling signals</title> <p>A signal can be received by a
process at any time and is handled immediately, unless it is currently blocked.
You can handle a signal in the following ways: </p> <ol id="GUID-F03B299F-A527-5365-81D3-DDDC607A4094">
<li id="GUID-DF0E70C8-74C2-5ACC-B556-8D216275C554"><p> <b>Use default handling:</b> The
default action for each signal supported on the Symbian platform
is listed in the following table. </p> <p> <b>Note:</b> The default action
for all of the signals sent by the P.I.P.S. runtime (<codeph>SIGPIPE</codeph>, <codeph>SIGCHLD</codeph> or <codeph>SIGALRM</codeph>)
is process termination. You must provide a custom handler for each of these
signals. </p> <table id="GUID-7101041B-CC50-5367-A3A2-6D15FB15C3DD">
<tgroup cols="2"><colspec colname="col0"/><colspec colname="col1"/>
<thead>
<row>
<entry>Signal </entry>
<entry>Default Action</entry>
</row>
</thead>
<tbody>
<row>
<entry><p> <codeph>SIGHUP</codeph> </p> </entry>
<entry><p>Ignore </p> </entry>
</row>
<row>
<entry><p> <codeph> SIGINT</codeph> </p> </entry>
<entry><p>Ignore </p> </entry>
</row>
<row>
<entry><p> <codeph>SIGQUIT</codeph> </p> </entry>
<entry><p>Ignore </p> </entry>
</row>
<row>
<entry><p> <codeph> SIGILL</codeph> </p> </entry>
<entry><p>Ignore </p> </entry>
</row>
<row>
<entry><p> <codeph> SIGTRAP</codeph> </p> </entry>
<entry><p>Ignore </p> </entry>
</row>
<row>
<entry><p> <codeph> SIGABRT</codeph> </p> </entry>
<entry><p>Ignore </p> </entry>
</row>
<row>
<entry><p> <codeph> SIGIOT</codeph> </p> </entry>
<entry><p>Ignore </p> </entry>
</row>
<row>
<entry><p> <codeph> SIGEMT</codeph> </p> </entry>
<entry><p>Ignore </p> </entry>
</row>
<row>
<entry><p> <codeph> SIGFPE</codeph> </p> </entry>
<entry><p>Ignore </p> </entry>
</row>
<row>
<entry><p> <codeph> SIGKILL</codeph> </p> </entry>
<entry><p>Process termination </p> </entry>
</row>
<row>
<entry><p> <codeph> SIGBUS</codeph> </p> </entry>
<entry><p>Ignore </p> </entry>
</row>
<row>
<entry><p> <codeph> SIGSEGV</codeph> </p> </entry>
<entry><p>Ignore </p> </entry>
</row>
<row>
<entry><p> <codeph> SIGSYS</codeph> </p> </entry>
<entry><p>Ignore </p> </entry>
</row>
<row>
<entry><p> <codeph> SIGPIPE</codeph> </p> </entry>
<entry><p>Process termination </p> </entry>
</row>
<row>
<entry><p> <codeph> SIGALRM</codeph> </p> </entry>
<entry><p>Process termination </p> </entry>
</row>
<row>
<entry><p> <codeph> SIGTERM</codeph> </p> </entry>
<entry><p>Process termination </p> </entry>
</row>
<row>
<entry><p> <codeph> SIGURG</codeph> </p> </entry>
<entry><p>Ignore </p> </entry>
</row>
<row>
<entry><p> <codeph> SIGSTOP</codeph> </p> </entry>
<entry><p>Ignore </p> </entry>
</row>
<row>
<entry><p> <codeph> SIGTSTP</codeph> </p> </entry>
<entry><p>Ignore </p> </entry>
</row>
<row>
<entry><p> <codeph> SIGCONT</codeph> </p> </entry>
<entry><p>Ignore </p> </entry>
</row>
<row>
<entry><p> <codeph> SIGCHLD</codeph> </p> </entry>
<entry><p>Ignore </p> </entry>
</row>
<row>
<entry><p> <codeph> SIGTTIN</codeph> </p> </entry>
<entry><p>Ignore </p> </entry>
</row>
<row>
<entry><p> <codeph> SIGTTOU </codeph> </p> </entry>
<entry><p>Ignore </p> </entry>
</row>
<row>
<entry><p> <codeph>SIGIO</codeph> </p> </entry>
<entry><p>Ignore </p> </entry>
</row>
<row>
<entry><p> <codeph> SIGXCPU</codeph> </p> </entry>
<entry><p>Ignore </p> </entry>
</row>
<row>
<entry><p> <codeph> SIGXFSZ</codeph> </p> </entry>
<entry><p>Ignore </p> </entry>
</row>
<row>
<entry><p> <codeph> SIGVTALRM</codeph> </p> </entry>
<entry><p>Ignore </p> </entry>
</row>
<row>
<entry><p> <codeph> SIGPROF</codeph> </p> </entry>
<entry><p>Ignore </p> </entry>
</row>
<row>
<entry><p> <codeph> SIGWINCH</codeph> </p> </entry>
<entry><p>Ignore </p> </entry>
</row>
<row>
<entry><p> <codeph> SIGINFO</codeph> </p> </entry>
<entry><p>Ignore </p> </entry>
</row>
<row>
<entry><p> <codeph> SIGUSR1</codeph> </p> </entry>
<entry><p>Ignore </p> </entry>
</row>
<row>
<entry><p> <codeph> SIGUSR2</codeph> </p> </entry>
<entry><p>Ignore </p> </entry>
</row>
<row>
<entry><p> <codeph> SIGTHR</codeph> </p> </entry>
<entry><p>Ignore </p> </entry>
</row>
<row>
<entry><p> <codeph> SIGRTMIN</codeph> </p> </entry>
<entry><p>Ignore </p> </entry>
</row>
<row>
<entry><p> <codeph> SIGRTMAX</codeph> </p> </entry>
<entry><p>Ignore </p> </entry>
</row>
</tbody>
</tgroup>
</table> </li>
<li id="GUID-5FEF9FD7-22C1-5722-AB35-56C6EC27713D"><p> <b> Ignore the signal:</b> You
can choose to ignore a signal when it is delivered. </p> </li>
<li id="GUID-83529703-4593-51B6-ACFD-78AF3634B3E5"><p> <b> Use a custom signal
handler function:</b> You can set a custom signal handler function to be invoked
when the signal arrives. </p> <p>The following example code demonstrates how
you can handle a <codeph>SIGCHLD</codeph> signal by setting a custom signal
handler function: </p> <codeblock id="GUID-4C7E5A1C-A0D6-5F7D-B444-8465B48122D4" xml:space="preserve">#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
void sighandler(int signum)
{
if(signum == SIGCHLD)
{
// Program logic for custom signal handling
}
else
printf(“Error: Unknown signal”);
}
int main()
{
// When SIGCHLD arrives, invoke sighandler()
signal(SIGCHLD,sighandler);
// program logic
return 0;
}</codeblock> </li>
</ol> </section>
<section id="GUID-252E0621-51F1-443A-A4FC-689BD27597E3"><title>Blocking signals</title> <p>A P.I.P.S. process can choose
to block (and subsequently unblock) signals to itself using <xref href="GUID-02901E24-3615-3018-AF20-F5D5D63FD708.dita"><apiname>sighold()</apiname></xref>, <xref href="GUID-AE4CC3C8-C6D4-3F5C-A28F-C4AAB63E8992.dita"><apiname>sigset()</apiname></xref>, <xref href="GUID-68BD2914-FB73-3D91-9D81-425BF2436473.dita"><apiname>sigrelse()</apiname></xref> and <xref href="GUID-C7279C75-CB98-3F24-ABAA-76CF0009A8ED.dita"><apiname>sigprocmask()</apiname></xref>. Signals that are blocked on a P.I.P.S.
process are not be delivered for handling. Instead, they are queued to be
handled when they are unblocked. </p> <p>Non-realtime signals are queued only
once, even when they are delivered multiple times. However, real-time signals
are queued every time they are delivered. </p> <p> <b> Note:</b> You can force
non-realtime signals to be queued multiple times by sending the signal using <xref href="GUID-3C70BF0B-CD6E-3A30-A9E6-4CCF11D47EEC.dita"><apiname>sigqueue()</apiname></xref>. </p> <p><b>Examples</b> </p> <p>The
following example code demonstrates how real-time signals are queued when
they are blocked: </p> <codeblock id="GUID-D3E99770-0E31-5B31-8AD4-DB5991AC4E03" xml:space="preserve">#include <stdio.h>
#include <signal.h>
void func(int sig)
{
printf("Signal was received");
}
int main(void)
{
signal(SIGRTMIN+3,func);
sighold(SIGRTMIN+3);
raise(SIGRTMIN+3);
raise(SIGRTMIN+3);
raise(SIGRTMIN+3);
//This will cause func() to be called thrice
sigrelse(SIGRTMIN+3);
return 0;
}</codeblock> <p>The output displayed is: </p> <codeblock id="GUID-BB3F1695-8BD4-5AAA-8CF4-BECA435327D4" xml:space="preserve">Signal was received
Signal was received
Signal was received</codeblock> <p>The following example code demonstrates
how non-realtime signals are queued when they are blocked: </p> <codeblock id="GUID-0F984C01-54F9-50DB-8112-CF5F79E344D6" xml:space="preserve">#include <stdio.h>
#include <signal.h>
void func(int sig)
{
printf("Signal was received");
}
int main(void)
{
signal(SIGINT,func);
sighold(SIGINT);
raise(SIGINT);
raise(SIGINT);
raise(SIGINT);
// This will cause func() to be called only ONCE, since SIGINT is a non-realtime signal.
sigrelse(SIGINT);
return 0;
}</codeblock> <p>The output displayed is: </p> <codeblock id="GUID-3AAF3CF0-4B9D-5F75-9461-31A1EB628291" xml:space="preserve">Signal was received</codeblock> <p>The
following example code demonstrates how you can force a non-realtime signal
to be queued multiple times by sending the signal using <xref href="GUID-3C70BF0B-CD6E-3A30-A9E6-4CCF11D47EEC.dita"><apiname>sigqueue()</apiname></xref>: </p> <codeblock id="GUID-C3EFB6FC-3592-5F69-9AAE-F796EB483DEA" xml:space="preserve">#include <stdio.h>
#include <signal.h>
#include <unistd.h>
void func(int sig)
{
printf("Signal was received");
}
int main(void)
{
union sigval val;
val.sigval_int = 0;
signal(SIGINT,func);
sighold(SIGINT);
sigqueue(getpid(), SIGINT,val);
sigqueue(getpid(), SIGINT,val);
sigqueue(getpid(), SIGINT,val);
// This will cause func() to be called thrice
sigrelse(SIGINT);
return 0;
}</codeblock> <p>The output displayed is: </p> <codeblock id="GUID-6F2BA135-2134-5176-9A80-80EB15286D7F" xml:space="preserve">Signal was received
Signal was received
Signal was received</codeblock> </section>
</conbody><related-links>
<link href="GUID-E65D91AE-482F-5592-B83C-0F29126C2EFA.dita"><linktext>Using Signals
to Handle Exceptions</linktext></link>
<link href="GUID-186B9876-2A08-5F23-BB49-49EC34C51507.dita"><linktext>Using Signals
to Terminate Processes</linktext></link>
<link href="GUID-6CF8A41B-C2DD-5D57-A71D-6405CE08A06B.dita"><linktext>Using Signals
to Handle Asynchronous Events</linktext></link>
</related-links></concept>