Make core initialization replying to the UI at the end of initialization.

Also, this CL contains a minor fix to formatting boot options passed to the kernel

Change-Id: I267172d82094a0cbbbced2cee7a2990bb7fa3793
diff --git a/vl-android.c b/vl-android.c
index 13f4dac..a946a35 100644
--- a/vl-android.c
+++ b/vl-android.c
@@ -189,6 +189,7 @@
 #include "balloon.h"
 #include "android/hw-lcd.h"
 #include "android/boot-properties.h"
+#include "android/core-init-utils.h"
 
 #ifdef CONFIG_STANDALONE_CORE
 /* Verbose value used by the standalone emulator core (without UI) */
@@ -378,6 +379,16 @@
 /* -lcd-density option value. */
 char* android_op_lcd_density = NULL;
 
+/* -ui-port option value. This port will be used to report the core
+ * initialization completion.
+ */
+char* android_op_ui_port = NULL;
+
+/* -ui-settings option value. This value will be passed to the UI when new UI
+ * process is attaching to the core.
+ */
+char* android_op_ui_settings = NULL;
+
 extern int android_display_width;
 extern int android_display_height;
 extern int android_display_bpp;
@@ -386,6 +397,26 @@
 
 #define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR)
 
+/* Reports the core initialization failure to the error stdout and to the UI
+ * socket before exiting the application.
+ * Parameters that are passed to this macro are used to format the error
+ * mesage using sprintf routine.
+ */
+#ifdef CONFIG_ANDROID
+#define  PANIC(...) android_core_init_failure(__VA_ARGS__)
+#else
+#define  PANIC(...) do { fprintf(stderr, __VA_ARGS__);  \
+                         exit(1);                       \
+                    } while (0)
+#endif  // CONFIG_ANDROID
+
+/* Exits the core during initialization. */
+#ifdef CONFIG_ANDROID
+#define  QEMU_EXIT(exit_code) android_core_init_exit(exit_code)
+#else
+#define  QEMU_EXIT(exit_code) exit(exit_code)
+#endif  // CONFIG_ANDROID
+
 /***********************************************************/
 /* x86 ISA bus support */
 
@@ -3279,7 +3310,7 @@
 #endif
            DEFAULT_GDBSTUB_PORT,
            "/tmp/qemu.log");
-    exit(exitcode);
+    QEMU_EXIT(exitcode);
 }
 
 #define HAS_ARG 0x0001
@@ -3406,7 +3437,11 @@
             printf ("%-11s %s\n", c->name, c->descr);
         }
         printf ("\n-soundhw all will enable all of the above\n");
-        exit (*optarg != '?');
+        if (*optarg != '?') {
+            PANIC("Unknown sound card name: %s", optarg);
+        } else {
+            QEMU_EXIT(0);
+        }
     }
     else {
         size_t l;
@@ -3434,15 +3469,16 @@
             }
 
             if (!c->name) {
+#ifndef CONFIG_ANDROID
                 if (l > 80) {
                     fprintf (stderr,
                              "Unknown sound card name (too big to show)\n");
-                }
-                else {
+                } else {
                     fprintf (stderr, "Unknown sound card name `%.*s'\n",
                              (int) l, p);
                 }
-                bad_card = 1;
+#endif  // !CONFIG_ANDROID
+	            bad_card = 1;
             }
             p += l + (e != NULL);
         }
@@ -3471,8 +3507,7 @@
         xenfb_enabled = 1;
     } else if (!strstart(p, "none", &opts)) {
     invalid_vga:
-        fprintf(stderr, "Unknown vga type: %s\n", p);
-        exit(1);
+        PANIC("Unknown vga type: %s", p);
     }
     while (*opts) {
         const char *nextopt;
@@ -3773,6 +3808,12 @@
     char tmp_str[1024];
     int    dns_count = 0;
 
+    /* Initialize sockets before anything else, so we can properly report
+     * initialization failures back to the UI. */
+#ifdef _WIN32
+    socket_init();
+#endif
+
     init_clocks();
 
     qemu_cache_utils_init(envp);
@@ -3877,9 +3918,8 @@
             popt = qemu_options;
             for(;;) {
                 if (!popt->name) {
-                    fprintf(stderr, "%s: invalid option -- '%s'\n",
-                            argv[0], r);
-                    exit(1);
+                    PANIC("%s: invalid option -- '%s'",
+                                      argv[0], r);
                 }
                 if (!strcmp(popt->name, r + 1))
                     break;
@@ -3887,9 +3927,8 @@
             }
             if (popt->flags & HAS_ARG) {
                 if (optind >= argc) {
-                    fprintf(stderr, "%s: option '%s' requires an argument\n",
-                            argv[0], r);
-                    exit(1);
+                    PANIC("%s: option '%s' requires an argument",
+                                      argv[0], r);
                 }
                 optarg = argv[optind++];
             } else {
@@ -3907,7 +3946,12 @@
                                m->name, m->desc,
                                m->is_default ? " (default)" : "");
                     }
