Subversion Repositories Kolibri OS

Rev

Rev 6664 | 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
 
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;
6074 serge 31
    int    __subsystem__;
4349 Serge 32
    void  *__idata_start;
33
    void  *__idata_end;
34
    int  (*main)(int argc, char **argv, char **envp);
35
};
36
 
6536 serge 37
extern void _pei386_runtime_relocator (void);
38
extern void init_loader(void *libc_image);
6664 serge 39
extern void init_global_reent(void);
6536 serge 40
extern void init_stdio(void);
4349 Serge 41
 
6536 serge 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
 
5190 serge 49
char* __appenv;
50
int   __appenv_size;
4349 Serge 51
 
52
 
53
char * __libc_getenv(const char *name)
54
{
55
    return NULL;
56
}
57
 
5190 serge 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
    };
4349 Serge 66
 
5190 serge 67
    enum quote_state state;
68
    unsigned int argc;
69
    char *p = cmdline;
70
    char *new_arg, *start;
4349 Serge 71
 
5190 serge 72
    argc = 0;
4349 Serge 73
 
5190 serge 74
    for(;;)
75
    {
76
        /* skip over spaces and tabs */
77
        if ( *p )
78
        {
79
            while (*p == ' ' || *p == '\t')
80
                ++p;
81
        }
4349 Serge 82
 
5190 serge 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
 
6536 serge 172
__attribute__((noreturn))
173
void  libc_crt_startup (void *libc_base)
4349 Serge 174
{
6536 serge 175
    struct app_hdr *header = NULL;
5190 serge 176
    int retval = 0;
4349 Serge 177
 
5190 serge 178
    char **argv;
179
    int    argc;
4349 Serge 180
 
181
    _pei386_runtime_relocator();
182
 
6536 serge 183
    tls_init();
6664 serge 184
    init_global_reent();
4921 Serge 185
    init_stdio();
6074 serge 186
 
187
    if(header->__subsystem__ == 3)
188
        __init_conio();
189
 
4349 Serge 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
    {
5190 serge 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);
4349 Serge 204
    }
5190 serge 205
    else
206
    {
207
        argc = 1;
208
        argv = alloca((argc+1)*sizeof(char*));
209
        argv[0] = header->path;
210
    }
211
    argv[argc] = NULL;
4349 Serge 212
 
5190 serge 213
    retval = header->main(argc, argv, NULL);
4349 Serge 214
done:
6074 serge 215
    if(header->__subsystem__ == 3)
216
        __fini_conio();
217
 
4349 Serge 218
    exit (retval);
219
}
220