diff options
-rw-r--r-- | emulator/qemud/qemud.c | 6 | ||||
-rw-r--r-- | emulator/tools/Android.mk | 36 | ||||
-rw-r--r-- | emulator/tools/qemu-props.c | 114 |
3 files changed, 154 insertions, 2 deletions
diff --git a/emulator/qemud/qemud.c b/emulator/qemud/qemud.c index c578145..5edf8a6 100644 --- a/emulator/qemud/qemud.c +++ b/emulator/qemud/qemud.c @@ -857,8 +857,10 @@ fdhandler_shutdown( FDHandler* f ) fdhandler_remove(f); fdhandler_prepend(f, &f->list->closing); - /* notify the receiver that we're closing */ - receiver_close(f->receiver); + /* prevent later fdhandler_close() to + * call the receiver's close. + */ + f->receiver->close = NULL; return; } diff --git a/emulator/tools/Android.mk b/emulator/tools/Android.mk new file mode 100644 index 0000000..c9d9613 --- /dev/null +++ b/emulator/tools/Android.mk @@ -0,0 +1,36 @@ +# Copyright (C) 2009 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# this file is used to build emulator-specific program tools +# that should only run in the emulator. +# + +LOCAL_PATH := $(call my-dir) + +ifneq ($(TARGET_PRODUCT),sim) + +# The 'qemu-props' program is run from /system/etc/init.goldfish.rc +# to setup various system properties sent by the emulator program. +# +include $(CLEAR_VARS) +LOCAL_MODULE := qemu-props +LOCAL_SRC_FILES := qemu-props.c +LOCAL_SHARED_LIBRARIES := libcutils +# we don't want this in 'user' builds which don't have +# emulator-specific binaries. +LOCAL_MODULE_TAGS := debug +include $(BUILD_EXECUTABLE) + +endif # TARGET_PRODUCT != sim + diff --git a/emulator/tools/qemu-props.c b/emulator/tools/qemu-props.c new file mode 100644 index 0000000..09105fc --- /dev/null +++ b/emulator/tools/qemu-props.c @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* this program is used to read a set of system properties and their values + * from the emulator program and set them in the currently-running emulated + * system. It does so by connecting to the 'boot-properties' qemud service. + * + * This program should be run as root and called from + * /system/etc/init.goldfish.rc exclusively. + */ + +#define LOG_TAG "qemu-props" + +#define DEBUG 1 + +#if DEBUG +# include <cutils/log.h> +# define DD(...) LOGI(__VA_ARGS__) +#else +# define DD(...) ((void)0) +#endif + +#include <cutils/properties.h> +#include <unistd.h> +#include <hardware/qemud.h> + +/* Name of the qemud service we want to connect to. + */ +#define QEMUD_SERVICE "boot-properties" + +#define MAX_TRIES 5 + +int main(void) +{ + int qemud_fd, count = 0; + + /* try to connect to the qemud service */ + { + int tries = MAX_TRIES; + + while (1) { + qemud_fd = qemud_channel_open( "boot-properties" ); + if (qemud_fd >= 0) + break; + + if (--tries <= 0) { + DD("Could not connect after too many tries. Aborting"); + return 1; + } + + DD("waiting 1s to wait for qemud."); + sleep(1); + } + } + + DD("connected to '%s' qemud service.", QEMUD_SERVICE); + + /* send the 'list' command to the service */ + if (qemud_channel_send(qemud_fd, "list", -1) < 0) { + DD("could not send command to '%s' service", QEMUD_SERVICE); + return 1; + } + + /* read each system property as a single line from the service, + * until exhaustion. + */ + for (;;) + { +#define BUFF_SIZE (PROPERTY_KEY_MAX + PROPERTY_VALUE_MAX + 2) + + char* q; + char temp[BUFF_SIZE]; + int len = qemud_channel_recv(qemud_fd, temp, sizeof temp - 1); + + if (len < 0 || len > BUFF_SIZE-1) + break; + + temp[len] = '\0'; /* zero-terminate string */ + + DD("received: %.*s", len, temp); + + /* separate propery name from value */ + q = strchr(temp, '='); + if (q == NULL) { + DD("invalid format, ignored."); + continue; + } + *q++ = '\0'; + + if (property_set(temp, q) < 0) { + DD("could not set property '%s' to '%s'", temp, q); + } else { + count += 1; + } + } + + /* finally, close the channel and exit */ + close(qemud_fd); + DD("exiting (%d properties set).", count); + return 0; +} |