source: mainline/uspace/lib/posix/src/unistd.c@ a35b458

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since a35b458 was 1b20da0, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 7 years ago

style: Remove trailing whitespace on non-empty lines, in certain file types.

Command used: tools/srepl '\([^[:space:]]\)\s\+$' '\1' -- *.c *.h *.py *.sh *.s *.S *.ag

  • Property mode set to 100644
File size: 10.3 KB
Line 
1/*
2 * Copyright (c) 2011 Jiri Zarevucky
3 * Copyright (c) 2011 Petr Koupy
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 Miscellaneous standard definitions.
34 */
35
36#include "internal/common.h"
37#include "posix/unistd.h"
38
39#include <errno.h>
40
41#include "posix/string.h"
42#include "posix/fcntl.h"
43
44#include "libc/task.h"
45#include "libc/thread.h"
46#include "libc/stats.h"
47#include "libc/malloc.h"
48#include "libc/vfs/vfs.h"
49
50#include <libarch/config.h>
51
52// FIXME: replace with a hash table
53aoff64_t posix_pos[MAX_OPEN_FILES];
54
55/* Array of environment variable strings (NAME=VALUE). */
56char **environ = NULL;
57
58/**
59 * Sleep for the specified number of seconds.
60 *
61 * Note that POSIX allows this call to be interrupted and then the return
62 * value represents remaining seconds for the sleep. HelenOS does not offer
63 * such functionality and thus always the whole sleep is taken.
64 *
65 * @param seconds Number of seconds to sleep.
66 * @return Always 0 on HelenOS.
67 */
68unsigned int sleep(unsigned int seconds)
69{
70 return thread_sleep(seconds);
71}
72
73/**
74 * Get current user name.
75 *
76 * @return User name (static) string or NULL if not found.
77 */
78char *getlogin(void)
79{
80 /* There is currently no support for user accounts in HelenOS. */
81 return (char *) "user";
82}
83
84/**
85 * Get current user name.
86 *
87 * @param name Pointer to a user supplied buffer.
88 * @param namesize Length of the buffer.
89 * @return Zero on success, error code otherwise.
90 */
91int getlogin_r(char *name, size_t namesize)
92{
93 /* There is currently no support for user accounts in HelenOS. */
94 if (namesize >= 5) {
95 strcpy(name, (char *) "user");
96 return 0;
97 } else {
98 errno = ERANGE;
99 return -1;
100 }
101}
102
103/**
104 * Test whether open file descriptor is associated with a terminal.
105 *
106 * @param fd Open file descriptor to test.
107 * @return Boolean result of the test.
108 */
109int isatty(int fd)
110{
111 // TODO
112 /* Always returns false, because there is no easy way to find
113 * out under HelenOS. */
114 return 0;
115}
116
117/**
118 * Get the pathname of the current working directory.
119 *
120 * @param buf Buffer into which the pathname shall be put.
121 * @param size Size of the buffer.
122 * @return Buffer pointer on success, NULL on failure.
123 */
124char *getcwd(char *buf, size_t size)
125{
126 if (failed(vfs_cwd_get(buf, size)))
127 return NULL;
128 return buf;
129}
130
131/**
132 * Change the current working directory.
133 *
134 * @param path New working directory.
135 */
136int chdir(const char *path)
137{
138 if (failed(vfs_cwd_set(path)))
139 return -1;
140 return 0;
141}
142
143/**
144 * Determine the page size of the current run of the process.
145 *
146 * @return Page size of the process.
147 */
148int getpagesize(void)
149{
150 return PAGE_SIZE;
151}
152
153/**
154 * Get the process ID of the calling process.
155 *
156 * @return Process ID.
157 */
158pid_t getpid(void)
159{
160 return task_get_id();
161}
162
163/**
164 * Get the real user ID of the calling process.
165 *
166 * @return User ID.
167 */
168uid_t getuid(void)
169{
170 /* There is currently no support for user accounts in HelenOS. */
171 return 0;
172}
173
174/**
175 * Get the real group ID of the calling process.
176 *
177 * @return Group ID.
178 */
179gid_t getgid(void)
180{
181 /* There is currently no support for user accounts in HelenOS. */
182 return 0;
183}
184
185/**
186 * Close a file.
187 *
188 * @param fildes File descriptor of the opened file.
189 * @return 0 on success, -1 on error.
190 */
191int close(int fildes)
192{
193 posix_pos[fildes] = 0;
194 if (failed(vfs_put(fildes)))
195 return -1;
196 else
197 return 0;
198}
199
200/**
201 * Read from a file.
202 *
203 * @param fildes File descriptor of the opened file.
204 * @param buf Buffer to which the read bytes shall be stored.
205 * @param nbyte Upper limit on the number of read bytes.
206 * @return Number of read bytes on success, -1 otherwise.
207 */
208ssize_t read(int fildes, void *buf, size_t nbyte)
209{
210 size_t nread;
211 if (failed(vfs_read(fildes, &posix_pos[fildes], buf, nbyte, &nread)))
212 return -1;
213 return (ssize_t) nread;
214}
215
216/**
217 * Write to a file.
218 *
219 * @param fildes File descriptor of the opened file.
220 * @param buf Buffer to write.
221 * @param nbyte Size of the buffer.
222 * @return Number of written bytes on success, -1 otherwise.
223 */
224ssize_t write(int fildes, const void *buf, size_t nbyte)
225{
226 size_t nwr;
227 if (failed(vfs_write(fildes, &posix_pos[fildes], buf, nbyte, &nwr)))
228 return -1;
229 return nwr;
230}
231
232/**
233 * Reposition read/write file offset
234 *
235 * @param fildes File descriptor of the opened file.
236 * @param offset New offset in the file.
237 * @param whence The position from which the offset argument is specified.
238 * @return Upon successful completion, returns the resulting offset
239 * as measured in bytes from the beginning of the file, -1 otherwise.
240 */
241off_t lseek(int fildes, off_t offset, int whence)
242{
243 vfs_stat_t st;
244
245 switch (whence) {
246 case SEEK_SET:
247 posix_pos[fildes] = offset;
248 break;
249 case SEEK_CUR:
250 posix_pos[fildes] += offset;
251 break;
252 case SEEK_END:
253 if (failed(vfs_stat(fildes, &st)))
254 return -1;
255 posix_pos[fildes] = st.size + offset;
256 break;
257 }
258 if (posix_pos[fildes] > INT64_MAX) {
259 /* The native width is too large for the POSIX interface. */
260 errno = ERANGE;
261 return -1;
262 }
263 return posix_pos[fildes];
264}
265
266/**
267 * Requests outstanding data to be written to the underlying storage device.
268 *
269 * @param fildes File descriptor of the opened file.
270 * @return Zero on success, -1 otherwise.
271 */
272int fsync(int fildes)
273{
274 if (failed(vfs_sync(fildes)))
275 return -1;
276 else
277 return 0;
278}
279
280/**
281 * Truncate a file to a specified length.
282 *
283 * @param fildes File descriptor of the opened file.
284 * @param length New length of the file.
285 * @return Zero on success, -1 otherwise.
286 */
287int ftruncate(int fildes, off_t length)
288{
289 if (failed(vfs_resize(fildes, (aoff64_t) length)))
290 return -1;
291 else
292 return 0;
293}
294
295/**
296 * Remove a directory.
297 *
298 * @param path Directory pathname.
299 * @return Zero on success, -1 otherwise.
300 */
301int rmdir(const char *path)
302{
303 if (failed(vfs_unlink_path(path)))
304 return -1;
305 else
306 return 0;
307}
308
309/**
310 * Remove a link to a file.
311 *
312 * @param path File pathname.
313 * @return Zero on success, -1 otherwise.
314 */
315int unlink(const char *path)
316{
317 if (failed(vfs_unlink_path(path)))
318 return -1;
319 else
320 return 0;
321}
322
323/**
324 * Duplicate an open file descriptor.
325 *
326 * @param fildes File descriptor to be duplicated.
327 * @return On success, new file descriptor for the same file, otherwise -1.
328 */
329int dup(int fildes)
330{
331 return fcntl(fildes, F_DUPFD, 0);
332}
333
334/**
335 * Duplicate an open file descriptor.
336 *
337 * @param fildes File descriptor to be duplicated.
338 * @param fildes2 File descriptor to be paired with the same file description
339 * as is paired fildes.
340 * @return fildes2 on success, -1 otherwise.
341 */
342int dup2(int fildes, int fildes2)
343{
344 int file;
345 if (failed(vfs_clone(fildes, fildes2, false, &file))) {
346 return -1;
347 }
348 return file;
349}
350
351/**
352 * Determine accessibility of a file.
353 *
354 * @param path File to check accessibility for.
355 * @param amode Either check for existence or intended access mode.
356 * @return Zero on success, -1 otherwise.
357 */
358int access(const char *path, int amode)
359{
360 if (amode == F_OK || (amode & (X_OK | W_OK | R_OK))) {
361 /* HelenOS doesn't support permissions, permission checks
362 * are equal to existence check.
363 *
364 * Check file existence by attempting to open it.
365 */
366 int fd = open(path, O_RDONLY);
367 if (fd < 0)
368 return -1;
369 close(fd);
370 return 0;
371 } else {
372 /* Invalid amode argument. */
373 errno = EINVAL;
374 return -1;
375 }
376}
377
378/**
379 * Get configurable system variables.
380 *
381 * @param name Variable name.
382 * @return Variable value.
383 */
384long sysconf(int name)
385{
386 long clk_tck = 0;
387 size_t cpu_count = 0;
388 stats_cpu_t *cpu_stats = stats_get_cpus(&cpu_count);
389 if (cpu_stats && cpu_count > 0) {
390 clk_tck = ((long) cpu_stats[0].frequency_mhz) * 1000000L;
391 }
392 if (cpu_stats) {
393 free(cpu_stats);
394 cpu_stats = 0;
395 }
396
397 long phys_pages = 0;
398 long avphys_pages = 0;
399 stats_physmem_t *mem_stats = stats_get_physmem();
400 if (mem_stats) {
401 phys_pages = (long) (mem_stats->total / getpagesize());
402 avphys_pages = (long) (mem_stats->free / getpagesize());
403 free(mem_stats);
404 mem_stats = 0;
405 }
406
407 switch (name) {
408 case _SC_PHYS_PAGES:
409 return phys_pages;
410 case _SC_AVPHYS_PAGES:
411 return avphys_pages;
412 case _SC_PAGESIZE:
413 return getpagesize();
414 case _SC_CLK_TCK:
415 return clk_tck;
416 default:
417 errno = EINVAL;
418 return -1;
419 }
420}
421
422/**
423 *
424 * @param path
425 * @param name
426 * @return
427 */
428long pathconf(const char *path, int name)
429{
430 // TODO: low priority, just a compile-time dependency of binutils
431 not_implemented();
432 return -1;
433}
434
435/**
436 *
437 * @return
438 */
439pid_t fork(void)
440{
441 // TODO: low priority, just a compile-time dependency of binutils
442 not_implemented();
443 return -1;
444}
445
446/**
447 *
448 * @param path
449 * @param argv
450 * @return
451 */
452int execv(const char *path, char *const argv[])
453{
454 // TODO: low priority, just a compile-time dependency of binutils
455 not_implemented();
456 return -1;
457}
458
459/**
460 *
461 * @param file
462 * @param argv
463 * @return
464 */
465int execvp(const char *file, char *const argv[])
466{
467 // TODO: low priority, just a compile-time dependency of binutils
468 not_implemented();
469 return -1;
470}
471
472/**
473 *
474 * @param fildes
475 * @return
476 */
477int pipe(int fildes[2])
478{
479 // TODO: low priority, just a compile-time dependency of binutils
480 not_implemented();
481 return -1;
482}
483
484unsigned int alarm(unsigned int seconds)
485{
486 not_implemented();
487 return 0;
488}
489
490/** @}
491 */
Note: See TracBrowser for help on using the repository browser.