Subversion Repositories Kolibri OS

Rev

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