Unable to create directories using nacl-mounts

Get help with compiling or installing the game, and discuss announcements of new official releases.

Moderator: Forum Moderators

Post Reply
symadept
Posts: 1
Joined: June 26th, 2012, 6:48 pm

Unable to create directories using nacl-mounts

Post by symadept »

Hi,
I saw this game was ported well to Nacl and hence I was looking to use the same technique used in this game to mount few directories and able to access the prepackaged files as same as local file storage. I am facing few issues, like, I am unable to create directories and unable to copy say images/x.jpg to /usr/local/share/dirSDLTest directory. And I don't see any callbacks are called either.

Can anyone help me to understand what am I missing on this.

Here is the code: http://www.4shared.com/zip/2Pre95Ji/sdltest_2.html

Any pointers are highly appreciable.

Regards
Mustafa

// Copyright (c) 2011 The Native Client Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>

#include <ppapi/cpp/instance.h>
#include <ppapi/cpp/module.h>
#include <ppapi/cpp/rect.h>
#include <ppapi/cpp/size.h>

#include <SDL_video.h>
extern "C" {
extern int sdl_main(int argc, const char *argv[]);
}
#include <SDL.h>
#include <SDL_nacl.h>

#include <nacl-mounts/base/KernelProxy.h>
#include <nacl-mounts/base/MainThreadRunner.h>
#include <nacl-mounts/http2/HTTP2Mount.h>
#include <nacl-mounts/pepper/PepperMount.h>


/*const char* http_dirs[] = {
#include "dir_list.h"
};*/

/*struct http_file_info {
const char* path;
size_t size;
} http_files[] = {
#include "file_list.h"
};*/

/*struct http_pack_info {
const char* path;
const char* pack_path;
off_t offset;
} http_packs[] = {
#include "pack_list.h"
};*/


