Creating a processes and I\+P\+C (Inter process communication)

In this example we will show how to create a new process and communicate with it in a portable way using the Ecore\+\_\+exe module.

In this example we will have two process and both will communicate with each other using messages. A father process will start a child process and it will keep sending messages to the child until it receives a message to quit. To see the full source use the links\+: \begin{DoxyItemize}
\item \hyperlink{ecore_exe_example_8c-example}{Father} \item \hyperlink{ecore_exe_example_child_8c-example}{Child}\end{DoxyItemize}
Let's start the tutorial. The implementation of the child it's pretty simple. We just read strings from stdin and write a message in the stdout. But you should be asking yourself right know. \char`\"{}\+If I'm receiving data from an other
process why I'm reading and writing in stdin/stdout?\char`\"{}. That's because, when you spawn a process using the Ecore\+\_\+\+Exe module it will create a pipe between the father and the child process and the stdin/stdout of the child process will be redirected to the pipe. So when the child wants to receive or send data to the father, just use the stdin/stdout. However the steps to send data from the father to the child is quite different, but we will get there.

The child will register a fd handler to monitor the stdin. So we start registering the ecore F\+D handler\+:  
\begin{DoxyCodeInclude}
   \hyperlink{group__Ecore__FD__Handler__Group_ga832e68eb7f15912abeadef816bb5d2f5}{ecore\_main\_fd\_handler\_add}(STDIN\_FILENO,
                             ECORE\_FD\_READ,
                             \_fd\_handler\_cb,
                             NULL, NULL, NULL);

\end{DoxyCodeInclude}


If you don't remenber the parameters of \hyperlink{group__Ecore__FD__Handler__Group_ga832e68eb7f15912abeadef816bb5d2f5}{ecore\+\_\+main\+\_\+fd\+\_\+handler\+\_\+add}, please check its documentation.

Now that we have our handler registered we will start the ecore's main loop\+: 
\begin{DoxyCodeInclude}
   \hyperlink{group__Ecore__Main__Loop__Group_gaf103b9f668bb3e4fed12e52c6180132d}{ecore\_main\_loop\_begin}();

\end{DoxyCodeInclude}


Now let's take a look in the callback function. Its a simple function that will read from stdin 3 times and at the third time will say to the father\+: \char`\"{}quit\char`\"{}.  
\begin{DoxyCodeInclude}
\textcolor{keyword}{static} \hyperlink{group__Eina__Types__Group_ga3fe0caf72e93b1bab1ca8ee3ccf3f226}{Eina\_Bool}
\_fd\_handler\_cb(\textcolor{keywordtype}{void} *data EINA\_UNUSED, \hyperlink{group__Ecore__FD__Handler__Group_ga225121ed2123da4b52b76aa08d78c220}{Ecore\_Fd\_Handler} *fd\_handler EINA\_UNUSED)
\{
   \textcolor{keyword}{static} \textcolor{keywordtype}{int} numberOfMessages = 0;
   \textcolor{keywordtype}{char} message[BUFFER\_SIZE];

   \textcolor{keywordflow}{if} (!fgets(message, BUFFER\_SIZE, stdin))
     \textcolor{keywordflow}{return} \hyperlink{group__Ecore__Main__Loop__Group_ga1ee9db07f9a46a8b20fb83e1c6dbed09}{ECORE\_CALLBACK\_RENEW};

   numberOfMessages++;

   \textcolor{keywordflow}{if} (numberOfMessages < 3)
     \{
        fprintf(stdout, \textcolor{stringliteral}{"My father sent this message to me:%s\(\backslash\)n"}, message);
        fflush(stdout);
        \textcolor{keywordflow}{return} \hyperlink{group__Ecore__Main__Loop__Group_ga1ee9db07f9a46a8b20fb83e1c6dbed09}{ECORE\_CALLBACK\_RENEW};
     \}
   \textcolor{keywordflow}{else}
     \{
        fprintf(stdout, \textcolor{stringliteral}{"quit\(\backslash\)n"});
        fflush(stdout);
        \hyperlink{group__Ecore__Main__Loop__Group_ga95cf8e97dff0716433c2c5474d606a98}{ecore\_main\_loop\_quit}();
        \textcolor{keywordflow}{return} \hyperlink{group__Ecore__Main__Loop__Group_ga780091d7d49a4bb6cb753f12e1a3b19d}{ECORE\_CALLBACK\_DONE};
     \}
\}

