You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@celix.apache.org by pn...@apache.org on 2015/11/03 16:09:48 UTC

[22/50] [abbrv] celix git commit: CELIX-230: Merge branch 'develop' into shell refactor. Refactored shell service and update shell_tui and remote_shell for refactored shell service

CELIX-230: Merge branch 'develop' into shell refactor. Refactored shell service and update shell_tui and remote_shell for refactored shell service

Conflicts:
	launcher/private/src/launcher.c
	shell/private/src/help_command.c


Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/c35a74c7
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/c35a74c7
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/c35a74c7

Branch: refs/heads/master
Commit: c35a74c762837711df59fcde447889164cb29402
Parents: bafe2ef 6c93851
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Tue Oct 27 16:19:18 2015 +0100
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Tue Oct 27 16:19:18 2015 +0100

----------------------------------------------------------------------
 .gitignore                                      |    4 +
 .travis.yml                                     |   41 +
 CMakeLists.txt                                  |   17 +-
 LICENSE                                         |   26 +-
 README.md                                       |    2 +-
 cmake/CMakeCelix.cmake                          |    6 +-
 cmake/FindCppUTest.cmake                        |   34 +-
 cmake/FindFFI.cmake                             |   57 +
 cmake/cmake_celix/CodeCoverage.cmake            |   48 +-
 cmake/cmake_celix/Test.cmake                    |   52 -
 dependency_manager_2/CMakeLists.txt             |    2 +-
 deployment_admin/CMakeLists.txt                 |   10 +-
 deployment_admin/private/src/deployment_admin.c |   55 +-
 .../private/src/deployment_package.c            |    1 +
 device_access/device_access/CMakeLists.txt      |    4 +-
 .../device_access/private/src/device_manager.c  |    1 +
 .../private/src/driver_attributes.c             |    1 +
 .../device_access/private/src/driver_loader.c   |    1 +
 device_access/driver_locator/CMakeLists.txt     |    4 +-
 .../example/base_driver/CMakeLists.txt          |    4 +-
 .../base_driver/private/src/base_driver.c       |    2 +-
 .../example/consuming_driver/CMakeLists.txt     |    4 +-
 .../private/src/consuming_driver.c              |    1 +
 .../example/refining_driver/CMakeLists.txt      |    4 +-
 .../private/src/refining_driver.c               |    1 +
 examples/CMakeLists.txt                         |    7 +-
 examples/deploy.cmake                           |    6 +-
 framework/CMakeLists.txt                        |  144 +-
 framework/private/include/framework_private.h   |    6 +-
 framework/private/mock/bundle_context_mock.c    |   25 +-
 framework/private/mock/bundle_mock.c            |   13 +-
 framework/private/mock/framework_mock.c         |    6 +-
 framework/private/src/bundle_archive.c          |    2 +-
 framework/private/src/bundle_cache.c            |    5 +-
 framework/private/src/celix_launcher.c          |  190 +++
 framework/private/src/celix_log.c               |    5 +-
 framework/private/src/framework.c               |  318 ++--
 framework/private/src/properties.c              |   13 +-
 framework/private/src/service_registration.c    |   13 +-
 framework/private/src/service_registry.c        |    2 +-
 framework/private/test/bundle_context_test.cpp  |   75 +-
 framework/public/include/celix_launcher.h       |   41 +
 framework/public/include/properties.h           |    3 +
 framework/tst/CMakeLists.txt                    |   30 +
 framework/tst/config.properties.in              |    2 +
 framework/tst/framework1.properties.in          |    3 +
 framework/tst/framework2.properties.in          |    3 +
 framework/tst/multiple_frameworks_test.cpp      |   89 ++
 framework/tst/run_tests.cpp                     |    9 +
 framework/tst/single_framework_test.cpp         |   69 +
 launcher/CMakeLists.txt                         |   10 +-
 launcher/private/src/launcher.c                 |  202 ---
 launcher/private/src/main.c                     |   88 ++
 log_service/CMakeLists.txt                      |    2 +-
 log_service/private/src/log_factory.c           |    2 +-
 log_writer/CMakeLists.txt                       |    2 +-
 .../private/src/log_writer_syslog.c             |    2 -
 remote_services/CMakeLists.txt                  |   11 +-
 .../discovery/private/src/discovery.c           |    1 +
 .../discovery/private/src/discovery_activator.c |  186 +--
 .../private/src/endpoint_discovery_poller.c     |  191 ++-
 .../private/src/endpoint_discovery_server.c     |   51 +-
 .../discovery_configured/CMakeLists.txt         |   24 +-
 remote_services/discovery_etcd/CMakeLists.txt   |    2 +-
 .../discovery_etcd/private/include/etcd.h       |    2 +-
 .../discovery_etcd/private/src/discovery_impl.c |    9 +-
 .../discovery_etcd/private/src/etcd.c           |  135 +-
 .../discovery_etcd/private/src/etcd_watcher.c   |   78 +-
 .../discovery_shm/private/src/shm_watcher.c     |    3 +-
 .../public/include/endpoint_listener.h          |   48 -
 remote_services/examples/CMakeLists.txt         |    2 +-
 .../private/src/calculator_endpoint_activator.c |    8 +-
 .../private/src/calculator_proxy_activator.c    |   12 +-
 .../examples/calculator_service/CMakeLists.txt  |    5 +-
 .../private/src/calculator_activator.c          |   12 +-
 .../public/include/calculator_service.h         |    8 +-
 ...apache.celix.calc.api.Calculator2.descriptor |   11 +
 .../examples/calculator_shell/CMakeLists.txt    |    4 +
 .../calculator_shell/private/src/add_command.c  |    3 +-
 .../calculator_shell/private/src/sqrt_command.c |    3 +-
 .../calculator_shell/private/src/sub_command.c  |    3 +-
 remote_services/examples/deploy.cmake           |    4 +-
 .../remote_service_admin/CMakeLists.txt         |    8 +-
 .../private/include/export_registration_impl.h  |    3 -
 .../private/include/remote_service_admin_impl.h |   17 -
 .../private/src/export_registration_impl.c      |   22 +-
 .../private/src/import_registration_impl.c      |   22 +-
 .../private/src/remote_proxy_factory_impl.c     |    7 +
 .../public/include/endpoint_listener.h          |   48 +
 .../public/include/export_registration.h        |   22 +
 .../public/include/import_registration.h        |   22 +
 .../public/include/remote_constants.h           |   38 +
 .../public/include/remote_service_admin.h       |    6 +-
 .../remote_service_admin_dfi/CMakeLists.txt     |   31 +
 .../dynamic_function_interface/CMakeLists.txt   |   22 +
 .../dynamic_function_interface/dfi_log_util.h   |   48 +
 .../dynamic_function_interface/dyn_common.c     |  136 ++
 .../dynamic_function_interface/dyn_common.h     |   32 +
 .../dynamic_function_interface/dyn_function.c   |  320 ++++
 .../dynamic_function_interface/dyn_function.h   |   46 +
 .../dynamic_function_interface/dyn_interface.c  |  416 +++++
 .../dynamic_function_interface/dyn_interface.h  |   48 +
 .../dynamic_function_interface/dyn_type.c       | 1129 +++++++++++++
 .../dynamic_function_interface/dyn_type.h       |  142 ++
 .../dynamic_function_interface/json_rpc.c       |  296 ++++
 .../dynamic_function_interface/json_rpc.h       |   22 +
 .../json_serializer.c                           |  452 ++++++
 .../json_serializer.h                           |   22 +
 .../memstream/README.md                         |   49 +
 .../memstream/fmemopen.c                        |   78 +
 .../memstream/fmemopen.h                        |   52 +
 .../memstream/open_memstream.c                  |  130 ++
 .../memstream/open_memstream.h                  |   15 +
 .../CMakeLists.txt                              |   27 +
 .../avro_descriptor_translator_tests.cpp        |  164 ++
 .../descriptors/example1.descriptor             |   13 +
 .../descriptors/example2.descriptor             |    9 +
 .../descriptors/example3.descriptor             |   11 +
 .../dyn_closure_tests.cpp                       |  146 ++
 .../dyn_function_tests.cpp                      |  237 +++
 .../dyn_interface_tests.cpp                     |  103 ++
 .../dyn_type_tests.cpp                          |  281 ++++
 .../json_rpc_tests.cpp                          |  329 ++++
 .../json_serializer_tests.cpp                   |  462 ++++++
 .../run_tests.cpp                               |    9 +
 .../schemas/complex.avdl                        |   11 +
 .../schemas/complex.avpr                        |   36 +
 .../schemas/invalid1.avpr                       |   29 +
 .../schemas/invalid2.avpr                       |   31 +
 .../schemas/simple.avdl                         |    6 +
 .../schemas/simple.avpr                         |   33 +
 .../schemas/simple_min.avpr                     |    1 +
 .../remote_service_admin_dfi/rsa/CMakeLists.txt |   47 +
 .../private/include/export_registration_dfi.h   |   21 +
 .../private/include/import_registration_dfi.h   |   26 +
 .../private/include/remote_service_admin_dfi.h  |   56 +
 .../rsa/private/src/export_registration_dfi.c   |  222 +++
 .../rsa/private/src/import_registration_dfi.c   |  355 +++++
 .../src/remote_service_admin_activator.c        |  124 ++
 .../rsa/private/src/remote_service_admin_dfi.c  |  737 +++++++++
 .../rsa_tst/CMakeLists.txt                      |   45 +
 .../rsa_tst/bundle/CMakeLists.txt               |   24 +
 .../rsa_tst/bundle/tst_activator.c              |  137 ++
 .../rsa_tst/bundle/tst_service.h                |   17 +
 .../rsa_tst/client.properties.in                |    8 +
 .../rsa_tst/config.properties.in                |    3 +
 .../rsa_tst/rsa_client_server_tests.cpp         |  114 ++
 .../rsa_tst/rsa_tests.cpp                       |  201 +++
 .../rsa_tst/run_tests.cpp                       |    9 +
 .../rsa_tst/server.properties.in                |    7 +
 .../remote_service_admin_http/CMakeLists.txt    |    8 +-
 .../src/remote_service_admin_activator.c        |    3 +-
 .../private/src/remote_service_admin_impl.c     |  160 +-
 .../private/src/remote_service_admin_impl.c     |   27 +-
 .../private/include/topology_manager.h          |    7 +
 .../topology_manager/private/src/activator.c    |  296 ++--
 .../private/src/topology_manager.c              |  940 ++++++-----
 .../utils/private/include/civetweb.h            |    4 +-
 remote_services/utils/private/src/civetweb.c    |   10 +-
 .../utils/public/include/remote_constants.h     |   38 -
 remote_shell/CMakeLists.txt                     |    4 +-
 remote_shell/private/include/shell_mediator.h   |    2 +-
 remote_shell/private/src/activator.c            |    2 +-
 remote_shell/private/src/connection_listener.c  |    1 +
 remote_shell/private/src/remote_shell.c         |   49 +-
 remote_shell/private/src/shell_mediator.c       |   22 +-
 shell/CMakeLists.txt                            |    2 +-
 shell/private/include/shell_private.h           |    2 +-
 shell/private/src/activator.c                   |    6 +-
 shell/private/src/help_command.c                |  121 +-
 shell/private/src/inspect_command.c             |    7 +
 shell/private/src/shell.c                       |   10 +-
 shell/private/src/update_command.c              |    2 +-
 shell/public/include/shell.h                    |    2 +-
 shell_tui/CMakeLists.txt                        |    2 +-
 shell_tui/private/src/shell_tui.c               |    5 +-
 utils/CMakeLists.txt                            |   57 +-
 utils/private/src/hash_map.c                    |   57 +-
 utils/private/src/linked_list.c                 |    2 +-
 utils/private/test/array_list_test.c            |  357 -----
 utils/private/test/array_list_test.cpp          |  500 +++++-
 utils/private/test/celix_threads_test.cpp       |  349 ++++
 utils/private/test/hash_map_test.c              |  478 ------
 utils/private/test/hash_map_test.cpp            | 1492 ++++++++++++++++++
 utils/private/test/hash_map_test_hash.c         |  359 -----
 utils/private/test/linked_list_test.c           |   96 --
 utils/private/test/linked_list_test.cpp         |  794 ++++++++++
 utils/public/include/celix_threads.h            |    2 +-
 utils/public/include/hash_map.h                 |    4 +-
 utils/public/include/linked_list.h              |    2 +-
 190 files changed, 13478 insertions(+), 3180 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/c35a74c7/remote_shell/private/include/shell_mediator.h
