{"id":5403,"date":"2022-06-25T00:01:01","date_gmt":"2022-06-25T07:01:01","guid":{"rendered":"https:\/\/c-for-dummies.com\/blog\/?p=5403"},"modified":"2022-07-02T08:11:06","modified_gmt":"2022-07-02T15:11:06","slug":"introduction-to-pipes","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=5403","title":{"rendered":"Introduction to Pipes"},"content":{"rendered":"<p>If you&#8217;re like me, you&#8217;re probably more familiar with the concept of pipes at the command prompt than in a programming environment. Or maybe you don&#8217;t care either way. Regardless, both types of pipe are similar forms of communications, but programming pipes seem specifically weird to me.<br \/>\n<!--more--><br \/>\nBefore crawling into it, be aware that the programming pipe covered in this Lesson is a POSIX thing: Unix, Linux, and macOS. Windows implements pipe programming differently, more akin to server programming. This aspect of pipe programming isn&#8217;t covered here.<\/p>\n<p>All major operating systems do support the command line pipe, the <code>|<\/code> operator, which flows the output from one program into the input for another:<\/p>\n<p><code>grep \"something\" *.txt | less<\/code><\/p>\n<p>The <em>grep<\/em> command&#8217;s output is redirected &mdash; or piped &mdash; into the <em>less<\/em> command as input. The output stream is diverted from standard output and provided as input. In fact, if you think of I\/O as a stream of water, the pipe concept might begin to make sense.<\/p>\n<p>Pipes in C programming work kinda sorta like pipes at the command prompt. What a pipe does is to create a pair of file descriptors, one for input and another for output. These file descriptors aren&#8217;t connected to any file or I\/O device; they stand alone, but are connected with each other: One file descriptor handles input, which is sent to the second file descriptor as output.<\/p>\n<p>Here is the <em>man<\/em> page (2) format for the <em>pipe()<\/em> function:<\/p>\n<p><code>int pipe(int fildes[2]);<\/code><\/p>\n<p>The sole argument is an integer array containing two elements. Upon success, the function returns zero. Array element <code>filedes[0]<\/code> is opened for reading and <code>filedes[1]<\/code> is used for writing. The element order and numbers parallel the standard I\/O file descriptors, where <em>stdin<\/em> is assigned to zero and <em>stdout<\/em> is assigned to one.<\/p>\n<p>Upon failure, the <em>pipe()<\/em> function returns -1, with the <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=1735\">errno variable<\/a> set accordingly.<\/p>\n<p>The <em>pipe()<\/em> function is prototyped in the <code>unistd.h<\/code> header file.<\/p>\n<p>One it&#8217;s created, you use file I\/O commands to send and retrieve data to and from the pipe. The following code demonstrates how this communications takes place.<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2022_06_25-Lesson.c\" rel=\"noopener\" target=\"_blank\">2022_06_25-Lesson.c<\/a><\/h3>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n#include &lt;stdlib.h&gt;\r\n#include &lt;unistd.h&gt;\r\n#include &lt;string.h&gt;\r\n\r\n#define FD_WRITE 1\r\n#define FD_READ 0\r\n\r\nint main()\r\n{\r\n    const int size = 32;\r\n    int x,r;\r\n    int fp[2];\r\n    const char *text = \"This is a test\";\r\n    char buffer[size];\r\n\r\n    <span class=\"comments\">\/* initialize the buffer *\/<\/span>\r\n    for( x=0; x&lt;size; x++ )\r\n        buffer[x] = 0;\r\n\r\n    <span class=\"comments\">\/* create the pipe *\/<\/span>\r\n    r = pipe(fp);\r\n    if( r==-1 )\r\n    {\r\n        perror(\"Pipe\");\r\n        exit(1);\r\n    }\r\n\r\n    <span class=\"comments\">\/* write to the pipe *\/<\/span>\r\n    r = write(fp[FD_WRITE], text, strlen(text) );\r\n    printf(\"Wrote '%s', %d bytes\\n\",text,r);\r\n    <span class=\"comments\">\/* read from the pipe *\/<\/span>\r\n    r = read(fp[FD_READ], buffer, size );\r\n    printf(\"Read '%s', %d bytes\\n\",buffer,r);\r\n\r\n    return(0);\r\n}<\/pre>\n<p>The <em>pipe()<\/em> function is called at Line 22. Its argument is <em>int<\/em> array <code>fp[]<\/code>, which holds two elements. Upon success, write and read file descriptors are placed into the array&#8217;s elements zero and one. These file descriptors are open and ready for I\/O. At this point, the <em>write()<\/em> and <em>read()<\/em> functions send and fetch data through the pipe.<\/p>\n<p>At Line 30, the <em>write()<\/em> function writes to the pipe&#8217;s <code>FD_WRITE<\/code> element, the file descriptor for writing. It&#8217;s sent a chunk of text, which is stored internally in the pipe&#8217;s I\/O buffer.<\/p>\n<p>At Line 33, data  is read from the pipe&#8217;s <code>FD_READ<\/code> element. The retrieved text is stored in a buffer, which is output at Line 34:<\/p>\n<p><code>Wrote 'This is a test', 14 bytes<br \/>\nRead 'This is a test', 14 bytes<\/code><\/p>\n<p>The programming pipe&#8217;s I\/O takes place as a low-level; it&#8217;s not streaming I\/O. Therefore, the low-level functions <em>read()<\/em> and write() are used instead of <em>fread()<\/em> and <em>fwrite()<\/em> or the other high-level file I\/O functions.<\/p>\n<p>In <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=5418\">next week&#8217;s Lesson<\/a>, I show how to use a pipe to communicate with a thread.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Pipes are true weirdos in communications programming. <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=5403\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-5403","post","type-post","status-publish","format-standard","hentry","category-main"],"_links":{"self":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/5403","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=5403"}],"version-history":[{"count":7,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/5403\/revisions"}],"predecessor-version":[{"id":5441,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/5403\/revisions\/5441"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=5403"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=5403"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=5403"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}