\textcolor{keywordtype}{int}
main(\textcolor{keywordtype}{void})
\{
   \textcolor{keywordflow}{if} (!\hyperlink{group__Ecore__Init__Group_ga77757609684a2c922dc5ec398274751b}{ecore\_init}())
     \textcolor{keywordflow}{goto} error;

   \hyperlink{group__Ecore__FD__Handler__Group_ga832e68eb7f15912abeadef816bb5d2f5}{ecore\_main\_fd\_handler\_add}(STDIN\_FILENO,
                             ECORE\_FD\_READ,
                             \_fd\_handler\_cb,
                             NULL, NULL, NULL);
   \hyperlink{group__Ecore__Main__Loop__Group_gaf103b9f668bb3e4fed12e52c6180132d}{ecore\_main\_loop\_begin}();

   \hyperlink{group__Ecore__Init__Group_ga768298b932f18d7e7593a447493e5cde}{ecore\_shutdown}();

   \textcolor{keywordflow}{return} EXIT\_SUCCESS;

error:
   \textcolor{keywordflow}{return} EXIT\_FAILURE;
\}

\end{DoxyCodeInclude}


You may notice that we are sending the messages to stdout, and our father will receive it. Also our string must have a \char`\"{}\textbackslash{}n\char`\"{} because the string will be buffered in the pipe until it finds E\+O\+F or a \char`\"{}newline\char`\"{} in our case we won't have a E\+O\+F unless we close the pipe, so we use the \char`\"{}\textbackslash{}n\char`\"{} char.

One more thing, we use fflush(stdout) because probably our message won't fill our entire buffer and the father would never receive the message. So we use this function to flush the buffer and the father can receive as fast as possible.

Now that we have our child ready, let's start our work in the father's source code.

We start creating the child process like this\+:  
\begin{DoxyCodeInclude}
   childHandle = \hyperlink{group__Ecore__Exe__Group_gacd208a964c62424424d4c4c92a651db1}{ecore\_exe\_pipe\_run}(\textcolor{stringliteral}{"./ecore\_exe\_example\_child"},
                                    \hyperlink{group__Ecore__Exe__Group_gga6fb12d2a7c21ff1340c0f69447f91599a83dcb150caa9f5f4ce548eaa4a92c6af}{ECORE\_EXE\_PIPE\_WRITE} |
                                    \hyperlink{group__Ecore__Exe__Group_gga6fb12d2a7c21ff1340c0f69447f91599ae97566413d58b792e92369966ffeece5}{ECORE\_EXE\_PIPE\_READ\_LINE\_BUFFERED} |
                                    \hyperlink{group__Ecore__Exe__Group_gga6fb12d2a7c21ff1340c0f69447f91599a76bc9e447a456727dc2d686b4682b512}{ECORE\_EXE\_PIPE\_READ}, NULL);

\end{DoxyCodeInclude}


With the command above we are creating our child process, the first parameter is the command to be executed, the second are the pipe flags and in our case we will write and read in the pipe so we must say what we are doing in the pipe. You may notice the flag E\+C\+O\+R\+E\+\_\+\+E\+X\+E\+\_\+\+P\+I\+P\+E\+\_\+\+R\+E\+A\+D\+\_\+\+L\+I\+N\+E\+\_\+\+B\+U\+F\+F\+E\+R\+E\+D, this means that reads are buffered until I find a newline. And the third parameter is data that we would like to send to the process in its creating. This case we are sending nothing, so just use N\+U\+L\+L.

Then we check if the process was created\+: 
\begin{DoxyCodeInclude}
   \textcolor{keywordflow}{if} (childHandle == NULL)
     \{
        fprintf(stderr, \textcolor{stringliteral}{"Could not create a child process!\(\backslash\)n"});
        \textcolor{keywordflow}{goto} \hyperlink{group__Ecore__Init__Group_ga768298b932f18d7e7593a447493e5cde}{ecore\_shutdown};
     \}

\end{DoxyCodeInclude}


After this we get the P\+I\+D of the child process and just print it in the screen. The P\+I\+D stands for Process identification. This is just an internal identifier of your process\+:


\begin{DoxyCodeInclude}
   childPid = \hyperlink{group__Ecore__Exe__Group_ga31fa4d88303d0dc45b3dfdb55fb53883}{ecore\_exe\_pid\_get}(childHandle);

   \textcolor{keywordflow}{if} (childPid == -1)
     fprintf(stderr, \textcolor{stringliteral}{"Could not retrive the PID!\(\backslash\)n"});
   \textcolor{keywordflow}{else}
     fprintf(stdout, \textcolor{stringliteral}{"The child process has PID:%u\(\backslash\)n"}, (\textcolor{keywordtype}{unsigned} \textcolor{keywordtype}{int})childPid);

\end{DoxyCodeInclude}


The way that Ecore\+\_\+exe works is\+: when we want to read data sent from our child we must use an ecore event. So let's start register our event listener\+: 
\begin{DoxyCodeInclude}
   \hyperlink{group__Ecore__Event__Group_gae75b0b1b2c50e73b8e42afc628b00a62}{ecore\_event\_handler\_add}(\hyperlink{group__Ecore__Exe__Group_ga3a5071bbc714abfbcede55c39c6ecf8a}{ECORE\_EXE\_EVENT\_DATA}, 
      \_msg\_from\_child\_handler, NULL);

\end{DoxyCodeInclude}


Now to send messages to our child we will use a timer, so every 1 second we will send a message to the child. 
\begin{DoxyCodeInclude}
   ecore\_timer\_add(1, \_sendMessage, childHandle);

