Chromium Code Reviews| Index: tests/manifest_file/irt_manifest_file_test.cc |
| =================================================================== |
| --- tests/manifest_file/irt_manifest_file_test.cc (revision 0) |
| +++ tests/manifest_file/irt_manifest_file_test.cc (revision 0) |
| @@ -0,0 +1,284 @@ |
| +/* |
| + * 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. |
| + */ |
| + |
| +// |
| +// Post-message based test for simple rpc based access to name services. |
| +// |
| + |
| +#include <string> |
| + |
| +#include <assert.h> |
| +#include <stdio.h> |
| +#include <stdlib.h> |
| +#include <inttypes.h> |
| +#include <sys/fcntl.h> |
| +#include <string.h> |
| +#include <unistd.h> |
| +#include <pthread.h> |
| + |
| +#include "native_client/src/include/elf32.h" |
| +#include "native_client/src/include/elf_auxv.h" |
| +#include "native_client/src/include/nacl_base.h" |
| + |
| +#include "native_client/src/shared/platform/nacl_sync.h" |
| +#include "native_client/src/shared/platform/nacl_sync_checked.h" |
| +#include "native_client/src/shared/platform/nacl_sync_raii.h" |
| + |
| +#include "native_client/src/untrusted/irt/irt.h" |
| +#include "native_client/src/untrusted/irt/irt_ppapi.h" |
| +#include "native_client/src/untrusted/nacl_ppapi_util/nacl_ppapi_util.h" |
| +#include "native_client/src/untrusted/nacl_ppapi_util/string_buffer.h" |
| + |
| +#include "ppapi/c/pp_errors.h" |
| +#include "ppapi/c/pp_module.h" |
| +#include "ppapi/c/pp_var.h" |
| +#include "ppapi/c/ppb.h" |
| +#include "ppapi/c/ppb_instance.h" |
| +#include "ppapi/c/ppb_messaging.h" |
| +#include "ppapi/c/ppb_var.h" |
| +#include "ppapi/c/ppp.h" |
| +#include "ppapi/c/ppp_instance.h" |
| +#include "ppapi/c/ppp_messaging.h" |
| +//#include "ppapi/cpp/instance.h" |
| +//#include "ppapi/cpp/module.h" |
| +//#include "ppapi/cpp/var.h" |
| + |
| +#include <nacl/nacl_srpc.h> |
| +#include <sys/nacl_name_service.h> |
| +#include <sys/nacl_syscalls.h> |
| + |
| +/* |
| + * TODO(mcgrathr): This extremely stupid function should not exist. |
| + * If the startup calling sequence were sane, this would be done |
| + * someplace that has the initial pointer locally rather than stealing |
| + * it from environ. |
| + * See http://code.google.com/p/nativeclient/issues/detail?id=651 |
| + */ |
| +static Elf32_auxv_t *find_auxv(void) { |
| + /* |
| + * This presumes environ has its startup-time value on the stack. |
| + */ |
| + char **ep = environ; |
| + while (*ep != NULL) |
| + ++ep; |
| + return (Elf32_auxv_t *) (ep + 1); |
| +} |
| + |
| +/* |
| + * Scan the auxv for AT_SYSINFO, which is the pointer to the IRT query function. |
| + * TODO(mcgrathr): Could get this from __nacl_irt_query, where the libnacl |
| + * startup code stored it, but that would have to be also added as part of |
| + * the glibc ABI. |
| + */ |
| +static TYPE_nacl_irt_query grok_auxv(const Elf32_auxv_t *auxv) { |
| + const Elf32_auxv_t *av; |
| + for (av = auxv; av->a_type != AT_NULL; ++av) { |
| + if (av->a_type == AT_SYSINFO) |
| + return (TYPE_nacl_irt_query) av->a_un.a_val; |
| + } |
| + return NULL; |
| +} |
| + |
| +int module_id; |
| +struct PPB_Messaging *ppb_message_interface; |
| +struct PPB_Var *ppb_var_interface; |
| +const char *kHello = "hello"; |
| +std::string str; |
| +const char *kWorld = "world"; |
| + |
| +static char *VarToCStr(struct PP_Var var) { |
| + uint32_t len = 0; |
| + if (ppb_var_interface != NULL) { |
| + const char *var_c_str = ppb_var_interface->VarToUtf8(var, &len); |
| + if (len > 0) { |
| + char *c_str = (char*)malloc(len + 1); |
| + memcpy(c_str, var_c_str, len); |
| + c_str[len] = (char)0; |
| + return c_str; |
| + } |
| + } |
| + return NULL; |
| +} |
| + |
| +static PP_Bool Instance_DidCreate(PP_Instance instance, |
| + uint32_t argc, |
| + const char* argn[], |
| + const char* argv[]) { |
| + return PP_TRUE; |
| +} |
| + |
| +static void Instance_DidDestroy(PP_Instance instance) { |
| +} |
| + |
| +static void Instance_DidChangeView(PP_Instance instance, |
| + const struct PP_Rect* position, |
| + const struct PP_Rect* clip) { |
| +} |
| + |
| +static void Instance_DidChangeFocus(PP_Instance instance, |
| + PP_Bool has_focus) { |
| +} |
| + |
| +static PP_Bool Instance_HandleDocumentLoad(PP_Instance instance, |
| + PP_Resource url_loader) { |
| + /* NaCl modules do not need to handle the document load function. */ |
| + return PP_FALSE; |
| +} |
| + |
| +void Messaging_HandleMessage(PP_Instance instance, struct PP_Var var_message) { |
| + if (var_message.type != PP_VARTYPE_STRING) { |
| + /* Only handle string messages */ |
| + return; |
| + } |
| + char *message = VarToCStr(var_message); |
| + if (message == NULL) |
| + return; |
| + struct PP_Var var_result = PP_MakeUndefined(); |
| + if (strncmp(message, kHello, strlen(kHello)) == 0) { |
|
bsy
2011/08/11 02:32:43
why use strncmp instead of strcmp? did you intend
halyavin
2011/08/12 08:52:07
I rewrote test to use C++ API.
|
| + var_result = ppb_var_interface->VarFromUtf8(module_id, str.c_str(), |
| + strlen(str.c_str())); |
| + } |
| + free(message); |
| + /* Echo the return result back to browser. Note that HandleMessage is always |
| + * called on the main thread, so it's OK to post the message back to the |
| + * browser directly from here. This return post is asynchronous. |
| + */ |
| + ppb_message_interface->PostMessage(instance, var_result); |
| + /* If the message was created using VarFromUtf8() it needs to be released. |
| + * See the comments about VarFromUtf8() in ppapi/c/ppb_var.h for more |
| + * information. |
| + */ |
| + if (var_result.type == PP_VARTYPE_STRING) { |
| + ppb_var_interface->Release(var_result); |
| + } |
| +} |
| + |
| +int32_t PPP_InitializeModule( |
| + PP_Module param_module_id, |
| + PPB_GetInterface browser_interface) { |
| + module_id = param_module_id; |
| + ppb_message_interface = |
| + (struct PPB_Messaging*)browser_interface(PPB_MESSAGING_INTERFACE); |
| + ppb_var_interface = (struct PPB_Var*)(browser_interface(PPB_VAR_INTERFACE)); |
| + return PP_OK; |
| +} |
| + |
| +void PPP_ShutdownModule() { |
| +} |
| + |
| +const void *PPP_GetInterface(const char *interface_name) { |
| + if (strcmp(interface_name, PPP_INSTANCE_INTERFACE) == 0) { |
| + static struct PPP_Instance instance_interface = { |
| + &Instance_DidCreate, |
| + &Instance_DidDestroy, |
| + &Instance_DidChangeView, |
| + &Instance_DidChangeFocus, |
| + &Instance_HandleDocumentLoad, |
| + }; |
| + return &instance_interface; |
| + } else if (strcmp(interface_name, PPP_MESSAGING_INTERFACE) == 0) { |
| + static struct PPP_Messaging messaging_interface = { |
| + &Messaging_HandleMessage, |
| + }; |
| + return &messaging_interface; |
| + } |
| + return NULL; |
| +} |
| + |
| +const struct PP_StartFunctions funcs = { |
| + &PPP_InitializeModule, |
| + &PPP_ShutdownModule, |
| + &PPP_GetInterface, |
| +}; |
| + |
| +void load_thread(void *arg) { |
| + TYPE_nacl_irt_query *query_func = (TYPE_nacl_irt_query*)arg; |
| + struct nacl_irt_manifest_open nacl_irt_manifest_open; |
| + printf("inside\n"); |
| + if (sizeof(nacl_irt_manifest_open) != |
| + (*query_func)( |
| + NACL_IRT_MANIFEST_OPEN_v0_0, |
| + &nacl_irt_manifest_open, |
| + sizeof(nacl_irt_manifest_open))) { |
| + printf("irt manifest api not found\n"); |
| + return; |
| + } |
| + int desc; |
| + desc = nacl_irt_manifest_open.open_file_in_manifest("files/test_file"); |
| + if (-1 == desc) { |
| + str = "Invalid file descriptor\n"; |
| + printf("%s", str.c_str()); |
| + return; |
| + } |
| + |
| + str = "File Contents:\n"; |
| + |
| + FILE *iob = fdopen(desc, "r"); |
| + char buffer[4096]; |
| + while (fgets(buffer, sizeof buffer, iob) != NULL) { |
| + // NB: fgets does not discard the newline nor any carriage return |
| + // character before that. |
| + // |
| + // Note that CR LF is the default end-of-line style for Windows. |
| + // Furthermore, when the test_file (input data, which happens to |
| + // be the nmf file) is initially created in a change list, the |
| + // patch is sent to our try bots as text. This means that when |
| + // the file arrives, it has CR LF endings instead of the original |
| + // LF line endings. Since the expected or golden data is |
| + // (manually) encoded in the HTML file's JavaScript, there will be |
| + // a mismatch. After submission, the svn property svn:eol-style |
| + // will be set to LF, so a clean check out should have LF and not |
| + // CR LF endings, and the tests will pass without CR removal. |
| + // However -- and there's always a however in long discourses -- |
| + // if the nmf file is edited, say, because the test is being |
| + // modified, and the modification is being done on a Windows |
| + // machine, then it is likely that the editor used by the |
| + // programmer will convert the file to CR LF endings. Which, |
| + // unfortunatly, implies that the test will mysteriously fail |
| + // again. |
| + // |
| + // To defend against such nonsense, we weaken the test slighty, |
| + // and just strip the CR if it is present. |
| + int len = strlen(buffer); |
| + if (len >= 2 && buffer[len-1] == '\n' && buffer[len-2] == '\r') { |
| + buffer[len-2] = '\n'; |
| + buffer[len-1] = '\0'; |
| + } |
| + str += buffer; |
| + } |
| + printf("here %d\n", strlen(str.c_str())); |
| + printf("%s\n", str.c_str()); |
| + fclose(iob); // closed desc |
| + struct nacl_irt_ppapihook hooks; |
| + if (sizeof(hooks) == (*query_func)( |
| + NACL_IRT_PPAPIHOOK_v0_1, &hooks, sizeof(hooks))) { |
| + hooks.ppapi_start(&funcs); |
| + } else { |
| + printf("PpapiPluginStart: PPAPI hooks not found\n"); |
| + } |
| + return; |
| +} |
| + |
| +int main() { |
| + TYPE_nacl_irt_query query_func = grok_auxv(find_auxv()); |
| + printf("main\n"); |
| + |
| + if (NULL == query_func) |
| + printf("PpapiPluginStart: No AT_SYSINFO item found in auxv, " |
| + "so cannot start PPAPI. Is the IRT library not present?\n"); |
| + |
| + struct nacl_irt_ppapihook_0_2 hooks; |
| + int result; |
| + result = query_func(NACL_IRT_PPAPIHOOK_v0_2, &hooks, sizeof(hooks)); |
| + if (sizeof(hooks) != result) |
| + printf("PpapiPluginStart: PPAPI advanced hooks not found %d %d\n", |
| + sizeof(hooks), result); |
| + hooks.ppapi_pre_start(); |
| + load_thread(&query_func); |
| + printf("shouldn't reach here\n"); |
| + return 0; |
| + //return hooks.ppapi_ld_start(&load_thread, &query_func); |
| +} |