LCOV - code coverage report
Current view: directory - src/shared/platform/osx - nacl_host_dir.c (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 79 62 78.5 %
Date: 2014-06-18 Functions: 0 0 -

       1                 : /*
       2                 :  * Copyright (c) 2008 The Native Client Authors. All rights reserved.
       3                 :  * Use of this source code is governed by a BSD-style license that can be
       4                 :  * found in the LICENSE file.
       5                 :  */
       6                 : 
       7                 : /*
       8                 :  * NaCl Service Runtime.  Directory descriptor / Handle abstraction.
       9                 :  *
      10                 :  * Note that we avoid using the thread-specific data / thread local
      11                 :  * storage access to the "errno" variable, and instead use the raw
      12                 :  * system call return interface of small negative numbers as errors.
      13                 :  */
      14                 : 
      15                 : #include <stddef.h>
      16                 : #include <stdint.h>
      17                 : #include <string.h>
      18                 : #include <sys/types.h>
      19                 : #include <sys/stat.h>
      20                 : #include <fcntl.h>
      21                 : #include <errno.h>
      22                 : #include <sys/mman.h>
      23                 : #include <unistd.h>
      24                 : #include <dirent.h>
      25                 : 
      26                 : #include "native_client/src/include/nacl_platform.h"
      27                 : 
      28                 : #include "native_client/src/shared/platform/nacl_host_desc.h"
      29                 : #include "native_client/src/shared/platform/nacl_host_dir.h"
      30                 : #include "native_client/src/shared/platform/nacl_log.h"
      31                 : #include "native_client/src/shared/platform/nacl_sync.h"
      32                 : #include "native_client/src/shared/platform/nacl_sync_checked.h"
      33                 : 
      34                 : #include "native_client/src/trusted/service_runtime/include/bits/mman.h"
      35                 : #include "native_client/src/trusted/service_runtime/include/sys/dirent.h"
      36                 : #include "native_client/src/trusted/service_runtime/include/sys/errno.h"
      37                 : #include "native_client/src/trusted/service_runtime/include/sys/fcntl.h"
      38                 : #include "native_client/src/trusted/service_runtime/include/sys/stat.h"
      39                 : 
      40                 : 
      41                 : #ifndef SSIZE_T_MAX
      42                 : # define SSIZE_T_MAX ((ssize_t) ((~(size_t) 0) >> 1))
      43                 : #endif
      44                 : 
      45                 : 
      46               4 : int NaClHostDirOpen(struct NaClHostDir  *d,
      47               4 :                     char                *path) {
      48               4 :   DIR  *dirp;
      49                 : 
      50               4 :   NaClLog(3, "NaClHostDirOpen(0x%08"NACL_PRIxPTR", %s)\n", (uintptr_t) d, path);
      51               4 :   if (NULL == d) {
      52               0 :     NaClLog(LOG_FATAL, "NaClHostDirOpen: 'this' is NULL\n");
      53               0 :   }
      54                 : 
      55               4 :   if (!NaClMutexCtor(&d->mu)) {
      56               0 :     NaClLog(LOG_ERROR,
      57                 :             "NaClHostDirOpen: could not initialize mutex\n");
      58               0 :     return -NACL_ABI_ENOMEM;
      59                 :   }
      60                 : 
      61               4 :   NaClLog(3, "NaClHostDirOpen: invoking POSIX opendir(%s)\n", path);
      62               4 :   dirp = opendir(path);
      63               4 :   NaClLog(3, "NaClHostDirOpen: got DIR* 0x%08"NACL_PRIxPTR"\n",
      64                 :           (uintptr_t) dirp);
      65               4 :   if (NULL == dirp) {
      66               0 :     NaClLog(LOG_ERROR,
      67               0 :             "NaClHostDirOpen: open returned NULL, errno %d\n", errno);
      68               0 :     return -NaClXlateErrno(errno);
      69                 :   }
      70               4 :   d->dirp = dirp;
      71               4 :   d->dp = readdir(d->dirp);
      72               4 :   d->off = 0;
      73               4 :   NaClLog(3, "NaClHostDirOpen: success.\n");
      74               4 :   return 0;
      75               4 : }
      76                 : 
      77              22 : ssize_t NaClHostDirGetdents(struct NaClHostDir  *d,
      78              22 :                             void                *buf,
      79              22 :                             size_t              len) {
      80              22 :   struct nacl_abi_dirent *p;
      81              22 :   int                    rec_length;
      82              22 :   ssize_t                i;
      83                 : 
      84              22 :   if (NULL == d) {
      85               0 :     NaClLog(LOG_FATAL, "NaClHostDirGetdents: 'this' is NULL\n");
      86               0 :   }
      87              22 :   NaClLog(3, "NaClHostDirGetdents(0x%08"NACL_PRIxPTR", %"NACL_PRIuS"):\n",
      88                 :           (uintptr_t) buf, len);
      89                 : 
      90              22 :   NaClXMutexLock(&d->mu);
      91                 : 
      92              22 :   i = 0;
      93             115 :   while ((size_t) i < len) {
      94              92 :     if (NULL == d->dp) {
      95               6 :       goto done;
      96                 :     }
      97              86 :     if (i > SSIZE_T_MAX - d->dp->d_reclen) {
      98               0 :       NaClLog(LOG_FATAL, "NaClHostDirGetdents: buffer impossibly large\n");
      99               0 :     }
     100              86 :     if ((size_t) i + d->dp->d_reclen > len) {
     101              15 :       if (0 == i) {
     102               8 :         i = (size_t) -NACL_ABI_EINVAL;
     103               8 :       }
     104              15 :       goto done;
     105                 :     }
     106              71 :     p = (struct nacl_abi_dirent *) (((char *) buf) + i);
     107              71 :     p->nacl_abi_d_ino = 0x6c43614e;
     108              71 :     p->nacl_abi_d_off = ++d->off;
     109             213 :     memcpy(p->nacl_abi_d_name,
     110                 :            d->dp->d_name,
     111                 :            d->dp->d_namlen + 1);
     112                 :     /*
     113                 :      * Newlib expects entries to start on 0mod4 boundaries.
     114                 :      * Round reclen to the next multiple of four.
     115                 :      */
     116              71 :     rec_length = (offsetof(struct nacl_abi_dirent, nacl_abi_d_name) +
     117                 :                   (d->dp->d_namlen + 1 + 3)) & ~3;
     118                 :     /*
     119                 :      * We cast to a volatile pointer so that the compiler won't ever
     120                 :      * pick up the rec_length value from that user-accessible memory
     121                 :      * location, rather than actually using the value in a register or
     122                 :      * in the local frame.
     123                 :      */
     124              71 :     ((volatile struct nacl_abi_dirent *) p)->nacl_abi_d_reclen = rec_length;
     125              71 :     if ((size_t) i > SIZE_T_MAX - rec_length) {
     126               0 :       NaClLog(LOG_FATAL, "NaClHostDirGetdents: buffer offset overflow\n");
     127               0 :     }
     128              71 :     i += rec_length;
     129              71 :     d->dp = readdir(d->dirp);
     130              72 :   }
     131                 :  done:
     132              22 :   NaClXMutexUnlock(&d->mu);
     133              22 :   return (ssize_t) i;
     134                 : }
     135                 : 
     136               1 : int NaClHostDirRewind(struct NaClHostDir *d) {
     137               1 :   if (NULL == d) {
     138               0 :     NaClLog(LOG_FATAL, "NaClHostDirRewind: 'this' is NULL\n");
     139               0 :   }
     140               1 :   rewinddir(d->dirp);
     141               1 :   d->dp = readdir(d->dirp);
     142               1 :   return 0;
     143                 : }
     144                 : 
     145               3 : int NaClHostDirClose(struct NaClHostDir *d) {
     146               3 :   int retval;
     147                 : 
     148               3 :   if (NULL == d) {
     149               0 :     NaClLog(LOG_FATAL, "NaClHostDirClose: 'this' is NULL\n");
     150               0 :   }
     151               3 :   NaClLog(3, "NaClHostDirClose(0x%08"NACL_PRIxPTR")\n", (uintptr_t) d->dirp);
     152               3 :   retval = closedir(d->dirp);
     153               3 :   if (-1 != retval) {
     154               3 :     d->dirp = NULL;
     155               3 :   }
     156               3 :   NaClMutexDtor(&d->mu);
     157               9 :   return (-1 == retval) ? -NaClXlateErrno(errno) : retval;
     158                 : }

Generated by: LCOV version 1.7