source: mainline/uspace/lib/posix/src/stdlib.c@ 1be7bee

Last change on this file since 1be7bee was 9b8be79, checked in by Jiří Zárevúcky <jiri.zarevucky@…>, 7 years ago

libposix: Change header organization and remove passthrough headers

Posix headers now function like an overlay. The system include directories
are searched after posix directories. The headers don't need to be patched
for export now. libposix files now include headers using bracket notation
instead of quoted notation.

  • Property mode set to 100644
File size: 6.3 KB
Line 
1/*
2 * Copyright (c) 2011 Petr Koupy
3 * Copyright (c) 2011 Jiri Zarevucky
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * - Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * - The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30/** @addtogroup libposix
31 * @{
32 */
33/** @file Standard library definitions.
34 */
35
36#include "internal/common.h"
37#include <stdlib.h>
38
39#include <errno.h>
40#include <tmpfile.h>
41
42#include <fcntl.h>
43#include <limits.h>
44#include <string.h>
45#include <sys/stat.h>
46#include <unistd.h>
47
48#include <qsort.h>
49#include <str.h>
50#include <vfs/vfs.h>
51#include <stats.h>
52
53/**
54 *
55 * @param name
56 * @param resolved
57 * @return
58 */
59int putenv(char *string)
60{
61 // TODO: low priority, just a compile-time dependency of binutils
62 not_implemented();
63 return 0;
64}
65
66/**
67 * Resolve absolute pathname.
68 *
69 * @param name Pathname to be resolved.
70 * @param resolved Either buffer for the resolved absolute pathname or NULL.
71 * @return On success, either resolved (if it was not NULL) or pointer to the
72 * newly allocated buffer containing the absolute pathname (if resolved was
73 * NULL). Otherwise NULL.
74 *
75 */
76char *realpath(const char *restrict name, char *restrict resolved)
77{
78#ifndef PATH_MAX
79 assert(resolved == NULL);
80#endif
81
82 if (name == NULL) {
83 errno = EINVAL;
84 return NULL;
85 }
86
87 // TODO: symlink resolution
88
89 /*
90 * Function absolutize is implemented in libc and declared in vfs.h.
91 * No more processing is required as HelenOS doesn't have symlinks
92 * so far (as far as I can tell), although this function will need
93 * to be updated when that support is implemented.
94 */
95 char *absolute = vfs_absolutize(name, NULL);
96
97 if (absolute == NULL) {
98 /*
99 * POSIX requires some specific errnos to be set
100 * for some cases, but there is no way to find out from
101 * absolutize().
102 */
103 errno = EINVAL;
104 return NULL;
105 }
106
107 if (resolved == NULL) {
108 return absolute;
109 } else {
110#ifdef PATH_MAX
111 str_cpy(resolved, PATH_MAX, absolute);
112#endif
113 free(absolute);
114 return resolved;
115 }
116}
117
118/**
119 * Converts a string representation of a floating-point number to
120 * its native representation. See strtold().
121 *
122 * @param nptr String representation of a floating-point number.
123 * @return Double-precision number resulting from the string conversion.
124 */
125double atof(const char *nptr)
126{
127 return strtod(nptr, NULL);
128}
129
130/**
131 * Converts a string representation of a floating-point number to
132 * its native representation. See strtold().
133 *
134 * @param nptr String representation of a floating-point number.
135 * @param endptr Pointer to the final part of the string which
136 * was not used for conversion.
137 * @return Single-precision number resulting from the string conversion.
138 */
139float strtof(const char *restrict nptr, char **restrict endptr)
140{
141 return (float) strtold(nptr, endptr);
142}
143
144/**
145 * Converts a string representation of a floating-point number to
146 * its native representation. See strtold().
147 *
148 * @param nptr String representation of a floating-point number.
149 * @param endptr Pointer to the final part of the string which
150 * was not used for conversion.
151 * @return Double-precision number resulting from the string conversion.
152 */
153double strtod(const char *restrict nptr, char **restrict endptr)
154{
155 return (double) strtold(nptr, endptr);
156}
157
158/**
159 * Creates and opens an unique temporary file from template.
160 *
161 * @param tmpl Template. Last six characters must be XXXXXX.
162 * @return The opened file descriptor or -1 on error.
163 */
164int mkstemp(char *tmpl)
165{
166 int tmpl_len;
167 int file;
168
169 tmpl_len = strlen(tmpl);
170 if (tmpl_len < 6) {
171 errno = EINVAL;
172 return -1;
173 }
174
175 char *tptr = tmpl + tmpl_len - 6;
176 if (strcmp(tptr, "XXXXXX") != 0) {
177 errno = EINVAL;
178 return -1;
179 }
180
181 file = __tmpfile_templ(tmpl, true);
182 if (file < 0) {
183 errno = EIO; // XXX could be more specific
184 return -1;
185 }
186
187 return file;
188}
189
190/**
191 * Creates an unique temporary file name from template.
192 *
193 * @param tmpl Template. Last six characters must be XXXXXX.
194 * @return The value of tmpl. The template is modified in place.
195 * If no temporary file name can be created, template is
196 * reduced to an empty string.
197 */
198char *mktemp(char *tmpl)
199{
200 int tmpl_len;
201 int rc;
202
203 tmpl_len = strlen(tmpl);
204 if (tmpl_len < 6) {
205 errno = EINVAL;
206 *tmpl = '\0';
207 return tmpl;
208 }
209
210 char *tptr = tmpl + tmpl_len - 6;
211 if (strcmp(tptr, "XXXXXX") != 0) {
212 errno = EINVAL;
213 *tmpl = '\0';
214 return tmpl;
215 }
216
217 rc = __tmpfile_templ(tmpl, false);
218 if (rc != 0) {
219 errno = EIO; // XXX could be more specific
220 *tmpl = '\0';
221 return tmpl;
222 }
223
224 return tmpl;
225}
226
227/**
228 * Get system load average statistics.
229 *
230 * @param loadavg Array where the load averages shall be placed.
231 * @param nelem Maximum number of elements to be placed into the array.
232 * @return Number of elements placed into the array on success, -1 otherwise.
233 */
234int bsd_getloadavg(double loadavg[], int nelem)
235{
236 assert(nelem > 0);
237
238 size_t count;
239 load_t *loads = stats_get_load(&count);
240
241 if (loads == NULL) {
242 return -1;
243 }
244
245 if (((size_t) nelem) < count) {
246 count = nelem;
247 }
248
249 for (size_t i = 0; i < count; ++i) {
250 loadavg[i] = (double) loads[i];
251 }
252
253 free(loads);
254 return count;
255}
256
257/** @}
258 */
Note: See TracBrowser for help on using the repository browser.