title: Read() is returning without reading
body: <p>I did a project for college where I had to implement a function that:</p>
  <blockquote>
  <p>Repeated calls (e.g., using a loop) to <code>get_next_line()</code> should let you read the text file pointed to by the file descriptor, one line at a time.
  Returns the line that was read. If there is nothing else to read or if an error occurred, it returns <code>NULL</code>.
  The returned line includes the terminating <code>\n</code> character, except if the end of file was reached and does not end with a <code>\n</code> character.</p>
  </blockquote>
  <p>However now that I am doing another project I had to implement this function to read a file and noticed that it crashes my program with SIGABRT whenever finish reading a file close it and then run it on the same file descriptor again.</p>
  <p>(run <code>get_next_line()</code> several times until end of file; close file; open it again on same fd; run <code>get_next_line()</code>).</p>
  <p>However for the life of me I can't figure out what is causing this. I suspect some weird behaviour of <code>read()</code> but I am not sure.</p>
  <p>My code:</p>
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;string.h&gt;
  #include &lt;math.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;unistd.h&gt;
  #include &lt;fcntl.h&gt;
  #define BUFFER_SIZE 42
  #define NUM_OF_FD 255
  
  size_t  ft_strlen(const char *s)
  {
      size_t  i;
  
      if (!s)
          return (0);
      i = 0;
      while (s[i])
      {
          i++;
      }
      return (i);
  }
  
  char    *ft_strchr(const char *s, int c)
  {
      char    chr;
  
      chr = (char)c;
      if(!s)
          return (NULL);
      while (*s &amp;&amp; *s != chr)
          s++;
      if (*s == chr)
          return ((char *)s);
      else
          return (NULL);
  }
  
  char    *strldup(char *s1, int start, int end)
  {
      char    *ptr;
      int     i;
  
      i = 0;
      ptr = malloc(end - start + 1);
      if (!ptr)
          return (NULL);
      while (start &lt; end)
          ptr[i++] = s1[start++];
      ptr[i] = 0;
      return (ptr);
  }
  
  /*
      Allocates (with malloc) and returns a new string,
      result of the concatenation of s1 and s2
      S1 is freed
  */
  char    *ft_strjoinfree(char *s1, char *s2)
  {
      int     i;
      char    *str;
      char    *hld;
      size_t  size;
  
      if (!s1 &amp;&amp; !s2)
          return (NULL);
      i = 0;
      size = (ft_strlen(s1) + ft_strlen(s2) + 1);
      str = malloc(sizeof(char) * size);
      if (!str)
          return (NULL);
      hld = s1;
      if (s1)
          while (*s1)
              str[i++] = *s1++;
      if (s2)
          while (*s2)
              str[i++] = *s2++;
      str[i] = '\0';
      if (hld)
          free(hld);
      return (str);
  }
  
  char    *returner(char **backup, int fd)
  {
      int     index;
      char    *line;
      char    *temp;
  
      index = ft_strchr(backup[fd], '\n') - backup[fd] + 1;
      line = strldup(backup[fd], 0, index);
      temp = strldup(backup[fd], index, ft_strlen(backup[fd]));
      free(backup[fd]);
      backup[fd] = temp;
      return (line);
  }
  
  char    *cycle(char **backup, int fd, char *buf)
  {
      int size;
  
      size = read(fd, buf, BUFFER_SIZE);
      buf[size] = '\0';
      while (size &gt; 0)
      {
          backup[fd] = ft_strjoinfree(backup[fd], buf);
          if (ft_strchr(backup[fd], '\n') != NULL)
              return (returner(backup, fd));
          size = read(fd, buf, BUFFER_SIZE);
          buf[size] = '\0';
      }
      return (NULL);
  }
  
  char    *get_next_line(int fd)
  {
      char        buf[BUFFER_SIZE + 1];
      static char *backup[NUM_OF_FD];
      char        *line;
  
      if (fd &lt; 0 || fd &gt; NUM_OF_FD)
          return (NULL);
      line = NULL;
      if (ft_strchr(backup[fd], '\n') == NULL)
      {
          line = cycle(backup, fd, buf);
          if (line != NULL)
              return (line);
      }
      else
          return (returner(backup, fd));
      if (backup[fd] != NULL &amp;&amp; *backup[fd] != '\0')
      {
          line = backup[fd];
          backup[fd] = NULL;
          return (line);
      }
      free(line);
      free(backup[fd]);
      return (NULL);
  }
  
  
  int main(int argc, char **argv)
  {
      int     fd;
      char    *line;  
  
      //open file
      if (argc != 2)
          exit(1);
      fd = open(argv[1], O_RDONLY);
      if (fd &lt; 0)
          exit(2);
  
      //check file and get sizes
      line = get_next_line(fd);
      while (line != NULL)
      {
          printf(&quot;%s&quot;, line);
          free(line);
          line = NULL;
          line = get_next_line(fd);
      }
      close(fd);
  
      fd = open(argv[1], O_RDONLY);
      if (fd &lt; 0)
          exit(2);
      //Generates SIGABRT
      line = get_next_line(fd);
      while (line != NULL)
          {
          printf(&quot;%s&quot;, line);
          free(line);
          line = NULL;
          line = get_next_line(fd);
      }
      close(fd);
  }
  </code></pre>
  <p>File:</p>
  <pre><code>0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  0  0 10 10  0  0 10 10  0  0  0 10 10 10 10 10  0  0  0
  0  0 10 10  0  0 10 10  0  0  0  0  0  0  0 10 10  0  0
  0  0 10 10  0  0 10 10  0  0  0  0  0  0  0 10 10  0  0
  0  0 10 10 10 10 10 10  0  0  0  0 10 10 10 10  0  0  0
  0  0  0 10 10 10 10 10  0  0  0 10 10  0  0  0  0  0  0
  0  0  0  0  0  0 10 10  0  0  0 10 10  0  0  0  0  0  0
  0  0  0  0  0  0 10 10  0  0  0 10 10 10 10 10 10  0  0
  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  </code></pre>
  <p>I get <code>SIGABRT</code></p>
  <p>I know that the <code>SIGABRT</code> is coming from the <code>free()</code> in <code>ft_strjoinfree</code> but for that to happen read must return a value but read nothing.</p>
  <p>Note that the code is formatted that way as it is a college requirement no more than 25 lines per function.</p>