\end{DoxyCodeInclude}


After all this we start the main loop. Now let's pass to the callback functions.

Now we will see how we actually send the data and receive it. Let's start with \+\_\+send\+Message\+:  
\begin{DoxyCodeInclude}
\_sendMessage(\textcolor{keywordtype}{void} *data)
\{
   \textcolor{keyword}{static} \textcolor{keywordtype}{int} numberOfMessages = 0;
   \hyperlink{group__Ecore__Exe__Group_ga4f1476f2054418e6436880883e04a141}{Ecore\_Exe} *childHandle = (\hyperlink{group__Ecore__Exe__Group_ga4f1476f2054418e6436880883e04a141}{Ecore\_Exe} *)data;
   \textcolor{keywordtype}{char} msg[BUFFER\_SIZE];

   sprintf(msg, \textcolor{stringliteral}{" Message: %d\(\backslash\)n"}, numberOfMessages);
   numberOfMessages++;

   \textcolor{keywordflow}{if} (\hyperlink{group__Ecore__Exe__Group_gac5a7d73f64baf6b752154836ff4123b9}{ecore\_exe\_send}(childHandle, msg, strlen(msg)) != \hyperlink{group__Eina__Types__Group_ga05c12dacc8b4058994df842b41be85fc}{EINA\_TRUE})
     fprintf(stderr, \textcolor{stringliteral}{"Could not send my name to the child\(\backslash\)n"});
   \textcolor{keywordflow}{else}
     fprintf(stdout,
             \textcolor{stringliteral}{"I'm the father and I sent this message to the child: %s\(\backslash\)n"}, msg);

   \textcolor{keywordflow}{return} \hyperlink{group__Ecore__Main__Loop__Group_ga1ee9db07f9a46a8b20fb83e1c6dbed09}{ECORE\_CALLBACK\_RENEW};
\}

\end{DoxyCodeInclude}


We use ecore\+\_\+exe\+\_\+send to send data to the child process, it's pretty simple. To know what the parameters stands for, check the docs.

\begin{DoxyNote}{Note}
The function {\bfseries ecore\+\_\+exe\+\_\+send} will never block your program, also there is no partial send of the data. This means either the function will send all the data or it will fail.
\end{DoxyNote}
Now let's take a look in our event callback and see how we retrieve the messages.  
\begin{DoxyCodeInclude}
\textcolor{keyword}{static} \hyperlink{group__Eina__Types__Group_ga3fe0caf72e93b1bab1ca8ee3ccf3f226}{Eina\_Bool}
\_msg\_from\_child\_handler(\textcolor{keywordtype}{void} *data EINA\_UNUSED, \textcolor{keywordtype}{int} type EINA\_UNUSED, \textcolor{keywordtype}{void} *event)
\{
   \hyperlink{struct__Ecore__Exe__Event__Data}{Ecore\_Exe\_Event\_Data} *dataFromProcess = (
      \hyperlink{struct__Ecore__Exe__Event__Data}{Ecore\_Exe\_Event\_Data} *)event;
   \textcolor{keywordtype}{char} msg[BUFFER\_SIZE];

   \textcolor{keywordflow}{if} (dataFromProcess->\hyperlink{struct__Ecore__Exe__Event__Data_a7d28f61d1dc37d2582ed1028c692c46f}{size} >= (BUFFER\_SIZE - 1))
     \{
        fprintf(stdout, \textcolor{stringliteral}{"Data too big for bugger. error\(\backslash\)n"});
        \textcolor{keywordflow}{return} \hyperlink{group__Ecore__Main__Loop__Group_ga780091d7d49a4bb6cb753f12e1a3b19d}{ECORE\_CALLBACK\_DONE};
     \}

   strncpy(msg, dataFromProcess->\hyperlink{struct__Ecore__Exe__Event__Data_a81848de0f19ad311c27b9e5d480d645f}{data}, dataFromProcess->\hyperlink{struct__Ecore__Exe__Event__Data_a7d28f61d1dc37d2582ed1028c692c46f}{size});
   msg[dataFromProcess->\hyperlink{struct__Ecore__Exe__Event__Data_a7d28f61d1dc37d2582ed1028c692c46f}{size}] = 0;

   \textcolor{keywordflow}{if} (strcmp(msg, \textcolor{stringliteral}{"quit"}) == 0)
     \{
        fprintf(stdout, \textcolor{stringliteral}{"My child said to me, QUIT!\(\backslash\)n"});
        \hyperlink{group__Ecore__Main__Loop__Group_ga95cf8e97dff0716433c2c5474d606a98}{ecore\_main\_loop\_quit}();
     \}

\end{DoxyCodeInclude}


It's just like an normal event, we get a reference to Ecore\+\_\+\+Exe\+\_\+\+Event\+\_\+\+Data, extract the data and then show it in the screen.

And that's it, after all it's not complicated to create a process and communicate with it. 