class PluginInstance : public pp::Instance {
public:
explicit PluginInstance(PP_Instance instance) : pp::Instance(instance),
sdl_main_thread_(0),
width_(0),
height_(0),
progress_handler_(this),
directory_reader_(this)
{
fprintf(stdout, "********* Requesting an HTML5 local persistent filesystem. *********\n");
fflush(stdout);

proxy_ = KernelProxy::KPInstance();
runner_ = new MainThreadRunner(this);
fs_ = new pp::FileSystem(this, PP_FILESYSTEMTYPE_LOCALPERSISTENT);
}

~PluginInstance()
{
if (sdl_main_thread_)
{
pthread_join(sdl_main_thread_, NULL);
}
}

virtual void DidChangeView(const pp::Rect& position, const pp::Rect& clip)
{
fprintf(stdout, "did change view, new %dx%d, old %dx%d\n",
position.size().width(), position.size().height(),
width_, height_);
fflush(stdout);

if (position.size().width() == width_
&& position.size().height() == height_)
return; // Size didn't change, no need to update anything.

if (sdl_thread_started_ == false)
{
width_ = position.size().width();
height_ = position.size().height();

SDL_NACL_SetInstance(pp_instance(), width_, height_);

// It seems this call to SDL_Init is required. Calling from
// sdl_main() isn't good enough.
// Perhaps it must be called from the main thread?
int lval = SDL_Init(SDL_INIT_VIDEO);
assert(lval >= 0);
if (0 == pthread_create(&sdl_main_thread_, NULL, sdl_thread_static, this)) {
sdl_thread_started_ = true;
}
}
}

bool HandleInputEvent(const pp::InputEvent& event)
{
SDL_NACL_PushEvent(event);
return true;
}

void HandleMessage(const pp::Var& message) {
std::string s = message.AsString();
directory_reader_.HandleResponse(s);
}

bool Init(int argc, const char* argn[], const char* argv[])
{
return true;
}

private:
bool sdl_thread_started_;
pthread_t sdl_main_thread_;
int width_;
int height_;
KernelProxy* proxy_;
MainThreadRunner* runner_;
pp::FileSystem* fs_;

static void* sdl_thread_static(void* param) {
return reinterpret_cast<PluginInstance*>(param)->sdl_thread();
}

void* sdl_thread()
{
#if 1
fprintf(stdout, "----Initializing nacl-mounts.\n");
fflush(stdout);

// Setup writable homedir.
PepperMount* pepper_mount = new PepperMount(runner_, fs_, 20 * 1024 * 1024);
pepper_mount->SetDirectoryReader(&directory_reader_);
pepper_mount->SetPathPrefix("/dirdirSDLTest-userdata");

proxy_->mkdir("/dirSDLTest-userdata", 0777);
int res = proxy_->mount("/dirSDLTest-userdata", pepper_mount);

// The following lines can be removed when nacl-mounts starts intercepting mkdir() calls.
proxy_->mkdir("/dirSDLTest-userdata/saves", 0777);

// Setup r/o data directory in /usr/local/share/dirSDLTest
HTTP2Mount* http2_mount = new HTTP2Mount(runner_, "./usr/local/share/dirSDLTest");
http2_mount->SetLocalCache(fs_, 350*1024*1024, "/dirSDLTest0", true);
http2_mount->SetProgressHandler(&progress_handler_);

/* fprintf(stdout, "Registering known files.\n");
fflush(stdout);
for (int i = 0; i < sizeof(http_dirs) / sizeof(*http_dirs); ++i) {
char* path = (char*)http_dirs;
if (path && *path)
http2_mount->AddDir(path);
}

for (int i = 0; i < sizeof(http_files) / sizeof(*http_files); ++i) {
char* path = (char*)http_files.path;
size_t size = http_files.size;
if (path && *path)
http2_mount->AddFile(path, size);
}

for (int i = 0; i < sizeof(http_packs) / sizeof(*http_packs); ++i) {
char* path = (char*)http_packs.path;
char* pack_path = (char*)http_packs.pack_path;
off_t offset = http_packs.offset;
if (path && *path) {
http2_mount->SetInPack(path, pack_path, offset);
}
}*/

fprintf(stdout, "SetInMemory.\n");
//fflush(stdout);

http2_mount->SetInMemory("/images/sunspots.jpg", true);

fprintf(stdout, "Mounting the filesystem.\n");
// fflush(stdout);
res = proxy_->mkdir("/usr", 0777);
if (!res) {
fprintf(stdout, "usr mkdir success.\n");
} else {
fprintf(stdout, "usr mkdir failure.\n");
}

proxy_->mkdir("/usr/local", 0777);
if (!res) {
fprintf(stdout, "local mkdir success.\n");
} else {
fprintf(stdout, "local mkdir failure.\n");
}

proxy_->mkdir("/usr/local/share", 0777);
if (!res) {
fprintf(stdout, "share mkdir success.\n");
} else {
fprintf(stdout, "share mkdir failure.\n");
}

/*proxy_->mkdir("/usr/local/share/dirSDLTest", 0777);
if (!res) {
fprintf(stdout, "dirSDLTest mkdir success.\n");
} else {
fprintf(stdout, "dirSDLTest mkdir failure.\n");
}*/


res = proxy_->mount("/usr/local/share/dirSDLTest", http2_mount);
if (!res) {
fprintf(stdout, "FS initialization success.\n");
} else {
fprintf(stdout, "FS initialization failure.\n");
}
fflush(stdout);

#endif
sdl_main(0, NULL);
return NULL;
}

///////// ProgressHandler /////////////////////
class ProgressHandler : public HTTP2ProgressHandler {
public:
pp::Instance* instance_;

ProgressHandler(pp::Instance* instance) : instance_(instance) {}

void HandleProgress(std::string& path, int64_t bytes, int64_t size) {
fprintf(stdout, "---- Inside HandleProgress. ----\n");

char buf[100];
snprintf(buf, sizeof(buf), "%llu,%llu", (unsigned long long)bytes,
(unsigned long long)size);
std::string message = "[\"" + path + "\"," + buf + "]";

fprintf(stdout, "XXX -- Posting :[%s].\n", message.c_str());
fflush(stdout);

instance_->PostMessage(message);
}
};
ProgressHandler progress_handler_;

///////// JSDirectoryReader /////////////////////
class JSDirectoryReader: public DirectoryReader {
public:
pp::Instance* instance_;
pp::CompletionCallback cc_;
std::set<std::string>* entries_;

JSDirectoryReader(pp::Instance* instance) : instance_(instance) {}

int ReadDirectory(const std::string& path, std::set<std::string>* entries, const pp::CompletionCallback& cc) {
cc_ = cc;
entries_ = entries;
std::string message = "[\"ReadDirectory\",\"" + path + "\"]";
fprintf(stdout, "YYY --- ReadDir: [ %s ].\n", message.c_str());
fflush(stdout);
instance_->PostMessage(message);
return 0;
}

void HandleResponse(const std::string& response) {
fprintf(stdout, "YYY--- HandleResponse: %s\n", response.c_str());
std::string::const_iterator ind = response.begin();
std::string::const_iterator next = response.begin();
while (ind != response.end() && next != response.end()) {
if (*next == '\n' && ind != next) {
if (*ind == '\n') {
++ind;
}
if (ind != next) {
entries_->insert(std::string(ind, next));
}
ind = next;
}
++next;
}
if (ind != next) {
std::string last(ind, next-1);
if (!last.empty()) {
entries_->insert(last);
}
}
fflush(stdout);
cc_.Run(PP_OK);
}
};
JSDirectoryReader directory_reader_;
};



class PepperModule : public pp::Module
{
public:
virtual pp::Instance* CreateInstance(PP_Instance instance)
{
return new PluginInstance(instance);
}
};

namespace pp
{
Module* CreateModule()
{
return new PepperModule();
}
}
Post Reply