title: C getline() returns -1 before EOF
body: <p>I'm using the getline() function in a c program to read lines from a file, place read info into a struct, creates a thread with that struct as an argument, and repeat.
  However, it getline() returns -1 before the EOF, after the second set of arguments under "id: test2" in the file provided.<br>
  Since <code>print errno</code> in gdb returns 0, I assume there's no error and getline() somehow seems to believe it has reached EOF.<br>
  The create thread portion has been commented out because it's unrelated to the problem at hand.  </p>
  
  <p>The code:</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;string.h&gt;
  #include &lt;signal.h&gt;
  #include &lt;fcntl.h&gt;
  #include &lt;unistd.h&gt;
  #include &lt;sys/socket.h&gt;
  #include &lt;netinet/in.h&gt;
  #include &lt;arpa/inet.h&gt;
  #include &lt;pthread.h&gt;
  #include &lt;sys/time.h&gt;
  
  #define BUFFER_SIZE 256
  
  time_t cur;
  char* keypath = "home/chy/.ssh/id_rsa";
  int logfreq = 1;
  int hashfreq = 180;
  
  struct getArgs
  {
    const char* id;
    const char* hostaddr;
    uint16_t port;
    const char* uname;
    const char* path;
  };
  
  int main(int argc, char **argv)
  {
    int th_max = 5;
    int th_count = 0;
    pthread_t* ths = (pthread_t*) malloc(th_max * sizeof(pthread_t));
  
    FILE* fp;
    fp = fopen("config.txt", "r");
  
    char* line = NULL;
    char buf[128];
    int r = 0;
    size_t len = 0;
    ssize_t read;
  
    system("mkdir logs &amp;&amp; chmod -R a+r logs");
  
    while(1)
    {
      pthread_t th;
  //Get ID
      while((read = getline(&amp;line, &amp;l, fp)) != -1)
      {
        if(!(read &gt; 0))
          continue;
        if(sscanf(line, "id: %[^\n]\n", buf) == 1)
          break;
        if(sscanf(line, "keypath: %[^\n]\n", buf) == 1)
          keypath = strdup(buf);
        else if(sscanf(line, "logfreq: %d\n", &amp;r) == 1)
          logfreq = r;
        else if(sscanf(line, "hashfreq: %d\n", &amp;r) == 1)
          hashfreq = r;
      }
      if(read == -1)
        break;
      struct getArgs* args = (struct getArgs*)malloc(sizeof(struct getArgs));
      args-&gt;id = strdup(buf);
  //Get Host Address
      if(getline(&amp;line, &amp;len, fp) == -1)
      {
        free_args(args);
        break;
      }
      if(sscanf(line, "hostaddr: %[^\n]\n", buf) != 1)
      {
        free_args(args);
        continue;
      }
      args-&gt;hostaddr = strdup(buf);
  //Get Port Number
      if(getline(&amp;line, &amp;len, fp) == -1)
      {
        free_args(args);
        break;
      }
      if(sscanf(line, "port: %d\n", &amp;r) != 1)
      {
        free_args(args);
        continue;
      }
      args-&gt;port = r;
  //Get Username
      if(getline(&amp;line, &amp;len, fp) == -1)
      {
        free_args(args);
        break;
      }
      if(sscanf(line, "username: %[^\n]\n", buf) != 1)
      {
        free_args(args);
        continue;
      }
  args-&gt;uname = strdup(buf);
  //def Path
      if(getline(&amp;line, &amp;len, fp) == -1)
      {
        free_args(args);
        break;
      }
      if(sscanf(line, "path: %[^\n]\n", buf) != 1)
      {
        free_args(args);
        continue;
      }
      args-&gt;path = strdup(buf);
  
  //    int err = pthread_create(&amp;th, NULL, &amp;getFiles, args);
  
      if(th_count &gt; th_max)
      {
        th_max *= 2;
        ths = (pthread_t*)realloc(ths, th_max * sizeof(pthread_t));
      }
      *(ths+th_count * sizeof(pthread_t)) = th;
      th_count++;
    }
  
    fclose(fp);
  
    while(1);
  }
  </code></pre>
  
  <p>The file:</p>
  
  <pre><code>keypath: /home/username/.ssh/id_rsaNOPASSWORD
  id: test1
  hostaddr: XXX.XXX.XXX.XXX
  port: 22
  username: hpc
  path: /home/hpc/
  id: test2
  hostaddr: XXX.XXX.XXX.XXX
  port: 22
  username: hpc
  path: /home/hpc/
  id: test3
  hostaddr: XXX.XXX.XXX.XXX
  port: 22
  username: hpc
  path: /home/hpc/
  id: test4
  hostaddr: XXX.XXX.XXX.XXX
  port: 3844
  username: uname
  path: /home/uname/hpc/
  </code></pre>
  
  <p>The contents of file pointer before the last getline():</p>
  
  <pre><code>{_flags = -72539000,
    _IO_read_ptr = 0x7ffff7ff80d0 "    \nid: test3\nhostaddr: XXX.XXX.XXX.XXX\nport: 22\nusername: hpc\npath: /home/hpc/\n    \nid: test4\nhostaddr: XXX.XXX.XXX.XXX\nport: 3844\nusername: uname\npath: /home/uname/hpc/\n\n",
    _IO_read_end = 0x401d10 "H\211l$\330L\211d$\340H\215-\277\006 ",
    _IO_read_base = 0x7ffff7ff8000 "keypath: /home/username/.ssh/id_rsaNOPASSWORD\n    \nid: test1\nhostaddr: XXX.XXX.XXX.XXX\nport: 22\nusername: hpc\npath: /home/hpc/\n    \nid: test2\nhostaddr: XXX.XXX.XXX.XXX\nport: 22\nusername: hpc\npath: /ho"...,
    _IO_write_base = 0x7ffff7ff8000 "keypath: /home/username/.ssh/id_rsaNOPASSWORD\n    \nid: test1\nhostaddr: XXX.XXX.XXX.XXX\nport: 22\nusername: hpc\npath: /home/hpc/\n    \nid: test2\nhostaddr: XXX.XXX.XXX.XXX\nport: 22\nusername: hpc\npath: /ho"...,
    _IO_write_ptr = 0x7ffff7ff8000 "keypath: /home/username/.ssh/id_rsaNOPASSWORD\n    \nid: test1\nhostaddr: XXX.XXX.XXX.XXX\nport: 22\nusername: hpc\npath: /home/hpc/\n    \nid: test2\nhostaddr: XXX.XXX.XXX.XXX\nport: 22\nusername: hpc\npath: /ho"...,
    _IO_write_end = 0x7ffff7ff8000 "keypath: /home/username/.ssh/id_rsaNOPASSWORD\n    \nid: test1\nhostaddr: XXX.XXX.XXX.XXX\nport: 22\nusername: hpc\npath: /home/hpc/\n    \nid: test2\nhostaddr: XXX.XXX.XXX.XXX\nport: 22\nusername: hpc\npath: /ho"...,
    _IO_buf_base = 0x7ffff7ff8000 "keypath: /home/username/.ssh/id_rsaNOPASSWORD\n    \nid: test1\nhostaddr: XXX.XXX.XXX.XXX\nport: 22\nusername: hpc\npath: /home/hpc/\n    \nid: test2\nhostaddr: XXX.XXX.XXX.XXX\nport: 22\nusername: hpc\npath: /ho"..., _IO_buf_end = 0x7ffff7ff9000 "P\220\377\367\377\177", _IO_save_base = 0x0, _IO_backup_base = 0x0, _IO_save_end = 0x0, _markers = 0x0, _chain = 0x7ffff7bbb880, _fileno = 7, _flags2 = 0, _old_offset = 0, _cur_column = 0,
    _vtable_offset = 0 '\000', _shortbuf = "", _lock = 0x603120, _offset = -1, __pad1 = 0x0, __pad2 = 0x603130, __pad3 = 0x0, __pad4 = 0x0, __pad5 = 0, _mode = -1, _unused2 = '\000' &lt;repeats 19 times&gt;}
  </code></pre>
  
  <p>After:</p>
  
  <pre><code>{_flags = -72538984,
    _IO_read_ptr = 0x7ffff7ff8000 "keypath: /home/username/.ssh/id_rsaNOPASSWORD\n    \nid: test1\nhostaddr: XXX.XXX.XXX.XXX\nport: 22\nusername: hpc\npath: /home/hpc/\n    \nid: test2\nhostaddr: XXX.XXX.XXX.XXX\nport: 22\nusername: hpc\npath: /ho"...,
    _IO_read_end = 0x7ffff7ff8000 "keypath: /home/username/.ssh/id_rsaNOPASSWORD\n    \nid: test1\nhostaddr: XXX.XXX.XXX.XXX\nport: 22\nusername: hpc\npath: /home/hpc/\n    \nid: test2\nhostaddr: XXX.XXX.XXX.XXX\nport: 22\nusername: hpc\npath: /ho"...,
    _IO_read_base = 0x7ffff7ff8000 "keypath: /home/username/.ssh/id_rsaNOPASSWORD\n    \nid: test1\nhostaddr: XXX.XXX.XXX.XXX\nport: 22\nusername: hpc\npath: /home/hpc/\n    \nid: test2\nhostaddr: XXX.XXX.XXX.XXX\nport: 22\nusername: hpc\npath: /ho"...,
    _IO_write_base = 0x7ffff7ff8000 "keypath: /home/username/.ssh/id_rsaNOPASSWORD\n    \nid: test1\nhostaddr: XXX.XXX.XXX.XXX\nport: 22\nusername: hpc\npath: /home/hpc/\n    \nid: test2\nhostaddr: XXX.XXX.XXX.XXX\nport: 22\nusername: hpc\npath: /ho"...,
    _IO_write_ptr = 0x7ffff7ff8000 "keypath: /home/username/.ssh/id_rsaNOPASSWORD\n    \nid: test1\nhostaddr: XXX.XXX.XXX.XXX\nport: 22\nusername: hpc\npath: /home/hpc/\n    \nid: test2\nhostaddr: XXX.XXX.XXX.XXX\nport: 22\nusername: hpc\npath: /ho"...,
    _IO_write_end = 0x7ffff7ff8000 "keypath: /home/username/.ssh/id_rsaNOPASSWORD\n    \nid: test1\nhostaddr: XXX.XXX.XXX.XXX\nport: 22\nusername: hpc\npath: /home/hpc/\n    \nid: test2\nhostaddr: XXX.XXX.XXX.XXX\nport: 22\nusername: hpc\npath: /ho"...,
    _IO_buf_base = 0x7ffff7ff8000 "keypath: /home/username/.ssh/id_rsaNOPASSWORD\n    \nid: test1\nhostaddr: XXX.XXX.XXX.XXX\nport: 22\nusername: hpc\npath: /home/hpc/\n    \nid: test2\nhostaddr: XXX.XXX.XXX.XXX\nport: 22\nusername: hpc\npath: /ho"..., _IO_buf_end = 0x7ffff7ff9000 "P\220\377\367\377\177", _IO_save_base = 0x0, _IO_backup_base = 0x0, _IO_save_end = 0x0, _markers = 0x0, _chain = 0x7ffff7bbb880, _fileno = 7, _flags2 = 0, _old_offset = 0, _cur_column = 0,
    _vtable_offset = 0 '\000', _shortbuf = "", _lock = 0x603120, _offset = -1, __pad1 = 0x0, __pad2 = 0x603130, __pad3 = 0x0, __pad4 = 0x0, __pad5 = 0, _mode = -1, _unused2 = '\000' &lt;repeats 19 times&gt;}
  </code></pre>
  
  <p>I also attempted to implement the same with fgets() instead of getline(), but with the same results.<br>
  What might be causing this problem?</p>
  
  <p>Edit:<br>
  I have ran the code over the same file, except without excess spaces/blank lines as well as switching up the order to see if anything is affected, but the results are the same.<br>
  I can also confirm that the structure for test1 and test2 are properly populated.</p>
  
  <pre><code>{id = 0x6032e0 "test1", hostaddr = 0x603300 "XXX.XXX.XXX.XXX", port = 22, uname = 0x603320 "hpc", path = 0x603340 "/home/hpc/"}
  {id = 0x603390 "test2", hostaddr = 0x6033b0 "XXX.XXX.XXX.XXX", port = 22, uname = 0x6033d0 "hpc", path = 0x6033f0 "/home/hpc/"}
  </code></pre>
  
  <p>edits:
  version change to code and file</p>