-                    exit(*optarg != '?');
+                    if (*optarg != '?') {
+                        PANIC("Invalid machine parameter: %s",
+                                          optarg);
+                    } else {
+                        QEMU_EXIT(0);
+                    }
                 }
                 break;
             case QEMU_OPTION_cpu:
@@ -3917,7 +3961,7 @@
 #if defined(cpu_list)
                     cpu_list(stdout, &fprintf);
 #endif
-                    exit(0);
+                    QEMU_EXIT(0);
                 } else {
                     cpu_model = optarg;
                 }
@@ -3988,8 +4032,7 @@
                             goto chs_fail;
                     } else if (*p != '\0') {
                     chs_fail:
-                        fprintf(stderr, "qemu: invalid physical CHS format\n");
-                        exit(1);
+                        PANIC("qemu: invalid physical CHS format");
                     }
 		    if (hda_index != -1)
                         snprintf(drives_opt[hda_index].opt,
@@ -4004,8 +4047,7 @@
                 break;
             case QEMU_OPTION_numa:
                 if (nb_numa_nodes >= MAX_NODES) {
-                    fprintf(stderr, "qemu: too many NUMA nodes\n");
-                    exit(1);
+                    PANIC("qemu: too many NUMA nodes");
                 }
                 numa_add(optarg);
                 break;
@@ -4048,13 +4090,11 @@
                          * implementation and firmware features.
                          */
                         if (*p < 'a' || *p > 'q') {
-                            fprintf(stderr, "Invalid boot device '%c'\n", *p);
-                            exit(1);
+                            PANIC("Invalid boot device '%c'", *p);
                         }
                         if (boot_devices_bitmap & (1 << (*p - 'a'))) {
-                            fprintf(stderr,
-                                    "Boot device '%c' was given twice\n",*p);
-                            exit(1);
+                            PANIC(
+                                    "Boot device '%c' was given twice",*p);
                         }
                         boot_devices_bitmap |= 1 << (*p - 'a');
                     }
@@ -4071,8 +4111,7 @@
 #endif
             case QEMU_OPTION_net:
                 if (nb_net_clients >= MAX_NET_CLIENTS) {
-                    fprintf(stderr, "qemu: too many network clients\n");
-                    exit(1);
+                    PANIC("qemu: too many network clients");
                 }
                 net_clients[nb_net_clients] = optarg;
                 nb_net_clients++;
@@ -4097,15 +4136,14 @@
 #endif
             case QEMU_OPTION_bt:
                 if (nb_bt_opts >= MAX_BT_CMDLINE) {
-                    fprintf(stderr, "qemu: too many bluetooth options\n");
-                    exit(1);
+                    PANIC("qemu: too many bluetooth options");
                 }
                 bt_opts[nb_bt_opts++] = optarg;
                 break;
 #ifdef HAS_AUDIO
             case QEMU_OPTION_audio_help:
                 AUD_help ();
-                exit (0);
+                QEMU_EXIT(0);
                 break;
             case QEMU_OPTION_soundhw:
                 select_soundhw (optarg);
@@ -4116,7 +4154,7 @@
                 break;
             case QEMU_OPTION_version:
                 version();
-                exit(0);
+                QEMU_EXIT(0);
                 break;
             case QEMU_OPTION_m: {
                 uint64_t value;
@@ -4131,8 +4169,7 @@
                     value <<= 30;
                     break;
                 default:
-                    fprintf(stderr, "qemu: invalid ram size: %s\n", optarg);
-                    exit(1);
+                    PANIC("qemu: invalid ram size: %s", optarg);
                 }
 
                 /* On 32-bit hosts, QEMU is limited by virtual address space */
@@ -4141,12 +4178,10 @@
                     && HOST_LONG_BITS == 32
 #endif
                     ) {
-                    fprintf(stderr, "qemu: at most 2047 MB RAM can be simulated\n");
-                    exit(1);
+                    PANIC("qemu: at most 2047 MB RAM can be simulated");
                 }
                 if (value != (uint64_t)(ram_addr_t)value) {
-                    fprintf(stderr, "qemu: ram size too large\n");
-                    exit(1);
+                    PANIC("qemu: ram size too large");
                 }
                 ram_size = value;
                 break;
