title: Finding the size of a file stream using file descriptors in C
body: <p>As a school assignment, I'm writing a simple HTTP webserver in C.
  I have most of the code ready to go, but <code>send()</code>/<code>write()</code> requires the length of the message to be sent.</p>
  
  <p>This is where I'm struggling. <code>fseek()</code> doesn't work and so <code>ftell()</code> returns an "Illegal seek" <code>errno</code>. After identifying the method and retrieving the correct response code, I use <code>fprintf()</code> to write directly to the file stream. </p>
  
  <pre><code>static void response(FILE *response, int code, char *path, int fd)
  {
      FILE *body;
      char *line = makestring(300) //Creates an empty string of size 300
  
      ... // Replace code in between with other code block
  
      if(code == 200){
          http_ok(response); //A function with fprintf's to write the headers.
          body = fopen(path, "w");
  
          while(!feof(body)){
              fgets(line, 300, body);
              fprintf(response, "%s\r\n", line);
          }
  
      fclose(body);
      }
  
      ... // Replace up to this point
  
  fseek(response, 0L, SEEK_END);
  int response_size = ftell(response);
  rewind(response);
  
  send(fd, response, response_size, 0);
  }
  </code></pre>
  
  <p>Now, this is a simplified version of my code, including only the status 200.
  The thing is here the response is returned properly, and the page opens in the browser. However, the <code>response_size</code> variable always prints to <code>-1</code>.</p>
  
  <p>Now proceeding the the status code 301 Moved Permanently, it's not working at all. This code can go as a replacement for the other <code>if</code>-statement between the two "..."s</p>
  
  <pre><code>...
  if(code == 301){
      http_moved(response, path);
  }
  ...
  </code></pre>
  
  <p>The http-functions have a general look like this</p>
  
  <pre><code>void http_ok/moved(FILE *response)
  {
      fprintf(response, "Correct codes and headers for the response type here\r\n")
      ...
      fprintf(response, "\r\n\r\n")
  }
  </code></pre>
  
  <p>The response <code>FILE</code> is opened on the socket's file descriptor using <code>fdopen(sockfd, "w")</code>, so it's not a normal <code>fopen()</code>. As far as my understanding goes, this means <code>fseek()</code> won't work as intended.</p>
  
  <p>As for the question itself, how can I get the proper length of the http response when I'm using the file descriptors?</p>