Example #1
0
static int undup_getattr(const char *path, struct stat *stbuf)
{
    char b[PATH_MAX+1];
    int n;
    struct stub *stub;

    n = snprintf(b, PATH_MAX, "%s/%s", state->basedir, path);
    if (n > PATH_MAX)
        return -ENAMETOOLONG;

    debug("getattr path=%s b=%s\n", path, b);

    n = stat(b, stbuf);
    if (n == -1)
        return -errno;

    if (S_ISDIR(stbuf->st_mode))
        return 0;

    stub = stub_open(state, b, O_RDONLY);
    if (stub == NULL)
        return -errno;

    stbuf->st_size = stub->hdr.len;
    stbuf->st_uid = stub->hdr.uid;
    stbuf->st_gid = stub->hdr.gid;

    stub_close(state, stub);
    return 0;
}
Example #2
0
static int undup_release(const char *path, struct fuse_file_info *fi)
{
    int n;
    struct stub *stub = (struct stub *)fi->fh;

    debug("undup_release(%s fi=%p stub=%p)\n", path, fi, stub);

    n = stub_close(state, stub);
    fi->fh = 0;

    return n < 0 ? -errno : n;
}
Example #3
0
static int undup_truncate(const char *path, off_t size)
{
    char b[PATH_MAX+1];
    int n, ret;
    struct stub *stub;

    n = snprintf(b, PATH_MAX, "%s/%s", state->basedir, path);
    if (n > PATH_MAX)
        return -ENAMETOOLONG;

    debug("truncate(%s, %lld)\n", b, (long long)size);

    if (n == -1)
       return -errno;

    stub = stub_open(state, b, O_RDWR);
    if (!stub)
        return -errno;

    ret = stub_update_len(stub, size, 1);
    stub_close(state, stub);
    return ret;
}
Example #4
0
static void generate_stub(int nparms)
{
  FILE *stream = open_stub();
  char formal[MAX_PARMSIZE];
  char actual[MAX_PARMSIZE];
  int i;
  int j;

  /* Generate "up-front" information, include correct header files */

  fprintf(stream, "/* Auto-generated %s stub file -- do not edit */\n\n", g_parm[0]);
  fprintf(stream, "#include <nuttx/config.h>\n");
  fprintf(stream, "#include <stdint.h>\n");
  fprintf(stream, "#include <%s>\n\n", g_parm[HEADER_INDEX]);

  if (g_parm[COND_INDEX][0] != '\0')
    {
      fprintf(stream, "#if %s\n\n", g_parm[COND_INDEX]);
    }

  /* Generate the function definition that matches standard function prototype */

  if (g_inline)
    {
      fprintf(stream, "static inline ");
    }
  fprintf(stream, "uintptr_t STUB_%s(", g_parm[NAME_INDEX]);

  /* Generate the formal parameter list.  A function received no parameters is a special case. */

  if (nparms <= 0)
    {
      fprintf(stream, "void");
    }
  else
    {
      for (i = 0; i < nparms; i++)
        {
          /* Treat the first argument in the list differently from the others..
           * It does not need a comma before it.
           */

          if (i > 0)
            {
              /* Check for a variable number of arguments */

              if (is_vararg(g_parm[PARM1_INDEX+i], i, nparms))
                {
                  /* Always receive six arguments in this case */

                  for (j = i+1; j <= 6; j++)
                    {
                      fprintf(stream, ", uintptr_t parm%d", j);
                    }
                }
              else
                {
                  fprintf(stream, ", uintptr_t parm%d", i+1);
                }
            }
          else
            {
              fprintf(stream, "uintptr_t parm%d", i+1);
            }
        }
    }
  fprintf(stream, ")\n{\n");

  /* Then call the proxied function.  Functions that have no return value are
   * a special case.
   */

  if (strcmp(g_parm[RETTYPE_INDEX], "void") == 0)
    {
      fprintf(stream, "  %s(", g_parm[NAME_INDEX]);
    }
  else
    {
      fprintf(stream, "  return (uintptr_t)%s(", g_parm[NAME_INDEX]);
    }

  /* The pass all of the system call parameters, casting to the correct type
   * as necessary.
   */

  for (i = 0; i < nparms; i++)
    {
      /* Get the formal type of the parameter, and get the type that we
       * actually have to cast to.  For example for a formal type like 'int parm[]'
       * we have to cast the actual parameter to 'int*'.  The worst is a union
       * type like 'union sigval' where we have to cast to (union sigval)((FAR void *)parm)
       * -- Yech.
       */

     get_formalparmtype(g_parm[PARM1_INDEX+i], formal);
     get_actualparmtype(g_parm[PARM1_INDEX+i], actual);

      /* Treat the first argument in the list differently from the others..
       * It does not need a comma before it.
       */

      if (i > 0)
        {
          /* Check for a variable number of arguments */

          if (is_vararg(actual, i, nparms))
            {
              /* Always pass six arguments */

              for (j = i+1; j <=6; j++)
                {
                  fprintf(stream, ", parm%d", j);
                }
            }
          else
            {
              if (is_union(formal))
                {
                  fprintf(stream, ", (%s)((%s)parm%d)", formal, actual, i+1);
                }
              else
                {
                  fprintf(stream, ", (%s)parm%d", actual, i+1);
                }
            }
        }
      else
        {
          if (is_union(formal))
            {
              fprintf(stream, "(%s)((%s)parm%d)", formal, actual, i+1);
            }
          else
            {
              fprintf(stream, "(%s)parm%d",actual, i+1);
            }
        }
    }

  /* Tail end of the function.  If the proxied function has no return
   * value, just return zero (OK).
   */

  if (strcmp(g_parm[RETTYPE_INDEX], "void") == 0)
    {
      fprintf(stream, ");\n  return 0;\n}\n\n");
    }
  else
    {
      fprintf(stream, ");\n}\n\n");
    }

  if (g_parm[COND_INDEX][0] != '\0')
    {
      fprintf(stream, "#endif /* %s */\n", g_parm[COND_INDEX]);
    }
  stub_close(stream);
}