Beispiel #1
0
// Sync readfile using libuv APIs as an API function.
static duk_ret_t duv_loadfile(duk_context *ctx) {
  const char* path = duk_require_string(ctx, 0);
  uv_fs_t req;
  int fd = 0;
  uint64_t size;
  char* chunk;
  uv_buf_t buf;

  if (uv_fs_open(&loop, &req, path, O_RDONLY, 0644, NULL) < 0) goto fail;
  fd = req.result;
  if (uv_fs_fstat(&loop, &req, fd, NULL) < 0) goto fail;
  size = req.statbuf.st_size;
  chunk = duk_alloc(ctx, size);
  buf = uv_buf_init(chunk, size);
  if (uv_fs_read(&loop, &req, fd, &buf, 1, 0, NULL) < 0) goto fail;
  duk_push_lstring(ctx, chunk, size);
  duk_free(ctx, chunk);
  uv_fs_close(&loop, &req, fd, NULL);
  uv_fs_req_cleanup(&req);

  return 1;

  fail:
  if (fd) uv_fs_close(&loop, &req, fd, NULL);
  uv_fs_req_cleanup(&req);
  duk_error(ctx, DUK_ERR_ERROR, "%s: %s: %s", uv_err_name(req.result), uv_strerror(req.result), path);
}
Beispiel #2
0
/*
 * fs.fstat
 */
