userspace/libc: implement std more functions

Signed-off-by: EnderIce2 <enderice2@protonmail.com>
This commit is contained in:
EnderIce2 2025-01-27 23:30:07 +02:00
parent f5a813380b
commit 2f71bccef2
No known key found for this signature in database
GPG Key ID: 2EE20AF089811A5A
15 changed files with 597 additions and 55 deletions

View File

@ -59,7 +59,7 @@ extern "C"
#define DT_TMO
int alphasort(const struct dirent **, const struct dirent **);
int closedir(DIR *);
int closedir(DIR *dirp);
int dirfd(DIR *);
DIR *fdopendir(int);
DIR *opendir(const char *);

View File

@ -23,6 +23,8 @@ extern "C"
{
#endif // __cplusplus
#include <sys/types.h>
typedef struct f_owner_ex
{
int type; /* Discriminator for pid. */

View File

@ -90,9 +90,9 @@ extern "C"
int feof(FILE *);
int ferror(FILE *);
int fflush(FILE *stream);
int fgetc(FILE *);
int fgetc(FILE *stream);
int fgetpos(FILE *restrict, fpos_t *restrict);
char *fgets(char *restrict, int, FILE *restrict);
char *fgets(char *restrict s, int n, FILE *restrict stream);
int fileno(FILE *);
void flockfile(FILE *);
FILE *fmemopen(void *restrict, size_t, const char *restrict);
@ -119,7 +119,7 @@ extern "C"
ssize_t getline(char **restrict, size_t *restrict, FILE *restrict);
FILE *open_memstream(char **, size_t *);
int pclose(FILE *);
void perror(const char *);
void perror(const char *s);
FILE *popen(const char *, const char *);
int printf(const char *restrict format, ...);
int putc(int c, FILE *stream);
@ -134,8 +134,8 @@ extern "C"
int scanf(const char *restrict, ...);
void setbuf(FILE *restrict, char *restrict);
int setvbuf(FILE *restrict, char *restrict, int, size_t);
int snprintf(char *restrict, size_t, const char *restrict, ...);
int sprintf(char *restrict, const char *restrict, ...);
int snprintf(char *restrict s, size_t n, const char *restrict format, ...);
int sprintf(char *restrict s, const char *restrict format, ...);
int sscanf(const char *restrict, const char *restrict, ...);
FILE *tmpfile(void);
char *tmpnam(char *);

View File

@ -51,7 +51,7 @@ extern "C"
long a64l(const char *);
void abort(void);
int abs(int);
int abs(int i);
int atexit(void (*func)(void));
double atof(const char *);
int atoi(const char *);
@ -66,7 +66,7 @@ extern "C"
char *fcvt(double, int, int *, int *);
void free(void *ptr);
char *gcvt(double, int, char *);
char *getenv(const char *);
char *getenv(const char *name);
int getsubopt(char **, char *const *, char **);
int grantpt(int);
char *initstate(unsigned int, char *, size_t);

View File

@ -36,7 +36,7 @@ extern "C"
char *stpcpy(char *restrict, const char *restrict);
char *stpncpy(char *restrict, const char *restrict, size_t);
char *strcat(char *restrict, const char *restrict);
char *strchr(const char *, int);
char *strchr(const char *s, int c);
int strcmp(const char *s1, const char *s2);
int strcoll(const char *, const char *);
int strcoll_l(const char *, const char *, locale_t);
@ -48,19 +48,19 @@ extern "C"
int strerror_r(int, char *, size_t);
size_t strlcat(char *restrict, const char *restrict, size_t);
size_t strlcpy(char *restrict, const char *restrict, size_t);
size_t strlen(const char *);
size_t strlen(const char *s);
char *strncat(char *restrict, const char *restrict, size_t);
int strncmp(const char *, const char *, size_t);
int strncmp(const char *s1, const char *s2, size_t n);
char *strncpy(char *restrict, const char *restrict, size_t);
char *strndup(const char *, size_t);
size_t strnlen(const char *, size_t);
char *strpbrk(const char *, const char *);
char *strpbrk(const char *s1, const char *s2);
char *strrchr(const char *, int);
char *strsignal(int);
size_t strspn(const char *, const char *);
char *strsignal(int signum);
size_t strspn(const char *s1, const char *s2);
char *strstr(const char *, const char *);
char *strtok(char *restrict, const char *restrict);
char *strtok_r(char *restrict, const char *restrict, char **restrict);
char *strtok(char *restrict s, const char *restrict sep);
char *strtok_r(char *restrict s, const char *restrict sep, char **restrict state);
size_t strxfrm(char *restrict, const char *restrict, size_t);
size_t strxfrm_l(char *restrict, const char *restrict, size_t, locale_t);

View File

@ -91,8 +91,8 @@ extern "C"
int fstatat(int, const char *restrict, struct stat *restrict, int);
int futimens(int, const struct timespec[2]);
int lstat(const char *restrict, struct stat *restrict);
int mkdir(const char *, mode_t);
int mkdirat(int, const char *, mode_t);
int mkdir(const char *path, mode_t mode);
int mkdirat(int fd, const char *path, mode_t mode);
int mkfifo(const char *, mode_t);
int mkfifoat(int, const char *, mode_t);
int mknod(const char *, mode_t, dev_t);

View File

@ -54,9 +54,9 @@ extern "C"
typedef unsigned int id_t;
typedef int pid_t;
pid_t wait(int *);
int waitid(idtype_t, id_t, siginfo_t *, int);
pid_t waitpid(pid_t, int *, int);
pid_t wait(int *stat_loc);
int waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options);
pid_t waitpid(pid_t pid, int *stat_loc, int options);
#ifdef __cplusplus
}