@@ -4159,10 +4194,10 @@
                     mask = cpu_str_to_log_mask(optarg);
                     if (!mask) {
                         printf("Log items (comma separated):\n");
-                    for(item = cpu_log_items; item->mask != 0; item++) {
-                        printf("%-10s %s\n", item->name, item->help);
-                    }
-                    exit(1);
+                        for(item = cpu_log_items; item->mask != 0; item++) {
+                            printf("%-10s %s\n", item->name, item->help);
+                        }
+                        PANIC("Invalid parameter -d=%s", optarg);
                     }
                     cpu_set_log(mask);
                 }
@@ -4184,8 +4219,7 @@
                 break;
             case QEMU_OPTION_S:
 #if 0  /* ANDROID */
-                fprintf(stderr, "Sorry, stopped launch is not supported in the Android emulator\n" );
-                exit(1);
+                PANIC("Sorry, stopped launch is not supported in the Android emulator" );
 #endif
                 autostart = 0;
                 break;
@@ -4209,8 +4243,7 @@
                     w = strtol(p, (char **)&p, 10);
                     if (w <= 0) {
                     graphic_error:
-                        fprintf(stderr, "qemu: invalid resolution or depth\n");
-                        exit(1);
+                        PANIC("qemu: invalid resolution or depth");
                     }
                     if (*p != 'x')
                         goto graphic_error;
@@ -4249,35 +4282,37 @@
                 break;
             case QEMU_OPTION_serial:
                 if (serial_device_index >= MAX_SERIAL_PORTS) {
-                    fprintf(stderr, "qemu: too many serial ports\n");
-                    exit(1);
+                    PANIC("qemu: too many serial ports");
                 }
                 serial_devices[serial_device_index] = optarg;
                 serial_device_index++;
                 break;
             case QEMU_OPTION_watchdog:
                 i = select_watchdog(optarg);
-                if (i > 0)
-                    exit (i == 1 ? 1 : 0);
+                if (i > 0) {
+                    if (i == 1) {
+                        PANIC("Invalid watchdog parameter: %s",
+                                          optarg);
+                    } else {
+                        QEMU_EXIT(0);
+                    }
+                }
                 break;
             case QEMU_OPTION_watchdog_action:
                 if (select_watchdog_action(optarg) == -1) {
-                    fprintf(stderr, "Unknown -watchdog-action parameter\n");
-                    exit(1);
+                    PANIC("Unknown -watchdog-action parameter");
                 }
                 break;
             case QEMU_OPTION_virtiocon:
                 if (virtio_console_index >= MAX_VIRTIO_CONSOLES) {
-                    fprintf(stderr, "qemu: too many virtio consoles\n");
-                    exit(1);
+                    PANIC("qemu: too many virtio consoles");
                 }
                 virtio_consoles[virtio_console_index] = optarg;
                 virtio_console_index++;
                 break;
             case QEMU_OPTION_parallel:
                 if (parallel_device_index >= MAX_PARALLEL_PORTS) {
-                    fprintf(stderr, "qemu: too many parallel ports\n");
-                    exit(1);
+                    PANIC("qemu: too many parallel ports");
                 }
                 parallel_devices[parallel_device_index] = optarg;
                 parallel_device_index++;
@@ -4314,14 +4349,12 @@
                 break;
             case QEMU_OPTION_acpitable:
                 if(acpi_table_add(optarg) < 0) {
-                    fprintf(stderr, "Wrong acpi table provided\n");
-                    exit(1);
+                    PANIC("Wrong acpi table provided");
                 }
                 break;
             case QEMU_OPTION_smbios:
                 if(smbios_entry_add(optarg) < 0) {
-                    fprintf(stderr, "Wrong smbios provided\n");
-                    exit(1);
+                    PANIC("Wrong smbios provided");
                 }
                 break;
 #endif
@@ -4347,8 +4380,7 @@
             case QEMU_OPTION_usbdevice:
                 usb_enabled = 1;
                 if (usb_devices_index >= MAX_USB_CMDLINE) {
-                    fprintf(stderr, "Too many USB devices\n");
-                    exit(1);
+                    PANIC("Too many USB devices");
                 }
                 usb_devices[usb_devices_index] = optarg;
                 usb_devices_index++;