----------------------------------------------------------------------
diff --cc remote_shell/private/include/shell_mediator.h
index e376d76,e376d76..faf86e8
--- a/remote_shell/private/include/shell_mediator.h
+++ b/remote_shell/private/include/shell_mediator.h
@@@ -48,6 -48,6 +48,6 @@@ typedef struct shell_mediator *shell_me
  
  celix_status_t shellMediator_create(bundle_context_pt context, shell_mediator_pt *instance);
  celix_status_t shellMediator_destroy(shell_mediator_pt instance);
--celix_status_t shellMediator_executeCommand(shell_mediator_pt instance, char *command, int socket);
++celix_status_t shellMediator_executeCommand(shell_mediator_pt instance, char *command, FILE *out, FILE *err);
  
  #endif /* shellMediator_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/c35a74c7/remote_shell/private/src/remote_shell.c
----------------------------------------------------------------------
diff --cc remote_shell/private/src/remote_shell.c
index 945946e,41a303d..73b76d4
--- a/remote_shell/private/src/remote_shell.c
+++ b/remote_shell/private/src/remote_shell.c
@@@ -49,7 -50,7 +50,7 @@@
  
  struct connection {
  	remote_shell_pt parent;
--	int socket;
++	FILE *socketStream;
  	fd_set pollset;
  	bool threadRunning;
  };
