Home | History | Annotate | Download | only in plugin
      1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // Some common file utilities for plugin code.
      6 
      7 #include "ppapi/native_client/src/trusted/plugin/file_utils.h"
      8 
      9 #include <fcntl.h>
     10 #include <stdio.h>
     11 #include <stdlib.h>
     12 
     13 #include <sys/stat.h>
     14 #include <sys/types.h>
     15 
     16 #include "native_client/src/include/nacl_scoped_ptr.h"
     17 #include "native_client/src/include/portability_io.h"
     18 #include "native_client/src/include/portability_string.h"
     19 
     20 
     21 namespace plugin {
     22 namespace file_utils {
     23 
     24 StatusCode SlurpFile(int32_t fd,
     25                      nacl::string& out_buf,
     26                      size_t max_size_to_read) {
     27   struct stat stat_buf;
     28   if (fstat(fd, &stat_buf) != 0) {
     29     CLOSE(fd);
     30     return PLUGIN_FILE_ERROR_STAT;
     31   }
     32 
     33   // Figure out how large a buffer we need to slurp the whole file (with a
     34   // '\0' at the end).
     35   size_t bytes_to_read = static_cast<size_t>(stat_buf.st_size);
     36   if (bytes_to_read > max_size_to_read - 1) {
     37     CLOSE(fd);
     38     return PLUGIN_FILE_ERROR_FILE_TOO_LARGE;
     39   }
     40 
     41   FILE* input_file = fdopen(fd, "rb");
     42   if (!input_file) {
     43     CLOSE(fd);
     44     return PLUGIN_FILE_ERROR_OPEN;
     45   }
     46   // From here on, closing input_file will automatically close fd.
     47 
     48   nacl::scoped_array<char> buffer(new char[bytes_to_read + 1]);
     49   if (buffer == NULL) {
     50     fclose(input_file);
     51     return PLUGIN_FILE_ERROR_MEM_ALLOC;
     52   }
     53 
     54   size_t total_bytes_read = 0;
     55   while (bytes_to_read > 0) {
     56     size_t bytes_this_read = fread(&buffer[total_bytes_read],
     57                                    sizeof(char),
     58                                    bytes_to_read,
     59                                    input_file);
     60     if (bytes_this_read < bytes_to_read && (feof(input_file) ||
     61                                             ferror(input_file))) {
     62       fclose(input_file);
     63       return PLUGIN_FILE_ERROR_READ;
     64     }
     65     total_bytes_read += bytes_this_read;
     66     bytes_to_read -= bytes_this_read;
     67   }
     68 
     69   fclose(input_file);
     70   buffer[total_bytes_read] = '\0';
     71   out_buf = buffer.get();
     72   return PLUGIN_FILE_SUCCESS;
     73 }
     74 
     75 }  // namespace file_utils
     76 }  // namespace plugin
     77 
     78