Subversion Repositories Kolibri OS

Rev

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

Rev 6074 Rev 6536
1
/*
1
/*
2
 * crt1.c
2
 * crt1.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 startup proceedures used by all programs. This code
7
 * Source code for the startup proceedures used by all programs. This code
8
 * is compiled to make crt1.o, which should be located in the library path.
8
 * is compiled to make crt1.o, which should be located in the library path.
9
 *
9
 *
10
 */
10
 */
11
 
11
 
12
/* Hide the declaration of _fmode with dllimport attribute in stdlib.h to
12
/* Hide the declaration of _fmode with dllimport attribute in stdlib.h to
13
   avoid problems with older GCC. */
13
   avoid problems with older GCC. */
14
 
-
 
15
#include 
-
 
16
#include 
14
 
17
#include 
-
 
18
#include 
-
 
19
#include 
-
 
20
#include 
15
#include 
21
 
16
 
22
struct app_hdr
17
struct app_hdr
23
{
18
{
24
    char  banner[8];
19
    char  banner[8];
25
    int   version;
20
    int   version;
26
    int   start;
21
    int   start;
27
    int   iend;
22
    int   iend;
28
    int   memsize;
23
    int   memsize;
29
    int   stacktop;
24
    int   stacktop;
30
    char  *cmdline;
25
    char  *cmdline;
31
    char  *path;
26
    char  *path;
32
    int    __subsystem__;
27
    int    __subsystem__;
33
};
28
};
-
 
29
 
-
 
30
extern void init_reent();
34
 
31
extern void init_stdio();
35
void __init_conio();
32
extern void __init_conio();
-
 
33
extern void __fini_conio();
36
void __fini_conio();
34
 
37
 
35
extern void tls_init(void);
38
extern int main (int, char **, char **);
36
extern int main (int, char **, char **);
39
 
37
 
40
/* NOTE: The code for initializing the _argv, _argc, and environ variables
38
/* NOTE: The code for initializing the _argv, _argc, and environ variables
41
 *       has been moved to a separate .c file which is included in both
39
 *       has been moved to a separate .c file which is included in both
42
 *       crt1.c and dllcrt1.c. This means changes in the code don't have to
40
 *       crt1.c and dllcrt1.c. This means changes in the code don't have to
43
 *       be manually synchronized, but it does lead to this not-generally-
41
 *       be manually synchronized, but it does lead to this not-generally-
44
 *       a-good-idea use of include. */
42
 *       a-good-idea use of include. */
45
 
43
 
46
char* __appenv;
44
char* __appenv;
47
int   __appenv_size;
45
int   __appenv_size;
48
 
-
 
49
extern char _tls_map[128];
-
 
50
 
46
 
51
char * __libc_getenv(const char *name)
47
char * __libc_getenv(const char *name)
52
{
48
{
53
    return NULL;
49
    return NULL;
54
}
50
}
55
 
51
 
