diff options
author | Rich Felker <dalias@aerifal.cx> | 2011-02-12 00:22:29 -0500 |
---|---|---|
committer | Rich Felker <dalias@aerifal.cx> | 2011-02-12 00:22:29 -0500 |
commit | 0b44a0315b47dd8eced9f3b7f31580cf14bbfc01 (patch) | |
tree | 6eaef0d8a720fa3da580de87b647fff796fe80b3 /src/linux | |
download | musl-0b44a0315b47dd8eced9f3b7f31580cf14bbfc01.tar.gz musl-0b44a0315b47dd8eced9f3b7f31580cf14bbfc01.tar.xz musl-0b44a0315b47dd8eced9f3b7f31580cf14bbfc01.zip |
initial check-in, version 0.5.0 v0.5.0
Diffstat (limited to 'src/linux')
34 files changed, 438 insertions, 0 deletions
diff --git a/src/linux/brk.c b/src/linux/brk.c new file mode 100644 index 00000000..3c2982c6 --- /dev/null +++ b/src/linux/brk.c @@ -0,0 +1,6 @@ +#include "syscall.h" + +int brk(void *end) +{ + return -(syscall1(__NR_brk, (long)end) == -1); +} diff --git a/src/linux/chroot.c b/src/linux/chroot.c new file mode 100644 index 00000000..b5af62dc --- /dev/null +++ b/src/linux/chroot.c @@ -0,0 +1,8 @@ +#include <unistd.h> +#define SYSCALL_STANDALONE +#include "syscall.h" + +int chroot(const char *path) +{ + return syscall1(__NR_chroot, (long)path); +} diff --git a/src/linux/daemon.c b/src/linux/daemon.c new file mode 100644 index 00000000..632d1203 --- /dev/null +++ b/src/linux/daemon.c @@ -0,0 +1,31 @@ +#include <fcntl.h> +#include <unistd.h> + +int daemon(int nochdir, int noclose) +{ + int fd; + + switch(fork()) { + case 0: break; + case -1: return -1; + default: _exit(0); + } + + if (setsid() < 0) return -1; + + switch(fork()) { + case 0: break; + case -1: return -1; + default: _exit(0); + } + + if (!nochdir) chdir("/"); + if (!noclose && (fd = open("/dev/null", O_RDWR)) >= 0) { + dup2(fd, 0); + dup2(fd, 1); + dup2(fd, 2); + if (fd > 2) close(fd); + } + + return 0; +} diff --git a/src/linux/epoll_create.c b/src/linux/epoll_create.c new file mode 100644 index 00000000..c9dea8ce --- /dev/null +++ b/src/linux/epoll_create.c @@ -0,0 +1,7 @@ +#include <sys/epoll.h> +#include "syscall.h" + +int epoll_create(int size) +{ + return syscall1(__NR_epoll_create, size); +} diff --git a/src/linux/epoll_create1.c b/src/linux/epoll_create1.c new file mode 100644 index 00000000..2e82e995 --- /dev/null +++ b/src/linux/epoll_create1.c @@ -0,0 +1,7 @@ +#include <sys/epoll.h> +#include "syscall.h" + +int epoll_create1(int flags) +{ + return syscall1(__NR_epoll_create1, flags); +} diff --git a/src/linux/epoll_ctl.c b/src/linux/epoll_ctl.c new file mode 100644 index 00000000..4214f407 --- /dev/null +++ b/src/linux/epoll_ctl.c @@ -0,0 +1,7 @@ +#include <sys/epoll.h> +#include "syscall.h" + +int epoll_ctl(int fd, int op, int fd2, struct epoll_event *ev) +{ + return syscall4(__NR_epoll_ctl, fd, op, fd2, (long)ev); +} diff --git a/src/linux/epoll_pwait.c b/src/linux/epoll_pwait.c new file mode 100644 index 00000000..5aaacba6 --- /dev/null +++ b/src/linux/epoll_pwait.c @@ -0,0 +1,7 @@ +#include <sys/epoll.h> +#include "syscall.h" + +int epoll_pwait(int fd, struct epoll_event *ev, int cnt, int to, const sigset_t *sigs) +{ + return syscall6(__NR_epoll_pwait, fd, (long)ev, cnt, to, (long)sigs, 8); +} diff --git a/src/linux/epoll_wait.c b/src/linux/epoll_wait.c new file mode 100644 index 00000000..8a68ebdd --- /dev/null +++ b/src/linux/epoll_wait.c @@ -0,0 +1,7 @@ +#include <sys/epoll.h> +#include "syscall.h" + +int epoll_wait(int fd, struct epoll_event *ev, int cnt, int to) +{ + return syscall4(__NR_epoll_wait, fd, (long)ev, cnt, to); +} diff --git a/src/linux/getdtablesize.c b/src/linux/getdtablesize.c new file mode 100644 index 00000000..623a6af3 --- /dev/null +++ b/src/linux/getdtablesize.c @@ -0,0 +1,9 @@ +#include <limits.h> +#include <sys/resource.h> + +int getdtablesize(void) +{ + struct rlimit rl; + getrlimit(RLIMIT_NOFILE, &rl); + return rl.rlim_max < INT_MAX ? rl.rlim_max : INT_MAX; +} diff --git a/src/linux/gethostid.c b/src/linux/gethostid.c new file mode 100644 index 00000000..ea65611a --- /dev/null +++ b/src/linux/gethostid.c @@ -0,0 +1,4 @@ +long gethostid() +{ + return 0; +} diff --git a/src/linux/getopt_long.c b/src/linux/getopt_long.c new file mode 100644 index 00000000..d80cd1b6 --- /dev/null +++ b/src/linux/getopt_long.c @@ -0,0 +1,52 @@ +#define _GNU_SOURCE +#include <stddef.h> +#include <getopt.h> +#include <stdio.h> + +static int __getopt_long(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx, int longonly) +{ + if (optind >= argc || !argv[optind] || argv[optind][0] != '-') return -1; + if ((longonly && argv[optind][1]) || + (argv[optind][1] == '-' && argv[optind][2])) + { + int i; + for (i=0; longopts[i].name; i++) { + const char *name = longopts[i].name; + char *opt = argv[optind]+1; + if (*opt == '-') opt++; + while (*name && *name++ == *opt++); + if (*name || (*opt && *opt != '=')) continue; + if (*opt == '=') { + if (!longopts[i].has_arg) continue; + optarg = opt+1; + } else { + if (longopts[i].has_arg == required_argument) { + if (!(optarg = argv[++optind])) + return ':'; + } else optarg = NULL; + } + optind++; + if (idx) *idx = i; + if (longopts[i].flag) { + *longopts[i].flag = longopts[i].val; + return 0; + } + return longopts[i].val; + } + if (argv[optind][1] == '-') { + optind++; + return '?'; + } + } + return getopt(argc, argv, optstring); +} + +int getopt_long(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx) +{ + return __getopt_long(argc, argv, optstring, longopts, idx, 0); +} + +int getopt_long_only(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx) +{ + return __getopt_long(argc, argv, optstring, longopts, idx, 1); +} diff --git a/src/linux/getpagesize.c b/src/linux/getpagesize.c new file mode 100644 index 00000000..5ede652b --- /dev/null +++ b/src/linux/getpagesize.c @@ -0,0 +1,7 @@ +#include <unistd.h> +#include <limits.h> + +int getpagesize(void) +{ + return PAGE_SIZE; +} diff --git a/src/linux/getpass.c b/src/linux/getpass.c new file mode 100644 index 00000000..d439a2a5 --- /dev/null +++ b/src/linux/getpass.c @@ -0,0 +1,39 @@ +#include <stdio.h> +#include <string.h> +#include <termios.h> +#include <unistd.h> +#include <fcntl.h> + +char *getpass(const char *prompt) +{ + int fd; + struct termios s, t; + ssize_t l; + static char password[128]; + + if ((fd = open("/dev/tty", O_RDONLY|O_NOCTTY)) < 0) fd = 0; + + tcgetattr(fd, &t); + s = t; + t.c_lflag &= ~(ECHO|ISIG); + t.c_lflag |= ICANON; + t.c_iflag &= ~(INLCR|IGNCR); + t.c_iflag |= ICRNL; + tcsetattr(fd, TCSAFLUSH, &t); + tcdrain(fd); + + fputs(prompt, stderr); + fflush(stderr); + + l = read(fd, password, sizeof password); + if (l >= 0) { + if (l > 0 && password[l-1] == '\n') l--; + password[l] = 0; + } + + tcsetattr(fd, TCSAFLUSH, &s); + + if (fd > 2) close(fd); + + return password; +} diff --git a/src/linux/initgroups.c b/src/linux/initgroups.c new file mode 100644 index 00000000..ef9bc10a --- /dev/null +++ b/src/linux/initgroups.c @@ -0,0 +1,15 @@ +#include <sys/types.h> +#include <unistd.h> +#include <grp.h> +#include <limits.h> + +int getgrouplist(const char *, gid_t, gid_t *, int *); +int setgroups(size_t, const gid_t *); + +int initgroups(const char *user, gid_t gid) +{ + gid_t groups[NGROUPS_MAX]; + int count; + if (getgrouplist(user, gid, groups, &count) < 0) return -1; + return setgroups(count, groups); +} diff --git a/src/linux/klogctl.c b/src/linux/klogctl.c new file mode 100644 index 00000000..6c288aff --- /dev/null +++ b/src/linux/klogctl.c @@ -0,0 +1,7 @@ +#define SYSCALL_STANDALONE +#include "syscall.h" + +int klogctl (int type, char *buf, int len) +{ + return syscall3(__NR_syslog, type, (long)buf, len); +} diff --git a/src/linux/mntent.c b/src/linux/mntent.c new file mode 100644 index 00000000..e3735666 --- /dev/null +++ b/src/linux/mntent.c @@ -0,0 +1,57 @@ +#include <stdio.h> +#include <string.h> +#include <mntent.h> + +FILE *setmntent(const char *name, const char *mode) +{ + return fopen(name, mode); +} + +int endmntent(FILE *f) +{ + fclose(f); + return 1; +} + +struct mntent *getmntent(FILE *f) +{ + static char linebuf[256]; + static struct mntent mnt; + int cnt, n[8]; + + mnt.mnt_freq = 0; + mnt.mnt_passno = 0; + + do { + fgets(linebuf, sizeof linebuf, f); + if (feof(f)) return NULL; + cnt = sscanf(linebuf, " %n%*s%n %n%*s%n %n%*s%n %n%*s%n %d %d", + n, n+1, n+2, n+3, n+4, n+5, n+6, n+7, + &mnt.mnt_freq, &mnt.mnt_passno); + } while (cnt >= 8 && linebuf[n[0]] != '#'); + + linebuf[n[1]] = 0; + linebuf[n[3]] = 0; + linebuf[n[5]] = 0; + linebuf[n[7]] = 0; + + mnt.mnt_fsname = linebuf+n[0]; + mnt.mnt_dir = linebuf+n[2]; + mnt.mnt_type = linebuf+n[4]; + mnt.mnt_opts = linebuf+n[6]; + + return &mnt; +} + +int addmntent(FILE *f, const struct mntent *mnt) +{ + fseek(f, 0, SEEK_END); + return fprintf(f, "%s\t%s\t%s\t%s\t%d\t%d\n", + mnt->mnt_fsname, mnt->mnt_dir, mnt->mnt_type, mnt->mnt_opts, + mnt->mnt_freq, mnt->mnt_passno) < 0; +} + +char *hasmntopt(const struct mntent *mnt, const char *opt) +{ + return strstr(mnt->mnt_opts, opt); +} diff --git a/src/linux/mount.c b/src/linux/mount.c new file mode 100644 index 00000000..61299d48 --- /dev/null +++ b/src/linux/mount.c @@ -0,0 +1,8 @@ +#include <sys/mount.h> +#define SYSCALL_STANDALONE +#include "syscall.h" + +int mount(const char *special, const char *dir, const char *fstype, unsigned long flags, const void *data) +{ + return syscall5(__NR_mount, (long)special, (long)dir, (long)fstype, flags, (long)data); +} diff --git a/src/linux/prctl.c b/src/linux/prctl.c new file mode 100644 index 00000000..d5516830 --- /dev/null +++ b/src/linux/prctl.c @@ -0,0 +1,13 @@ +#include <sys/prctl.h> +#include <stdarg.h> +#include "syscall.h" + +int prctl(int op, ...) +{ + unsigned long x[4]; + int i; + va_list ap; + va_start(ap, op); + for (i=0; i<4; i++) x[i] = va_arg(ap, unsigned long); + return syscall5(__NR_prctl, op, x[0], x[1], x[2], x[3]); +} diff --git a/src/linux/reboot.c b/src/linux/reboot.c new file mode 100644 index 00000000..68830d8e --- /dev/null +++ b/src/linux/reboot.c @@ -0,0 +1,8 @@ +#include <sys/reboot.h> +#include <errno.h> + +int reboot(int type) +{ + errno = ENOSYS; + return -1; +} diff --git a/src/linux/sbrk.c b/src/linux/sbrk.c new file mode 100644 index 00000000..56f60d1b --- /dev/null +++ b/src/linux/sbrk.c @@ -0,0 +1,7 @@ +#include <stddef.h> +#include "syscall.h" + +void *sbrk(ptrdiff_t inc) +{ + return (void *)syscall1(__NR_brk, syscall1(__NR_brk, 0)+inc); +} diff --git a/src/linux/sendfile.c b/src/linux/sendfile.c new file mode 100644 index 00000000..bfbc40ae --- /dev/null +++ b/src/linux/sendfile.c @@ -0,0 +1,10 @@ +#include <unistd.h> +#include "syscall.h" +#include "libc.h" + +ssize_t sendfile(int out_fd, int in_fd, off_t *ofs, size_t count) +{ + return syscall4(__NR_sendfile, out_fd, in_fd, (long)ofs, count); +} + +LFS64(sendfile); diff --git a/src/linux/setgroups.c b/src/linux/setgroups.c new file mode 100644 index 00000000..2368aa0d --- /dev/null +++ b/src/linux/setgroups.c @@ -0,0 +1,9 @@ +#include <unistd.h> +#define SYSCALL_STANDALONE +#include "syscall.h" + +int setgroups(int count, const gid_t list[]) +{ + /* this depends on our gid_t being 32bit */ + return syscall2(__NR_setgroups32, count, (long)list); +} diff --git a/src/linux/sethostname.c b/src/linux/sethostname.c new file mode 100644 index 00000000..f61e0cb4 --- /dev/null +++ b/src/linux/sethostname.c @@ -0,0 +1,8 @@ +#include <unistd.h> +#define SYSCALL_STANDALONE +#include "syscall.h" + +int sethostname(const char *name, size_t len) +{ + return syscall2(__NR_sethostname, (long)name, len); +} diff --git a/src/linux/settimeofday.c b/src/linux/settimeofday.c new file mode 100644 index 00000000..bd7e4104 --- /dev/null +++ b/src/linux/settimeofday.c @@ -0,0 +1,7 @@ +#include <sys/time.h> +#include "syscall.h" + +int settimeofday(const struct timeval *tv, void *tz) +{ + return syscall2(__NR_settimeofday, (long)tv, 0); +} diff --git a/src/linux/signalfd.c b/src/linux/signalfd.c new file mode 100644 index 00000000..ecda263e --- /dev/null +++ b/src/linux/signalfd.c @@ -0,0 +1,7 @@ +#include <sys/signalfd.h> +#include "syscall.h" + +int signalfd(int fd, const sigset_t *sigs, int flags) +{ + return syscall3(__NR_signalfd, fd, (long)sigs, 8); +} diff --git a/src/linux/stime.c b/src/linux/stime.c new file mode 100644 index 00000000..ec3ba821 --- /dev/null +++ b/src/linux/stime.c @@ -0,0 +1,7 @@ +#include <sys/time.h> + +int stime(time_t *t) +{ + struct timeval tv = { .tv_sec = *t, .tv_usec = 0 }; + return settimeofday(&tv, (void *)0); +} diff --git a/src/linux/swapoff.c b/src/linux/swapoff.c new file mode 100644 index 00000000..f6fa794e --- /dev/null +++ b/src/linux/swapoff.c @@ -0,0 +1,8 @@ +#include <sys/swap.h> +#define SYSCALL_STANDALONE +#include "syscall.h" + +int swapoff(const char *path) +{ + return syscall1(__NR_swapoff, (long)path); +} diff --git a/src/linux/swapon.c b/src/linux/swapon.c new file mode 100644 index 00000000..13d2876b --- /dev/null +++ b/src/linux/swapon.c @@ -0,0 +1,8 @@ +#include <sys/swap.h> +#define SYSCALL_STANDALONE +#include "syscall.h" + +int swapon(const char *path, int flags) +{ + return syscall2(__NR_swapon, (long)path, flags); +} diff --git a/src/linux/sysinfo.c b/src/linux/sysinfo.c new file mode 100644 index 00000000..98669472 --- /dev/null +++ b/src/linux/sysinfo.c @@ -0,0 +1,9 @@ +#define SYSCALL_STANDALONE +#include "syscall.h" + +struct sysinfo; + +int sysinfo(struct sysinfo *info) +{ + return syscall1(__NR_sysinfo, (long)info); +} diff --git a/src/linux/umount.c b/src/linux/umount.c new file mode 100644 index 00000000..c35f994d --- /dev/null +++ b/src/linux/umount.c @@ -0,0 +1,8 @@ +#include <sys/mount.h> +#define SYSCALL_STANDALONE +#include "syscall.h" + +int umount(const char *special) +{ + return syscall1(__NR_umount, (long)special); +} diff --git a/src/linux/umount2.c b/src/linux/umount2.c new file mode 100644 index 00000000..cab93fd0 --- /dev/null +++ b/src/linux/umount2.c @@ -0,0 +1,8 @@ +#include <sys/mount.h> +#define SYSCALL_STANDALONE +#include "syscall.h" + +int umount2(const char *special, int flags) +{ + return syscall2(__NR_umount2, (long)special, flags); +} diff --git a/src/linux/utimes.c b/src/linux/utimes.c new file mode 100644 index 00000000..99a3b2b8 --- /dev/null +++ b/src/linux/utimes.c @@ -0,0 +1,13 @@ +#include <sys/time.h> +#define SYSCALL_STANDALONE +#include "syscall.h" + +int utimes(const char *path, const struct timeval times[2]) +{ + long ktimes[2]; + if (times) { + ktimes[0] = times[0].tv_sec; + ktimes[1] = times[1].tv_sec; + } + return syscall2(__NR_utime, (long)path, times ? (long)ktimes : 0); +} diff --git a/src/linux/wait3.c b/src/linux/wait3.c new file mode 100644 index 00000000..dd63707c --- /dev/null +++ b/src/linux/wait3.c @@ -0,0 +1,11 @@ +#include <sys/wait.h> +#include <sys/resource.h> +#define SYSCALL_STANDALONE +#include "syscall.h" + +pid_t wait4(pid_t, int *, int, struct rusage *); + +pid_t wait3(int *status, int options, struct rusage *usage) +{ + return wait4(-1, status, options, usage); +} diff --git a/src/linux/wait4.c b/src/linux/wait4.c new file mode 100644 index 00000000..dda942d3 --- /dev/null +++ b/src/linux/wait4.c @@ -0,0 +1,19 @@ +#include <sys/wait.h> +#include <sys/resource.h> +#include <string.h> +#define SYSCALL_STANDALONE +#include "syscall.h" + +pid_t wait4(pid_t pid, int *status, int options, struct rusage *usage) +{ + pid_t ret = syscall4(__NR_wait4, pid, (long)status, options, (long)usage); + /* Fixup kernel time_t... */ + if (usage) { + long kusage[4]; + memcpy(kusage, usage, sizeof kusage); + memmove((struct timeval *)usage + 2, (long *)usage + 4, sizeof *usage - 2*sizeof(struct timeval)); + usage->ru_utime = (struct timeval){ kusage[0], kusage[1] }; + usage->ru_stime = (struct timeval){ kusage[2], kusage[3] }; + } + return ret; +} |