elua: safe logging within sandbox
authorDaniel Kolesa <quaker66@gmail.com>
Fri, 4 Apr 2014 15:25:39 +0000 (16:25 +0100)
committerDaniel Kolesa <d.kolesa@samsung.com>
Tue, 10 Jun 2014 14:48:46 +0000 (15:48 +0100)
src/bindings/luajit/eina/log.lua

index 7e8fa07..d1318bb 100644 (file)
@@ -30,6 +30,12 @@ ffi.cdef [[
                         int            line,
                         const char    *fmt,
                         ...);
+
+    typedef struct _Domain_Private {
+        int domain;
+    } Domain_Private;
+
+    typedef struct _Domain Domain;
 ]]
 
 local cutil = require("cutil")
@@ -38,16 +44,17 @@ local util  = require("util")
 local M = {}
 
 local eina
-local default_domain
+local default_domain, global_domain
 
 local init = function()
     eina = util.lib_load("eina")
-    default_domain = eina.EINA_LOG_DOMAIN_GLOBAL
+    global_domain  = ffi.new("Domain_Private", eina.EINA_LOG_DOMAIN_GLOBAL)
+    default_domain = global_domain
 end
 
 local shutdown = function()
     util.lib_unload("eina")
-    default_domain = nil
+    default_domain, global_domain = nil, nil
 end
 
 cutil.init_module(init, shutdown)
@@ -77,9 +84,19 @@ M.color = {
     HIGH      = "\x1B[1m"
 }
 
+local get_dom = function(dom)
+    dom = dom:__get_domain()
+    if not dom then return nil end
+    return ffi.cast("Domain_Private*", dom).domain
+end
+
+local unregister_dom = function(dom)
+    eina.eina_log_domain_unregister(ffi.cast("Domain_Private*", dom).domain)
+end
+
 local log_full = function(dom, level, file, func, line, msg)
-    dom = dom:get_domain()
-    if dom == -1 then return end
+    dom = get_dom(dom)
+    if not dom then return end
     eina.eina_log_print(dom, level, file, func, line, msg)
 end
 M.log_full = log_full
@@ -95,19 +112,19 @@ M.log = log
 
 M.Domain_Base = util.Object:clone {
     set_level = function(self, level)
-        local dom = self:get_domain()
-        if dom == -1 then return end
+        local dom = get_dom(self)
+        if not dom then return end
         eina.eina_log_domain_registered_level_set(dom, level)
     end,
 
     get_level = function(self)
-        local dom = self:get_domain()
-        if dom == -1 then return -1 end
+        local dom = get_dom(self)
+        if not dom then return -1 end
         return eina.eina_log_domain_registered_level_get(dom)
     end,
 
-    get_domain = function(self)
-        return -1
+    __get_domain = function(self)
+        return nil
     end,
 
     log = function(self, level, msg, loff)
@@ -116,15 +133,15 @@ M.Domain_Base = util.Object:clone {
 }
 
 M.Domain_Global = M.Domain_Base:clone {
-    get_domain = function(self)
-        return eina.EINA_LOG_DOMAIN_GLOBAL
+    __get_domain = function(self)
+        return global_domain
     end
 }
 
 M.global_domain = M.Domain_Global
 
 M.Domain_Default = M.Domain_Base:clone {
-    get_domain = function(self)
+    __get_domain = function(self)
         return default_domain
     end
 }
@@ -133,20 +150,18 @@ M.default_domain = M.Domain_Default
 
 M.Domain = M.Domain_Base:clone {
     __ctor = function(self, name, color)
-        self.__domain = eina.eina_log_domain_register(name, color)
-        self.__gc = newproxy(true)
-        getmetatable(self.__gc).__gc = function()
-            self:unregister()
-        end
+        self.__domain = ffi.cast("Domain*", ffi.new("Domain_Private",
+            eina.eina_log_domain_register(name, color)))
+        ffi.gc(self.__domain, unregister_dom)
     end,
 
     unregister = function(self)
-        if self.__domain == -1 then return end
-        eina.eina_log_domain_unregister(self.__domain)
-        self.__domain = -1
+        if not self.__domain then return end
+        unregister_dom(ffi.gc(self.__domain, nil))
+        self.__domain = nil
     end,
 
-    get_domain = function(self)
+    __get_domain = function(self)
         return self.__domain
     end
 }