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; }
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; }
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; }
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); }