Subversion Repositories Kolibri OS

Rev

Rev 6536 | Rev 9952 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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