View File

@ -57,9 +57,10 @@ extern "C"
extern char *optarg;
extern int optind, opterr, optopt;
extern char **environ;
int access(const char *, int);
unsigned int alarm(unsigned int);
unsigned int alarm(unsigned int seconds);
int brk(void *);
int chdir(const char *);
int chroot(const char *);
@ -72,12 +73,12 @@ extern "C"
int dup(int);
int dup2(int, int);
void encrypt(char[64], int);
int execl(const char *, const char *, ...);
int execle(const char *, const char *, ...);
int execlp(const char *, const char *, ...);
int execv(const char *, char *const[]);
int execve(const char *, char *const[], char *const[]);
int execvp(const char *, char *const[]);
int execl(const char *path, const char *arg0, ... /*, (char *)0 */);
int execle(const char *path, const char *arg0, ... /*, (char *)0, char *const envp[]*/);
int execlp(const char *file, const char *arg0, ... /*, (char *)0 */);
int execv(const char *path, char *const argv[]);
int execve(const char *path, char *const argv[], char *const envp[]);
int execvp(const char *file, char *const argv[]);
void _exit(int);
int fchown(int, uid_t, gid_t);
int fchdir(int);
@ -128,7 +129,7 @@ extern "C"
int setreuid(uid_t, uid_t);
pid_t setsid(void);
int setuid(uid_t);
unsigned int sleep(unsigned int);
unsigned int sleep(unsigned int seconds);
void swab(const void *, void *, ssize_t);
int symlink(const char *, const char *);
void sync(void);

View File

@ -0,0 +1,57 @@
/*
This file is part of Fennix C Library.
Fennix C Library is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix C Library. If not, see <https://www.gnu.org/licenses/>.
*/
#include <dirent.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
export int alphasort(const struct dirent **, const struct dirent **);
export int closedir(DIR *dirp)
{
if (!dirp)
{
errno = EBADF;
return -1;
}
int fd = dirfd(dirp);
if (fd == -1)
{
errno = EBADF;
return -1;
}
int result = close(fd);
if (result == -1)
return -1;
free(dirp);
return 0;
}
export int dirfd(DIR *);
export DIR *fdopendir(int);
export DIR *opendir(const char *);
export ssize_t posix_getdents(int, void *, size_t, int);
export struct dirent *readdir(DIR *);
export int readdir_r(DIR *restrict, struct dirent *restrict, struct dirent **restrict);
export void rewinddir(DIR *);
export int scandir(const char *, struct dirent ***, int (*)(const struct dirent *), int (*)(const struct dirent **, const struct dirent **));
export void seekdir(DIR *, long);
export long telldir(DIR *);

