mirror of
https://github.com/EnderIce2/Fennix.git
synced 2025-05-30 00:07:59 +00:00
300 lines
6.8 KiB
C
300 lines
6.8 KiB
C
/*
|
|
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 <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 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 *);
|
|
export int chown(const char *, uid_t, gid_t);
|
|
|
|
export int close(int fildes)
|
|
{
|
|
return __check_errno(call_close(fildes), -1);
|
|
}
|
|
|
|
export size_t confstr(int, char *, size_t);
|
|
export char *crypt(const char *, const char *);
|
|
export char *ctermid(char *);
|
|
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 *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)
|
|
{
|
|
return __check_errno(call_fork(), -1);
|
|
}
|
|
|
|
export long int fpathconf(int, int);
|
|
export int fsync(int);
|
|
export int ftruncate(int, off_t);
|
|
export char *getcwd(char *, size_t);
|
|
export int getdtablesize(void);
|
|
export gid_t getegid(void);
|
|
export uid_t geteuid(void);
|
|
export gid_t getgid(void);
|
|
export int getgroups(int, gid_t[]);
|
|
export long gethostid(void);
|
|
|
|
export int gethostname(char *name, size_t namelen)
|
|
{
|
|
if (namelen == 0)
|
|
{
|
|
errno = EINVAL;
|
|
return -1;
|
|
}
|
|
|
|
strncpy(name, "localhost", namelen);
|
|
if (namelen < strlen("localhost") + 1)
|
|
{
|
|
errno = ENAMETOOLONG;
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
export char *getlogin(void);
|
|
export int getlogin_r(char *, size_t);
|
|
export int getopt(int, char *const[], const char *);
|
|
|
|
export int getpagesize(void) { return 0x1000; } /* TODO: getpagesize */
|
|
|
|
export char *getpass(const char *);
|
|
export pid_t getpgid(pid_t);
|
|
export pid_t getpgrp(void);
|
|
|
|
export pid_t getpid(void) { return syscall0(SYS_GETPID); }
|
|
export pid_t getppid(void) { return syscall0(SYS_GETPPID); }
|
|
|
|
export pid_t getsid(pid_t);
|
|
export uid_t getuid(void);
|
|
export char *getwd(char *);
|
|
export int isatty(int);
|
|
export int lchown(const char *, uid_t, gid_t);
|
|
export int link(const char *, const char *);
|
|
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)
|
|
{
|
|
printf("pause() is unimplemented\n");
|
|
return __check_errno(-ENOSYS, -1);
|
|
}
|
|
|
|
export int pipe(int[2]);
|
|
|
|
export ssize_t pread(int fildes, void *buf, size_t nbyte, off_t offset)
|
|
{
|
|
return __check_errno(call_pread(fildes, buf, nbyte, offset), -1);
|
|
}
|
|
|
|
export int pthread_atfork(void (*)(void), void (*)(void), void (*)(void));
|
|
|
|
export ssize_t pwrite(int fildes, const void *buf, size_t nbyte, off_t offset)
|
|
{
|
|
return __check_errno(call_pwrite(fildes, buf, nbyte, offset), -1);
|
|
}
|
|
|
|
export ssize_t read(int fildes, void *buf, size_t nbyte)
|
|
{
|
|
return __check_errno(call_read(fildes, buf, nbyte), -1);
|
|
}
|
|
|
|
export int readlink(const char *, char *, size_t);
|
|
export int rmdir(const char *);
|
|
export void *sbrk(intptr_t);
|
|
export int setgid(gid_t);
|
|
export int setpgid(pid_t, pid_t);
|
|
export pid_t setpgrp(void);
|
|
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 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)
|
|
{
|
|
printf("sync() is unimplemented\n");
|
|
}
|
|
|
|
export long int sysconf(int);
|
|
export pid_t tcgetpgrp(int);
|
|
export int tcsetpgrp(int, pid_t);
|
|
export int truncate(const char *, off_t);
|
|
export char *ttyname(int);
|
|
export int ttyname_r(int, char *, size_t);
|
|
export useconds_t ualarm(useconds_t, useconds_t);
|
|
export int unlink(const char *);
|
|
export int usleep(useconds_t);
|
|
export pid_t vfork(void);
|
|
|
|
export ssize_t write(int fildes, const void *buf, size_t nbyte)
|
|
{
|
|
return __check_errno(call_write(fildes, buf, nbyte), -1);
|
|
}
|