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

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