@@ -4356,8 +4388,7 @@
             case QEMU_OPTION_smp:
                 smp_cpus = atoi(optarg);
                 if (smp_cpus < 1) {
-                    fprintf(stderr, "Invalid number of CPUs\n");
-                    exit(1);
+                    PANIC("Invalid number of CPUs");
                 }
                 break;
 	    case QEMU_OPTION_vnc:
@@ -4386,9 +4417,7 @@
                 break;
             case QEMU_OPTION_uuid:
                 if(qemu_uuid_parse(optarg, qemu_uuid) < 0) {
-                    fprintf(stderr, "Fail to parse UUID string."
-                            " Wrong format.\n");
-                    exit(1);
+                    PANIC("Fail to parse UUID string. Wrong format.");
                 }
                 break;
 #ifndef _WIN32
@@ -4398,8 +4427,7 @@
 #endif
 	    case QEMU_OPTION_option_rom:
 		if (nb_option_roms >= MAX_OPTION_ROMS) {
-		    fprintf(stderr, "Too many option ROMs\n");
-		    exit(1);
+		    PANIC("Too many option ROMs");
 		}
 		option_rom[nb_option_roms] = optarg;
 		nb_option_roms++;
@@ -4415,8 +4443,7 @@
 #if defined(TARGET_SPARC) || defined(TARGET_PPC)
             case QEMU_OPTION_prom_env:
                 if (nb_prom_envs >= MAX_PROM_ENVS) {
-                    fprintf(stderr, "Too many prom variables\n");
-                    exit(1);
+                    PANIC("Too many prom variables");
                 }
                 prom_envs[nb_prom_envs] = optarg;
                 nb_prom_envs++;
@@ -4460,9 +4487,8 @@
                         rtc_start_date = mktimegm(&tm);
                         if (rtc_start_date == -1) {
                         date_fail:
-                            fprintf(stderr, "Invalid date format. Valid format are:\n"
-                                    "'now' or '2006-06-17T16:01:21' or '2006-06-17'\n");
-                            exit(1);
+                            PANIC("Invalid date format. Valid format are:\n"
+                                    "'now' or '2006-06-17T16:01:21' or '2006-06-17'");
                         }
                         rtc_date_offset = time(NULL) - rtc_start_date;
                     }
