Subversion Repositories Kolibri OS

Rev

Rev 6664 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. /*
  2.  * crtdll.c
  3.  * This file has no copyright assigned and is placed in the Public Domain.
  4.  * This file is a part of the mingw-runtime package.
  5.  * No warranty is given; refer to the file DISCLAIMER within the package.
  6.  *
  7.  * Source code for the shared libc startup proceedures. This code is compiled
  8.  * to make libc.dll, which should be located in the library path.
  9.  *
  10.  */
  11.  
  12. #include <_ansi.h>
  13. #include <reent.h>
  14. #include <stdint.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #include <stdio.h>
  18. #include <unistd.h>
  19. #include <setjmp.h>
  20.  
  21. struct app_hdr
  22. {
  23.     char  banner[8];
  24.     int   version;
  25.     int   start;
  26.     int   iend;
  27.     int   memsize;
  28.     int   stacktop;
  29.     char  *cmdline;
  30.     char  *path;
  31.     int    __subsystem__;
  32.     void  *__idata_start;
  33.     void  *__idata_end;
  34.     int  (*main)(int argc, char **argv, char **envp);
  35. };
  36.  
  37. extern void _pei386_runtime_relocator (void);
  38. extern void init_loader(void *libc_image);
  39. extern void init_global_reent(void);
  40. extern void init_stdio(void);
  41.  
  42. extern void __init_conio(void);
  43. extern void __fini_conio(void);
  44. extern int link_app(void);
  45. extern void* get_entry_point(void *raw);
  46.  
  47. extern void tls_init(void);
  48.  
  49. char* __appenv;
  50. int   __appenv_size;
  51.  
  52.  
  53. char * __libc_getenv(const char *name)
  54. {
  55.     return NULL;
  56. }
  57.  
  58. static int split_cmdline(char *cmdline, char **argv)
  59. {
  60.     enum quote_state
  61.     {
  62.         QUOTE_NONE,         /* no " active in current parm       */
  63.         QUOTE_DELIMITER,    /* " was first char and must be last */
  64.         QUOTE_STARTED       /* " was seen, look for a match      */
  65.     };
  66.  
  67.     enum quote_state state;
  68.     unsigned int argc;
  69.     char *p = cmdline;
  70.     char *new_arg, *start;
  71.  
  72.     argc = 0;
  73.  
  74.     for(;;)
  75.     {
  76.         /* skip over spaces and tabs */
  77.         if ( *p )
  78.         {
  79.             while (*p == ' ' || *p == '\t')
  80.                 ++p;
  81.         }
  82.  
  83.         if (*p == '\0')
  84.             break;
  85.  
  86.         state = QUOTE_NONE;
  87.         if( *p == '\"' )
  88.         {
  89.             p++;
  90.             state = QUOTE_DELIMITER;
  91.         }
  92.         new_arg = start = p;
  93.         for (;;)
  94.         {
  95.             if( *p == '\"' )
  96.             {
  97.                 p++;
  98.                 if( state == QUOTE_NONE )
  99.                 {
  100.                     state = QUOTE_STARTED;
  101.                 }
  102.                 else
  103.                 {
  104.                     state = QUOTE_NONE;
  105.                 }
  106.                 continue;
  107.             }
  108.  
  109.             if( *p == ' ' || *p == '\t' )
  110.             {
  111.                 if( state == QUOTE_NONE )
  112.                 {
  113.                     break;
  114.                 }
  115.             }
  116.  
  117.             if( *p == '\0' )
  118.                 break;
  119.  
  120.             if( *p == '\\' )
  121.             {
  122.                 if( p[1] == '\"' )
  123.                 {
  124.                     ++p;
  125.                     if( p[-2] == '\\' )
  126.                     {
  127.                         continue;
  128.                     }
  129.                 }
  130.             }
  131.             if( argv )
  132.             {
  133.                 *(new_arg++) = *p;
  134.             }
  135.             ++p;
  136.         };
  137.  
  138.         if( argv )
  139.         {
  140.             argv[ argc ] = start;
  141.             ++argc;
  142.  
  143.             /*
  144.               The *new = '\0' is req'd in case there was a \" to "
  145.               translation. It must be after the *p check against
  146.               '\0' because new and p could point to the same char
  147.               in which case the scan would be terminated too soon.
  148.             */
  149.  
  150.             if( *p == '\0' )
  151.             {
  152.                 *new_arg = '\0';
  153.                 break;
  154.             }
  155.             *new_arg = '\0';
  156.             ++p;
  157.         }
  158.         else
  159.         {
  160.             ++argc;
  161.             if( *p == '\0' )
  162.             {
  163.                 break;
  164.             }
  165.             ++p;
  166.         }
  167.     }
  168.  
  169.     return argc;
  170. };
  171.  
  172. __attribute__((noreturn))
  173. void  libc_crt_startup (void *libc_base)
  174. {
  175.     struct app_hdr *header = NULL;
  176.     int retval = 0;
  177.  
  178.     char **argv;
  179.     int    argc;
  180.  
  181.     _pei386_runtime_relocator();
  182.  
  183.     tls_init();
  184.     init_global_reent();
  185.     init_stdio();
  186.  
  187.     if(header->__subsystem__ == 3)
  188.         __init_conio();
  189.  
  190.  //   __appenv = load_file("/sys/system.env", &__appenv_size);
  191.  
  192.     init_loader(libc_base);
  193.  
  194.     if( link_app() == 0)
  195.         goto done;
  196.  
  197.     if( header->cmdline[0] != 0)
  198.     {
  199.         argc = split_cmdline(header->cmdline, NULL) + 1;
  200.         argv = alloca((argc+1)*sizeof(char*));
  201.         argv[0] = header->path;
  202.  
  203.         split_cmdline(header->cmdline, argv + 1);
  204.     }
  205.     else
  206.     {
  207.         argc = 1;
  208.         argv = alloca((argc+1)*sizeof(char*));
  209.         argv[0] = header->path;
  210.     }
  211.     argv[argc] = NULL;
  212.  
  213.     retval = header->main(argc, argv, NULL);
  214. done:
  215.     if(header->__subsystem__ == 3)
  216.         __fini_conio();
  217.  
  218.     exit (retval);
  219. }
  220.  
  221.