title: Question about linked lists and reading from multiple files in C
body: <p>Here is a problem I am trying to solve. I have a task to create a function, which has to return newline from the file(accessing with fd). It has to use only functions <code>read</code>,<code>malloc</code>,<code>free</code> and the functions I wrote.</p>
  <p>I used linked lists to add and save the data from the files. 1 node represents 1 specific file.</p>
  <p>Please help me find out what is the problem in this case. It works well in all cases except when <code>BUFFER_SIZE</code> is <em>1</em> and we gave him more than <em>2</em> file descriptors.</p>
  <p>In the firs call of <code>get_next_line</code> function it reads well for first 2 file descriptors and returns the line properly. For the 3rd fd it returns 2nd file descriptors data. At the second call it returns 2nd line of each fd(1st and 2nd) and returns 1st line of 3rd file.</p>
  <p>Here is the way I have to compile my files for using this function.</p>
  <pre><code>gcc -Wall -Wextra -Werror -D BUFFER_SIZE=1 get_next_line_bonus.c get_next_line_utils_bonus.c get_next_line.h main.c 
  
  ./a.out
  </code></pre>
  <p><strong>get_next_line.h</strong></p>
  <pre><code># define GET_NEXT_LINE_H
  # include &lt;unistd.h&gt;
  # include &lt;stdlib.h&gt;
  
  typedef struct  s_info
  {
  
      int             fd;
      char            *info;
      int             check;
      struct s_info   *next;
  }               t_info;
  
  int             get_next_line(int fd, char **line);
  
  t_info          *ft_lstnew(int fd);
  
  char            *get_line(char *str);
  
  int             ncheck(char *str);
  
  unsigned long   ft_strlen(const char *s);
  
  char            *get_save(char *save);
  
  void            *ft_memmove(void *dest, const void *src, size_t len);
  
  char            *ft_strjoin(char const *s1, char const *s2);
  
  t_info          *ft_find(int fd, t_info **start);
  
  int             ft_lstdelone(t_info **start, int fd);
  
  #endif
  </code></pre>
  <p><strong>get_next_line.c</strong></p>
  <pre><code>
  size_t  ft_strlen(const char *s)
  {
      int i;
  
      i = 0;
      if (!s)
          return (0);
      while (s[i] != '\0')
          i++;
      return (i);
  }
  
  char    *ft_strjoin(char const *s1, char const *s2)
  {
      size_t  s1_len;
      size_t  s2_len;
      size_t  stot_len;
      char    *rtn;
  
      if (!s1 &amp;&amp; !s2)
          return (0);
      s1_len = ft_strlen((char *)s1);
      s2_len = ft_strlen((char *)s2);
      stot_len = s1_len + s2_len + 1;
      rtn = malloc(sizeof(char) * stot_len);
      if (!rtn)
          return (0);
      ft_memmove(rtn, s1, s1_len);
      ft_memmove(rtn + s1_len, s2, s2_len);
      rtn[stot_len - 1] = '\0';
      free((char *)s1);
      return (rtn);
  }
  
  t_info  *ft_lstnew(int fd)
  {
      t_info  *i;
  
      if ((i = (t_info*)malloc(sizeof(t_info))) == 0)
          return (0);
      i-&gt;fd = fd;
      if ((i-&gt;info = malloc(sizeof(char*) * (1 + BUFFER_SIZE))) == 0)
          return (0);
      i-&gt;check = 1;
      i-&gt;next = NULL;
      return (i);
  }
  
  t_info  *ft_find(int fd, t_info **start)
  {
      t_info *finder;
      t_info *new;
  
      finder = *start;
      while (finder)
      {
          if (finder-&gt;fd == fd)
              return (finder);
          finder = finder-&gt;next;
      }
      if ((new = ft_lstnew(fd)) == 0)
          return (0);
      if (!(*start))
      {
          *start = new;
          return (new);
      }
      new-&gt;next = *start;
      *start = new;
      return (new);
  }
  
  int     get_next_line(int fd, char **line)
  {
      static t_info   *start = NULL;
      t_info          *tmp;
      char            *buff;
  
      if (fd &lt; 0 || !line || BUFFER_SIZE &lt;= 0 ||
      ((tmp = ft_find(fd, &amp;start)) == 0) ||
      !(buff = malloc(sizeof(char) * (BUFFER_SIZE + 1))))
          return (-1);
      while (!ncheck(tmp-&gt;info) &amp;&amp; tmp-&gt;check != 0)
      {
          if ((tmp-&gt;check = read(fd, buff, BUFFER_SIZE)) == -1)
          {
              free(buff);
              return (-1);
          }
          buff[tmp-&gt;check] = '\0';
          tmp-&gt;info = ft_strjoin(tmp-&gt;info, buff);
      }
      free(buff);
      *line = get_line(tmp-&gt;info);
      tmp-&gt;info = get_save(tmp-&gt;info);
      if (tmp-&gt;check == 0)
          return (ft_lstdelone(&amp;start, fd));
      return (1);
  }
  </code></pre>
  <p><strong>get_next_line_utils.c</strong></p>
  <pre><code>
  char        *get_save(char *save)
  {
      char    *rtn;
      int     i;
      int     j;
  
      i = 0;
      j = 0;
      if (!save)
          return (0);
      while (save[i] &amp;&amp; save[i] != '\n')
          i++;
      if (!save[i])
      {
          free(save);
          return (0);
      }
      if (!(rtn = malloc(sizeof(char) * ((ft_strlen(save) - i) + 1))))
          return (0);
      i++;
      while (save[i])
          rtn[j++] = save[i++];
      rtn[j] = '\0';
      free(save);
      return (rtn);
  }
  
  char        *get_line(char *str)
  {
      int     i;
      char    *rtn;
  
      i = 0;
      if (!str)
          return (0);
      while (str[i] &amp;&amp; str[i] != '\n')
          i++;
      if (!(rtn = malloc(sizeof(char) * (i + 1))))
          return (0);
      i = 0;
      while (str[i] &amp;&amp; str[i] != '\n')
      {
          rtn[i] = str[i];
          i++;
      }
      rtn[i] = '\0';
      return (rtn);
  }
  
  void        *ft_memmove(void *dst, const void *src, size_t len)
  {
      char *d;
      char *s;
  
      d = (char *)dst;
      s = (char *)src;
      if (dst == src)
          return (dst);
      if (s &lt; d)
      {
          while (len--)
              *(d + len) = *(s + len);
          return (dst);
      }
      while (len--)
          *d++ = *s++;
      return (dst);
  }
  
  int         ncheck(char *str)
  {
      int i;
  
      i = 0;
      if (!str)
          return (0);
      while (str[i])
      {
          if (str[i] == '\n')
              return (1);
          i++;
      }
      return (0);
  }
  
  int         ft_lstdelone(t_info **start, int fd)
  {
      t_info *finder;
      t_info *tmp;
  
      finder = *start;
      if (finder-&gt;fd == fd)
      {
          free(finder-&gt;info);
          *start = (*start)-&gt;next;
          free(finder);
      }
      else
      {
          while (finder-&gt;next-&gt;fd != fd &amp;&amp; finder-&gt;next)
              finder = finder-&gt;next;
          free(finder-&gt;next-&gt;info);
          tmp = finder-&gt;next;
          finder-&gt;next = tmp-&gt;next;
          free(tmp);
      }
      return (0);
  }
  </code></pre>
  <p>Here is the behaviour of my test main I used.</p>
  <p>c1r6s3% gcc -Wall -Wextra -Werror -D BUFFER_SIZE=1 get_next_line_bonus.c get_next_line_utils_bonus.c get_next_line.h main.c &amp;&amp; ./a.out</p>
  <p>1st call</p>
  <p>buffer1=t morning; should have arrived at 6:46, but train w</p>
  <p>buffer2=1.Aasdasndmbc  <strong>this is 1st line of 2nd file</strong></p>
  <p>buffer3=1.Aasdasndmbc  <strong>this is not what supposed to be in 3rd file</strong></p>
  <p>2nd call</p>
  <p>buffer1=as anhour late. Buda-Pesth seems a wonderful place, from the glimpse which Igot of it from the train</p>
  <p>buffer2=2.Dcccsadkajskldjaskld</p>
  <p>buffer3=1.Abc    <strong>1st line of 3rd file</strong></p>
  <p>buffer1=and the little I could walk through thestreets. I feared to go very far from the station, as we had arr</p>
  <p>buffer2=3.Saksadklasjdlkasjd</p>
  <p>buffer3=2.Dccc</p>
  <p>buffer1=ivedlate and would start as near the correct time as possible. Theimpression I had was that we were leaving the West and entering theEast; the most western of splendid bridges over the Danube, which ish</p>
  <p>buffer2=4.Sakdljlkasjdlkasjsadlkasjdklasjd</p>
  <p>buffer3=3.Sak</p>