Subversion Repositories Kolibri OS

Rev

Rev 6068 | Rev 6536 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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