Changes in uspace/lib/c/generic/stdlib.c [c718bda:7d7bc09] in mainline
- File:
-
- 1 edited
-
uspace/lib/c/generic/stdlib.c (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/stdlib.c
rc718bda r7d7bc09 1 1 /* 2 2 * Copyright (c) 2006 Ondrej Palkovsky 3 * Copyright (c) 2018 Jiri Svoboda 3 4 * All rights reserved. 4 5 * … … 33 34 */ 34 35 36 #include <adt/list.h> 37 #include <fibril_synch.h> 35 38 #include <stdlib.h> 39 #include "private/libc.h" 40 #include "private/stdlib.h" 36 41 37 42 static int glbl_seed = 1; 38 43 44 static LIST_INITIALIZE(exit_handlers); 45 static FIBRIL_MUTEX_INITIALIZE(exit_handlers_lock); 46 47 static LIST_INITIALIZE(quick_exit_handlers); 48 static FIBRIL_MUTEX_INITIALIZE(quick_exit_handlers_lock); 49 50 39 51 int rand(void) 40 52 { … … 47 59 } 48 60 61 /** Register exit handler. 62 * 63 * @param func Function to be called during program terimnation 64 * @return Zero on success, nonzero on failure 65 */ 66 int atexit(void (*func)(void)) 67 { 68 __exit_handler_t *entry; 69 70 entry = malloc(sizeof(__exit_handler_t)); 71 if (entry == NULL) 72 return -1; 73 74 entry->func = func; 75 76 fibril_mutex_lock(&exit_handlers_lock); 77 list_prepend(&entry->llist, &exit_handlers); 78 fibril_mutex_unlock(&exit_handlers_lock); 79 return 0; 80 } 81 82 /** Terminate program with exit status. 83 * 84 * @param status Exit status 85 */ 86 void exit(int status) 87 { 88 link_t *link; 89 __exit_handler_t *eh; 90 91 /* Call exit handlers */ 92 fibril_mutex_lock(&exit_handlers_lock); 93 while (!list_empty(&exit_handlers)) { 94 link = list_first(&exit_handlers); 95 list_remove(link); 96 fibril_mutex_unlock(&exit_handlers_lock); 97 98 eh = list_get_instance(link, __exit_handler_t, llist); 99 eh->func(); 100 free(eh); 101 fibril_mutex_lock(&exit_handlers_lock); 102 } 103 104 fibril_mutex_unlock(&exit_handlers_lock); 105 106 _Exit(status); 107 } 108 109 /** Register quick exit handler. 110 * 111 * @param func Function to be called during quick program terimnation 112 * @return Zero on success, nonzero on failure 113 */ 114 int at_quick_exit(void (*func)(void)) 115 { 116 __exit_handler_t *entry; 117 118 entry = malloc(sizeof(__exit_handler_t)); 119 if (entry == NULL) 120 return -1; 121 122 entry->func = func; 123 124 fibril_mutex_lock(&exit_handlers_lock); 125 list_prepend(&entry->llist, &exit_handlers); 126 fibril_mutex_unlock(&exit_handlers_lock); 127 return 0; 128 } 129 130 /** Quickly terminate program with exit status. 131 * 132 * @param status Exit status 133 */ 134 void quick_exit(int status) 135 { 136 link_t *link; 137 __exit_handler_t *eh; 138 139 /* Call quick exit handlers */ 140 fibril_mutex_lock(&quick_exit_handlers_lock); 141 while (!list_empty(&quick_exit_handlers)) { 142 link = list_first(&quick_exit_handlers); 143 list_remove(link); 144 fibril_mutex_unlock(&quick_exit_handlers_lock); 145 146 eh = list_get_instance(link, __exit_handler_t, llist); 147 eh->func(); 148 free(eh); 149 fibril_mutex_lock(&quick_exit_handlers_lock); 150 } 151 152 fibril_mutex_unlock(&quick_exit_handlers_lock); 153 154 _Exit(status); 155 } 156 157 void _Exit(int status) 158 { 159 __libc_exit(status); 160 } 161 162 /** Abnormal program termination */ 163 void abort(void) 164 { 165 __libc_abort(); 166 } 167 168 /** Get environment list entry. 169 * 170 * Note that this function is not reentrant. The returned string is only 171 * guaranteed to be valid until the next call to @c getenv. 172 * 173 * @param name Entry name 174 * @return Pointer to string or @c NULL if not found 175 */ 176 char *getenv(const char *name) 177 { 178 (void) name; 179 return NULL; 180 } 181 182 /** Execute command. 183 * 184 * @param string Command to execute or @c NULL 185 * 186 * @return If @a string is @c NULL, return zero (no command processor 187 * available). If @a string is not @c NULL, return 1 (failure). 188 */ 189 int system(const char *string) 190 { 191 if (string == NULL) 192 return 0; 193 194 return 1; 195 } 196 197 /** Compute the absolute value of an integer. 198 * 199 * If the result cannot be represented, the behavior is undefined. 200 * 201 * @param j Integer 202 * @return The absolute value of @a j 203 */ 204 int abs(int j) 205 { 206 int aj; 207 208 if (j < 0) { 209 aj = -j; 210 assert(aj >= 0); 211 } else { 212 aj = j; 213 } 214 215 return aj; 216 } 217 218 /** Compute the absolute value of a long integer. 219 * 220 * If the result cannot be represented, the behavior is undefined. 221 * 222 * @param j Long integer 223 * @return The absolute value of @a j 224 */ 225 long labs(long j) 226 { 227 long aj; 228 229 if (j < 0) { 230 aj = -j; 231 assert(aj >= 0); 232 } else { 233 aj = j; 234 } 235 236 return aj; 237 } 238 239 /** Compute the absolute value of a long long integer. 240 * 241 * If the result cannot be represented, the behavior is undefined. 242 * 243 * @param j Long long integer 244 * @return The absolute value of @a j 245 */ 246 long long llabs(long long j) 247 { 248 long long aj; 249 250 if (j < 0) { 251 aj = -j; 252 assert(aj >= 0); 253 } else { 254 aj = j; 255 } 256 257 return aj; 258 } 259 260 /** Compute quotient and remainder of int division. 261 * 262 * @param numer Numerator 263 * @param denom Denominator 264 * @return Structure containing quotient and remainder 265 */ 266 div_t div(int numer, int denom) 267 { 268 div_t d; 269 270 d.quot = numer / denom; 271 d.rem = numer % denom; 272 273 return d; 274 } 275 276 /** Compute quotient and remainder of long division. 277 * 278 * @param numer Numerator 279 * @param denom Denominator 280 * @return Structure containing quotient and remainder 281 */ 282 ldiv_t ldiv(long numer, long denom) 283 { 284 ldiv_t d; 285 286 d.quot = numer / denom; 287 d.rem = numer % denom; 288 289 return d; 290 } 291 292 /** Compute quotient and remainder of long long division. 293 * 294 * @param numer Numerator 295 * @param denom Denominator 296 * @return Structure containing quotient and remainder 297 */ 298 lldiv_t lldiv(long long numer, long long denom) 299 { 300 lldiv_t d; 301 302 d.quot = numer / denom; 303 d.rem = numer % denom; 304 305 return d; 306 } 307 49 308 /** @} 50 309 */
Note:
See TracChangeset
for help on using the changeset viewer.