@@ -4522,9 +4548,8 @@
                 else if (strcmp(optarg, "on") == 0 && trace_filename)
                     tracing = 1;
                 else {
-                    fprintf(stderr, "Unexpected option to -tracing ('%s')\n",
+                    PANIC("Unexpected option to -tracing ('%s')",
                             optarg);
-                    exit(1);
                 }
                 break;
 #if 0
@@ -4631,6 +4656,14 @@
                 android_op_lcd_density = (char*)optarg;
                 break;
 
+            case QEMU_OPTION_ui_port:
+                android_op_ui_port = (char*)optarg;
+                break;
+
+            case QEMU_OPTION_ui_settings:
+                android_op_ui_settings = (char*)optarg;
+                break;
+
 #ifdef CONFIG_MEMCHECK
             case QEMU_OPTION_android_memcheck:
                 android_op_memcheck = (char*)optarg;
@@ -4649,14 +4682,13 @@
     /* Initialize character map. */
     if (android_charmap_setup(op_charmap_file)) {
         if (op_charmap_file) {
-            fprintf(stderr,
-                    "Unable to initialize character map from file %s.\n",
+            PANIC(
+                    "Unable to initialize character map from file %s.",
                     op_charmap_file);
         } else {
-            fprintf(stderr,
-                    "Unable to initialize default character map.\n");
+            PANIC(
+                    "Unable to initialize default character map.");
         }
-        exit(1);
     }
 
     /* If no data_dir is specified then try to find it relative to the
@@ -4674,8 +4706,7 @@
     if (android_op_hwini) {
       hw_ini = iniFile_newFromFile(android_op_hwini);
       if (hw_ini == NULL) {
-        fprintf(stderr, "Could not find %s file.\n", android_op_hwini);
-        exit(1);
+        PANIC("Could not find %s file.", android_op_hwini);
       }
     } else {
       hw_ini = iniFile_newFromMemory("", 0);
@@ -4701,15 +4732,13 @@
 
     /* Initialize net speed and delays stuff. */
     if (android_parse_network_speed(android_op_netspeed) < 0 ) {
-        fprintf(stderr, "invalid -netspeed parameter '%s'\n",
+        PANIC("invalid -netspeed parameter '%s'",
                 android_op_netspeed);
-        exit(1);
     }
 
     if ( android_parse_network_latency(android_op_netdelay) < 0 ) {
-        fprintf(stderr, "invalid -netdelay parameter '%s'\n",
+        PANIC("invalid -netdelay parameter '%s'",
                 android_op_netdelay);
-        exit(1);
     }
 
     if (android_op_netfast) {
@@ -4724,8 +4753,7 @@
         char*   end;
         long density = strtol(android_op_lcd_density, &end, 0);
         if (end == NULL || *end || density < 0) {
-            fprintf(stderr, "option -lcd-density must be a positive integer\n" );
-            exit(1);
+            PANIC("option -lcd-density must be a positive integer");
         }
         hwLcd_setBootProperty(density);
     }
@@ -4741,16 +4769,14 @@
     if (android_op_radio) {
         CharDriverState*  cs = qemu_chr_open("radio", android_op_radio, NULL);
         if (cs == NULL) {
-            fprintf(stderr, "unsupported character device specification: %s\n"
-                            "used -help-char-devices for list of available formats\n",
+            PANIC("unsupported character device specification: %s\n"
+                        "used -help-char-devices for list of available formats",
                     android_op_radio);
-            exit(1);
         }
         android_qemud_set_channel( ANDROID_QEMUD_GSM, cs);
     } else if (android_hw->hw_gsmModem != 0 ) {
         if ( android_qemud_get_channel( ANDROID_QEMUD_GSM, &android_modem_cs ) < 0 ) {
-            fprintf(stderr, "could not initialize qemud 'gsm' channel");
-            exit(1);
+            PANIC("could not initialize qemud 'gsm' channel");
         }
     }
 
@@ -4758,29 +4784,25 @@
     if (android_op_gps) {
         CharDriverState*  cs = qemu_chr_open("gps", android_op_gps, NULL);
         if (cs == NULL) {
-            fprintf(stderr, "unsupported character device specification: %s\n"
-                            "used -help-char-devices for list of available formats\n",
+            PANIC("unsupported character device specification: %s\n"
+                        "used -help-char-devices for list of available formats",
                     android_op_gps);
-            exit(1);
         }
         android_qemud_set_channel( ANDROID_QEMUD_GPS, cs);
     } else if (android_hw->hw_gps != 0) {
         if ( android_qemud_get_channel( "gps", &android_gps_cs ) < 0 ) {
-            fprintf(stderr, "could not initialize qemud 'gps' channel" );
-            exit(1);
+            PANIC("could not initialize qemud 'gps' channel");
         }
     }
 
     /* Initialize audio. */
     if (android_op_audio) {
         if (android_op_audio_in || android_op_audio_out) {
-            fprintf(stderr, "you can't use -audio with -audio-in or -audio-out\n" );
-            exit(1);
+            PANIC("you can't use -audio with -audio-in or -audio-out");
         }
         if ( !audio_check_backend_name( 0, android_op_audio ) ) {
-            fprintf(stderr, "'%s' is not a valid audio output backend. see -help-audio-out\n",
+            PANIC("'%s' is not a valid audio output backend. see -help-audio-out",
                     android_op_audio);
-            exit(1);
         }
         android_op_audio_out = android_op_audio;
         android_op_audio_in  = android_op_audio;
@@ -4796,9 +4818,8 @@
     if (android_op_audio_in) {
         static char  env[64]; /* note: putenv needs a static unique string buffer */
         if ( !audio_check_backend_name( 1, android_op_audio_in ) ) {
-            fprintf(stderr, "'%s' is not a valid audio input backend. see -help-audio-in\n",
+            PANIC("'%s' is not a valid audio input backend. see -help-audio-in",
                     android_op_audio_in);
-            exit(1);
         }
         bufprint( env, env+sizeof(env), "QEMU_AUDIO_IN_DRV=%s", android_op_audio_in );
         putenv( env );
@@ -4810,9 +4831,8 @@
     if (android_op_audio_out) {
         static char  env[64]; /* note: putenv needs a static unique string buffer */
         if ( !audio_check_backend_name( 0, android_op_audio_out ) ) {
-            fprintf(stderr, "'%s' is not a valid audio output backend. see -help-audio-out\n",
+            PANIC("'%s' is not a valid audio output backend. see -help-audio-out",
                     android_op_audio_out);
-            exit(1);
         }
         bufprint( env, env+sizeof(env), "QEMU_AUDIO_OUT_DRV=%s", android_op_audio_out );
         putenv( env );
@@ -4825,8 +4845,7 @@
         char*   end;
         long    delay = strtol(android_op_cpu_delay, &end, 0);
         if (end == NULL || *end || delay < 0 || delay > 1000 ) {
-            fprintf(stderr, "option -cpu-delay must be an integer between 0 and 1000\n" );
-            exit(1);
+            PANIC("option -cpu-delay must be an integer between 0 and 1000" );
         }
         if (delay > 0)
             delay = (1000-delay);
@@ -4868,7 +4887,7 @@
     if (dns_count == 0)
         dns_count = slirp_get_system_dns_servers();
     if (dns_count) {
-        snprintf(tmp_str, sizeof(tmp_str), "android.ndns=%d", dns_count);
+        snprintf(tmp_str, sizeof(tmp_str), "ndns=%d", dns_count);
         append_param(kernel_cmdline_append, tmp_str, sizeof(kernel_cmdline_append));
     }
 
@@ -4880,18 +4899,16 @@
 
 #if defined(CONFIG_KVM) && defined(CONFIG_KQEMU)
     if (kvm_allowed && kqemu_allowed) {
-        fprintf(stderr,
-                "You can not enable both KVM and kqemu at the same time\n");
-        exit(1);
+        PANIC(
+                "You can not enable both KVM and kqemu at the same time");
     }
 #endif
 
     machine->max_cpus = machine->max_cpus ?: 1; /* Default to UP */
     if (smp_cpus > machine->max_cpus) {
-        fprintf(stderr, "Number of SMP cpus requested (%d), exceeds max cpus "
-                "supported by machine `%s' (%d)\n", smp_cpus,  machine->name,
+        PANIC("Number of SMP cpus requested (%d), exceeds max cpus "
+                "supported by machine `%s' (%d)", smp_cpus,  machine->name,
                 machine->max_cpus);
-        exit(1);
     }
 
     if (display_type == DT_NOGRAPHIC) {
@@ -4907,8 +4924,9 @@
     if (daemonize) {
 	pid_t pid;
 
-	if (pipe(fds) == -1)
-	    exit(1);
+	if (pipe(fds) == -1) {
+	    PANIC("Unable to aquire pidfile");
+	}
 
 	pid = fork();
 	if (pid > 0) {
@@ -4922,23 +4940,26 @@
             if (len == -1 && (errno == EINTR))
                 goto again;
 
-            if (len != 1)
-                exit(1);
+            if (len != 1) {
+                PANIC("Error when aquiring pidfile");
+            }
             else if (status == 1) {
-                fprintf(stderr, "Could not acquire pidfile\n");
-                exit(1);
-            } else
-                exit(0);
-	} else if (pid < 0)
-            exit(1);
+                PANIC("Could not acquire pidfile");
+            } else {
+                QEMU_EXIT(0);
+            }
+	} else if (pid < 0) {
+        PANIC("Unable to daemonize");
+	}
 
 	setsid();
 
 	pid = fork();
-	if (pid > 0)
-	    exit(0);
-	else if (pid < 0)
-	    exit(1);
+	if (pid > 0) {
+	    QEMU_EXIT(0);
+	} else if (pid < 0) {
+         PANIC("Could not acquire pid file");
+	}
 
 	umask(027);
 
@@ -4954,9 +4975,10 @@
             do {
                 ret = write(fds[1], &status, 1);
             } while (ret < 0 && errno == EINTR);
-        } else
-            fprintf(stderr, "Could not acquire pid file\n");
-        exit(1);
+            PANIC("Could not acquire pid file");
+        } else {
+            PANIC("Could not acquire pid file");
+        }
     }
 #endif
 
@@ -4965,20 +4987,17 @@
         kqemu_allowed = 0;
 #endif
     if (qemu_init_main_loop()) {
-        fprintf(stderr, "qemu_init_main_loop failed\n");
-        exit(1);
+        PANIC("qemu_init_main_loop failed");
     }
     linux_boot = (kernel_filename != NULL);
     net_boot = (boot_devices_bitmap >> ('n' - 'a')) & 0xF;
 
     if (!linux_boot && *kernel_cmdline != '\0') {
-        fprintf(stderr, "-append only allowed with -kernel option\n");
-        exit(1);
+        PANIC("-append only allowed with -kernel option");
     }
 
     if (!linux_boot && initrd_filename != NULL) {
-        fprintf(stderr, "-initrd only allowed with -kernel option\n");
-        exit(1);
+        PANIC("-initrd only allowed with -kernel option");
     }
 
     /* boot to floppy or the default cd if no hard disk defined yet */
@@ -4988,15 +5007,10 @@
     setvbuf(stdout, NULL, _IOLBF, 0);
 
     if (init_timer_alarm() < 0) {
-        fprintf(stderr, "could not initialize alarm timer\n");
-        exit(1);
+        PANIC("could not initialize alarm timer");
     }
     configure_icount(icount_option);
 
-#ifdef _WIN32
-    socket_init();
-#endif
-
     /* init network clients */
     if (nb_net_clients == 0) {
         /* if no clients, we use a default config */
@@ -5007,8 +5021,9 @@
     }
 
     for(i = 0;i < nb_net_clients; i++) {
-        if (net_client_parse(net_clients[i]) < 0)
-            exit(1);
+        if (net_client_parse(net_clients[i]) < 0) {
+            PANIC("Unable to parse net clients");
+        }
     }
     net_client_check();
 
@@ -5027,8 +5042,7 @@
                 filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, buf);
                 if (filename && get_image_size(filename) > 0) {
                     if (nb_option_roms >= MAX_OPTION_ROMS) {
-                        fprintf(stderr, "Too many option ROMs\n");
-                        exit(1);
+                        PANIC("Too many option ROMs");
                     }
                     option_rom[nb_option_roms] = qemu_strdup(buf);
                     nb_option_roms++;
@@ -5040,16 +5054,16 @@
             }
 	}
 	if (netroms == 0) {
-	    fprintf(stderr, "No valid PXE rom found for network device\n");
-	    exit(1);
+	    PANIC("No valid PXE rom found for network device");
 	}
     }
 #endif
 
     /* init the bluetooth world */
     for (i = 0; i < nb_bt_opts; i++)
-        if (bt_parse(bt_opts[i]))
-            exit(1);
+        if (bt_parse(bt_opts[i])) {
+            PANIC("Unable to parse bluetooth options");
+        }
 
     /* init the memory */
     if (ram_size == 0)
@@ -5062,8 +5076,7 @@
         kqemu_phys_ram_size = ram_size + 8 * 1024 * 1024 + 4 * 1024 * 1024;
         kqemu_phys_ram_base = qemu_vmalloc(kqemu_phys_ram_size);
         if (!kqemu_phys_ram_base) {
-            fprintf(stderr, "Could not allocate physical memory\n");
-            exit(1);
+            PANIC("Could not allocate physical memory");
         }
     }
 #endif
@@ -5091,8 +5104,9 @@
     /* open the virtual block devices */
 
     for(i = 0; i < nb_drives_opt; i++)
-        if (drive_init(&drives_opt[i], snapshot, machine) == -1)
-	    exit(1);
+        if (drive_init(&drives_opt[i], snapshot, machine) == -1) {
+            PANIC("Could not open the virtual block devices");
+        }
 
     //register_savevm("timer", 0, 2, timer_save, timer_load, &timers_state);
     register_savevm_live("ram", 0, 3, ram_save_live, NULL, ram_load, NULL);
@@ -5164,16 +5178,15 @@
 
         ret = kvm_init(smp_cpus);
         if (ret < 0) {
-            fprintf(stderr, "failed to initialize KVM\n");
-            exit(1);
+            PANIC("failed to initialize KVM");
         }
     }
 
     if (monitor_device) {
         monitor_hd = qemu_chr_open("monitor", monitor_device, NULL);
         if (!monitor_hd) {
-            fprintf(stderr, "qemu: could not open monitor device '%s'\n", monitor_device);
-            exit(1);
+            PANIC("qemu: could not open monitor device '%s'",
+                              monitor_device);
         }
     }
 
@@ -5184,9 +5197,8 @@
             snprintf(label, sizeof(label), "serial%d", i);
             serial_hds[i] = qemu_chr_open(label, devname, NULL);
             if (!serial_hds[i]) {
-                fprintf(stderr, "qemu: could not open serial device '%s'\n",
+                PANIC("qemu: could not open serial device '%s'",
                         devname);
-                exit(1);
             }
         }
     }
@@ -5198,9 +5210,8 @@
             snprintf(label, sizeof(label), "parallel%d", i);
             parallel_hds[i] = qemu_chr_open(label, devname, NULL);
             if (!parallel_hds[i]) {
-                fprintf(stderr, "qemu: could not open parallel device '%s'\n",
+                PANIC("qemu: could not open parallel device '%s'",
                         devname);
-                exit(1);
             }
         }
     }
@@ -5212,9 +5223,8 @@
             snprintf(label, sizeof(label), "virtcon%d", i);
             virtcon_hds[i] = qemu_chr_open(label, devname, NULL);
             if (!virtcon_hds[i]) {
-                fprintf(stderr, "qemu: could not open virtio console '%s'\n",
+                PANIC("qemu: could not open virtio console '%s'",
                         devname);
-                exit(1);
             }
         }
     }
@@ -5270,8 +5280,7 @@
 
         ret = kvm_sync_vcpus();
         if (ret < 0) {
-            fprintf(stderr, "failed to initialize vcpus\n");
-            exit(1);
+            PANIC("failed to initialize vcpus");
         }
     }
 
@@ -5292,7 +5301,8 @@
                                          &android_display_width,
                                          &android_display_height,
                                          &android_display_bpp)) {
-                exit(1);
+                PANIC("Unable to parse -android-gui parameter: %s",
+                                  android_op_gui);
             }
             android_display_init_from(android_display_width,
                                       android_display_height, 0,
@@ -5306,7 +5316,8 @@
                                      &android_display_width,
                                      &android_display_height,
                                      &android_display_bpp)) {
-            exit(1);
+            PANIC("Unable to parse -android-gui parameter: %s",
+                              android_op_gui);
         }
         display_state->surface = qemu_resize_displaysurface(display_state,
                                                             android_display_width,
@@ -5346,8 +5357,9 @@
 #endif
     case DT_VNC:
         vnc_display_init(ds);
-        if (vnc_display_open(ds, vnc_display) < 0)
-            exit(1);
+        if (vnc_display_open(ds, vnc_display) < 0) {
+            PANIC("Unable to initialize VNC display");
+        }
 
         if (show_vnc_port) {
             printf("VNC server running on `%s'\n", vnc_display_local_addr(ds));
@@ -5403,9 +5415,8 @@
     }
 
     if (gdbstub_dev && gdbserver_start(gdbstub_dev) < 0) {
-        fprintf(stderr, "qemu: could not open gdbserver on device '%s'\n",
+        PANIC("qemu: could not open gdbserver on device '%s'",
                 gdbstub_dev);
-        exit(1);
     }
 
     if (loadvm)
@@ -5432,49 +5443,45 @@
 	if (len == -1 && (errno == EINTR))
 	    goto again1;
 
-	if (len != 1)
-	    exit(1);
+	if (len != 1) {
+	    PANIC("Unable to daemonize");
+	}
 
         if (chdir("/")) {
             perror("not able to chdir to /");
-            exit(1);
+            PANIC("not able to chdir to /");
         }
 	TFR(fd = open("/dev/null", O_RDWR));
 	if (fd == -1)
-	    exit(1);
+	    PANIC("open(\"/dev/null\") failed: %s", errno_str);
     }
 
     if (run_as) {
         pwd = getpwnam(run_as);
         if (!pwd) {
-            fprintf(stderr, "User \"%s\" doesn't exist\n", run_as);
-            exit(1);
+            PANIC("User \"%s\" doesn't exist", run_as);
         }
     }
 
     if (chroot_dir) {
         if (chroot(chroot_dir) < 0) {
-            fprintf(stderr, "chroot failed\n");
-            exit(1);
+            PANIC("chroot failed");
         }
         if (chdir("/")) {
             perror("not able to chdir to /");
-            exit(1);
+            PANIC("not able to chdir to /");
         }
     }
 
     if (run_as) {
         if (setgid(pwd->pw_gid) < 0) {
-            fprintf(stderr, "Failed to setgid(%d)\n", pwd->pw_gid);
-            exit(1);
+            PANIC("Failed to setgid(%d)", pwd->pw_gid);
         }
         if (setuid(pwd->pw_uid) < 0) {
-            fprintf(stderr, "Failed to setuid(%d)\n", pwd->pw_uid);
-            exit(1);
+            PANIC("Failed to setuid(%d)", pwd->pw_uid);
         }
         if (setuid(0) != -1) {
-            fprintf(stderr, "Dropping privileges failed\n");
-            exit(1);
+            PANIC("Dropping privileges failed");
         }
     }
 
@@ -5487,6 +5494,11 @@
     }
 #endif
 
+#ifdef CONFIG_ANDROID
+    // This will notify the UI that the core is successfuly initialized
+    android_core_init_completed();
+#endif  // CONFIG_ANDROID
+
     main_loop();
     quit_timers();
     net_cleanup();