{"id":6345,"date":"2024-04-13T00:01:49","date_gmt":"2024-04-13T07:01:49","guid":{"rendered":"https:\/\/c-for-dummies.com\/blog\/?p=6345"},"modified":"2024-04-06T11:03:37","modified_gmt":"2024-04-06T18:03:37","slug":"using-the-epoll-function-to-scan-for-standard-input","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=6345","title":{"rendered":"Using the <em>epoll()<\/em> Function to Scan for Standard Input"},"content":{"rendered":"<p>As with the <em>select()<\/em> function covered in <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=6321\">last week&#8217;s Lesson<\/a>, you can use other networking functions to scan for pending standard input while a program otherwise spins busy. The <em>epoll()<\/em> family of functions allow for such monitoring.<br \/>\n<!--more--><br \/>\nThe <em>epoll()<\/em> functions are preferred by network programmers over the older <em>select()<\/em> function. They rely more on functions than macros to get the job done, though the steps involved are similar: Create a set of file descriptors to monitor, monitor the descriptors, act when one of the descriptors resports as busy.<\/p>\n<p>Here is the updated code from last week&#8217;s Lesson:<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2024_04_13-Lesson.c\" rel=\"noopener\" target=\"_blank\">2024_04_13-Lesson.c<\/a><\/h3>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n#include &lt;unistd.h&gt;\r\n#include &lt;sys\/epoll.h&gt;\r\n\r\n#define MAX_EVENTS 5\r\n\r\nint main() {\r\n    char a = 'A';\r\n    int x,fd,nfds;\r\n    struct epoll_event evin,events[MAX_EVENTS];\r\n\r\n    <span class=\"comments\">\/* Create an epoll instance *\/<\/span>\r\n    fd = epoll_create1(0);\r\n    if (fd == -1)\r\n    {\r\n        perror(\"epoll_create1\");\r\n        return 1;\r\n    }\r\n\r\n    <span class=\"comments\">\/* add input event for standard input *\/<\/span>\r\n    evin.events = EPOLLIN;\r\n    evin.data.fd = STDIN_FILENO;\r\n    if (epoll_ctl(fd, EPOLL_CTL_ADD, STDIN_FILENO, &amp;evin) == -1)\r\n    {\r\n        perror(\"epoll_ctl\");\r\n        return 1;\r\n    }\r\n\r\n    <span class=\"comments\">\/* endless loop to scan for keyboard activity *\/<\/span>\r\n    while (1) {\r\n        <span class=\"comments\">\/* output the alphabet loop *\/<\/span>\r\n        printf(\" %c\",a++);\r\n        if( a=='Z' )\r\n            a = 'A';\r\n\r\n        <span class=\"comments\">\/* obtain number of file desciptors *\/<\/span>\r\n        nfds = epoll_wait(fd, events, MAX_EVENTS, 0);\r\n        if (nfds == -1)\r\n        {\r\n            perror(\"epoll_wait\");\r\n            return 1;\r\n        }\r\n\r\n        <span class=\"comments\">\/* scan file descriptors *\/<\/span>\r\n        for ( x=0; x&lt;nfds; x++)\r\n        {\r\n            <span class=\"comments\">\/* keyboard input buffer full *\/<\/span>\r\n            if ( events[x].data.fd==STDIN_FILENO )\r\n            {\r\n                getchar();\r\n                return 0;\r\n            }\r\n        }\r\n    }\r\n\r\n    return 0;\r\n}<\/pre>\n<p>The first task is to create an epoll instance: <code>fd = epoll_create1(0);<\/code> This step is followed by adding events to an <em>epoll_event<\/em> structure:<\/p>\n<p><code>evin.events = EPOLLIN;<br \/>\nevin.data.fd = STDIN_FILENO;<\/code><\/p>\n<p>The <code>EPOLLIN<\/code> defined constant sets an input event and <code>STDIN_FILENO<\/code> is the file descriptor for standard input (defined in the <code>unistd.h<\/code> header file). The <em>epoll_ctl()<\/em> function adds a control interface for the <code>evin<\/code> file descriptor:<\/p>\n<p><code>epoll_ctl(fd, EPOLL_CTL_ADD, STDIN_FILENO, &amp;evin)<\/code><\/p>\n<p>With everything set up, the endless <em>while<\/em> loop starts outputting letters of the alphabet, A through Z.<\/p>\n<p>Within the loop, the <em>epoll_wait()<\/em> function obtains the number of monitored file descriptors ready for I\/O. A <em>for<\/em> loop scans these descriptors. When one of the events monitored matches the standard input file descriptor, the loop is broken.<\/p>\n<p>For output, the program spews forth the alphabet over and over. You can type away at the keyboard, but only when you press the Enter key does the output stop. This behavior is identical to <em>select()<\/em> example from last week&#8217;s Lesson. Again, it&#8217;s a reason I wouldn&#8217;t choose this approach to monitor the keyboard as the <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=6305\"><em>kbhit()<\/em> function<\/a> does a far better job.<\/p>\n<p>I would love to dive in deeper for network programming, but it&#8217;s truly a complex topic and the code can be long and tedious. Further, to do any real testing you need multiple network devices available to confirm that everything works properly. Even given all that, it&#8217;s a fun task, and I may write an eBook on it in the future.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>It&#8217;s not perfect, but the <em>epoll()<\/em> functions can also scan for pending standard input. <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=6345\">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-6345","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\/6345","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=6345"}],"version-history":[{"count":3,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/6345\/revisions"}],"predecessor-version":[{"id":6357,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/6345\/revisions\/6357"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=6345"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=6345"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=6345"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}