static int fs_fstat(lua_State* L) {
  FSR__SETUP
  int fd = luaL_checkint(L, 1);
  FSR__SET_OPT_CB(2, on_fs_callback)
  uv_fs_fstat(loop, req, fd, cb);
  FSR__TEARDOWN
}
Beispiel #3
0
/* Reads the file from the current position to the end into a string. */
static MVMString * slurp(MVMThreadContext *tc, MVMOSHandle *h) {
    MVMIOFileData *data = (MVMIOFileData *)h->body.data;
    uv_fs_t req;
    ensure_decode_stream(tc, data);

    /* Typically we're slurping an entire file, so just request the bytes
     * until the end; repeat to ensure we get 'em all. */
    if (uv_fs_fstat(tc->loop, &req, data->fd, NULL) < 0) {
        MVM_exception_throw_adhoc(tc, "slurp from filehandle failed: %s", uv_strerror(req.result));
    }
    /* Sometimes - usually for special files like those in /proc - the file
     * size comes up 0, even though the S_ISREG test succeeds. So in that case
     * we try a small read and switch to a "read chunks until EOF" impl.
     * Otherwise we just read the exact size of the file. */
    if (req.statbuf.st_size == 0) {
        if (read_to_buffer(tc, data, 32) > 0) {
            while (read_to_buffer(tc, data, 4096) > 0)
                ;
        }
    } else {
        while (read_to_buffer(tc, data, req.statbuf.st_size) > 0)
            ;
    }
    return MVM_string_decodestream_get_all(tc, data->ds);
}
Beispiel #4
0
int async_fs_fstat(uv_file file, uv_fs_t *const req) {
	async_pool_enter(NULL);
	uv_fs_t _req[1];
	int const err = uv_fs_fstat(async_loop, req ? req : _req, file, NULL);
	uv_fs_req_cleanup(req ? req : _req);
	async_pool_leave(NULL);
	return err;
}
Beispiel #5
0
void fileSize(WrenVM* vm)
{
  uv_fs_t* request = createRequest(wrenGetSlotValue(vm, 1));

  int fd = *(int*)wrenGetSlotForeign(vm, 0);
  // TODO: Assert fd != -1.

  uv_fs_fstat(getLoop(), request, fd, fileSizeCallback);
}
Beispiel #6
0
DLLEXPORT int32_t jl_fstat(int fd, char *statbuf)
{
  uv_fs_t req;
  int ret;

  ret = uv_fs_fstat(uv_default_loop(), &req, fd, NULL);
  if (ret == 0)
    memcpy(statbuf, req.ptr, sizeof(struct stat));
  uv_fs_req_cleanup(&req);
  return ret;
}
Beispiel #7
0
/// Get the file information for a given file descriptor
///
/// @param file_descriptor File descriptor of the file.
/// @param[out] file_info Pointer to a FileInfo to put the information in.
/// @return `true` on success, `false` for failure.
bool os_get_file_info_fd(int file_descriptor, FileInfo *file_info)
{
  uv_fs_t request;
  int result = uv_fs_fstat(uv_default_loop(), &request, file_descriptor, NULL);
  file_info->stat = request.statbuf;
  uv_fs_req_cleanup(&request);
  if (result == kLibuvSuccess) {
    return true;
  }
  return false;
}
Beispiel #8
0
static int lluv_file_stat(lua_State *L){
  const char  *path = NULL;
  lluv_file_t *f    = lluv_check_file(L, 1, LLUV_FLAG_OPEN);
  lluv_loop_t *loop = f->loop;
  int          argc = 1;

  LLUV_PRE_FILE();
  lua_pushvalue(L, 1);
  req->file_ref = luaL_ref(L, LLUV_LUA_REGISTRY);
  err = uv_fs_fstat(loop->handle, &req->req, f->handle, cb);
  LLUV_POST_FILE();
}
Beispiel #9
0
/* Checks if the end of file has been reached. */
static MVMint64 mvm_eof(MVMThreadContext *tc, MVMOSHandle *h) {
    MVMIOFileData *data = (MVMIOFileData *)h->body.data;
    MVMint64 seek_pos;
    uv_fs_t  req;
    if (data->ds && !MVM_string_decodestream_is_empty(tc, data->ds))
        return 0;
    if (uv_fs_fstat(tc->loop, &req, data->fd, NULL) == -1) {
        MVM_exception_throw_adhoc(tc, "Failed to stat file descriptor: %s", uv_strerror(req.result));
    }
    if ((seek_pos = MVM_platform_lseek(data->fd, 0, SEEK_CUR)) == -1)
        MVM_exception_throw_adhoc(tc, "Failed to seek in filehandle: %d", errno);
    return req.statbuf.st_size == seek_pos;
}
Beispiel #10
0
/* Reads the file from the current position to the end into a string. */
static MVMString * slurp(MVMThreadContext *tc, MVMOSHandle *h) {
    MVMIOFileData *data = (MVMIOFileData *)h->body.data;
    uv_fs_t req;
    ensure_decode_stream(tc, data);

    /* Typically we're slurping an entire file, so just request the bytes
     * until the end; repeat to ensure we get 'em all. */
    if (uv_fs_fstat(tc->loop, &req, data->fd, NULL) < 0) {
        MVM_exception_throw_adhoc(tc, "slurp from filehandle failed: %s", uv_strerror(req.result));
    }
    while (read_to_buffer(tc, data, req.statbuf.st_size) > 0)
        ;
    return MVM_string_decodestream_get_all(tc, data->ds);
}
Beispiel #11
0
/* Checks if the end of file has been reached. */
static MVMint64 mvm_eof(MVMThreadContext *tc, MVMOSHandle *h) {
    MVMIOFileData *data = (MVMIOFileData *)h->body.data;
    MVMint64 seek_pos;
    uv_fs_t  req;
    if (data->ds && !MVM_string_decodestream_is_empty(tc, data->ds))
        return 0;
    if (uv_fs_fstat(tc->loop, &req, data->fd, NULL) == -1) {
        MVM_exception_throw_adhoc(tc, "Failed to stat file descriptor: %s", uv_strerror(req.result));
    }
    if ((seek_pos = MVM_platform_lseek(data->fd, 0, SEEK_CUR)) == -1)
        MVM_exception_throw_adhoc(tc, "Failed to seek in filehandle: %d", errno);
    /* Comparison with seek_pos for some special files, like those in /proc,
     * which file size is 0 can be false. In that case, we fall back to check
     * file size to detect EOF. */
    return req.statbuf.st_size == seek_pos || req.statbuf.st_size == 0;
}
Beispiel #12
0
static int lmz_reader_init(lua_State* L) {
  const char* path = luaL_checkstring(L, 1);
  mz_uint32 flags = luaL_optint(L, 2, 0);
  mz_uint64 size;
  lmz_file_t* zip = lua_newuserdata(L, sizeof(*zip));
  mz_zip_archive* archive = &(zip->archive);
  luaL_getmetatable(L, "miniz_reader");
  lua_setmetatable(L, -2);
  memset(archive, 0, sizeof(*archive));
  zip->loop = uv_default_loop();
  zip->fd = uv_fs_open(zip->loop, &(zip->req), path, O_RDONLY, 0644, NULL);
  uv_fs_fstat(zip->loop, &(zip->req), zip->fd, NULL);
  size = zip->req.statbuf.st_size;
  archive->m_pRead = lmz_file_read;
  archive->m_pIO_opaque = zip;
  if (!mz_zip_reader_init(archive, size, flags)) {
    lua_pushnil(L);
    lua_pushfstring(L, "read %s fail because of %s", path,
      mz_zip_get_error_string(mz_zip_get_last_error(archive)));
    return 2;
  }
  return 1;
}
void FileRequestBaton::file_opened(uv_fs_t *req) {
    FileRequestBaton *ptr = (FileRequestBaton *)req->data;
    assert(ptr->thread_id == std::this_thread::get_id());

    if (req->result < 0) {
        // Opening failed or was canceled. There isn't much left we can do.
        notify_error(req);
        cleanup(req);
    } else {
        const uv_file fd = uv_file(req->result);

        // We're going to reuse this handle, so we need to cleanup first.
        uv_fs_req_cleanup(req);

        if (ptr->canceled || !ptr->request) {
            // Either the FileRequest object has been destructed, or the
            // request was canceled.
            uv_fs_close(req->loop, req, fd, file_closed);
        } else {
            ptr->fd = fd;
            uv_fs_fstat(req->loop, req, fd, file_stated);
        }
    }
}
Beispiel #14
0
// Sync readfile using libuv APIs as an API function.
static duk_ret_t duv_loadfile(duk_context *ctx) {
  const char* path = duk_require_string(ctx, 0);
  uv_fs_t req;
  int fd = 0;
  uint64_t size;
  char* chunk;
  uv_buf_t buf;

  duk_push_thread_stash(ctx, ctx);
  duk_bool_t rc = duk_get_prop_string(ctx, -1, "__duk_loop");
  assert(rc);
  uv_loop_t *dukLoop = (uv_loop_t *)duk_get_pointer(ctx, -1);
  duk_pop(ctx);
  duk_pop(ctx);

  if (uv_fs_open(dukLoop, &req, path, O_RDONLY, 0644, NULL) < 0) goto fail;
  uv_fs_req_cleanup(&req);
  fd = req.result;
  if (uv_fs_fstat(dukLoop, &req, fd, NULL) < 0) goto fail;
  uv_fs_req_cleanup(&req);
  size = req.statbuf.st_size;
  chunk = (char*)duk_alloc(ctx, static_cast<duk_size_t>(size));
  buf = uv_buf_init(chunk, static_cast<unsigned int>(size));
  if (uv_fs_read(dukLoop, &req, fd, &buf, 1, 0, NULL) < 0) {
    duk_free(ctx, chunk);
    goto fail;
  }
  uv_fs_req_cleanup(&req);
  duk_push_lstring(ctx, chunk, static_cast<duk_size_t>(size));
  duk_free(ctx, chunk);
  uv_fs_close(dukLoop, &req, fd, NULL);
  uv_fs_req_cleanup(&req);

  return 1;

fail:
  uv_fs_req_cleanup(&req);
  if (fd) uv_fs_close(dukLoop, &req, fd, NULL);
  uv_fs_req_cleanup(&req);

  // TODO hacking in a fallback to look for modules in a directory called duk_modules
  // TODO what about windows... will this work?

  fd = 0;
  std::string path2 = "duk_modules/";
  path2 += path;

  if (uv_fs_open(dukLoop, &req, path2.c_str(), O_RDONLY, 0644, NULL) < 0) goto fail;
  uv_fs_req_cleanup(&req);
  fd = req.result;
  if (uv_fs_fstat(dukLoop, &req, fd, NULL) < 0) goto fail;
  uv_fs_req_cleanup(&req);
  size = req.statbuf.st_size;
  chunk = (char*)duk_alloc(ctx, static_cast<duk_size_t>(size));
  buf = uv_buf_init(chunk, static_cast<unsigned int>(size));
  if (uv_fs_read(dukLoop, &req, fd, &buf, 1, 0, NULL) < 0) {
    duk_free(ctx, chunk);
    goto fail2;
  }
  uv_fs_req_cleanup(&req);
  duk_push_lstring(ctx, chunk, static_cast<duk_size_t>(size));
  duk_free(ctx, chunk);
  uv_fs_close(dukLoop, &req, fd, NULL);
  uv_fs_req_cleanup(&req);

  return 1;

fail2:
  uv_fs_req_cleanup(&req);
  if (fd) uv_fs_close(dukLoop, &req, fd, NULL);
  uv_fs_req_cleanup(&req);

  duk_error(ctx, DUK_ERR_ERROR, "%s: %s: %s", uv_err_name(req.result), uv_strerror(req.result), path2.c_str());
}
Beispiel #15
0
extern "C" int
rust_uv_fs_fstat(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
  return uv_fs_fstat(loop, req, file, cb);
}
Beispiel #16
0
static void
on_fs_open(uv_fs_t* req) {
  http_request* request = (http_request*) req->data;
  int result = req->result;

  uv_fs_req_cleanup(req);
  free(req);
  if (result < 0) {
    fprintf(stderr, "Open error: %s: %s\n", uv_err_name(result), uv_strerror(result));
    response_error(request->handle, 404, "Not Found\n", NULL);
    destroy_request(request, 1);
    return;
  }

  uv_fs_t stat_req;
  int r = uv_fs_fstat(loop, &stat_req, result, NULL);
  if (r) {
    fprintf(stderr, "Stat error: %s: %s\n", uv_err_name(r), uv_strerror(r));
    response_error(request->handle, 404, "Not Found\n", NULL);
    destroy_request(request, 1);
    return;
  }

  uint64_t response_size = stat_req.statbuf.st_size;
  uv_fs_req_cleanup(&stat_req);

  const static char* ctype = "application/octet-stream";
  const char* dot = request->file_path;
  const char* ptr = dot;
  while (dot) {
    ptr = dot;
    dot = strchr(dot + 1, '.');
  }
  khint_t k = kh_get(mime_type, mime_type, ptr);
  if (k != kh_end(mime_type)) {
    ctype = kh_value(mime_type, k);
  }

  http_response* response = calloc(1, sizeof(http_response));
  if (response == NULL) {
    fprintf(stderr, "Allocate error: %s\n", strerror(r));
    response_error(request->handle, 404, "Not Found\n", NULL);
    destroy_request(request, 1);
    return;
  }
  response->response_size = response_size;
  response->fd = result;
  response->request = request;
  response->handle = request->handle;
  response->pbuf = malloc(WRITE_BUF_SIZE);
  if (response->pbuf == NULL) {
    fprintf(stderr, "Allocate error: %s\n", strerror(r));
    response_error(request->handle, 404, "Not Found\n", NULL);
    destroy_response(response, 1);
    return;
  }
  response->buf = uv_buf_init(response->pbuf, WRITE_BUF_SIZE);
  response->read_req.data = response;
  response->write_req.data = response;

  char bufline[1024];
  int nbuf = snprintf(bufline,
      sizeof(bufline),
      "HTTP/1.1 200 OK\r\n"
      "Content-Length: %" PRId64 "\r\n"
      "Content-Type: %s\r\n"
      "Connection: %s\r\n"
      "\r\n",
      response_size,
      ctype,
      (request->keep_alive ? "keep-alive" : "close"));
  uv_buf_t buf = uv_buf_init(bufline, nbuf);

#ifndef _WIN32
  r = uv_try_write((uv_stream_t*) request->handle, &buf, 1);
  if (r == 0) {
    fprintf(stderr, "Write error\n");
    destroy_response(response, 1);
    return;
  }
#else
  r = uv_write(&response->write_req, (uv_stream_t*) request->handle, &buf, 1, NULL);
  if (r) {
    fprintf(stderr, "Write error: %s: %s\n", uv_err_name(r), uv_strerror(r));
    destroy_response(response, 1);
    return;
  }
#endif

  r = uv_fs_read(loop, &response->read_req, result, &response->buf, 1, -1, on_fs_read);
  if (r) {
    response_error(request->handle, 500, "Internal Server Error\n", NULL);
    destroy_response(response, 1);
  }
}
Beispiel #17
0
/* Opens a file, returning a synchronous file handle. */
MVMObject * MVM_file_open_fh(MVMThreadContext *tc, MVMString *filename, MVMString *mode) {
    char * const fname = MVM_string_utf8_c8_encode_C_string(tc, filename);
    uv_fs_t req;
    uv_file fd;
    int flag;

    /* Resolve mode description to flags. */
    {
        char * const fmode  = MVM_string_utf8_encode_C_string(tc, mode);

        if (!resolve_open_mode(&flag, fmode)) {
            char *waste[] = { fname, fmode, NULL };
            MVM_exception_throw_adhoc_free(tc, waste, "Invalid open mode for file %s: %s", fname, fmode);
        }
        MVM_free(fmode);
    }

    /* Try to open the file. */
    if ((fd = uv_fs_open(tc->loop, &req, (const char *)fname, flag, DEFAULT_MODE, NULL)) < 0) {
        char *waste[] = { fname, NULL };
        const char *err = uv_strerror(req.result);

        uv_fs_req_cleanup(&req);
        MVM_exception_throw_adhoc_free(tc, waste, "Failed to open file %s: %s", fname, err);
    }
    uv_fs_req_cleanup(&req);

    /*  Check that we didn't open a directory by accident.
        If fstat fails, just move on: Most of the documented error cases should
        already have triggered when opening the file, and we can't do anything
        about the others; a failure also does not necessarily imply that the
        file descriptor cannot be used for reading/writing. */
    if (uv_fs_fstat(tc->loop, &req, fd, NULL) == 0 && (req.statbuf.st_mode & S_IFMT) == S_IFDIR) {
        char *waste[] = { fname, NULL };

        uv_fs_req_cleanup(&req);

        if (uv_fs_close(tc->loop, &req, fd, NULL) < 0) {
            const char *err = uv_strerror(req.result);

            uv_fs_req_cleanup(&req);
            MVM_exception_throw_adhoc_free(tc, waste, "Tried to open directory %s, which we failed to close: %s",
                fname, err);
        }
        uv_fs_req_cleanup(&req);

        MVM_exception_throw_adhoc_free(tc, waste, "Tried to open directory %s", fname);
    }
    uv_fs_req_cleanup(&req);

    /* Set up handle. */
    {
        MVMIOFileData * const data   = MVM_calloc(1, sizeof(MVMIOFileData));
        MVMOSHandle   * const result = (MVMOSHandle *)MVM_repr_alloc_init(tc, tc->instance->boot_types.BOOTIO);

        data->fd          = fd;
        data->filename    = fname;
        data->encoding    = MVM_encoding_type_utf8;
        MVM_string_decode_stream_sep_default(tc, &(data->sep_spec));
        result->body.ops  = &op_table;
        result->body.data = data;

        return (MVMObject *)result;
    }
}
Beispiel #18
0
 void FileObject::getSize(gc<Fiber> fiber)
 {
   FSTask* task = new FSTask(fiber);
   uv_fs_fstat(task->loop(), task->request(), file_, getSizeCallback);
 }