week 10 bug fix submission (SF PDK version): Bug 1892, Bug 1897, Bug 1319. Also 3 or 4 documents were found to contain code blocks with SFL, which has been fixed. Partial fix for broken links, links to Forum Nokia, and the 'Symbian platform' terminology issues.
<?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>Parentand 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 singlepipe. The following pseudo code details the mechanism used by code in theparent 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> asdescribed above, POSIX libraries including P.I.P.S. provide the <xref href="GUID-A9DB6E7C-B8D6-377A-BBE6-39E0A7A09E5D.dita"><apiname>popen()</apiname></xref> functionas defined in <filepath>stdio.h</filepath>. Rather than using a pipe for theIPC mechanism the parent process communicates with the child using the streamreturned by the <xref href="GUID-A9DB6E7C-B8D6-377A-BBE6-39E0A7A09E5D.dita"><apiname>popen()</apiname></xref> call, while the child process inputor 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 obtainedby using the <xref href="GUID-7A399B7D-553D-345E-92BD-43A8A8224D39.dita"><apiname>fileno()</apiname></xref> API call. For more information aboutthe <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> callsto create a Pipe for IPC. The example shown is the child process writing datato 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 104int 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 willbe 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 104int 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 whenit is executed using <xref href="GUID-A9DB6E7C-B8D6-377A-BBE6-39E0A7A09E5D.dita"><apiname>popen()</apiname></xref>. Note that ratherthan using a file descriptor for the communication via the pipe the <xref href="GUID-C0C1D22B-298F-3E8D-A1E9-6F5EFA81F9E8.dita"><apiname>stdin()</apiname></xref> orthe <codeph>stdout</codeph> streams are directed to the parent process, asdefined 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>