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>
26 static const char *errno_strings
[] = {
28 "Argument list too long.",
31 "Address not available.",
32 "Address family not supported.",
33 "Resource unavailable, try again.",
34 "Connection already in progress.",
35 "Bad file descriptor.",
37 "Device or resource busy.",
38 "Operation canceled.",
39 "No child processes.",
40 "Connection aborted.",
41 "Connection refused.",
43 "Resource deadlock would occur.",
44 "Destination address required.",
45 "Mathematics argument out of domain of function.",
50 "Host is unreachable.",
51 "Identifier removed.",
52 "Illegal byte sequence.",
53 "Operation in progress.",
54 "Interrupted function.",
57 "Socket is connected.",
59 "Too many levels of symbolic links.",
60 "Too many open files.",
66 "Connection aborted by network.",
67 "Network unreachable.",
68 "Too many files open in system.",
69 "No buffer space available.",
70 "No message is available on the STREAM head read queue.",
72 "No such file or directory.",
73 "Executable file format error.",
74 "No locks available.",
77 "No message of the desired type.",
78 "Protocol not available.",
79 "No space left on device.",
80 "No STREAM resources.",
82 "Function not supported.",
83 "The socket is not connected.",
85 "Directory not empty.",
88 "Inappropriate I/O control operation.",
89 "No such device or address.",
90 "Operation not supported on socket.",
91 "Value too large to be stored in data type.",
92 "Operation not permitted.",
95 "Protocol not supported.",
96 "Protocol wrong type for socket.",
98 "Read-only file system.",
102 "Stream ioctl() timeout.",
103 "Connection timed out.",
105 "Operation would block.",
111 * @param dest Destination for memory copy
112 * @param src Source for memory copy
113 * @param c Char which first oncurrence will stop copying
114 * @param n How many bytes to copy
117 void *memccpy(void *dest
,const void *src
,int c
,size_t n
) {
118 uint8_t *dest8
= (uint8_t*)dest
;
119 uint8_t *src8
= (uint8_t*)src
;
124 if (src8
[i
]==((uint8_t)c
)) break;
130 * Searches for c in src
131 * @param src Pointer where to search
132 * @param c Byte to search
133 * @param n How many bytes to search in
134 * @return Pointer to c in src
136 void *memchr(const void *src
,int c
,size_t n
) {
137 uint8_t *src8
= (uint8_t*)src
;
141 if (src8
[i
]==((uint8_t)c
)) return (void*)(src8
+i
);
148 * @param srca First source to compare
149 * @param srcb Second source to compare
150 * @param n How many bytes to compare
153 int memcmp(const void *srca
,const void *srcb
,size_t n
) {
154 if (srca
==srcb
) return 0;
155 size_t fast_count
= n
/sizeof(int);
156 size_t byte_count
= n
%sizeof(int);
157 int *fast_srca
= (int*)srca
;
158 int *fast_srcb
= (int*)srcb
;
159 uint8_t *byte_srca
= ((uint8_t*)srca
)+fast_count
*sizeof(int);
160 uint8_t *byte_srcb
= ((uint8_t*)srcb
)+fast_count
*sizeof(int);
163 for (i
=0;i
<fast_count
;i
++) {
164 if (fast_srca
[i
]!=fast_srcb
[i
]) return fast_srca
[i
]-fast_srcb
[i
];
166 for (i
=0;i
<byte_count
;i
++) {
167 if (byte_srca
[i
]!=byte_srcb
[i
]) return byte_srca
[i
]-byte_srcb
[i
];
174 * @param dest Destination for memory copy
175 * @param src Source for memory copy
176 * @param n How many bytes to copy
179 void *memcpy(void *dest
,const void *src
,size_t n
) {
180 if (dest
==src
) return dest
;
181 size_t fast_count
= n
/sizeof(int);
182 size_t byte_count
= n
%sizeof(int);
183 int *fast_dest
= (int*)dest
;
184 int *fast_src
= (int*)src
;
185 uint8_t *byte_dest
= ((uint8_t*)dest
)+fast_count
*sizeof(int);
186 uint8_t *byte_src
= ((uint8_t*)src
)+fast_count
*sizeof(int);
189 for (i
=0;i
<fast_count
;i
++) fast_dest
[i
] = fast_src
[i
];
190 for (i
=0;i
<byte_count
;i
++) byte_dest
[i
] = byte_src
[i
];
196 * @param dest Destination
198 * @param n How many bytes to move
199 * @todo Please do it the right way
201 void *memmove(void *dest
, const void *src
, size_t n
) {
202 if (dest
==src
) return dest
;
203 size_t fast_count
= n
/sizeof(int);
204 size_t byte_count
= n
%sizeof(int);
205 int *fast_dest
= (int*)dest
;
206 int *fast_src
= (int*)src
;
207 uint8_t *byte_dest
= ((uint8_t*)dest
)+fast_count
*sizeof(int);
208 uint8_t *byte_src
= ((uint8_t*)src
)+fast_count
*sizeof(int);
212 for (i
=0;i
<fast_count
;i
++) fast_dest
[i
] = fast_src
[i
];
213 for (i
=0;i
<byte_count
;i
++) byte_dest
[i
] = byte_src
[i
];
216 for (i
=byte_count
;i
>0;i
--) byte_dest
[i
-1] = byte_src
[i
-1];
217 for (i
=fast_count
;i
>0;i
--) fast_dest
[i
-1] = fast_src
[i
-1];
223 * Writes specified value in memory
224 * @param dest Destination memory
225 * @param val Value to write in memory
226 * @param n How many bytes to write
229 void *memset(void *dest
,int val
,size_t n
) {
230 /*size_t fast_count = n/sizeof(int);
231 size_t byte_count = n%sizeof(int);
232 int *fast_dest = (int*)dest;
233 uint8_t *byte_dest = ((uint8_t*)dest)+fast_count*sizeof(int);
234 uint8_t byte_val = (uint8_t)val;
238 for (i=0;i<sizeof(int)*8;i+=8) fast_val |= (val&0xFF)<<i;
239 for (i=0;i<fast_count;i++) fast_dest[i] = fast_val;
240 for (i=0;i<byte_count;i++) byte_dest[i] = byte_val;
244 uint8_t *byte_dest
= (uint8_t*)dest
;
245 for (i
=0;i
<n
;i
++) byte_dest
[i
] = val
;
250 * Puts two strings together
251 * @param str1 First string
252 * @param str2 Second string
255 char *strcat(char *str1
,const char *str2
) {
256 return strcpy(str1
+strlen(str1
),str2
);
260 * Locates the first occurrence of a character in a string
261 * @param str String to search in
262 * @param chr Character to search
263 * @return Pointer (String) to character
265 char *strchr(const char *str
,int chr
) {
267 for (i
=0;(str
[i
]!=0 && str
[i
]!=(char)chr
);i
++);
268 return str
[i
]==chr
?(char*)str
+i
:NULL
;
272 * Compares two strings
273 * @param str1 First string
274 * @param str2 Second string
275 * @return 0 if strings are equal
277 int strcmp(const char *str1
,const char *str2
) {
278 if (str1
==str2
) return 0;
281 for (i
=0;(str1
[i
] || str2
[i
]);i
++) {
282 if (str1
[i
]!=str2
[i
]) return str1
[i
]-str2
[i
];
289 * @param dest Destination where to store the string
290 * @param src Source string
291 * @return returns dest
293 char *strcpy(char *dest
,const char *src
) {
295 for (i
=0;src
[i
];i
++) dest
[i
] = src
[i
];
301 * Duplicates a string
302 * @param src String to duplicate
305 char *strdup(const char *src
) {
306 size_t len
= strlen(src
)+1;
307 return memcpy(malloc(len
),src
,len
);
311 * Returns an error string
312 * @param errnum Error number
313 * @return Error string
315 char *strerror(int errnum
) {
316 return (char*)errno_strings
[errnum
];
322 * @return length of string
324 size_t strlen(const char *str
) {
325 if (str
==NULL
) return 0;
327 for (i
=0;str
[i
];i
++);
332 * Appends one string to another with limited size
333 * @param src1 First string
334 * @param src2 Second string, it will be appended to src1
335 * @param n Maximal bytes to append
337 char *strncat(char *src1
,const char *src2
,size_t n
) {
338 size_t src2len
= strlen(src2
);
339 src2len
= n
<src2len
?n
:src2len
;
340 size_t src1len
= strlen(src1
);
343 for (i
=0;i
<src2len
;i
++) {
344 src1
[src1len
+i
] = src2
[i
];
346 src1
[src1len
+src2len
] = 0;
351 * Compares to strings until end of string or n bytes
352 * @param str1 String 1
353 * @param str2 String 2
354 * @param n How many bytes to compare maximum
355 * @return 0 if strings are equal
357 int strncmp(const char *str1
,const char *str2
,size_t n
) {
358 if (str1
==str2
) return 0;
361 for (i
=0;(str1
[i
] || str2
[i
]) && i
<n
;i
++) {
362 if (str1
[i
]!=str2
[i
]) return str1
[i
]-str2
[i
];
368 * Copies string, but maximal n bytes
369 * @param dest Destination to copy to
370 * @param src Source to copy from
371 * @param n How many bytes to copy maximal
374 char *strncpy(char *dest
,const char *src
,size_t n
) {
375 size_t len
= strlen(src
)+1;
377 memcpy(dest
,src
,len
-1);
382 static size_t __strxspn(const char *s
, const char *map
, int parity
)
384 char matchmap
[UCHAR_MAX
+ 1];
388 memset(matchmap
, 0, sizeof matchmap
);
390 matchmap
[(unsigned char)*map
++] = 1;
392 /* Make sure the null character never matches */
393 matchmap
[0] = parity
;
395 /* Calculate span length */
396 while (matchmap
[(unsigned char)*s
++] ^ parity
)
402 char *strpbrk(const char *s
, const char *accept
)
404 const char *ss
= s
+ __strxspn(s
, accept
, 1);
406 return *ss
? (char *)ss
: NULL
;
409 char *strsep(char **stringp
, const char *delim
)
417 e
= strpbrk(s
, delim
);
425 char *strtok(char *s
, const char *delim
)
433 s
= strsep(&holder
, delim
);
440 static inline int digitval(int ch
) {
441 if (ch
>='0' && ch
<='9') return ch
-'0';
442 else if (ch
>='A' && ch
<='Z') return ch
-'A'+10;
443 else if (ch
>='a' && ch
<='z') return ch
-'a'+10;
447 uintmax_t strntoumax(const char *nptr
, char **endptr
, int base
, size_t n
) {
452 while (n
&& isspace((unsigned char)*nptr
)) {
457 /* Single optional + or - */
460 if (c
=='-' || c
=='+') {
468 if (n
>=2 && nptr
[0]=='0' && (nptr
[1]=='x' || nptr
[1]=='X')) {
473 else if (n
>= 1 && nptr
[0] == '0') {
481 if (n
>=2 && nptr
[0]=='0' && (nptr
[1]=='x' || nptr
[1]=='X')) {
487 while (n
&& (d
= digitval(*nptr
))>=0 && d
<base
) {
494 *endptr
= (char*)nptr
;
499 intmax_t strntoimax(const char *nptr
,char **endptr
,int base
,size_t n
) {
500 return (intmax_t) strntoumax(nptr
,endptr
,base
,n
);
503 uintmax_t strtoumax(const char *nptr
,char **endptr
,int base
) {
504 return (uintmax_t)strntoumax(nptr
,endptr
,base
,~(size_t)0);
507 intmax_t strtoimax(const char *nptr
,char **endptr
,int base
) {
508 return (intmax_t)strntoumax(nptr
,endptr
,base
,~(size_t)0);
511 char *strrchr(const char *s
, int c
) {
515 if (s
[i
]==c
) l
= (char*)s
+i
;
520 static size_t strxspn(const char *s
,const char *map
,int parity
) {
521 char matchmap
[UCHAR_MAX
+1];
525 memset(matchmap
,0,sizeof matchmap
);
526 while (*map
) matchmap
[(unsigned char)*map
++] = 1;
528 /* Make sure the null character never matches */
529 matchmap
[0] = parity
;
531 /* Calculate span length */
532 while (matchmap
[(unsigned char)*s
++]^parity
) n
++;
537 size_t strspn(const char *s
,const char *accept
) {
538 return strxspn(s
,accept
,0);
541 size_t strcspn(const char *s
,const char *reject
) {
542 return strxspn(s
,reject
,1);
545 void *mempcpy(void *dest
,const void *src
,size_t n
) {
550 char *stpcpy(char *dest
,const char *src
) {
552 for (i
=0;src
[i
]!=0;i
++) {
558 void *memmem(const void *haystack
,size_t n
,const void *needle
,size_t m
) {
559 const unsigned char *y
= (const unsigned char*)haystack
;
560 const unsigned char *x
= (const unsigned char*)needle
;
563 if (m
>n
|| !m
|| !n
) return NULL
;
577 if (x
[1] != y
[j
+ 1]) j
+= k
;
579 if (!memcmp(x
+2,y
+j
+2,m
-2) && x
[0]==y
[j
]) return (void *)&y
[j
];
586 if (*y
== *x
) return (void *)y
;
593 char *strstr(const char *haystack
,const char *needle
) {
594 return (char*)memmem(haystack
,strlen(haystack
),needle
,strlen(needle
));
597 void memswap(void *m1
,void *m2
,size_t n
) {