00001 /* 00002 * Copyright (c) 2005 Martin Decky 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions 00007 * are met: 00008 * 00009 * - Redistributions of source code must retain the above copyright 00010 * notice, this list of conditions and the following disclaimer. 00011 * - Redistributions in binary form must reproduce the above copyright 00012 * notice, this list of conditions and the following disclaimer in the 00013 * documentation and/or other materials provided with the distribution. 00014 * - The name of the author may not be used to endorse or promote products 00015 * derived from this software without specific prior written permission. 00016 * 00017 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 00018 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00019 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 00020 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 00021 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 00022 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00023 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00024 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00025 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 00026 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00027 */ 00028 00043 #include <libc.h> 00044 #include <stdlib.h> 00045 #include <tls.h> 00046 #include <fibril.h> 00047 #include <task.h> 00048 #include <loader/pcb.h> 00049 #include "private/libc.h" 00050 #include "private/async.h" 00051 #include "private/async_sess.h" 00052 #include "private/malloc.h" 00053 #include "private/io.h" 00054 00055 #ifdef CONFIG_RTLD 00056 #include <rtld/rtld.h> 00057 #endif 00058 00059 static bool env_setup = false; 00060 00061 void __main(void *pcb_ptr) 00062 { 00063 /* Initialize user task run-time environment */ 00064 __malloc_init(); 00065 __async_init(); 00066 __async_sess_init(); 00067 00068 fibril_t *fibril = fibril_setup(); 00069 if (fibril == NULL) 00070 abort(); 00071 00072 __tcb_set(fibril->tcb); 00073 00074 /* Save the PCB pointer */ 00075 __pcb = (pcb_t *) pcb_ptr; 00076 00077 /* The basic run-time environment is setup */ 00078 env_setup = true; 00079 00080 int argc; 00081 char **argv; 00082 00083 #ifdef __IN_SHARED_LIBC__ 00084 if (__pcb != NULL && __pcb->rtld_runtime != NULL) { 00085 runtime_env = (runtime_env_t *) __pcb->rtld_runtime; 00086 } 00087 #endif 00088 /* 00089 * Get command line arguments and initialize 00090 * standard input and output 00091 */ 00092 if (__pcb == NULL) { 00093 argc = 0; 00094 argv = NULL; 00095 __stdio_init(0, NULL); 00096 } else { 00097 argc = __pcb->argc; 00098 argv = __pcb->argv; 00099 __stdio_init(__pcb->filc, __pcb->filv); 00100 (void) chdir(__pcb->cwd); 00101 } 00102 00103 /* 00104 * Run main() and set task return value 00105 * according the result 00106 */ 00107 int retval = main(argc, argv); 00108 exit(retval); 00109 } 00110 00111 void exit(int status) 00112 { 00113 if (env_setup) { 00114 __stdio_done(); 00115 task_retval(status); 00116 fibril_teardown(__tcb_get()->fibril_data); 00117 } 00118 00119 __SYSCALL1(SYS_TASK_EXIT, false); 00120 00121 /* Unreachable */ 00122 while (1); 00123 } 00124 00125 void abort(void) 00126 { 00127 __SYSCALL1(SYS_TASK_EXIT, true); 00128 00129 /* Unreachable */ 00130 while (1); 00131 } 00132