diff -r f345bda72bc4 -r 43e37759235e Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/basic_signals_8c_source.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/basic_signals_8c_source.html Tue Mar 30 16:16:55 2010 +0100 @@ -0,0 +1,410 @@ + + +
+ +00001 // basicSignals.c +00002 // +00003 // Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +00004 // All rights reserved. +00005 // This component and the accompanying materials are made available +00006 // under the terms of "Eclipse Public License v1.0" +00007 // which accompanies this distribution, and is available +00008 // at the URL "http://www.eclipse.org/legal/epl-v10.html". +00009 // +00010 // Initial Contributors: +00011 // Nokia Corporation - initial contribution. +00012 // +00013 // Contributors: +00014 // +00015 // Description:This example demonstrates the basic signal functionality . +00016 // +00017 +00018 #include <stdio.h> +00019 #include <stdlib.h> +00020 #include <unistd.h> +00021 #include <sys/types.h> +00022 #include <signal.h> //The header for signal functionality. +00023 #include <time.h> //The header for timer functionality. +00024 #include <e32def.h> +00025 +00026 char const *gstr = "\nPress '7'+Enter to return to the options menu or 'e'+ENTER to exit the example\n"; +00027 char const *gnote = "\nPress the Enter key to proceed with the use case\n"; +00028 +00032 void PressKey() +00033 { +00034 fflush(stdout); +00035 getchar(); +00036 } +00037 +00042 void timestamp(char *str) +00043 { +00044 time_t t; +00045 time(&t); +00046 printf("The time %s is %s\n", str, ctime(&t)); +00047 } +00048 +00053 void SIGCHLD_handler(int signum) +00054 { +00055 if(signum == SIGCHLD) +00056 printf("Now in SIGCHLD handler function\n"); +00057 } +00058 +00063 void SIGALRM_handler(int signum) +00064 { +00065 if(signum == SIGALRM) +00066 printf("Now in SIGALRM handler function\n"); +00067 } +00068 +00073 void SIGUSR1_handler(int signum) +00074 { +00075 if(signum == SIGUSR1) +00076 printf("Now in SIGUSR1 handler function\n"); +00077 } +00078 +00083 void SIGUSR2_handler(int signum) +00084 { +00085 if(signum == SIGUSR2) +00086 printf("Now in SIGUSR2 handler function\n"); +00087 +00088 sigrelse(SIGUSR1); +00089 printf("SIGUSR1 got released and hence its handler function will get called\n"); +00090 } +00091 +00096 void SIGPIPE_handler(int signum) +00097 { +00098 if(signum == SIGPIPE) +00099 printf("In SIGPIPE handler function\n"); +00100 } +00101 +00105 void DisplaySignalOptions() +00106 { +00107 printf("\nSignal options:\n"); +00108 printf("1) Sending and handling a signal using the default handler\n"); +00109 printf("2) Sending and handling a signal using a customized signal handler\n"); +00110 printf("3) Ignoring an incoming signal\n"); +00111 printf("4) Blocking and releasing a signal\n"); +00112 printf("5) Waiting for a signal\n"); +00113 printf("6) Generating and handling a SIGPIPE signal\n"); +00114 printf("Type the number of the option you wish to run followed by an enter,\n"); +00115 printf("or type 'e'+Enter to exit the example.\n"); +00116 } +00117 +00121 void CallDefaultHandler() +00122 { +00123 pid_t my_pid; +00124 my_pid = getpid(); +00125 printf("Raising a SIGCHLD signal\n"); +00126 +00127 signal(SIGCHLD, SIG_DFL); +00128 +00129 //Raising SIGCHLD signal using kill command. +00130 kill(my_pid, SIGCHLD); +00131 +00132 printf("Default handler causes SIGCHLD to get ignored\n"); +00133 PressKey(); +00134 +00135 printf("\nRaising a SIGALRM signal\nDefault handler of SIGALRM will terminate the existing process.\n"); +00136 printf("\nRestart the example to view the other use cases.\n"); +00137 printf("Press the enter key to terminate the example.\n"); +00138 PressKey(); +00139 +00140 signal(SIGALRM, SIG_DFL); +00141 +00142 //Raising SIGALRM signal. +00143 kill(my_pid, SIGALRM); +00144 printf("After SIGALRM being raised\n"); +00145 +00146 printf(gstr); +00147 } +00148 +00152 void CallSignalHandler() +00153 { +00154 struct sigaction sa1,sa2; +00155 sa1.sa_handler = SIGCHLD_handler; +00156 sigemptyset(&sa1.sa_mask); +00157 sa1.sa_flags = 0; +00158 +00159 sa2.sa_handler = SIGALRM_handler; +00160 sigemptyset(&sa2.sa_mask); +00161 sa2.sa_flags = 0; +00162 +00163 if (sigaction(SIGCHLD, &sa1, NULL) == -1) +00164 { +00165 printf("error in setting the handler for SIGCHLD\n"); +00166 } +00167 +00168 if (sigaction(SIGALRM, &sa2, NULL) == -1) +00169 { +00170 printf("error in setting the handler for SIGALRM\n"); +00171 } +00172 +00173 printf("\nRaising a SIGCHLD signal\n"); +00174 kill(getpid(), SIGCHLD); //Raising SIGCHLD signal using kill command. +00175 printf("SIGCHLD has been handled\n"); +00176 +00177 printf("\nRaising a SIGALRM signal\n"); +00178 kill(getpid(), SIGALRM); //Raising SIGALRM signal using kill command. +00179 printf("SIGALRM has been handled\n"); +00180 +00181 printf(gstr); +00182 } +00183 +00187 void IgnoreSignal() +00188 { +00189 struct sigaction sa1,sa2; //The variables for holding signal specific settings, used in sigaction function call. +00190 sa1.sa_handler = SIG_IGN; +00191 sigemptyset(&sa1.sa_mask); +00192 sa1.sa_flags = 0; +00193 +00194 sa2.sa_handler = SIG_IGN; +00195 sigemptyset(&sa2.sa_mask); +00196 sa2.sa_flags = 0; +00197 +00198 // Set the signal handler for SIGCHLD. +00199 if (sigaction(SIGCHLD, &sa1, NULL) == -1) +00200 printf("sigaction for SIGCHLD failed\n"); +00201 +00202 // Set the signal handler for SIGALRM. +00203 if (sigaction(SIGALRM, &sa2, NULL) == -1) +00204 printf("sigaction for SIGALRM failed\n"); +00205 +00206 printf("\nRaising a SIGCHLD signal\n"); +00207 kill(getpid(), SIGCHLD); //Raisisng SIGCHLD signal using kill command. +00208 printf("SIGCHLD was ignored\n"); +00209 +00210 printf("\nRaising a SIGALRM signal\n"); +00211 kill(getpid(), SIGALRM); //Raisisng SIGALRM signal using kill command. +00212 printf("SIGALRM was ignored\n"); +00213 +00214 printf(gstr); +00215 } +00216 +00220 void MaskSignal() +00221 { +00222 // Define a new mask set. +00223 sigset_t mask_set; +00224 +00225 printf("* This use case uses SIGUSR1 and SIGUSR2 signals to demonstrate the mask and the release of a signal\n"); +00226 printf("* We mask the SIGUSR1 signal so that when it is raised it gets blocked and keeps pending until it is\nreleased.\n"); +00227 printf("* We then raise the SIGUSR2 signal to release the blocked SIGUSR1 signal.\n"); +00228 printf("* The custom handler of the SIGUSR2 signal releases SIGUSR1, and SIGUSR1's\ncustom handler gets called to handle it.\n"); +00229 +00230 printf(gnote); +00231 PressKey(); +00232 PressKey(); +00233 +00234 // Set the signal handler for SIGUSR1 and SIGUSR2 signals. +00235 signal(SIGUSR1, SIGUSR1_handler); +00236 signal(SIGUSR2, SIGUSR2_handler); +00237 +00238 // Clearing the mask set so that it doesn't contain any signal numbers. +00239 sigemptyset(&mask_set); +00240 // Adding SIGUSR1 to the mask set. +00241 sigaddset(&mask_set, SIGUSR1); +00242 // Masking the signal. +00243 printf("Masking the SIGUSR1 signal\n"); +00244 sigprocmask(SIG_SETMASK, &mask_set, NULL); +00245 +00246 printf("\nRaising the SIGUSR1 signal"); +00247 printf(gnote); +00248 PressKey(); +00249 +00250 raise(SIGUSR1); +00251 printf("SIGUSR1 was ignored as it was masked\n"); +00252 +00253 printf("\nRaising the SIGUSR2 signal"); +00254 printf(gnote); +00255 PressKey(); +00256 +00257 raise(SIGUSR2); +00258 printf("SIGUSR2 has been handled\n"); +00259 +00260 printf(gstr); +00261 } +00262 +00266 void WaitForSignal() +00267 { +00268 int count,result; +00269 const int delay = 2; //Time delay of 2 seconds. +00270 sigset_t waitset,outset; // Define new mask sets. +00271 struct timespec timeout; // A variable for holding timeout values. +00272 siginfo_t info; // A variable for holding signal info. +00273 +00274 signal(SIGALRM, SIGALRM_handler); // Set the signal handler for SIGALRM. +00275 sigemptyset(&waitset); +00276 sigaddset(&waitset, SIGALRM); // Adding SIGALRM to mask set. +00277 sigprocmask(SIG_BLOCK, &waitset, NULL); +00278 +00279 printf("* This use case demonstrates how a process waits for a SIGALRM signal.\n"); +00280 printf("* A fixed timeout period of 5 seconds is set.\n"); +00281 printf("* The SIGALRM signal is first blocked and then we wait on it until it is raised.\n"); +00282 printf("* The SIGALRM signal is raised twice, once after 6 seconds and another after 4 seconds.\n"); +00283 printf("* When SIGALRM is raised after 6 seconds an error is generated as timeout has occurred.\nBut when SIGALRM is raised after 4 seconds the signal is received.\n"); +00284 printf("* Even though the SIGALRM signal is received it cannot be handled as it is blocked.\nHence we finally unblock it and handle it.\n"); +00285 +00286 printf(gnote); +00287 PressKey(); +00288 PressKey(); +00289 +00290 //Setting the timeout for 5 seconds. +00291 timeout.tv_sec = 5; +00292 timeout.tv_nsec = 500; +00293 +00294 for(count=0;count<2;count++) +00295 { +00296 if(count) +00297 { +00298 printf("Raising SIGALRM after 6 sec\n"); +00299 printf(gnote); +00300 PressKey(); +00301 alarm(6); +00302 } +00303 else +00304 { +00305 printf("Raising SIGALRM after 4 sec\n"); +00306 printf(gnote); +00307 PressKey(); +00308 alarm(4); +00309 } +00310 timestamp("before sigwait()"); +00311 result = sigtimedwait(&waitset, &info, &timeout); +00312 +00313 if( result == SIGALRM ) +00314 printf("sigwait() returned successful for signal %d\n", info.si_signo); +00315 else +00316 { +00317 printf("sigwait() returned an error, since the alarm was generated after the specified time period.error number = %d\n", errno); +00318 } +00319 timestamp("after sigwait()"); +00320 sleep(delay); +00321 } +00322 +00323 printf("Press Enter to unblock the SIGALRM signal and handle it\n"); +00324 PressKey(); +00325 sigemptyset(&outset); +00326 sigprocmask(SIG_UNBLOCK, &waitset, &outset); +00327 +00328 printf(gstr); +00329 } +00330 +00334 void HandleSigpipe() +00335 { +00336 int ret,fds[2]; // fds, used for holding the read and write descriptors for pipe +00337 printf("* This use case demonstrates how writing to a broken pipe generates a SIGPIPE signal.\n"); +00338 printf("* We first create a pipe and obtain the read and write descriptors.\n"); +00339 printf("* To obtain a broken pipe we close the read end of the pipe.\n"); +00340 printf("* Once a write is performed to the broken pipe, an EPIPE error is returned\nand hence the SIGPIPE signal is generated.\n"); +00341 +00342 printf(gnote); +00343 getchar(); +00344 PressKey(); +00345 +00346 //Set the signal handler for the SIGPIPE signal. +00347 signal(SIGPIPE, SIGPIPE_handler); +00348 +00349 //Create a pipe. +00350 ret = pipe(fds); +00351 if(ret != 0) +00352 { +00353 printf("Failed to create a pipe and the errno is %d\n",errno); +00354 } +00355 else +00356 { +00357 printf("The pipe was created successfully\n"); +00358 } +00359 //Close the read end of a pipe. +00360 close(fds[0]); +00361 +00362 //Write to a pipe whose read end is closed (a broken pipe). +00363 printf("Writing to a broken pipe\n"); +00364 ret = write(fds[1], "sigpipe", 10); +00365 if((ret != -1) && (errno != EPIPE)) +00366 { +00367 printf("Failed to generate the SIGPIPE signal on pipe\n"); +00368 } +00369 else +00370 { +00371 printf("Writing to a pipe with the read end closed, has returned EPIPE and hence generated the SIGPIPE signal\n"); +00372 } +00373 +00374 printf(gstr); +00375 } +00376 +00381 int main() +00382 { +00383 int character; +00384 int val = TRUE; +00385 //Welcome Note. +00386 printf("************************************************************************\n"); +00387 printf("* Welcome to the Signal Example *\n"); +00388 printf("* This example demonstrates some basic signal use cases *\n"); +00389 printf("************************************************************************\n"); +00390 printf("Please refer to the overview for a better understanding of this example.\n"); +00391 +00392 //Generating menu for various signal functions. +00393 DisplaySignalOptions(); +00394 while(val) +00395 { +00396 while((character = getchar())!= '\n') +00397 { +00398 switch(character) +00399 { +00400 case '1': +00401 printf("\nDemonstrating sending and handling of 2 signals by the default handler\n"); +00402 printf("**********************************************************************\n"); +00403 CallDefaultHandler(); +00404 break; +00405 case '2': +00406 printf("\nDemonstrating sending and handling of 2 signals using a custom signal handler\n"); +00407 printf("*****************************************************************************\n"); +00408 CallSignalHandler(); +00409 break; +00410 case '3': +00411 printf("\nDemonstrating ignoring an incoming signal\n"); +00412 printf("*****************************************\n"); +00413 IgnoreSignal(); +00414 break; +00415 case '4': +00416 printf("\nDemonstrating masking and releasing of a signal\n"); +00417 printf("***********************************************\n"); +00418 MaskSignal(); +00419 break; +00420 case '5': +00421 printf("\nDemonstrating waiting for a signal\n"); +00422 printf("**********************************\n"); +00423 WaitForSignal(); +00424 break; +00425 case '6': +00426 printf("\nDemonstrating generating and handling a SIGPIPE signal\n"); +00427 printf("******************************************************\n"); +00428 HandleSigpipe(); +00429 break; +00430 case '7': +00431 DisplaySignalOptions(); +00432 break; +00433 case 'e': +00434 printf("Exiting from the main menu\n"); +00435 val = FALSE; +00436 break; +00437 default: +00438 printf("You chose a wrong option!!! Select again.\n"); +00439 break; +00440 } +00441 } +00442 } +00443 printf("Ok [Press the Enter key to exit]\n"); +00444 PressKey(); +00445 return EXIT_SUCCESS; //Returns the success code. +00446 } +