View File

@ -18,6 +18,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fennix/syscalls.h>
#include "../print/printf.h"
@ -109,9 +110,54 @@ export int fflush(FILE *stream)
return 0;
}
export int fgetc(FILE *);
export int fgetc(FILE *stream)
{
if (!stream || !(stream->flags & _i_READ))
return EOF;
if (stream->buffer_pos >= stream->buffer_size)
{
int res = call_read(stream->fd, stream->buffer, 4096);
if (res <= 0)
{
if (res == 0)
stream->eof = 1;
else
stream->error = 1;
return EOF;
}
stream->buffer_pos = 0;
stream->buffer_size = res;
}
return (unsigned char)stream->buffer[stream->buffer_pos++];
}
export int fgetpos(FILE *restrict, fpos_t *restrict);
export char *fgets(char *restrict, int, FILE *restrict);
export char *fgets(char *restrict s, int n, FILE *restrict stream)
{
if (!s || n <= 0 || !stream)
return NULL;
int i = 0;
while (i < n - 1)
{
int c = fgetc(stream);
if (c == EOF)
{
if (i == 0)
return NULL;
break;
}
s[i++] = (char)c;
if (c == '\n')
break;
}
s[i] = '\0';
return s;
}
export int fileno(FILE *);
export void flockfile(FILE *);
export FILE *fmemopen(void *restrict, size_t, const char *restrict);
@ -302,7 +348,15 @@ export ssize_t getdelim(char **restrict, size_t *restrict, int, FILE *restrict);
export ssize_t getline(char **restrict, size_t *restrict, FILE *restrict);
export FILE *open_memstream(char **, size_t *);
export int pclose(FILE *);
export void perror(const char *);
export void perror(const char *s)
{
fputs(s, stderr);
fputs(": ", stderr);
fputs(strerror(errno), stderr);
fputc('\n', stderr);
}
export FILE *popen(const char *, const char *);
export int printf(const char *restrict format, ...)
@ -327,8 +381,25 @@ export void rewind(FILE *);
export int scanf(const char *restrict, ...);
export void setbuf(FILE *restrict, char *restrict);
export int setvbuf(FILE *restrict, char *restrict, int, size_t);
export int snprintf(char *restrict, size_t, const char *restrict, ...);
export int sprintf(char *restrict, const char *restrict, ...);
export int snprintf(char *restrict s, size_t n, const char *restrict format, ...)
{
va_list args;
va_start(args, format);
int ret = vsnprintf_(s, n, format, args);
va_end(args);
return ret;
}
export int sprintf(char *restrict s, const char *restrict format, ...)
{
va_list args;
va_start(args, format);
int ret = vsprintf_(s, format, args);
va_end(args);
return ret;
}
export int sscanf(const char *restrict, const char *restrict, ...);
export FILE *tmpfile(void);
export char *tmpnam(char *);

View File

