{"id":7727,"date":"2026-08-22T00:01:34","date_gmt":"2026-08-22T07:01:34","guid":{"rendered":"https:\/\/c-for-dummies.com\/blog\/?p=7727"},"modified":"2026-08-15T13:02:25","modified_gmt":"2026-08-15T20:02:25","slug":"two-file-descriptors","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=7727","title":{"rendered":"Two File Descriptors?"},"content":{"rendered":"<p>Having two file descriptors available to access the same file might seem redundant. In a way it is. It&#8217;s like having two sets of keys to a car: Yes, one could be a backup, but it&#8217;s more common that two different people are using the same car. But first, an example is necessary.<br \/>\n<!--more--><br \/>\nContinuing from <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=7720\">last week&#8217;s Lesson<\/a>, the following code opens a file for low-level writing access. Immediately, a second (duplicate) file descriptor is summoned. As with last week&#8217;s code, separate <em>write()<\/em> statements use both descriptors to send text to the file. But this time, after the second descriptor is closed, more text is written to the file by using the remaining, open file descriptor:<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2026_08_22-Lesson.c\" rel=\"noopener\" target=\"_blank\">2026_08_22-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;fcntl.h&gt;\r\n#include &lt;stdlib.h&gt;\r\n\r\nint main()\r\n{\r\n    char filename[] = \"test.txt\";\r\n    int fd1,fd2;\r\n\r\n    <span class=\"comments\">\/* open\/create the file *\/<\/span>\r\n    fd1 = creat(filename,0);\r\n    <span class=\"comments\">\/* duplicate the handle *\/<\/span>\r\n    fd2 = dup(fd1);\r\n    if( fd1==-1 || fd2==-1 )\r\n    {\r\n        fprintf(stderr,\"Oh we got file problems!\\n\");\r\n        exit(1);\r\n    }\r\n\r\n    <span class=\"comments\">\/* write data to the file *\/<\/span>\r\n    write(fd1,\"Hello, \",7);\r\n    write(fd2,\"world!\\n\",8);\r\n\r\n    <span class=\"comments\">\/* close the duplicate fd *\/<\/span>\r\n    close(fd2);\r\n\r\n    <span class=\"comments\">\/* continue with fd1 *\/<\/span>\r\n    write(fd1,\"I mean Earth!\\n\",15);\r\n\r\n    <span class=\"comments\">\/* clean-up *\/<\/span>\r\n    close(fd1);\r\n    return 0;\r\n}<\/pre>\n<p>To reduce the number of lines in the code, I open the file for low-level access then immediately use the <em>dup(<\/em>) function to create the duplicate file descriptor. Both variables (<code>fd1<\/code> and <code>fd2<\/code>) are then tested for success. It would be better to test <code>fd1<\/code> immediately after calling the <em>creat()<\/em> function, which is what I would do with code released to the wild.<\/p>\n<p>Two <em>write()<\/em> statements use separate descriptors to write text to the file. The text is written sequentially as both descriptors reference the same file, same offset, same everything at this point.<\/p>\n<p>File descriptor <code>fd2<\/code> is then closed, but <code>fd1<\/code> remains open. So the final <em>write()<\/em> statement adds text to the file by using <code>fd1<\/code>.<\/p>\n<p>The program has no output, though the file <code>test.txt<\/code> is written. Here are its contents:<\/p>\n<pre>Hello, world!\r\nI mean Earth!<\/pre>\n<p>At this point, using the separate file descriptors doesn&#8217;t provide any advantage over using a single descriptor. No, the advantage comes by using the <em>fcntl()<\/em> function on one of the file descriptors. In fact, you might have noticed that the <code>fcntl.h<\/code> header is included in the source code. This function, which I believe stands for &#8220;file control,&#8221; lets you manipulate how a file is accessed at a low level, even after the file is opened. It&#8217;s this function that makes the second file descriptor useful, through doing so adds a level of complexity that&#8217;s a bit too deep for me to get into here. Still, that&#8217;s the reason for creating the duplicate.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Yes, you can have two file descriptors referencing the same open file. It&#8217;s weird, and potentially useful. <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=7727\">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-7727","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\/7727","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=7727"}],"version-history":[{"count":3,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/7727\/revisions"}],"predecessor-version":[{"id":7740,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/7727\/revisions\/7740"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=7727"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=7727"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=7727"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}