{"id":357,"date":"2018-11-07T21:59:02","date_gmt":"2018-11-07T13:59:02","guid":{"rendered":"https:\/\/codestrian.com\/?p=357"},"modified":"2018-11-07T22:03:10","modified_gmt":"2018-11-07T14:03:10","slug":"a-simple-implementation-of-the-tee-command","status":"publish","type":"post","link":"https:\/\/codestrian.com\/index.php\/2018\/11\/07\/a-simple-implementation-of-the-tee-command\/","title":{"rendered":"A simple implementation of the &#8220;tee&#8221; command"},"content":{"rendered":"<p>Recently, I have started to read the book \"The Linux Programming Interface\". In chapter 4 of the book, the reader is given the exercise to create the <strong>tee<\/strong> command. For those of you who is not familiar what a <strong>tee<\/strong> command does, it is a simple command that reads the input from <em>stdin<\/em> and write it to a file as well as the <em>stdout<\/em>. So with that in mind, below is my solution to the exercise.<\/p>\n<pre><code>#include &lt;sys\/types.h&gt;\n#include &lt;sys\/stat.h&gt;\n#include &lt;fcntl.h&gt;\n#include \".\/tlpi-dist\/lib\/tlpi_hdr.h\" \/\/ You may download this header file from book author's website\n\n#ifndef BUF_SIZE\n#define BUF_SIZE 1024\n#endif\n\nint main(int argc, char *argv[]){\n  int flags, output_fd;\n  ssize_t num_read;\n  char buffer[BUF_SIZE];\n  char *file_name;\n  if (argc &gt; 3 || strcmp(argv[1], \"--help\") == 0)\n    usageErr(\"%s [-a] filename\\n\", argv[0]);\n\n  if(strcmp(argv[1], \"-a\") == 0) {\n    flags = O_CREAT | O_APPEND | O_WRONLY;\n    file_name = argv[2];\n  } else {\n    flags = O_CREAT | O_TRUNC | O_WRONLY;\n    file_name = argv[1];\n  }\n\n  mode_t file_perm = S_IRUSR | S_IWUSR | S_IXUSR | \n                     S_IRGRP | S_IWGRP | S_IXGRP |\n                     S_IROTH | S_IWOTH | S_IXOTH; \/\/ file permission 777\n\n  output_fd = open(file_name, flags, file_perm);\n  if (output_fd == -1)\n    errExit(\"opening file %s\", argv[1]);\n\n  while((num_read = read(0, buffer, BUF_SIZE)) &gt; 0){\n    if(write(1, buffer, num_read) != num_read)\n      fatal(\"couldn't write whole buffer stdou\");\n    if(write(output_fd, buffer, num_read) != num_read)\n      fatal(\"couldn't write whole buffer to %s\", output_fd);\n  }\n\n  if(num_read == -1)\n    errExit(\"read\");\n\n  if (close(output_fd) == -1)\n    errExit(\"close file %s\", argv[1]);\n\n  exit(EXIT_SUCCESS);\n}\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Recently, I have started to read the book &#8220;The Linux Programming Interface&#8221;. In chapter 4 of the book, the reader is given the exercise to create the tee command. For those of you who is not familiar what a tee command does, it is a simple command that reads the [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[42],"tags":[43,51],"_links":{"self":[{"href":"https:\/\/codestrian.com\/index.php\/wp-json\/wp\/v2\/posts\/357"}],"collection":[{"href":"https:\/\/codestrian.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/codestrian.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/codestrian.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/codestrian.com\/index.php\/wp-json\/wp\/v2\/comments?post=357"}],"version-history":[{"count":4,"href":"https:\/\/codestrian.com\/index.php\/wp-json\/wp\/v2\/posts\/357\/revisions"}],"predecessor-version":[{"id":362,"href":"https:\/\/codestrian.com\/index.php\/wp-json\/wp\/v2\/posts\/357\/revisions\/362"}],"wp:attachment":[{"href":"https:\/\/codestrian.com\/index.php\/wp-json\/wp\/v2\/media?parent=357"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/codestrian.com\/index.php\/wp-json\/wp\/v2\/categories?post=357"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/codestrian.com\/index.php\/wp-json\/wp\/v2\/tags?post=357"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}