@@@ -98,26 -99,26 +99,34 @@@ celix_status_t remoteShell_addConnectio
  
  	if (connection != NULL) {
  		connection->parent = instance;
--		connection->socket = socket;
  		connection->threadRunning = false;
++		connection->socketStream = fdopen(socket, "w");
+ 
 -		celixThreadMutex_lock(&instance->mutex);
++		if (connection->socketStream != NULL) {
 +
- 		celixThreadMutex_lock(&instance->mutex);
++			celixThreadMutex_lock(&instance->mutex);
++
++			if (arrayList_size(instance->connections) < instance->maximumConnections) {
++				celix_thread_t connectionRunThread = celix_thread_default;
++				arrayList_add(instance->connections, connection);
++				status = celixThread_create(&connectionRunThread, NULL, &remoteShell_connection_run, connection);
++			} else {
++				status = CELIX_BUNDLE_EXCEPTION;
++				remoteShell_connection_print(connection, RS_MAXIMUM_CONNECTIONS_REACHED);
++			}
++			celixThreadMutex_unlock(&instance->mutex);
  
--		if (arrayList_size(instance->connections) < instance->maximumConnections) {
--			celix_thread_t connectionRunThread = celix_thread_default;
--			arrayList_add(instance->connections, connection);
--			status = celixThread_create(&connectionRunThread, NULL, &remoteShell_connection_run, connection);
  		} else {
  			status = CELIX_BUNDLE_EXCEPTION;
--			remoteShell_connection_print(connection, RS_MAXIMUM_CONNECTIONS_REACHED);
  		}
--		celixThreadMutex_unlock(&instance->mutex);
  	} else {
  		status = CELIX_ENOMEM;
  	}
  
  	if (status != CELIX_SUCCESS) {
--		close(connection->socket);
++		if (connection->socketStream != NULL) {
++			fclose(connection->socketStream);
++		}
  		free(connection);
  	}
  
@@@ -149,6 -150,6 +158,8 @@@ void *remoteShell_connection_run(void *
  	int result;
  	struct timeval timeout; /* Timeout for select */
  
++	int fd = fileno(connection->socketStream);
++
  	connection->threadRunning = true;
  	status = remoteShell_connection_print(connection, RS_WELCOME);
  
@@@ -158,15 -159,15 +169,15 @@@
  			timeout.tv_usec = 0;
  
  			FD_ZERO(&connection->pollset);
--			FD_SET(connection->socket, &connection->pollset);
--			result = select(connection->socket + 1, &connection->pollset, NULL, NULL, &timeout);
++			FD_SET(fd, &connection->pollset);
++			result = select(fd + 1, &connection->pollset, NULL, NULL, &timeout);
  		} while (result == -1 && errno == EINTR && connection->threadRunning == true);
  
  		/* The socket_fd has data available to be read */
--		if (result > 0 && FD_ISSET(connection->socket, &connection->pollset)) {
++		if (result > 0 && FD_ISSET(fd, &connection->pollset)) {
  			char buff[COMMAND_BUFF_SIZE];
  
--			len = recv(connection->socket, buff, COMMAND_BUFF_SIZE - 1, 0);
++			len = recv(fd, buff, COMMAND_BUFF_SIZE - 1, 0);
  			if (len < COMMAND_BUFF_SIZE) {
  				celix_status_t commandStatus = CELIX_SUCCESS;
  				buff[len] = '\0';
@@@ -196,7 -197,7 +207,7 @@@
  	arrayList_removeElement(connection->parent->connections, connection);
  	celixThreadMutex_unlock(&connection->parent->mutex);
  
--	close(connection->socket);
++	fclose(connection->socketStream);
  
  	return NULL;
  }
@@@ -214,7 -215,7 +225,8 @@@ static celix_status_t remoteShell_conne
  		} else if (len == 4 && strncmp("exit", line, 4) == 0) {
  			status = CELIX_FILE_IO_EXCEPTION;
  		} else {
--			status = shellMediator_executeCommand(connection->parent->mediator, line, connection->socket);
++			status = shellMediator_executeCommand(connection->parent->mediator, line, connection->socketStream, connection->socketStream);
++            fflush(connection->socketStream);
  		}
  
  		free(dline);
@@@ -225,5 -226,5 +237,6 @@@
  
  celix_status_t remoteShell_connection_print(connection_pt connection, char *text) {
  	size_t len = strlen(text);
--	return (send(connection->socket, text, len, 0) > 0) ? CELIX_SUCCESS : CELIX_FILE_IO_EXCEPTION;
++    int fd = fileno(connection->socketStream);
++	return (send(fd, text, len, 0) > 0) ? CELIX_SUCCESS : CELIX_FILE_IO_EXCEPTION;
  }

http://git-wip-us.apache.org/repos/asf/celix/blob/c35a74c7/remote_shell/private/src/shell_mediator.c
----------------------------------------------------------------------
diff --cc remote_shell/private/src/shell_mediator.c
index 95d3aa0,3f3fb36..ab60f3e
--- a/remote_shell/private/src/shell_mediator.c
+++ b/remote_shell/private/src/shell_mediator.c
@@@ -35,12 -36,12 +36,6 @@@
  #include "log_service.h"
  #include "shell_mediator.h"
  
--//NOTE: multiple instances of shell_mediator are not supported, because we need
--// 		a non ADT - shared between instances - variable.
--static int currentOutputSocket = -1;
--
--static void shellMediator_writeOnCurrentSocket(char *buff);
--
  static celix_status_t shellMediator_addingService(void *handler, service_reference_pt reference, void **service);
  static celix_status_t shellMediator_addedService(void *handler, service_reference_pt reference, void * service);
  static celix_status_t shellMediator_modifiedService(void *handler, service_reference_pt reference, void * service);
@@@ -95,21 -96,21 +90,14 @@@ celix_status_t shellMediator_destroy(sh
  	return status;
  }
  
--static void shellMediator_writeOnCurrentSocket(char *buff) {
--
--	size_t len = strlen(buff);
--	send(currentOutputSocket, buff, len, 0);
--}
--
--celix_status_t shellMediator_executeCommand(shell_mediator_pt instance, char *command, int socket) {
++celix_status_t shellMediator_executeCommand(shell_mediator_pt instance, char *command, FILE *out, FILE *err) {
  	celix_status_t status = CELIX_SUCCESS;
  
  	celixThreadMutex_lock(&instance->mutex);
  
++
  	if (instance->shellService != NULL) {
--		currentOutputSocket = socket;
--		instance->shellService->executeCommand(instance->shellService->shell, command, shellMediator_writeOnCurrentSocket, shellMediator_writeOnCurrentSocket);
--		currentOutputSocket = -1;
++		instance->shellService->executeCommand(instance->shellService->shell, command, out, err);
  	}
  
  	celixThreadMutex_unlock(&instance->mutex);

http://git-wip-us.apache.org/repos/asf/celix/blob/c35a74c7/shell/CMakeLists.txt
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/celix/blob/c35a74c7/shell/private/include/shell_private.h
----------------------------------------------------------------------
diff --cc shell/private/include/shell_private.h
index 5761431,db609ca..092f6e3
--- a/shell/private/include/shell_private.h
+++ b/shell/private/include/shell_private.h
@@@ -33,18 -33,20 +33,18 @@@
  #include "command.h"
  
  struct shell {
 -	bundle_context_pt bundleContext;
 -	hash_map_pt commandReferenceMap;
 -	hash_map_pt commandNameMap;
 +	bundle_context_pt bundle_context_ptr;
 +	hash_map_pt command_reference_map_ptr;
 +	hash_map_pt command_name_map_ptr;
  };
  
 -celix_status_t shell_create(bundle_context_pt, shell_service_pt* shellService);
 -celix_status_t shell_destroy(shell_service_pt* shellService);
 -celix_status_t shell_addCommand(shell_pt shell, service_reference_pt reference);
 +celix_status_t shell_create(bundle_context_pt context_ptr, shell_service_pt *shell_service_ptr);
 +celix_status_t shell_destroy(shell_service_pt *shell_service_ptr);
 +celix_status_t shell_addCommand(shell_pt shell_ptr, service_reference_pt reference_ptr);
 +celix_status_t shell_removeCommand(shell_pt shell_ptr, service_reference_pt reference_ptr);
  
 -
 -char * shell_getCommandUsage(shell_pt shell, char * commandName);
 -char * shell_getCommandDescription(shell_pt shell, char * commandName);
 -service_reference_pt shell_getCommandReference(shell_pt shell, char * command);
 -void shell_executeCommand(shell_pt shell, char * commandLine, void (*out)(char *), void (*error)(char *));
 -void shell_serviceChanged(service_listener_pt listener, service_event_pt event);
 +celix_status_t shell_getCommandReference(shell_pt shell_ptr, char *command_name_str, service_reference_pt *command_reference_ptr);
- celix_status_t shell_executeCommand(shell_pt shell_ptr, char *command_line_str, void (*out)(char *), void (*error)(char *));
++celix_status_t shell_executeCommand(shell_pt shell_ptr, char *command_line_str, FILE *out, FILE *err);
 +celix_status_t shell_serviceChanged(service_listener_pt listener_ptr, service_event_pt event_ptr);
  
  #endif /* SHELL_PRIVATE_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/c35a74c7/shell/private/src/activator.c
----------------------------------------------------------------------
diff --cc shell/private/src/activator.c
index 6915e82,92ba36e..7cb2946
--- a/shell/private/src/activator.c
+++ b/shell/private/src/activator.c
@@@ -51,126 -89,21 +51,126 @@@ struct bundle_instance 
  
  typedef struct bundle_instance *bundle_instance_pt;
  
 -static celix_status_t shell_createCommandService(command_pt command, command_service_pt *commandService) {
 +celix_status_t bundleActivator_create(bundle_context_pt context_ptr, void **_pptr) {
  	celix_status_t status = CELIX_SUCCESS;
  
 -	*commandService = calloc(1, sizeof(**commandService));
 -
 -	if (!*commandService) {
 -		status = CELIX_ENOMEM;
 -	}
 -	else {
 -		(*commandService)->command = command;
 -		(*commandService)->executeCommand = command->executeCommand;
 -		(*commandService)->getName = command_getName;
 -		(*commandService)->getShortDescription = command_getShortDescription;
 -		(*commandService)->getUsage = command_getUsage;
 -	}
 +    bundle_instance_pt instance_ptr = NULL;
 +
 +    if (!_pptr || !context_ptr) {
 +        status = CELIX_ENOMEM;
 +    }
 +
 +    if (status == CELIX_SUCCESS) {
 +        instance_ptr = (bundle_instance_pt) calloc(1, sizeof(struct bundle_instance));
 +        if (!instance_ptr) {
 +            status = CELIX_ENOMEM;
 +        }
 +    }
 +
 +    if (status == CELIX_SUCCESS) {
 +        status = shell_create(context_ptr, &instance_ptr->shellService);
 +    }
 +
 +    if (status == CELIX_SUCCESS) {
 +        instance_ptr->std_commands[0] =
 +                (struct command) {
 +                        .exec = psCommand_execute,
-                         .name = "ps",
-                         .description = "list installed bundles.",
-                         .usage = "ps [-l | -s | -u]"
++                        .name = "lb",
++                        .description = "list bundles.",
++                        .usage = "lb [-l | -s | -u]"
 +                };
 +        instance_ptr->std_commands[1] =
 +                (struct command) {
 +                        .exec = startCommand_execute,
 +                        .name = "start",
 +                        .description = "start bundle(s).",
 +                        .usage = "start <id> [<id> ...]"
 +                };
 +        instance_ptr->std_commands[2] =
 +                (struct command) {
 +                        .exec = stopCommand_execute,
 +                        .name = "stop",
 +                        .description = "stop bundle(s).",
 +                        .usage = "stop <id> [<id> ...]"
 +                };
 +        instance_ptr->std_commands[3] =
 +                (struct command) {
 +                        .exec = installCommand_execute,
 +                        .name = "install",
 +                        .description = "install bundle(s).",
 +                        .usage = "install <file> [<file> ...]"
 +                };
 +        instance_ptr->std_commands[4] =
 +                (struct command) {
 +                        .exec = uninstallCommand_execute,
 +                        .name = "uninstall",
 +                        .description = "uninstall bundle(s).",
 +                        .usage = "uninstall <file> [<file> ...]"
 +                };
 +        instance_ptr->std_commands[5] =
 +                (struct command) {
 +                        .exec = updateCommand_execute,
 +                        .name = "update",
 +                        .description = "update bundle(s).",
 +                        .usage = "update <id> [<URL>]"
 +                };
 +        instance_ptr->std_commands[6] =
 +                (struct command) {
 +                        .exec = helpCommand_execute,
 +                        .name = "help",
 +                        .description = "display available commands and description.",
 +                        .usage = "help <command>]"
 +                };
 +        instance_ptr->std_commands[7] =
 +                (struct command) {
 +                        .exec = logCommand_execute,
 +                        .name = "log",
 +                        .description = "print log.",
 +                        .usage = "log"
 +                };
 +        instance_ptr->std_commands[8] =
 +                (struct command) {
 +                        .exec = inspectCommand_execute,
 +                        .name = "inspect",
 +                        .description = "inspect services and components.",
 +                        .usage = "inspect (service) (capability|requirement) [<id> ...]"
 +                };
 +        instance_ptr->std_commands[9] =
 +                (struct command) { NULL, NULL, NULL, NULL, NULL, NULL, NULL }; /*marker for last element*/
 +
 +        unsigned int i = 0;
 +        while (instance_ptr->std_commands[i].exec != NULL) {
 +            instance_ptr->std_commands[i].props = properties_create();
 +            if (!instance_ptr->std_commands[i].props) {
 +                status = CELIX_BUNDLE_EXCEPTION;
 +                break;
 +            }
 +
 +            properties_set(instance_ptr->std_commands[i].props, OSGI_SHELL_COMMAND_NAME, instance_ptr->std_commands[i].name);
 +            properties_set(instance_ptr->std_commands[i].props, OSGI_SHELL_COMMAND_USAGE, instance_ptr->std_commands[i].usage);
 +            properties_set(instance_ptr->std_commands[i].props, OSGI_SHELL_COMMAND_DESCRIPTION, instance_ptr->std_commands[i].description);
 +
 +            instance_ptr->std_commands[i].service = calloc(1, sizeof(*instance_ptr->std_commands[i].service));
 +            if (!instance_ptr->std_commands[i].service) {
 +                status = CELIX_ENOMEM;
 +                break;
 +            }
 +
 +            instance_ptr->std_commands[i].service->handle = context_ptr;
 +            instance_ptr->std_commands[i].service->executeCommand = instance_ptr->std_commands[i].exec;
 +
 +            i += 1;
 +        }
 +    }
 +
 +    if (status == CELIX_SUCCESS) {
 +        *_pptr = instance_ptr;
 +    }
 +
 +
 +    if (status != CELIX_SUCCESS) {
 +        bundleActivator_destroy(instance_ptr, context_ptr);
 +    }
  
  	return status;
  }

http://git-wip-us.apache.org/repos/asf/celix/blob/c35a74c7/shell/private/src/help_command.c
----------------------------------------------------------------------
diff --cc shell/private/src/help_command.c
index 78b6b01,0a11ba9..b8408ad
--- a/shell/private/src/help_command.c
+++ b/shell/private/src/help_command.c
@@@ -25,92 -25,84 +25,87 @@@
   */
  #include <stdlib.h>
  #include <string.h>
++#include <stdint.h>
  
 -#include "command_impl.h"
  #include "array_list.h"
  #include "bundle_context.h"
 -#include "bundle.h"
  #include "shell.h"
 +#include "std_commands.h"
  
 -void helpCommand_execute(command_pt command, char * line, void (*out)(char *), void (*err)(char *));
 +celix_status_t helpCommand_execute(void *_ptr, char *line_str, FILE *out_ptr, FILE *err_ptr) {
 +	celix_status_t status = CELIX_SUCCESS;
  
 -command_pt helpCommand_create(bundle_context_pt context) {
 -	command_pt command = (command_pt) malloc(sizeof(*command));
 -	command->bundleContext = context;
 -	command->name = "help";
 -	command->shortDescription = "display available command usage and description.";
 -	command->usage = "start [<command> ...]";
 -	command->executeCommand = helpCommand_execute;
 -	return command;
 -}
 +	bundle_context_pt context_ptr = _ptr;
 +	service_reference_pt shell_service_reference_ptr = NULL;
 +	shell_service_pt shell_ptr = NULL;
  
 -void helpCommand_destroy(command_pt command) {
 -	free(command);
 -}
 +	if (!context_ptr || !line_str || !out_ptr || !err_ptr) {
 +		status = CELIX_ILLEGAL_ARGUMENT;
 +	}
 +
 +	if (status == CELIX_SUCCESS) {
 +		status = bundleContext_getServiceReference(context_ptr, (char *) OSGI_SHELL_SERVICE_NAME, &shell_service_reference_ptr);
 +	}
  
 +	if (status == CELIX_SUCCESS) {
 +		status = bundleContext_getService(context_ptr, shell_service_reference_ptr, (void **) &shell_ptr);
 +	}
  
 -void helpCommand_execute(command_pt command, char * line, void (*out)(char *), void (*err)(char *)) {
 -	service_reference_pt shellService = NULL;
 -	bundleContext_getServiceReference(command->bundleContext, (char *) OSGI_SHELL_SERVICE_NAME, &shellService);
 +	if (status == CELIX_SUCCESS) {
- 		uint32_t out_len = 256;
- 		char *sub = NULL;
- 		char *save_ptr = NULL;
- 		char out_str[out_len];
- 
- 		memset(out_str, 0, sizeof(out_str));
- 
- 		strtok_r(line_str, OSGI_SHELL_COMMAND_SEPARATOR, &save_ptr);
- 		sub = strtok_r(NULL, OSGI_SHELL_COMMAND_SEPARATOR, &save_ptr);
- 
- 		if (sub == NULL) {
- 			unsigned int i;
- 			array_list_pt commands = NULL;
- 
- 			status = shell_ptr->getCommands(shell_ptr->shell, &commands);
- 			for (i = 0; i < arrayList_size(commands); i++) {
- 				char *name = arrayList_get(commands, i);
- 				fprintf(out_ptr, "%s\n", name);
- 			}
- 			fprintf(out_ptr, "\nUse 'help <command-name>' for more information.\n");
- 		} else {
- 			bool found = false;
- 			while (sub != NULL) {
- 				unsigned int i;
- 				array_list_pt commands = NULL;
- 				status = shell_ptr->getCommands(shell_ptr->shell, &commands);
- 				for (i = 0; i < arrayList_size(commands); i++) {
- 					char *name = arrayList_get(commands, i);
- 					if (strcmp(sub, name) == 0) {
- 						celix_status_t sub_status_desc;
- 						celix_status_t sub_status_usage;
- 
- 						char *usage_str = NULL;
- 						char *desc_str = NULL;
- 
- 						sub_status_desc = shell_ptr->getCommandDescription(shell_ptr->shell, name, &desc_str);
- 						sub_status_usage = shell_ptr->getCommandUsage(shell_ptr->shell, name, &usage_str);
- 
- 						if (sub_status_usage == CELIX_SUCCESS && sub_status_desc == CELIX_SUCCESS) {
- 							if (found) {
- 								fprintf(out_ptr, "---\n");
- 							}
- 							found = true;
- 							fprintf(out_ptr, "Command     : %s\n", name);
- 							fprintf(out_ptr, "Usage       : %s\n", usage_str);
- 							fprintf(out_ptr, "Description : %s\n", desc_str);
- 						}
- 
- 						if (sub_status_desc != CELIX_SUCCESS && status == CELIX_SUCCESS) {
- 							status = sub_status_desc;
- 						}
- 						if (sub_status_usage != CELIX_SUCCESS && status == CELIX_SUCCESS) {
- 							status = sub_status_usage;
- 						}
- 					}
- 				}
- 				sub = strtok_r(NULL, OSGI_SHELL_COMMAND_SEPARATOR, &save_ptr);
- 			}
- 		}
- 	}
- 
- 	return status;
- }
++        uint32_t out_len = 256;
++        char *sub = NULL;
++        char *save_ptr = NULL;
++        char out_str[out_len];
+ 
 -	if (shellService != NULL) {
 -		shell_service_pt shell = NULL;
 -		bundleContext_getService(command->bundleContext, shellService, (void **) &shell);
++        memset(out_str, 0, sizeof(out_str));
+ 
 -		if (shell != NULL) {
 -			char delims[] = " ";
 -			char * sub = NULL;
 -			char *save_ptr = NULL;
 -			char outString[256];
++        strtok_r(line_str, OSGI_SHELL_COMMAND_SEPARATOR, &save_ptr);
++        sub = strtok_r(NULL, OSGI_SHELL_COMMAND_SEPARATOR, &save_ptr);
+ 
 -			sub = strtok_r(line, delims, &save_ptr);
 -			sub = strtok_r(NULL, delims, &save_ptr);
++        if (sub == NULL) {
++            unsigned int i;
++            array_list_pt commands = NULL;
+ 
 -			if (sub == NULL) {
 -				int i;
 -				array_list_pt commands = shell->getCommands(shell->shell);
 -				for (i = 0; i < arrayList_size(commands); i++) {
 -					char *name = arrayList_get(commands, i);
 -					sprintf(outString, "%s\n", name);
 -					out(outString);
 -				}
 -				out("\nUse 'help <command-name>' for more information.\n");
 -				arrayList_destroy(commands);
 -			} else {
 -				bool found = false;
 -				while (sub != NULL) {
 -					int i;
 -					array_list_pt commands = shell->getCommands(shell->shell);
 -					for (i = 0; i < arrayList_size(commands); i++) {
 -						char *name = arrayList_get(commands, i);
 -						if (strcmp(sub, name) == 0) {
 -							char *desc = shell->getCommandDescription(shell->shell, name);
 -							char *usage = shell->getCommandUsage(shell->shell, name);
++            status = shell_ptr->getCommands(shell_ptr->shell, &commands);
++            for (i = 0; i < arrayList_size(commands); i++) {
++                char *name = arrayList_get(commands, i);
++                fprintf(out_ptr, "%s\n", name);
++            }
++            fprintf(out_ptr, "\nUse 'help <command-name>' for more information.\n");
++        } else {
++            celix_status_t sub_status_desc;
++            celix_status_t sub_status_usage;
++            int i;
++            array_list_pt commands = NULL;
++            shell_ptr->getCommands(shell_ptr->shell, &commands);
++            for (i = 0; i < arrayList_size(commands); i++) {
++                char *name = arrayList_get(commands, i);
++                if (strcmp(sub, name) == 0) {
++                    char *usage_str = NULL;
++                    char *desc_str = NULL;
+ 
 -							if (found) {
 -								out("---\n");
 -							}
 -							found = true;
 -							sprintf(outString, "Command     : %s\n", name);
 -							out(outString);
 -							sprintf(outString, "Usage       : %s\n", usage);
 -							out(outString);
 -							sprintf(outString, "Description : %s\n", desc);
 -							out(outString);
 -						}
 -					}
 -					sub = strtok_r(NULL, delims, &save_ptr);
 -					arrayList_destroy(commands);
 -				}
 -			}
 -		}
 -	}
++                    sub_status_desc = shell_ptr->getCommandDescription(shell_ptr->shell, name, &desc_str);
++                    sub_status_usage = shell_ptr->getCommandUsage(shell_ptr->shell, name, &usage_str);
++
++                    if (sub_status_usage == CELIX_SUCCESS && sub_status_desc == CELIX_SUCCESS) {
++                        fprintf(out_ptr, "Command     : %s\n", name);
++                        fprintf(out_ptr, "Usage       : %s\n", usage_str == NULL ? "" : usage_str);
++                        fprintf(out_ptr, "Description : %s\n", desc_str == NULL ? "" : desc_str);
++                    } else {
++                        fprintf(err_ptr, "Error retreiving help info for command '%s'\n", sub);
++                    }
++
++                    if (sub_status_desc != CELIX_SUCCESS && status == CELIX_SUCCESS) {
++                        status = sub_status_desc;
++                    }
++                    if (sub_status_usage != CELIX_SUCCESS && status == CELIX_SUCCESS) {
++                        status = sub_status_usage;
++                    }
++                }
++            }
++            arrayList_destroy(commands);
++        }
++    }
++
++    return status;
+ }

http://git-wip-us.apache.org/repos/asf/celix/blob/c35a74c7/shell/private/src/inspect_command.c
----------------------------------------------------------------------
diff --cc shell/private/src/inspect_command.c
index 68b7625,944d929..24a343b
--- a/shell/private/src/inspect_command.c
+++ b/shell/private/src/inspect_command.c
@@@ -61,31 -79,39 +61,32 @@@ celix_status_t inspectCommand_execute(v
  
  			if (strcmp(type, SERVICE_TYPE) == 0) {
  				if (strcmp(direction, CAPABILITY) == 0) {
 -					status = inspectCommand_printExportedServices(command, ids, out, err);
 +					status = inspectCommand_printExportedServices(context, ids, outStream, errStream);
  					if (status != CELIX_SUCCESS) {
 -						out("INSPECT: Error\n");
 +						fprintf(errStream, "INSPECT: Error\n");
  					}
  				} else if (strcmp(direction, REQUIREMENT) == 0) {
 -                    status = inspectCommand_printImportedServices(command, ids, out, err);
 +                    status = inspectCommand_printImportedServices(context, ids, outStream, errStream);
                      if (status != CELIX_SUCCESS) {
 -                        out("INSPECT: Error\n");
 +						fprintf(errStream, "INSPECT: Error\n");
                      }
  				} else {
 -				    out("INSPECT: Invalid argument\n");
 -                    sprintf(outString, "%s\n", command->usage);
 -                    out(outString);
 +					fprintf(errStream, "INSPECT: Invalid argument\n");
  				}
  			} else {
 -				out("INSPECT: Invalid argument\n");
 -				sprintf(outString, "%s\n", command->usage);
 -                out(outString);
 +				fprintf(errStream, "INSPECT: Invalid argument\n");
  			}
+ 			arrayList_destroy(ids);
  		} else {
 -			out("INSPECT: Too few arguments\n");
 -			sprintf(outString, "%s\n", command->usage);
 -			out(outString);
 +			fprintf(errStream, "INSPECT: Too few arguments\n");
  		}
  	} else {
 -		out("INSPECT: Too few arguments\n");
 -		sprintf(outString, "%s\n", command->usage);
 -		out(outString);
 +		fprintf(errStream, "INSPECT: Too few arguments\n");
  	}
 +	return status;
  }
  
 -celix_status_t inspectCommand_printExportedServices(command_pt command, array_list_pt ids, void (*out)(char *), void (*err)(char *)) {
 +celix_status_t inspectCommand_printExportedServices(bundle_context_pt context, array_list_pt ids, FILE *outStream, FILE *errStream) {
  	celix_status_t status = CELIX_SUCCESS;
  	array_list_pt bundles = NULL;
  
@@@ -238,8 -278,10 +242,9 @@@ celix_status_t inspectCommand_printImpo
                                          char *value = NULL;
                                          serviceReference_getProperty(ref, key, &value);
  
 -                                        sprintf(line, "%s = %s\n", key, value);
 -                                        out(line);
 +										fprintf(outStream, "%s = %s\n", key, value);
                                      }
+                                     free(keys);
  
  //                                  objectClass = properties_get(props, (char *) OSGI_FRAMEWORK_OBJECTCLASS);
  //                                  sprintf(line, "ObjectClass = %s\n", objectClass);

http://git-wip-us.apache.org/repos/asf/celix/blob/c35a74c7/shell/private/src/shell.c
----------------------------------------------------------------------
diff --cc shell/private/src/shell.c
index 03c30da,18ee201..8a37e88
--- a/shell/private/src/shell.c
+++ b/shell/private/src/shell.c
@@@ -179,153 -113,65 +179,151 @@@ celix_status_t shell_removeCommand(shel
  	return status;
  }
  
 -array_list_pt shell_getCommands(shell_pt shell) {
 -	array_list_pt commands = NULL;
 -	hash_map_iterator_pt iter = hashMapIterator_create(shell->commandNameMap);
 +celix_status_t shell_getCommands(shell_pt shell_ptr, array_list_pt *commands_ptr) {
 +	celix_status_t status = CELIX_SUCCESS;
 +
 +	hash_map_iterator_pt iter = NULL;
  
 -	arrayList_create(&commands);
 -	while (hashMapIterator_hasNext(iter)) {
 -		char * name = hashMapIterator_nextKey(iter);
 -		arrayList_add(commands, name);
 +	if (!shell_ptr || !commands_ptr) {
 +		status = CELIX_ILLEGAL_ARGUMENT;
 +	}
 +
 +	if (status == CELIX_SUCCESS) {
 +		iter = hashMapIterator_create(shell_ptr->command_name_map_ptr);
 +		if (!iter) {
 +			status = CELIX_BUNDLE_EXCEPTION;
 +		}
  	}
 -	hashMapIterator_destroy(iter);
 -	return commands;
 -}
  
 -char * shell_getCommandUsage(shell_pt shell, char * commandName) {
 -	command_service_pt command = hashMap_get(shell->commandNameMap, commandName);
 -	return (command == NULL) ? NULL : command->getUsage(command->command);
 +	if (status == CELIX_SUCCESS) {
 +		arrayList_create(commands_ptr);
 +		while (hashMapIterator_hasNext(iter)) {
 +			char *name_str = hashMapIterator_nextKey(iter);
 +			arrayList_add(*commands_ptr, name_str);
 +		}
 +		hashMapIterator_destroy(iter);
 +	}
 +
 +	return status;
  }
  
 -char * shell_getCommandDescription(shell_pt shell, char * commandName) {
 -	command_service_pt command = hashMap_get(shell->commandNameMap, commandName);
 -	return (command == NULL) ? NULL : command->getShortDescription(command->command);
 +
 +celix_status_t shell_getCommandUsage(shell_pt shell_ptr, char *command_name_str, char **usage_pstr) {
 +	celix_status_t status = CELIX_SUCCESS;
 +
 +	service_reference_pt reference = NULL;
 +
 +	if (!shell_ptr || !command_name_str || !usage_pstr) {
 +		status = CELIX_ILLEGAL_ARGUMENT;
 +	}
 +
 +	if (status == CELIX_SUCCESS) {
 +		status = shell_getCommandReference(shell_ptr, command_name_str, &reference);
 +		if (!reference) {
 +			status = CELIX_BUNDLE_EXCEPTION;
 +		}
 +	}
 +
 +	if (status == CELIX_SUCCESS) {
 +		status = serviceReference_getProperty(reference, "command.usage", usage_pstr);
 +	}
 +
 +	return status;
  }
  
 -service_reference_pt shell_getCommandReference(shell_pt shell, char * command) {
 -	hash_map_iterator_pt iter = hashMapIterator_create(shell->commandReferenceMap);
 -	while (hashMapIterator_hasNext(iter)) {
 -		hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
 -		command_service_pt cmd = (command_service_pt) hashMapEntry_getValue(entry);
 -		if (strcmp(cmd->getName(cmd->command), command) == 0) {
 -			return (service_reference_pt) hashMapEntry_getValue(entry);
 +celix_status_t shell_getCommandDescription(shell_pt shell_ptr, char *command_name_str, char **command_description_pstr) {
 +	celix_status_t status = CELIX_SUCCESS;
 +
 +	service_reference_pt reference = NULL;
 +
 +	if (!shell_ptr || !command_name_str || !command_description_pstr) {
 +		status = CELIX_ILLEGAL_ARGUMENT;
 +	}
 +
 +	if (status == CELIX_SUCCESS) {
 +		status = shell_getCommandReference(shell_ptr, command_name_str, &reference);
 +		if (!reference) {
 +			status = CELIX_BUNDLE_EXCEPTION;
  		}
  	}
 -	hashMapIterator_destroy(iter);
 -	return NULL;
 +
 +	if (status == CELIX_SUCCESS) {
 +		serviceReference_getProperty(reference, "command.description", command_description_pstr);
 +	}
 +
 +	return status;
  }
  
 -void shell_executeCommand(shell_pt shell, char * commandLine, void (*out)(char *), void (*error)(char *)) {
 -	unsigned int pos = strcspn(commandLine, " ");
 -	char * commandName = (pos != strlen(commandLine)) ? string_ndup((char *) commandLine, pos) : strdup(commandLine);
 -	command_service_pt command = shell_getCommand(shell, commandName);
 -	if (command != NULL) {
 -		command->executeCommand(command->command, commandLine, out, error);
 -	} else {
 -		error("No such command\n");
 +celix_status_t shell_getCommandReference(shell_pt shell_ptr, char *command_name_str, service_reference_pt *command_reference_ptr) {
 +	celix_status_t status = CELIX_SUCCESS;
 +
 +	if (!shell_ptr || !command_name_str || !command_reference_ptr) {
 +		status = CELIX_ILLEGAL_ARGUMENT;
 +	}
 +
 +	if (status == CELIX_SUCCESS) {
 +		*command_reference_ptr = NULL;
 +		hash_map_iterator_pt iter = hashMapIterator_create(shell_ptr->command_reference_map_ptr);
 +		while (hashMapIterator_hasNext(iter)) {
 +			hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
 +			service_reference_pt reference = hashMapEntry_getKey(entry);
 +			char *name_str = NULL;
 +			serviceReference_getProperty(reference, "command.name", &name_str);
 +			if (strcmp(name_str, command_name_str) == 0) {
 +				*command_reference_ptr = (service_reference_pt) hashMapEntry_getKey(entry);
 +				break;
 +			}
 +		}
 +		hashMapIterator_destroy(iter);
  	}
 -	free(commandName);
 +
 +	return status;
  }
  
- celix_status_t shell_executeCommand(shell_pt shell_ptr, char *command_line_str, void (*out)(char *), void (*error)(char *)) {
 -static command_service_pt shell_getCommand(shell_pt shell, char * commandName) {
 -	command_service_pt command = hashMap_get(shell->commandNameMap, commandName);
 -	return (command == NULL) ? NULL : command;
++celix_status_t shell_executeCommand(shell_pt shell_ptr, char *command_line_str, FILE *out, FILE *err) {
 +	celix_status_t status = CELIX_SUCCESS;
 +
 +	command_service_pt command_ptr = NULL;
 +
- 	if (!shell_ptr || !command_line_str || !out || !error) {
++	if (!shell_ptr || !command_line_str || !out || !err) {
 +		status = CELIX_ILLEGAL_ARGUMENT;
 +	}
 +
 +	if (status == CELIX_SUCCESS) {
 +		size_t pos = strcspn(command_line_str, " ");
 +
 +		char *command_name_str = (pos != strlen(command_line_str)) ? strndup(command_line_str, pos) : strdup(command_line_str);
 +		command_ptr = hashMap_get(shell_ptr->command_name_map_ptr, command_name_str);
 +		free(command_name_str);
 +		if (!command_ptr) {
- 			error("No such command");
++			fprintf(err, "No such command\n");
 +			status = CELIX_BUNDLE_EXCEPTION;
 +		}
 +	}
 +
 +	if (status == CELIX_SUCCESS) {
- 		printf("TODO\n");
- 		//FIXME udpate shell_executeCommand with FILE
- 		status = command_ptr->executeCommand(command_ptr->handle, command_line_str, stdout, stderr);
++		status = command_ptr->executeCommand(command_ptr->handle, command_line_str, out, err);
 +	}
 +
 +	return status;
  }
  
 -void shell_serviceChanged(service_listener_pt listener, service_event_pt event) {
 -	shell_pt shell = (shell_pt) listener->handle;
 -	if (event->type == OSGI_FRAMEWORK_SERVICE_EVENT_REGISTERED) {
 -		shell_addCommand(shell, event->reference);
 -	} else if (event->type == OSGI_FRAMEWORK_SERVICE_EVENT_UNREGISTERING) {
 -		shell_removeCommand(shell, event->reference);
 +celix_status_t shell_serviceChanged(service_listener_pt listener_ptr, service_event_pt event_ptr) {
 +	celix_status_t status = CELIX_SUCCESS;
 +
 +	if (!listener_ptr || !event_ptr || !listener_ptr->handle || !event_ptr->type || !event_ptr->reference) {
 +		status = CELIX_ILLEGAL_ARGUMENT;
  	}
 +
 +	if (status == CELIX_SUCCESS) {
 +		shell_pt shell_ptr = (shell_pt) listener_ptr->handle;
 +		if (event_ptr->type == OSGI_FRAMEWORK_SERVICE_EVENT_REGISTERED) {
 +			status = shell_addCommand(shell_ptr, event_ptr->reference);
 +		} else if (event_ptr->type == OSGI_FRAMEWORK_SERVICE_EVENT_UNREGISTERING) {
 +			status = shell_removeCommand(shell_ptr, event_ptr->reference);
 +		}
 +	}
 +
 +	return status;
  }
  

http://git-wip-us.apache.org/repos/asf/celix/blob/c35a74c7/shell/private/src/update_command.c
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/celix/blob/c35a74c7/shell/public/include/shell.h
----------------------------------------------------------------------
diff --cc shell/public/include/shell.h
index c6f1792,25706c7..f7c5edd
--- a/shell/public/include/shell.h
+++ b/shell/public/include/shell.h
@@@ -36,12 -36,11 +36,12 @@@ typedef struct shell * shell_pt
  
  struct shellService {
  	shell_pt shell;
 -	array_list_pt (*getCommands)(shell_pt shell);
 -	char * (*getCommandUsage)(shell_pt shell, char * commandName);
 -	char * (*getCommandDescription)(shell_pt shell, char * commandName);
 -	service_reference_pt (*getCommandReference)(shell_pt shell, char * command);
 -	void (*executeCommand)(shell_pt shell, char * commandLine, void (*out)(char *), void (*error)(char *));
 +
 +	celix_status_t (*getCommands)(shell_pt shell_ptr, array_list_pt *commands_ptr);
 +	celix_status_t (*getCommandUsage)(shell_pt shell_ptr, char *command_name_str, char **usage_str);
 +	celix_status_t (*getCommandDescription)(shell_pt shell_ptr, char *command_name_str, char **command_description_str);
 +	celix_status_t (*getCommandReference)(shell_pt shell_ptr, char *command_name_str, service_reference_pt *command_reference_ptr);
- 	celix_status_t (*executeCommand)(shell_pt shell_ptr, char * command_line_str, void (*out)(char *), void (*error)(char *));
++	celix_status_t (*executeCommand)(shell_pt shell_ptr, char * command_line_str, FILE *out, FILE *err);
  };
  
  typedef struct shellService * shell_service_pt;

http://git-wip-us.apache.org/repos/asf/celix/blob/c35a74c7/shell_tui/private/src/shell_tui.c
----------------------------------------------------------------------
diff --cc shell_tui/private/src/shell_tui.c
index 9dae4f0,9dae4f0..c106ece
--- a/shell_tui/private/src/shell_tui.c
+++ b/shell_tui/private/src/shell_tui.c
@@@ -45,9 -45,9 +45,6 @@@ struct shellTuiActivator 
  
  typedef struct shellTuiActivator * shell_tui_activator_pt;
  
--void shellTui_write(char * line) {
--	fprintf(stdout, "%s", line);
--}
  
  static void* shellTui_runnable(void *data) {
  	shell_tui_activator_pt act = (shell_tui_activator_pt) data;
@@@ -83,7 -83,7 +80,7 @@@
  				continue;
  			}
  
--			act->shell->executeCommand(act->shell->shell, line, shellTui_write, shellTui_write);
++			act->shell->executeCommand(act->shell->shell, line, stdout, stderr);
  		}
  	}