PageRenderTime 6ms CodeModel.GetById 1ms app.highlight 2ms RepoModel.GetById 1ms app.codeStats 0ms

/src/wrappers/posix/dynamic-linking/library/dynamic_shared_object.e

http://github.com/tybor/Liberty
Specman e | 130 lines | 48 code | 19 blank | 63 comment | 2 complexity | dbbad3952097080691a09eb05a3dec3d MD5 | raw file
  1class DYNAMIC_SHARED_OBJECT
  2	-- A dynamic shared object loaded with the support of the operative system,
  3	-- also known as .so libraries or as DLL.
  4
  5	-- Insert DYNAMIC_LINKING_LOADER and use `new_dynamic_shared_object' or
  6	-- `main_program' to get an instance of this class.
  7
  8	-- Currently available only on POSIX systems where it wraps dlopen
  9
 10inherit 
 11	WRAPPER
 12
 13insert
 14	DL_FLAGS
 15	DLFCN_EXTERNALS
 16
 17create {DYNAMIC_LINKING_LOADER} from_external_pointer
 18
 19feature {ANY} -- Command
 20	set_flags (some_flags: INTEGER)
 21		-- Change the flags 
 22	require are_valid_dlflags(some_flags)
 23	local h,ptr: POINTER
 24	do
 25		-- Using dlopen with rtld_noload to promote the flags on a library that
 26		-- is already loaded.  For example, a library that was previously
 27		-- loaded with RTLD_LOCAL can be re-opened with RTLD_NOLOAD |
 28		-- RTLD_GLOBAL.  This flag is not specified in POSIX.1-2001.
 29		if name/=Void then h:=name.to_external end
 30		ptr:=dlopen(h,some_flags)
 31		check
 32			handle=ptr
 33		end
 34	end
 35
 36feature {DYNAMIC_LINKING_LOADER, DL_LOADER}
 37	set_name (a_name: ABSTRACT_STRING)
 38		do
 39			name:=a_name
 40		end
 41
 42feature {ANY} -- Symbol query
 43	name: ABSTRACT_STRING
 44		-- The filename where Current have been loaded from. Void when Current refers to the main program
 45		attribute
 46	end
 47
 48	symbol (a_symbol: ABSTRACT_STRING): POINTER
 49		-- The address where `a_symbol' - belonging to Current - is loaded into
 50		-- memory.  If it is not found, either in Current or in its dependecies
 51		-- Result will be default_pointer. The search performed is breadth
 52		-- first through the dependency tree of these libraries. Since the
 53		-- value of the symbol could actually be default_pointer (defined as
 54		-- NULL in C) the  correct  way  to test for an error is to assign
 55		-- `error' to a local string, invoke `symbol' and assign `error' again
 56		-- checking for the last value.
 57
 58		-- foo (a_dll: DYNAMIC_SHARED_OBJECT) is 
 59		-- require a_dll/=Void
 60		-- local precall_status, post_status: STRING; my_symbol: POINTER
 61		-- do
 62		--   precall_status := a_dll.error
 63		--   my_symbol := a_dll.symbol("foo")
 64		--   post_status := a_dll.error
 65		--   if post_status/=Void then -- everything ok
 66		--   else -- error resolving "foo"
 67		-- end
 68		
 69		-- Do not write "if a_dll.symbol("foo").is_not_null", defaull_pointer may be the actual value of "foo"
 70
 71		-- Do not write "my_symbol:=a_dll.symbol("foo") if a_dll.error/=Void
 72		-- then print(a_dll.error)", because error is resetted every time it
 73		-- invoked; the print command will ALWAYS fails because its argument
 74		-- will be NULL.
 75
 76		 -- There are two special pseudo-handles, "RTLD_DEFAULT" and
 77		 -- "RTLD_NEXT". The former will find the first occurrence of the
 78		 -- desired symbol using the default library search order. The latter
 79		 -- will find the next occurrence of a function in  the search order
 80		 -- after the current library. This allows one to provide a wrapper
 81		 -- around a function in another shared library.
 82
 83		do
 84			Result:=dlsym(handle,a_symbol.to_external)
 85		end
 86
 87feature {ANY} -- Error handling
 88	error: FIXED_STRING
 89		--  A human  readable description of the most recent error that
 90		--  occurred during DYNAMIC_SHARED_OBJECT lifetime - creation, symbol
 91		--  query and disposing. Void when no error occurred. A new string is allocated at every query
 92	local ptr: POINTER
 93	do	
 94		ptr :=dlerror
 95		if ptr.is_not_null then
 96			create Result.from_external_copy(ptr)
 97		end
 98	end
 99
100feature {ANY} -- Disposing
101	dispose
102		-- Invokes dlclose; it decrements the reference count on the dynamic library  handle  handle.   If  the  reference
103		-- count drops to zero and no other loaded libraries use symbols in it, then the dynamic library is unloaded.
104	local r: INTEGER
105	do
106		r:=dlclose(handle)
107		-- TODO: handle dlclose results: 0 on success, and non-zero on error.
108	end
109		
110feature {} -- Unwrapped
111	-- TODO: provide access to Glibc dladdr() and dlvsym() extensions functions
112end -- class DYNAMIC_SHARED_OBJECT
113
114-- Liberty Eiffel wrappers for GNU C library Copyright (C) 2013-2017: Paolo Redaelli, Free Software Foundation
115-- 
116-- The GNU C Library is free software; you can redistribute it and/or
117-- modify it under the terms of the GNU Lesser General Public
118-- License as published by the Free Software Foundation; either
119-- version 2.1 of the License, or (at your option) any later version.
120-- 
121-- The GNU C Library is distributed in the hope that it will be useful,
122-- but WITHOUT ANY WARRANTY; without even the implied warranty of
123-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
124-- Lesser General Public License for more details.
125-- 
126-- You should have received a copy of the GNU Lesser General Public
127-- License along with the GNU C Library; if not, write to the Free
128-- Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
129-- 02110-1301 USA
130