56
static int split_cmdline(char *cmdline, char **argv)
52
static int split_cmdline(char *cmdline, char **argv)
57
{
53
{
58
    enum quote_state
54
    enum quote_state
59
    {
55
    {
60
        QUOTE_NONE,         /* no " active in current parm       */
56
        QUOTE_NONE,         /* no " active in current parm       */
61
        QUOTE_DELIMITER,    /* " was first char and must be last */
57
        QUOTE_DELIMITER,    /* " was first char and must be last */
62
        QUOTE_STARTED       /* " was seen, look for a match      */
58
        QUOTE_STARTED       /* " was seen, look for a match      */
63
    };
59
    };
64
 
60
 
65
    enum quote_state state;
61
    enum quote_state state;
66
    unsigned int argc;
62
    unsigned int argc;
67
    char *p = cmdline;
63
    char *p = cmdline;
68
    char *new_arg, *start;
64
    char *new_arg, *start;
69
 
65
 
70
    argc = 0;
66
    argc = 0;
71
 
67
 
72
    for(;;)
68
    for(;;)
73
    {
69
    {
74
        /* skip over spaces and tabs */
70
        /* skip over spaces and tabs */
75
        if ( *p )
71
        if ( *p )
76
        {
72
        {
77
            while (*p == ' ' || *p == '\t')
73
            while (*p == ' ' || *p == '\t')
78
                ++p;
74
                ++p;
79
        }
75
        }
80
 
76
 
81
        if (*p == '\0')
77
        if (*p == '\0')
82
            break;
78
            break;
83
 
79
 
84
        state = QUOTE_NONE;
80
        state = QUOTE_NONE;
85
        if( *p == '\"' )
81
        if( *p == '\"' )
86
        {
82
        {
87
            p++;
83
            p++;
88
            state = QUOTE_DELIMITER;
84
            state = QUOTE_DELIMITER;
89
        }
85
        }
90
        new_arg = start = p;
86
        new_arg = start = p;
91
        for (;;)
87
        for (;;)
92
        {
88
        {
93
            if( *p == '\"' )
89
            if( *p == '\"' )
94
            {
90
            {
95
                p++;
91
                p++;
96
                if( state == QUOTE_NONE )
92
                if( state == QUOTE_NONE )
97
                {
93
                {
98
                    state = QUOTE_STARTED;
94
                    state = QUOTE_STARTED;
99
                }
95
                }
100
                else
96
                else
101
                {
97
                {
102
                    state = QUOTE_NONE;
98
                    state = QUOTE_NONE;
103
                }
99
                }
104
                continue;
100
                continue;
105
            }
101
            }
106
 
102
 
107
            if( *p == ' ' || *p == '\t' )
103
            if( *p == ' ' || *p == '\t' )
108
            {
104
            {
109
                if( state == QUOTE_NONE )
105
                if( state == QUOTE_NONE )
110
                {
106
                {
111
                    break;
107
                    break;
112
                }
108
                }
113
            }
109
            }
114
 
110
 
115
            if( *p == '\0' )
111
            if( *p == '\0' )
116
                break;
112
                break;
117
 
113
 
118
            if( *p == '\\' )
114
            if( *p == '\\' )
119
            {
115
            {
120
                if( p[1] == '\"' )
116
                if( p[1] == '\"' )
121
                {
117
                {
122
                    ++p;
118
                    ++p;
123
                    if( p[-2] == '\\' )
119
                    if( p[-2] == '\\' )
124
                    {
120
                    {
125
                        continue;
121
                        continue;
126
                    }
122
                    }
127
                }
123
                }
128
            }
124
            }
129
            if( argv )
125
            if( argv )
130
            {
126
            {
131
                *(new_arg++) = *p;
127
                *(new_arg++) = *p;
132
            }
128
            }
133
            ++p;
129
            ++p;
134
        };
130
        };
135
 
131
 
136
        if( argv )
132
        if( argv )
137
        {
133
        {
138
            argv[ argc ] = start;
134
            argv[ argc ] = start;
139
            ++argc;
135
            ++argc;
140
 
136
 
141
            /*
137
            /*
142
              The *new = '\0' is req'd in case there was a \" to "
138
              The *new = '\0' is req'd in case there was a \" to "
143
              translation. It must be after the *p check against
139
              translation. It must be after the *p check against
144
              '\0' because new and p could point to the same char
140
              '\0' because new and p could point to the same char
145
              in which case the scan would be terminated too soon.
141
              in which case the scan would be terminated too soon.
146
            */
142
            */
147
 
143
 
148
            if( *p == '\0' )
144
            if( *p == '\0' )
149
            {
145
            {
150
                *new_arg = '\0';
146
                *new_arg = '\0';
151
                break;
147
                break;
152
            }
148
            }
153
            *new_arg = '\0';
149
            *new_arg = '\0';
154
            ++p;
150
            ++p;
155
        }
151
        }
156
        else
152
        else
157
        {
153
        {
158
            ++argc;
154
            ++argc;
159
            if( *p == '\0' )
155
            if( *p == '\0' )
160
            {
156
            {
161
                break;
157
                break;
162
            }
158
            }
163
            ++p;
159
            ++p;
164
        }
160
        }
165
    }
161
    }
166
 
162
 
167
    return argc;
163
    return argc;
168
};
164
};
169
 
165
 
170
void  __attribute__((noreturn))
166
void  __attribute__((noreturn))
171
__crt_startup (void)
167
__libc_init (void)
172
{
168
{
173
    struct   app_hdr *header = NULL;
169
    struct   app_hdr *header = NULL;
174
    int retval = 0;
170
    int retval = 0;
175
 
171
 
176
    char **argv;
172
    char **argv;
177
    int    argc;
173
    int    argc;
178
 
-
 
179
    memset(_tls_map, 0xFF, 32*4);
174
 
180
    _tls_map[0] = 0xE0;
175
    tls_init();
181
    init_reent();
176
    init_reent();
182
    init_stdio();
177
    init_stdio();
183
 
178
 
184
    if(header->__subsystem__ == 3)
179
    if(header->__subsystem__ == 3)
185
        __init_conio();
180
        __init_conio();
186
 
181
 
187
    if( header->cmdline[0] != 0)
182
    if( header->cmdline[0] != 0)
188
    {
183
    {
189
        argc = split_cmdline(header->cmdline, NULL) + 1;
184
        argc = split_cmdline(header->cmdline, NULL) + 1;
190
        argv = alloca((argc+1)*sizeof(char*));
185
        argv = alloca((argc+1)*sizeof(char*));
191
        argv[0] = header->path;
186
        argv[0] = header->path;
192
 
187
 
193
        split_cmdline(header->cmdline, argv + 1);
188
        split_cmdline(header->cmdline, argv + 1);
194
    }
189
    }
195
    else
190
    else
196
    {
191
    {
197
        argc = 1;
192
        argc = 1;
198
        argv = alloca((argc+1)*sizeof(char*));
193
        argv = alloca((argc+1)*sizeof(char*));
199
        argv[0] = header->path;
194
        argv[0] = header->path;
200
    }
195
    }
201
    argv[argc] = NULL;
196
    argv[argc] = NULL;
202
 
197
 
203
    retval = main(argc, argv, NULL);
198
    retval = main(argc, argv, NULL);
204
done:
199
done:
205
    if(header->__subsystem__ == 3)
200
    if(header->__subsystem__ == 3)
206
        __fini_conio();
201
        __fini_conio();
207
 
202
 
208
    exit (retval);
203
    exit (retval);
209
}
204
}