Symbian3/SDK/Source/GUID-AA49FB68-22A1-417F-AB57-9C22CE016B21.dita
changeset 0 89d6a7a84779
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Symbian3/SDK/Source/GUID-AA49FB68-22A1-417F-AB57-9C22CE016B21.dita	Thu Jan 21 18:18:20 2010 +0000
@@ -0,0 +1,179 @@
+<?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-AA49FB68-22A1-417F-AB57-9C22CE016B21" xml:lang="en"><title>Parent
+and Child IPC Using a Single Pipe</title><prolog><metadata><keywords/></metadata></prolog><conbody>
+<p>In this scenario, the parent and child processes communicate using a single
+pipe. The following pseudo code details the mechanism used by code in the
+parent process in a Unix-like system. <codeblock xml:space="preserve">//Call pipe() to create the pipe.
+//Call Fork().
+if (child process)
+{
+   //Child Process.
+   //duplicate (via a dup2() call) the read/write end of the pipe using  
+   //prior agreed file descriptor numbers which will subsequently be used by the   //child process following the exec() call.
+   //Close the original file descriptors.
+   //Call exec() to replace the code image in the child process.
+}
+else
+{
+   //Parent process
+   //Do Whatever
+}
+</codeblock></p>
+<p>Instead of using the <codeph>fork()</codeph>/<codeph>exec()</codeph> as
+described above, POSIX libraries including P.I.P.S. provide the <xref href="GUID-A9DB6E7C-B8D6-377A-BBE6-39E0A7A09E5D.dita"><apiname>popen()</apiname></xref> function
+as defined in <filepath>stdio.h</filepath>. Rather than using a pipe for the
+IPC mechanism the parent process communicates with the child using the stream
+returned by the <xref href="GUID-A9DB6E7C-B8D6-377A-BBE6-39E0A7A09E5D.dita"><apiname>popen()</apiname></xref> call, while the child process input
+or output is using the <xref href="GUID-C0C1D22B-298F-3E8D-A1E9-6F5EFA81F9E8.dita"><apiname>stdin()</apiname></xref>/<xref href="GUID-85797574-E2A2-3C0C-9670-C178078DE199.dita"><apiname>stdout()</apiname></xref> streams. </p>
+<p>However if the parent process requires a file descriptor it can be obtained
+by using the <xref href="GUID-7A399B7D-553D-345E-92BD-43A8A8224D39.dita"><apiname>fileno()</apiname></xref> API call. For more information about
+the <xref href="GUID-A9DB6E7C-B8D6-377A-BBE6-39E0A7A09E5D.dita"><apiname>popen()</apiname></xref> function, see <xref href="http://www.opengroup.org" scope="external">http:\\www.opengroup.org</xref>. </p>
+<p><b>Parent process <codeph>fork()</codeph> and <codeph>exec()</codeph> functions</b></p>
+<p>The following code shows the use of a pipe and subsequent <codeph>fork()</codeph>/<codeph>exec()</codeph> calls
+to create a Pipe for IPC. The example shown is the child process writing data
+to the pipe, and the parent process receiving the data.</p>
+<codeblock xml:space="preserve">//Child Process File Descriptors for the pipe. These should be defined in a common header 
+//file used to compile both the parent and child process's executable.
+//However #define is here for clarity.
+#define WRITE_FD  104
+int main(int argc, char *argv[])
+{
+  int pipeEnds[2]; //Pipe file descriptors [0] is for read [1] is for write
+  
+  //create the pipe
+  if(pipe(pipeEnds) != 0)
+  {
+     //Pipe creation error
+     return EXIT_FAILURE;
+  }
+  else
+  {
+     pid_t Childpid = fork();
+     
+     if(Childpid == 0)
+     {
+         //close the redundant read FD obtained from the parent process
+         (void)close(pipeEnds[0]);
+    
+         //duplicate the file descriptor for use following exec().
+         if(dup2(pipeEnds[1], WRITE_FD) == -1)
+         {
+            printf("dup2 error\n");
+            return EXIT_FAILURE;
+         }
+         //close the redundant write FD obtained from the parent process
+         (void)close(pipeEnds[1]);
+    
+         //exec() to replace the child process executable
+         char execFileName[] = "/root/PortDoc/Example1_c/Posix/Child/ChildProg";
+         execl(execFileName,NULL);
+      }
+      else
+      {
+         //Parent process. This reads from the pipe. Therefore close the write end of the
+         //pipe.
+         close(pipeEnds[1]);
+    
+         //declare receive buffer, and clear its contents
+         char RxBuffer[100];
+         memset(RxBuffer,0,sizeof(RxBuffer));
+    
+         //Wait for data from the child process. Child sends a string.
+         read(pipeEnds[0],RxBuffer,sizeof(RxBuffer));
+    
+         printf(RxBuffer);
+
+         //close the Read end of the pipe
+         close(pipeEnds[0]);
+    
+         //Wait for the child process to terminate
+         waitpid(Childpid,NULL,0);
+      }
+   }
+   return EXIT_SUCCESS;
+}
+</codeblock>
+<p><b>Child process created using <codeph>fork()</codeph> or <codeph>exec()</codeph> functions</b></p>
+<p>The following code shows an example of the child process source which will
+be executed following the <codeph>exec()</codeph>. </p>
+<codeblock xml:space="preserve">//Child Process File Descriptors for the pipe. These should be defined in a common header 
+//file used to compile both the parent and child process's executable. Shown here for
+//clarity.
+#define WRITE_FD  104
+
+int main(void)
+{
+   char TxMsg[] = "Hello Parent\n";
+    
+   //Send the message to the parent
+   write(WRITE_FD,TxMsg,sizeof(TxMsg));
+    
+   //close the File Descriptor
+   close(WRITE_FD);
+   return EXIT_SUCCESS;
+}
+</codeblock>
+<p><b>Parent process P.I.P.S. example for <xref href="GUID-A9DB6E7C-B8D6-377A-BBE6-39E0A7A09E5D.dita"><apiname>popen()</apiname></xref> function</b></p>
+<p>The following code shows how the above code can be modified to use <codeph>popen()</codeph>,
+rather than the <codeph>fork()</codeph>/<codeph>exec()</codeph> combination. </p>
+<codeblock xml:space="preserve">int main(int argc, char *argv[])
+{
+   //Create child process using popen(). Child process writes to the Parent therefore "r" 
+   //parameter.
+   FILE* ChildProcessStream = popen("/root/PortDoc/Example1_c/Symbian/Child/ChildProg","r");
+          
+   if(ChildProcessStream == NULL)
+   {
+      printf("\n Failure to create child process with popen()\n");
+      return EXIT_FAILURE;
+   }
+   else
+   {
+      //Use a file descriptor rather than a stream
+      int ChildProcessFD = fileno(ChildProcessStream);
+
+      //Create a receive buffer, and zero contents before receiving.
+      char RxBuffer[100];
+      memset(RxBuffer,0,sizeof(RxBuffer));
+      
+      //Wait for data from the child process. Child sends a string.
+      int nbytes = read(ChildProcessFD,RxBuffer,sizeof(RxBuffer));
+
+      //printf is slightly different from the POSIX example to verify that the data output to the 
+      //screen is done by the parent process.
+      printf("\n Message Received by Parent=%s",RxBuffer);
+      
+      //Wait for Child Process to complete
+      pclose(ChildProcessStream);
+   }
+   return EXIT_SUCCESS;
+}
+</codeblock>
+<p><b>Child process P.I.P.S. example for <xref href="GUID-A9DB6E7C-B8D6-377A-BBE6-39E0A7A09E5D.dita"><apiname>popen()</apiname></xref> function</b></p>
+<p>The following code shows how the child process source can be modified when
+it is executed using <xref href="GUID-A9DB6E7C-B8D6-377A-BBE6-39E0A7A09E5D.dita"><apiname>popen()</apiname></xref>. Note that rather
+than using a file descriptor for the communication via the pipe the <xref href="GUID-C0C1D22B-298F-3E8D-A1E9-6F5EFA81F9E8.dita"><apiname>stdin()</apiname></xref> or
+the <codeph>stdout</codeph> streams are directed to the parent process, as
+defined in the usage of the <xref href="GUID-A9DB6E7C-B8D6-377A-BBE6-39E0A7A09E5D.dita"><apiname>popen()</apiname></xref> call. </p>
+<codeblock xml:space="preserve">int main(void)
+{
+    //Child process created by popen() so that its stdout is streamed to the parent process
+    char TxMsg[] = "Hello Parent\n";
+    
+    //Send the message to the parent
+    printf(TxMsg);
+    
+    return EXIT_SUCCESS;
+}
+</codeblock>
+</conbody></concept>
\ No newline at end of file