@ -17,6 +17,7 @@
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "../mem/liballoc_1_1.h"
#define MAX_ATEXIT_FUNCS 32
@ -31,7 +32,10 @@ export _Noreturn void abort(void)
__builtin_unreachable();
}
export int abs(int);
export int abs(int i)
{
return (i < 0) ? -i : i;
}
export int atexit(void (*func)(void))
{
@ -62,7 +66,18 @@ export void exit(int status)
export char *fcvt(double, int, int *, int *);
export void free(void *ptr) { return PREFIX(free)(ptr); }
export char *gcvt(double, int, char *);
export char *getenv(const char *);
export char *getenv(const char *name)
{
for (char **env = environ; *env != 0; ++env)
{
char *thisEnv = *env;
if (strncmp(thisEnv, name, strlen(name)) == 0 && thisEnv[strlen(name)] == '=')
return thisEnv + strlen(name) + 1;
}
return NULL;
}
export int getsubopt(char **, char *const *, char **);
export int grantpt(int);
export char *initstate(unsigned int, char *, size_t);

View File

@ -17,6 +17,7 @@
#include <sys/types.h>
#include <string.h>
#include <fennix/syscalls.h>
export void *memccpy(void *restrict, const void *restrict, int, size_t);
export void *memchr(const void *, int, size_t);
@ -46,7 +47,19 @@ export void *memset(void *, int, size_t);
export char *stpcpy(char *restrict, const char *restrict);
export char *stpncpy(char *restrict, const char *restrict, size_t);
export char *strcat(char *restrict, const char *restrict);
export char *strchr(const char *, int);
export char *strchr(const char *s, int c)
{
while (*s)
{
if (*s == (char)c)
return (char *)s;
s++;
}
if (c == '\0')
return (char *)s;
return NULL;
}
export int strcmp(const char *s1, const char *s2)
{
@ -69,18 +82,171 @@ export char *strerror_l(int, locale_t);
export int strerror_r(int, char *, size_t);
export size_t strlcat(char *restrict, const char *restrict, size_t);
export size_t strlcpy(char *restrict, const char *restrict, size_t);
export size_t strlen(const char *);
export size_t strlen(const char *s)
{
const char *start = s;
while (*s)
s++;
return s - start;
}
export char *strncat(char *restrict, const char *restrict, size_t);
export int strncmp(const char *, const char *, size_t);
export int strncmp(const char *s1, const char *s2, size_t n)
{
while (n--)
{
if (*s1 != *s2)
return *(unsigned char *)s1 - *(unsigned char *)s2;
if (*s1 == '\0')
return 0;
s1++;
s2++;
}
return 0;
}
export char *strncpy(char *restrict, const char *restrict, size_t);
export char *strndup(const char *, size_t);
export size_t strnlen(const char *, size_t);
export char *strpbrk(const char *, const char *);
export char *strpbrk(const char *s1, const char *s2)
{
while (*s1)
{
const char *s = s2;
while (*s)
{
if (*s1 == *s)
return (char *)s1;
s++;
}
s1++;
}
return NULL;
}
export char *strrchr(const char *, int);
export char *strsignal(int);
export size_t strspn(const char *, const char *);
export char *strsignal(int signum)
{
switch (signum)
{
case __SYS_SIGNULL:
return "NULL signal";
case __SYS_SIGABRT:
return "Aborted";
case __SYS_SIGALRM:
return "Alarm clock";
case __SYS_SIGBUS:
return "Bus error";
case __SYS_SIGCHLD:
return "Child status changed";
case __SYS_SIGCONT:
return "Continued";
case __SYS_SIGFPE:
return "Arithmetic exception";
case __SYS_SIGHUP:
return "Hangup";
case __SYS_SIGILL:
return "Illegal instruction";
case __SYS_SIGINT:
return "Interrupt";
case __SYS_SIGKILL:
return "Killed";
case __SYS_SIGPIPE:
return "Broken pipe";
case __SYS_SIGQUIT:
return "Quit";
case __SYS_SIGSEGV:
return "Segmentation fault";
case __SYS_SIGSTOP:
return "Stopped (signal)";
case __SYS_SIGTERM:
return "Terminated";
case __SYS_SIGTSTP:
return "Stopped (user)";
case __SYS_SIGTTIN:
return "Stopped (tty input)";
case __SYS_SIGTTOU:
return "Stopped (tty output)";
case __SYS_SIGUSR1:
return "User defined signal 1";
case __SYS_SIGUSR2:
return "User defined signal 2";
case __SYS_SIGPOLL:
return "Pollable event occurred";
case __SYS_SIGPROF:
return "Profiling timer expired";
case __SYS_SIGSYS:
return "Bad system call";
case __SYS_SIGTRAP:
return "Trace/breakpoint trap";
case __SYS_SIGURG:
return "Urgent I/O condition";
case __SYS_SIGVTALRM:
return "Virtual timer expired";
case __SYS_SIGXCPU:
return "CPU time limit exceeded";
case __SYS_SIGXFSZ:
return "File size limit exceeded";
default:
return NULL;
}
}
export size_t strspn(const char *s1, const char *s2)
{
const char *p = s1;
const char *spanp;
char c, sc;
cont:
c = *p++;
for (spanp = s2; (sc = *spanp++) != 0;)
{
if (sc == c)
goto cont;
}
return p - 1 - s1;
}
export char *strstr(const char *, const char *);
export char *strtok(char *restrict, const char *restrict);
export char *strtok_r(char *restrict, const char *restrict, char **restrict);
export char *strtok(char *restrict s, const char *restrict sep)
{
static char *last;
return strtok_r(s, sep, &last);
}
export char *strtok_r(char *restrict s, const char *restrict sep, char **restrict state)
{
char *start;
char *end;
if (s == NULL)
s = *state;
s += strspn(s, sep);
if (*s == '\0')
{
*state = s;
return NULL;
}
start = s;
end = strpbrk(start, sep);
if (end)
{
*end = '\0';
*state = end + 1;
}
else
*state = start + strlen(start);
return start;
}
export size_t strxfrm(char *restrict, const char *restrict, size_t);
export size_t strxfrm_l(char *restrict, const char *restrict, size_t, locale_t);

View File

@ -0,0 +1,47 @@
/*
This file is part of Fennix C Library.
Fennix C Library is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix C Library. If not, see <https://www.gnu.org/licenses/>.
*/
#include <sys/stat.h>
#include <errno.h>
#include <stdio.h>
export int chmod(const char *, mode_t);
export int fchmod(int, mode_t);
export int fchmodat(int, const char *, mode_t, int);
export int fstat(int, struct stat *);
export int fstatat(int, const char *restrict, struct stat *restrict, int);
export int futimens(int, const struct timespec[2]);
export int lstat(const char *restrict, struct stat *restrict);
export int mkdir(const char *path, mode_t mode)
{
return __check_errno(call_mkdir(path, mode), -1);
}
export int mkdirat(int fd, const char *path, mode_t mode)
{
printf("mkdirat() is unimplemented\n");
return __check_errno(-ENOSYS, -1);
}
export int mkfifo(const char *, mode_t);
export int mkfifoat(int, const char *, mode_t);
export int mknod(const char *, mode_t, dev_t);
export int mknodat(int, const char *, mode_t, dev_t);
export int stat(const char *restrict, struct stat *restrict);
export mode_t umask(mode_t);
export int utimensat(int, const char *, const struct timespec[2], int);

View File

@ -0,0 +1,38 @@
/*
This file is part of Fennix C Library.
Fennix C Library is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix C Library. If not, see <https://www.gnu.org/licenses/>.
*/
#include <sys/wait.h>
#include <fennix/syscalls.h>
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
export pid_t wait(int *stat_loc)
{
return waitpid((pid_t)-1, stat_loc, 0);
}
export int waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options)
{
printf("waitid() is unimplemented\n");
return __check_errno(-ENOSYS, -1);
}
export pid_t waitpid(pid_t pid, int *stat_loc, int options)
{
return __check_errno(call_waitpid(pid, stat_loc, options), -1);
}

View File

@ -16,13 +16,26 @@
*/
#include <unistd.h>
#include <stdarg.h>
#include <errno.h>
#include <stdlib.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <fennix/syscalls.h>
export char *optarg;
export int optind, opterr, optopt;
export char **environ;
export int access(const char *, int);
export unsigned int alarm(unsigned int);
export unsigned int alarm(unsigned int seconds)
{
printf("alarm() is unimplemented\n");
return __check_errno(-ENOSYS, -1);
}
export int brk(void *);
export int chdir(const char *);
export int chroot(const char *);
@ -35,17 +48,122 @@ export char *cuserid(char *s);
export int dup(int);
export int dup2(int, int);
export void encrypt(char[64], int);
export int execl(const char *, const char *, ...);
export int execle(const char *, const char *, ...);
export int execlp(const char *, const char *, ...);
export int execv(const char *, char *const[]);
export int execve(const char *, char *const[], char *const[]);
export int execvp(const char *, char *const[]);
export int execl(const char *path, const char *arg0, ...)
{
va_list args;
va_start(args, arg0);
int argc = 1;
while (va_arg(args, const char *))
argc++;
va_end(args);
char *argv[argc + 1];
va_start(args, arg0);
argv[0] = (char *)arg0;
for (int i = 1; i < argc; i++)
argv[i] = va_arg(args, char *);
argv[argc] = NULL;
va_end(args);
return execve(path, argv, environ);
}
export int execle(const char *path, const char *arg0, ...)
{
va_list args;
va_start(args, arg0);
int argc = 1;
while (va_arg(args, const char *))
argc++;
va_end(args);
char *argv[argc + 1];
va_start(args, arg0);
argv[0] = (char *)arg0;
for (int i = 1; i < argc; i++)
argv[i] = va_arg(args, char *);
argv[argc] = NULL;
char *const *envp = va_arg(args, char *const *);
va_end(args);
return execve(path, argv, envp);
}
export int execlp(const char *file, const char *arg0, ...)
{
va_list args;
va_start(args, arg0);
int argc = 1;
while (va_arg(args, const char *))
argc++;
va_end(args);
char *argv[argc + 1];
va_start(args, arg0);
argv[0] = (char *)arg0;
for (int i = 1; i < argc; i++)
argv[i] = va_arg(args, char *);
argv[argc] = NULL;
va_end(args);
return execvp(file, argv);
}
export int execv(const char *path, char *const argv[])
{
return execve(path, argv, environ);
}
export int execve(const char *path, char *const argv[], char *const envp[])
{
return __check_errno(call_execve(path, argv, envp), -1);
}
export int execvp(const char *file, char *const argv[])
{
if (strchr(file, '/'))
return execve(file, argv, environ);
char *path = getenv("PATH");
if (!path)
{
errno = ENOENT;
return -1;
}
char *p = strtok(path, ":");
while (p)
{
char fullpath[PATH_MAX];
snprintf(fullpath, sizeof(fullpath), "%s/%s", p, file);
execve(fullpath, argv, environ);
if (errno != ENOENT && errno != ENOTDIR)
return -1;
p = strtok(NULL, ":");
}
errno = ENOENT;
return -1;
}
export void _exit(int);
export int fchown(int, uid_t, gid_t);
export int fchdir(int);
export int fdatasync(int);
export pid_t fork(void);
export pid_t fork(void)
{
return __check_errno(call_fork(), -1);
}
export long int fpathconf(int, int);
export int fsync(int);
export int ftruncate(int, off_t);
@ -79,7 +197,13 @@ export int lockf(int, int, off_t);
export off_t lseek(int, off_t, int);
export int nice(int);
export long int pathconf(const char *, int);
export int pause(void);
export int pause(void)
{
printf("pause() is unimplemented\n");
return __check_errno(-ENOSYS, -1);
}
export int pipe(int[2]);
export ssize_t pread(int, void *, size_t, off_t);
export int pthread_atfork(void (*)(void), void (*)(void), void (*)(void));
@ -95,10 +219,31 @@ export int setregid(gid_t, gid_t);
export int setreuid(uid_t, uid_t);
export pid_t setsid(void);
export int setuid(uid_t);
export unsigned int sleep(unsigned int);
export unsigned int sleep(unsigned int seconds)
{
unsigned int unslept = alarm(0); /* Cancel any existing alarm */
if (unslept > 0)
{
alarm(unslept); /* Restore the previous alarm if it was set */
return unslept;
}
alarm(seconds); /* Set the alarm for the requested sleep time */
pause(); /* Suspend execution until a signal is received */
unslept = alarm(0); /* Cancel the alarm and get the remaining time */
return unslept;
}
export void swab(const void *, void *, ssize_t);
export int symlink(const char *, const char *);
export void sync(void);
export void sync(void)
{
printf("sync() is unimplemented\n");
}
export long int sysconf(int);
export pid_t tcgetpgrp(int);
export int tcsetpgrp(int, pid_t);