The Pedigree Project  0.1
crt0.c
1 /*
2  * Copyright (c) 2008-2014, Pedigree Developers
3  *
4  * Please see the CONTRIB file in the root of the source tree for a full
5  * list of contributors.
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include <fcntl.h>
21 #include <newlib.h>
22 #include <stdlib.h>
23 #include <unistd.h>
24 
25 extern int main(int, char **, char **);
26 extern void _init_signals(void);
27 
28 void _start(char **argv, char **env) _ATTRIBUTE((noreturn))
29  __attribute__((section(".text.crt0")));
30 void _start(char **argv, char **env)
31 {
32  _init_signals();
33 
34  if (write(2, 0, 0) == -1)
35  {
36  open("/dev/tty", O_RDONLY, 0);
37  open("/dev/tty", O_WRONLY, 0);
38  open("/dev/tty", O_WRONLY, 0);
39  }
40 
41  // Count how many args we have.
42  int argc;
43  if (argv == 0)
44  {
45  char *p = 0;
46  argv = &p;
47  argc = 0;
48  environ = &p;
49  }
50  else
51  {
52  char **i = argv;
53  argc = 0;
54  while (*i++)
55  argc++;
56  if (!env)
57  env = environ;
58  i = env;
59  while (env && (*i))
60  {
61  // Save the key.
62  char *key = *i;
63  char *value = *i;
64  // Iterate until we see the end of the string or an '='.
65  while (*value && *value != '=')
66  value++;
67  // If we found a '=', change it to a NULL terminator (for the key)
68  // and increment position.
69  if (*value == '=')
70  *value++ = '\0';
71  // Set the env var.
72  setenv(key, value, 1);
73  i++;
74  }
75  }
76 
77  exit(main(argc, argv, env));
78 
79  // Unreachable.
80  for (;;)
81  ;
82 }