Tried to fix whole execution system (Shell, Unnamed Pipes)
[meinos.git] / apps / lib / stdlibc / stdlib.c
blob1c378dcbe3f5636676f604ff2ec1caf210ecfcd6
1 /*
2 meinOS - A unix-like x86 microkernel operating system
3 Copyright (C) 2008 Janosch Gräf <janosch.graef@gmx.net>
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include <sys/types.h>
20 #include <string.h>
21 #include <errno.h>
22 #include <stdlib.h>
23 #include <limits.h>
24 #include <ctype.h>
25 #include <llist.h>
26 #include <syscall.h>
27 #include <stdint.h>
29 // some variables/functions needed
30 void stdio_init(); ///< @see stdio.h
31 void env_init(); ///< @see env.c
32 llist_t atexit_list; ///< @see stdlib.c
33 void _close_all_filehandles(); ///< @see files.c
34 void _signal_init(); ///< @see signal.c
35 void _fs_init(char *_stdin,char *_stdout,char *_stderr); ///< @see apps/lib/stdlibc/files.c
37 void _stdlib_init_pre() {
38 rand_seed = rand_seed%RAND_MAX;
39 errno = 0;
40 atexit_list = llist_create();
41 _signal_init();
43 #include <stdio.h>
44 void _stdlib_init_post(char *_stdin,char *_stdout,char *_stderr) {
45 env_init();
46 _fs_init(_stdin,_stdout,_stderr);
47 stdio_init();
50 /**
51 * Exits process
52 * @param result Program result value
53 * @see also used by crt0.asm
55 void exit(int result) {
56 void (*func)(void);
57 while ((func = llist_pop(atexit_list))!=NULL) func();
58 _Exit(result);
61 /**
62 * Closes all filehandles and exits
63 * @param result Program result
65 void _Exit(int result) {
66 _close_all_filehandles();
67 syscall_call(SYSCALL_PROC_EXIT,1,result);
70 /**
71 * Registers a function to run at process termination
72 * @param func Function
73 * @return 0=successful; -1=failed
75 int atexit(void (*func)(void)) {
76 return llist_push(atexit_list,func)!=NULL?0:-1;
79 /**
80 * Converts a string to a number
81 * @param str String representing a number
82 * @return Represented number from string
84 int atoi(const char *str) {
85 size_t len,i;
86 int num = 0;
87 int sign = 0;
89 len = strlen(str);
90 for (i=0;i<len;i++) {
91 if (str[i]=='+') sign = 0;
92 else if (str[i]=='-') sign = 1;
93 else num = num*10+str[i]-'0';
95 if (sign) num *= -1;
96 return num;
99 /**
100 * Returns absolute number
101 * @param num Number to get absolute number of
102 * @return Absolute number
104 int abs(int num) {
105 if (num<0) num = -num;
106 return num;
110 * Devides a number
111 * @param numer Numer
112 * @param denom Denom
113 * @return Devision result
115 div_t div(int numer, int denom) {
116 div_t res;
117 res.quot = numer/denom;
118 res.rem = numer%denom;
119 return res;
123 * Binary search a sorted table
124 * @param vdkey Key
125 * @param vdbase Base
126 * @param nel Num elements
127 * @param width Size of an element
128 * @param compar Function called when match found
130 void *bsearch(const void *vdkey,const void *vdbase,size_t nel,size_t width,int (*compar)(const void *, const void *)) {
131 char *key = (char*)vdkey;
132 char *cpkey = memcpy(malloc(width),key,width);
133 char *base = (char*)vdbase;
134 void *last = NULL;
135 size_t found = 0;
136 size_t i;
138 for (i=0;i<nel;i++) {
139 if (*(base+nel*width)==*key) found++;
140 if (found==width) {
141 char *cpbase = memcpy(malloc(width),base,width);
142 if (compar!=NULL) compar(key,base);
143 *key = *cpkey;
144 *base = *cpbase;
145 free(cpbase);
146 found = 0;
147 last = (void*)(vdbase+nel*width);
151 free(cpkey);
152 return last;
156 * Gets a new page from kernel
157 * @param size How many bytes (should be devidable by PAGESIZE)
158 * @return Pointer to new page
160 void *sbrk(intptr_t size) {
161 return (void*)syscall_call(SYSCALL_MEM_MALLOC,1,size);
164 /// @todo FIXME
165 int rand() {
166 return 0xD00FC0DE;
167 const int N = 624;
168 const int M = 397;
169 const unsigned A[2] = { 0, 0x9908b0df };
170 const unsigned HI = 0x80000000;
171 const unsigned LO = 0x7fffffff;
173 static unsigned *y;
174 static int init = 0;
175 static int index;
176 if (!init) {
177 index = N;
178 init = 1;
181 if (index >= N) {
182 if (index > N) {
183 // initialisiere y mit Pseudozufallszahlen:
184 y = calloc(N,sizeof(unsigned int));
185 unsigned r = 9, s = 3402;
186 int i;
187 for (i=0 ; i<N ; ++i) {
188 r = 509845221 * r + 3;
189 s *= s + 1;
190 y[i] = s + (r >> 10);
193 unsigned h;
194 int k;
195 for (k=0 ; k<N-M ; ++k) {
196 h = (y[k] & HI) | (y[k+1] & LO);
197 y[k] = y[k+M] ^ (h >> 1) ^ A[h & 1];
199 for (k=N-M ; k<N-1 ; ++k) {
200 h = (y[k] & HI) | (y[k+1] & LO);
201 y[k] = y[k+(M-N)] ^ (h >> 1) ^ A[h & 1];
203 h = (y[N-1] & HI) | (y[0] & LO);
204 y[N-1] = y[M-1] ^ (h >> 1) ^ A[h & 1];
205 index = 0;
208 unsigned e = y[index++];
209 // tempering:
210 e ^= (e >> 11);
211 e ^= (e << 7) & 0x9d2c5680;
212 e ^= (e << 15) & 0xefc60000;
213 e ^= (e >> 18);
214 return e%RAND_MAX;