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 | |
initial check-in, version 0.5.0v0.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; +} | 
