mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-27 14:58:30 +00:00
Initial import
This commit is contained in:
commit
c91b3c5006
14915 changed files with 590219 additions and 0 deletions
56
libc/calls/atfork.c
Normal file
56
libc/calls/atfork.c
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/runtime/internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
static struct AtFork {
|
||||
size_t i;
|
||||
struct AtForkCallback {
|
||||
void (*fn)(void *);
|
||||
void *arg;
|
||||
} p[ATEXIT_MAX];
|
||||
} g_atfork;
|
||||
|
||||
/**
|
||||
* Registers function to be called when PID changes.
|
||||
*
|
||||
* @return 0 on success, or -1 w/ errno
|
||||
*/
|
||||
int atfork(void *fn, void *arg) {
|
||||
if (g_atfork.i == ARRAYLEN(g_atfork.p)) return enomem();
|
||||
g_atfork.p[g_atfork.i++] = (struct AtForkCallback){.fn = fn, .arg = arg};
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggers atfork() callbacks.
|
||||
*
|
||||
* Only fork() should call this.
|
||||
*/
|
||||
void __onfork(void) {
|
||||
size_t i;
|
||||
for (i = 0; i < g_atfork.i; ++i) {
|
||||
g_atfork.p[i].fn(g_atfork.p[i].arg);
|
||||
}
|
||||
}
|
292
libc/calls/calls.h
Normal file
292
libc/calls/calls.h
Normal file
|
@ -0,0 +1,292 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_CALLS_SYSCALLS_H_
|
||||
#define COSMOPOLITAN_LIBC_CALLS_SYSCALLS_H_
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
#include "libc/calls/typedef/sighandler_t.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/fmt/pflink.h"
|
||||
#include "libc/sysv/consts/s.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
|
||||
#define EOF -1 /* end of file */
|
||||
#define WEOF -1u /* end of file (multibyte) */
|
||||
#define _IOFBF 0 /* fully buffered */
|
||||
#define _IOLBF 1 /* line buffered */
|
||||
#define _IONBF 2 /* no buffering */
|
||||
#define SEEK_SET 0 /* relative to beginning */
|
||||
#define SEEK_CUR 1 /* relative to current position */
|
||||
#define SEEK_END 2 /* relative to end */
|
||||
|
||||
#define SIG_ERR ((void (*)(int))(-1))
|
||||
#define SIG_DFL ((void *)0)
|
||||
#define SIG_IGN ((void *)1)
|
||||
|
||||
#define MAP_FAILED ((void *)__SIZE_MAX__)
|
||||
|
||||
#define ARCH_SET_GS 0x1001
|
||||
#define ARCH_SET_FS 0x1002
|
||||
#define ARCH_GET_FS 0x1003
|
||||
#define ARCH_GET_GS 0x1004
|
||||
|
||||
#define MAP_HUGE_2MB (21 << MAP_HUGE_SHIFT)
|
||||
#define MAP_HUGE_1GB (30 << MAP_HUGE_SHIFT)
|
||||
|
||||
#define S_ISDIR(mode) (((mode)&S_IFMT) == S_IFDIR)
|
||||
#define S_ISCHR(mode) (((mode)&S_IFMT) == S_IFCHR)
|
||||
#define S_ISBLK(mode) (((mode)&S_IFMT) == S_IFBLK)
|
||||
#define S_ISREG(mode) (((mode)&S_IFMT) == S_IFREG)
|
||||
#define S_ISFIFO(mode) (((mode)&S_IFMT) == S_IFIFO)
|
||||
#define S_ISLNK(mode) (((mode)&S_IFMT) == S_IFLNK)
|
||||
#define S_ISSOCK(mode) (((mode)&S_IFMT) == S_IFSOCK)
|
||||
|
||||
#define WCOREDUMP(s) ((s)&0x80)
|
||||
#define WEXITSTATUS(s) (((s)&0xff00) >> 8)
|
||||
#define WIFCONTINUED(s) ((s) == 0xffff)
|
||||
#define WIFEXITED(s) (!WTERMSIG(s))
|
||||
#define WIFSIGNALED(s) (((s)&0xffff) - 1U < 0xffu)
|
||||
#define WIFSTOPPED(s) ((short)((((s)&0xffff) * 0x10001) >> 8) > 0x7f00)
|
||||
#define WSTOPSIG(s) WEXITSTATUS(s)
|
||||
#define WTERMSIG(s) ((s)&0x7f)
|
||||
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
/*───────────────────────────────────────────────────────────────────────────│─╗
|
||||
│ cosmopolitan § system calls ─╬─│┼
|
||||
╚────────────────────────────────────────────────────────────────────────────│*/
|
||||
|
||||
struct dirstream;
|
||||
struct iovec;
|
||||
struct rlimit;
|
||||
struct rusage;
|
||||
struct sigaction;
|
||||
struct siginfo;
|
||||
struct sigset;
|
||||
struct stat;
|
||||
struct sysinfo;
|
||||
struct tms;
|
||||
struct ucontext;
|
||||
struct utsname;
|
||||
|
||||
typedef int sig_atomic_t;
|
||||
typedef struct dirstream DIR;
|
||||
|
||||
extern const struct sigset kSigsetFull;
|
||||
extern const struct sigset kSigsetEmpty;
|
||||
|
||||
DIR *fdopendir(int) nodiscard;
|
||||
DIR *opendir(const char *) nodiscard;
|
||||
bool fileexists(const char *);
|
||||
bool isdirectory(const char *);
|
||||
bool isexecutable(const char *);
|
||||
bool isregularfile(const char *);
|
||||
bool32 isatty(int) nosideeffect;
|
||||
bool32 ischardev(int) nosideeffect;
|
||||
char *get_current_dir_name(void) nodiscard;
|
||||
char *getcwd(char *, size_t) paramsnonnull();
|
||||
char *realpath(const char *, char *);
|
||||
char *replaceuser(const char *) nodiscard;
|
||||
char *slurp(const char *, size_t *) nodiscard;
|
||||
char *ttyname(int);
|
||||
const char *commandv(const char *);
|
||||
int access(const char *, int) nothrow paramsnonnull();
|
||||
int arch_prctl();
|
||||
int chdir(const char *) paramsnonnull();
|
||||
int chmod(const char *, uint32_t);
|
||||
int chown(const char *, uint32_t, uint32_t) paramsnonnull();
|
||||
int close(int);
|
||||
int closedir(DIR *);
|
||||
int copyfile(const char *, const char *, bool);
|
||||
int creat(const char *, uint32_t) nodiscard;
|
||||
int dirfd(DIR *);
|
||||
int dup(int) nodiscard;
|
||||
int dup2(int, int);
|
||||
int dup3(int, int, int);
|
||||
int execl(const char *, const char *, ...) nullterminated();
|
||||
int execle(const char *, const char *, ...) nullterminated((1));
|
||||
int execlp(const char *, const char *, ...) nullterminated();
|
||||
int execv(const char *, char *const[]) paramsnonnull();
|
||||
int execve(const char *, char *const[], char *const[]) paramsnonnull();
|
||||
int execvp(const char *, char *const[]) paramsnonnull();
|
||||
int execvpe(const char *, char *const[], char *const[]) paramsnonnull();
|
||||
int faccessat(int, const char *, int, uint32_t);
|
||||
int fadvise(int, uint64_t, uint64_t, int);
|
||||
int fallocate(int, int32_t, int64_t, int64_t);
|
||||
int fchmod(int, uint32_t) nothrow;
|
||||
int fchmodat(int, const char *, uint32_t, uint32_t);
|
||||
int fchown(int, uint32_t, uint32_t);
|
||||
int fchownat(int, const char *, uint32_t, uint32_t, uint32_t);
|
||||
int fcntl();
|
||||
int fdatasync(int);
|
||||
int filecmp(const char *, const char *);
|
||||
int flock(int, int);
|
||||
int fork(void);
|
||||
int fstat(int, struct stat *) paramsnonnull();
|
||||
int fstatat(int, const char *, struct stat *, uint32_t);
|
||||
int fsync(int);
|
||||
int ftruncate(int, int64_t);
|
||||
int getppid(void);
|
||||
int getpriority(int, unsigned);
|
||||
int getrlimit(int, struct rlimit *);
|
||||
int getrusage(int, struct rusage *);
|
||||
int kill(int, int);
|
||||
int killpg(int, int);
|
||||
int link(const char *, const char *) nothrow;
|
||||
int linkat(int, const char *, int, const char *, uint32_t);
|
||||
int lstat(const char *, struct stat *) paramsnonnull();
|
||||
int madvise(void *, uint64_t, int);
|
||||
int mkdir(const char *, uint32_t);
|
||||
int mkdirat(int, const char *, uint32_t);
|
||||
int mkfifo(const char *, uint32_t);
|
||||
int mknod(const char *, uint32_t, uint64_t);
|
||||
int mknodat(int, const char *, int32_t, uint64_t);
|
||||
int mlock(const void *, size_t);
|
||||
int mlock2(const void *, size_t, int);
|
||||
int mlockall(int);
|
||||
int mprotect(void *, uint64_t, int) paramsnonnull() privileged;
|
||||
int msync(void *, size_t, int);
|
||||
int munlock(const void *, size_t);
|
||||
int munlockall(void);
|
||||
int munmap(void *, uint64_t);
|
||||
int munmap_s(void *, uint64_t);
|
||||
int nice(int);
|
||||
int open(const char *, int, ...) nodiscard;
|
||||
int openanon(char *, unsigned) nodiscard;
|
||||
int openat();
|
||||
int pause(void);
|
||||
int personality(uint64_t);
|
||||
int pipe(int[hasatleast 2]) paramsnonnull() nodiscard;
|
||||
int pipe2(int[hasatleast 2], int) paramsnonnull() nodiscard;
|
||||
int posix_fadvise(int, uint64_t, uint64_t, int);
|
||||
int posix_fallocate(int, int64_t, int64_t);
|
||||
int posix_madvise(void *, uint64_t, int);
|
||||
int raise(int);
|
||||
int readlink(const char *, char *, size_t);
|
||||
int remove(const char *);
|
||||
int rename(const char *, const char *);
|
||||
int renameat(int, const char *, int, const char *);
|
||||
int renameat2(long, const char *, long, const char *, int);
|
||||
int rmdir(const char *);
|
||||
int sched_getaffinity(int, uint64_t, void *);
|
||||
int sched_setaffinity(int, uint64_t, const void *);
|
||||
int sched_yield(void);
|
||||
int setpgid(int, int);
|
||||
int setpriority(int, unsigned, int);
|
||||
int setrlimit(int, const struct rlimit *);
|
||||
int setsid(void);
|
||||
int setuid(uint32_t);
|
||||
int setgid(uint32_t);
|
||||
int seteuid(uint32_t);
|
||||
int setegid(uint32_t);
|
||||
int setreuid(uint32_t, uint32_t);
|
||||
int setregid(uint32_t, uint32_t);
|
||||
int setresuid(uint32_t, uint32_t, uint32_t);
|
||||
int setresgid(uint32_t, uint32_t, uint32_t);
|
||||
int sigaction(int, const struct sigaction *, struct sigaction *);
|
||||
int sigignore(int);
|
||||
int sigprocmask(int, const struct sigset *, struct sigset *);
|
||||
int sigsuspend(const struct sigset *);
|
||||
int stat(const char *, struct stat *) paramsnonnull();
|
||||
int symlink(const char *, const char *);
|
||||
int symlinkat(const char *, int, const char *);
|
||||
int sync_file_range(int, int64_t, int64_t, unsigned);
|
||||
int sysinfo(struct sysinfo *) paramsnonnull();
|
||||
int touch(const char *, uint32_t);
|
||||
int truncate(const char *, uint64_t);
|
||||
int ttyname_r(int, char *, size_t);
|
||||
int uname(struct utsname *);
|
||||
int unlink(const char *);
|
||||
int unlink_s(const char **);
|
||||
int unlinkat(int, const char *, int);
|
||||
int vfork(void);
|
||||
int wait(int *);
|
||||
int wait3(int *, int, struct rusage *);
|
||||
int wait4(int, int *, int, struct rusage *);
|
||||
int waitpid(int, int *, int);
|
||||
int64_t lseek(int, int64_t, int);
|
||||
int64_t pread(int, void *, size_t, int64_t);
|
||||
int64_t preadv(int, struct iovec *, int, int64_t);
|
||||
int64_t pwrite(int, const void *, size_t, int64_t);
|
||||
int64_t pwritev(int, const struct iovec *, int, int64_t);
|
||||
int64_t syscall();
|
||||
long telldir(DIR *);
|
||||
int getpid(void);
|
||||
long times(struct tms *);
|
||||
sighandler_t signal(int, sighandler_t);
|
||||
size_t GetFileSize(const char *);
|
||||
size_t getfiledescriptorsize(int);
|
||||
ssize_t copy_file_range(int, long *, int, long *, size_t, uint32_t);
|
||||
ssize_t copyfd(int, int64_t *, int, int64_t *, size_t, uint32_t);
|
||||
ssize_t read(int, void *, size_t);
|
||||
ssize_t readlinkat(int, const char *, char *, size_t);
|
||||
ssize_t splice(int, int64_t *, int, int64_t *, size_t, uint32_t);
|
||||
ssize_t vmsplice(int, const struct iovec *, int64_t, uint32_t);
|
||||
ssize_t write(int, const void *, size_t);
|
||||
struct dirent *readdir(DIR *);
|
||||
uint32_t getegid(void) nosideeffect;
|
||||
uint32_t geteuid(void) nosideeffect;
|
||||
uint32_t getgid(void) nosideeffect;
|
||||
uint32_t getpgrp(void) nosideeffect;
|
||||
uint32_t getsid(int) nosideeffect;
|
||||
uint32_t gettid(void) nosideeffect;
|
||||
uint32_t getuid(void) nosideeffect;
|
||||
uint32_t umask(int32_t);
|
||||
void *getprocaddressmodule(const char *, const char *);
|
||||
void *mmap(void *, uint64_t, int32_t, int32_t, int32_t, int64_t) vallocesque;
|
||||
void *mremap(void *, uint64_t, uint64_t, int32_t, void *);
|
||||
|
||||
#define getcwd(BUF, SIZE) \
|
||||
(isconstant(BUF) && (&(BUF)[0] == NULL) ? get_current_dir_name() \
|
||||
: getcwd(BUF, SIZE))
|
||||
|
||||
/*───────────────────────────────────────────────────────────────────────────│─╗
|
||||
│ cosmopolitan § system calls » formatting ─╬─│┼
|
||||
╚────────────────────────────────────────────────────────────────────────────│*/
|
||||
|
||||
int dprintf(int, const char *, ...) printfesque(2) paramsnonnull((2));
|
||||
int vdprintf(int, const char *, va_list) paramsnonnull();
|
||||
|
||||
/*───────────────────────────────────────────────────────────────────────────│─╗
|
||||
│ cosmopolitan § system calls » link-time optimizations ─╬─│┼
|
||||
╚────────────────────────────────────────────────────────────────────────────│*/
|
||||
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
|
||||
|
||||
void _init_onntconsoleevent(void);
|
||||
void _init_onwincrash(void);
|
||||
|
||||
#define __SIGACTION(FN, SIG, ...) \
|
||||
({ \
|
||||
if (SupportsWindows()) { \
|
||||
if (isconstant(SIG)) { \
|
||||
switch (SIG) { \
|
||||
case SIGINT: \
|
||||
case SIGQUIT: \
|
||||
case SIGHUP: \
|
||||
case SIGTERM: \
|
||||
YOINK(_init_onntconsoleevent); \
|
||||
break; \
|
||||
case SIGTRAP: \
|
||||
case SIGILL: \
|
||||
case SIGSEGV: \
|
||||
case SIGABRT: \
|
||||
case SIGFPE: \
|
||||
YOINK(_init_onwincrash); \
|
||||
break; \
|
||||
default: \
|
||||
break; \
|
||||
} \
|
||||
} else { \
|
||||
YOINK(_init_onntconsoleevent); \
|
||||
YOINK(_init_onwincrash); \
|
||||
} \
|
||||
} \
|
||||
(FN)(SIG, __VA_ARGS__); \
|
||||
})
|
||||
|
||||
#define dprintf(FD, FMT, ...) (dprintf)(FD, PFLINK(FMT), ##__VA_ARGS__)
|
||||
#define sigaction(SIG, ACT, OLD) __SIGACTION(sigaction, SIG, ACT, OLD)
|
||||
#define signal(SIG, HAND) __SIGACTION(signal, SIG, HAND)
|
||||
#define vdprintf(FD, FMT, VA) (vdprintf)(FD, PFLINK(FMT), VA)
|
||||
|
||||
#endif /* GNU && !ANSI */
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_CALLS_SYSCALLS_H_ */
|
90
libc/calls/calls.mk
Normal file
90
libc/calls/calls.mk
Normal file
|
@ -0,0 +1,90 @@
|
|||
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
||||
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# System Call Compatibility Layer
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# This package exports a familiar system call interface that works
|
||||
# across platforms.
|
||||
|
||||
PKGS += LIBC_CALLS
|
||||
|
||||
LIBC_CALLS_ARTIFACTS += LIBC_CALLS_A
|
||||
LIBC_CALLS = $(LIBC_CALLS_A_DEPS) $(LIBC_CALLS_A)
|
||||
LIBC_CALLS_A = o/$(MODE)/libc/calls/syscalls.a
|
||||
LIBC_CALLS_A_FILES := \
|
||||
$(wildcard libc/calls/typedef/*) \
|
||||
$(wildcard libc/calls/thunks/*) \
|
||||
$(wildcard libc/calls/struct/*) \
|
||||
$(wildcard libc/calls/*)
|
||||
LIBC_CALLS_A_HDRS = $(filter %.h,$(LIBC_CALLS_A_FILES))
|
||||
LIBC_CALLS_A_SRCS_S = $(filter %.S,$(LIBC_CALLS_A_FILES))
|
||||
LIBC_CALLS_A_SRCS_C = $(filter %.c,$(LIBC_CALLS_A_FILES))
|
||||
|
||||
LIBC_CALLS_A_SRCS = \
|
||||
$(LIBC_CALLS_A_SRCS_S) \
|
||||
$(LIBC_CALLS_A_SRCS_C)
|
||||
|
||||
LIBC_CALLS_A_OBJS = \
|
||||
$(LIBC_CALLS_A_SRCS:%=o/$(MODE)/%.zip.o) \
|
||||
$(LIBC_CALLS_A_SRCS_S:%.S=o/$(MODE)/%.o) \
|
||||
$(LIBC_CALLS_A_SRCS_C:%.c=o/$(MODE)/%.o)
|
||||
|
||||
LIBC_CALLS_A_CHECKS = \
|
||||
$(LIBC_CALLS_A).pkg \
|
||||
$(LIBC_CALLS_A_HDRS:%=o/$(MODE)/%.ok)
|
||||
|
||||
LIBC_CALLS_A_DIRECTDEPS = \
|
||||
LIBC_FMT \
|
||||
LIBC_STR \
|
||||
LIBC_RAND \
|
||||
LIBC_CONV \
|
||||
LIBC_STUBS \
|
||||
LIBC_NEXGEN32E \
|
||||
LIBC_NT_NTDLL \
|
||||
LIBC_NT_ADVAPI32 \
|
||||
LIBC_NT_KERNEL32 \
|
||||
LIBC_NT_KERNELBASE \
|
||||
LIBC_SYSV_CALLS \
|
||||
LIBC_SYSV
|
||||
|
||||
LIBC_CALLS_A_DEPS := \
|
||||
$(call uniq,$(foreach x,$(LIBC_CALLS_A_DIRECTDEPS),$($(x))))
|
||||
|
||||
$(LIBC_CALLS_A): \
|
||||
libc/calls/ \
|
||||
$(LIBC_CALLS_A).pkg \
|
||||
$(LIBC_CALLS_A_OBJS)
|
||||
|
||||
$(LIBC_CALLS_A).pkg: \
|
||||
$(LIBC_CALLS_A_OBJS) \
|
||||
$(foreach x,$(LIBC_CALLS_A_DIRECTDEPS),$($(x)_A).pkg)
|
||||
|
||||
o/$(MODE)/libc/calls/raise.o: \
|
||||
OVERRIDE_COPTS += \
|
||||
$(NO_MAGIC)
|
||||
|
||||
o/$(MODE)/libc/calls/siggy.o: \
|
||||
OVERRIDE_COPTS += \
|
||||
-ffunction-sections
|
||||
|
||||
o/$(MODE)/libc/calls/xnutrampoline.o \
|
||||
o/$(MODE)/libc/calls/ntcontext2linux.o: \
|
||||
OVERRIDE_COPTS += \
|
||||
-O3
|
||||
|
||||
LIBC_CALLS_LIBS = $(foreach x,$(LIBC_CALLS_ARTIFACTS),$($(x)))
|
||||
LIBC_CALLS_SRCS = $(foreach x,$(LIBC_CALLS_ARTIFACTS),$($(x)_SRCS))
|
||||
LIBC_CALLS_HDRS = $(foreach x,$(LIBC_CALLS_ARTIFACTS),$($(x)_HDRS))
|
||||
LIBC_CALLS_BINS = $(foreach x,$(LIBC_CALLS_ARTIFACTS),$($(x)_BINS))
|
||||
LIBC_CALLS_CHECKS = $(foreach x,$(LIBC_CALLS_ARTIFACTS),$($(x)_CHECKS))
|
||||
LIBC_CALLS_OBJS = $(foreach x,$(LIBC_CALLS_ARTIFACTS),$($(x)_OBJS))
|
||||
LIBC_CALLS_TESTS = $(foreach x,$(LIBC_CALLS_ARTIFACTS),$($(x)_TESTS))
|
||||
|
||||
.PHONY: o/$(MODE)/libc/calls
|
||||
o/$(MODE)/libc/calls: \
|
||||
o/$(MODE)/libc/calls/hefty \
|
||||
$(LIBC_CALLS_CHECKS)
|
38
libc/calls/chdir-nt.c
Normal file
38
libc/calls/chdir-nt.c
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
textwindows int chdir$nt(const char *path) {
|
||||
int len;
|
||||
char16_t path16[PATH_MAX];
|
||||
if ((len = mkntpath(path, path16)) == -1) return -1;
|
||||
if (path16[len - 1] != u'/' && path16[len - 1] != u'\\') {
|
||||
path16[len + 0] = u'/';
|
||||
path16[len + 1] = u'\0';
|
||||
}
|
||||
if (SetCurrentDirectory(path16)) {
|
||||
return 0;
|
||||
} else {
|
||||
return winerr();
|
||||
}
|
||||
}
|
34
libc/calls/chdir.c
Normal file
34
libc/calls/chdir.c
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
|
||||
/**
|
||||
* Sets current directory.
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
int chdir(const char *path) {
|
||||
if (!IsWindows()) {
|
||||
return chdir$sysv(path);
|
||||
} else {
|
||||
return chdir$nt(path);
|
||||
}
|
||||
}
|
49
libc/calls/chmod.c
Normal file
49
libc/calls/chmod.c
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/sysv/consts/at.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
* Changes permissions on file, e.g.:
|
||||
*
|
||||
* CHECK_NE(-1, chmod("foo/bar.txt", 0644));
|
||||
* CHECK_NE(-1, chmod("o/default/program.com", 0755));
|
||||
* CHECK_NE(-1, chmod("privatefolder/", 0700));
|
||||
*
|
||||
* The esoteric bits generally available on System Five are:
|
||||
*
|
||||
* CHECK_NE(-1, chmod("/opt/", 01000)); // sticky bit
|
||||
* CHECK_NE(-1, chmod("/usr/bin/sudo", 04755)); // setuid bit
|
||||
* CHECK_NE(-1, chmod("/usr/bin/wall", 02755)); // setgid bit
|
||||
*
|
||||
* This works on Windows NT if you ignore the error ;-)
|
||||
*
|
||||
* @param pathname must exist
|
||||
* @param mode contains octal flags (base 8)
|
||||
* @errors ENOENT, ENOTDIR, ENOSYS
|
||||
* @asyncsignalsafe
|
||||
* @see fchmod()
|
||||
*/
|
||||
int chmod(const char *pathname, uint32_t mode) {
|
||||
return fchmodat$sysv(AT_FDCWD, pathname, mode, 0);
|
||||
}
|
38
libc/calls/chown.c
Normal file
38
libc/calls/chown.c
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/sysv/consts/at.h"
|
||||
|
||||
/**
|
||||
* Changes owner and/or group of pathname.
|
||||
*
|
||||
* @param uid is user id, or -1u to not change
|
||||
* @param gid is group id, or -1u to not change
|
||||
* @return 0 on success, or -1 w/ errno
|
||||
* @see fchown() if pathname is already open()'d
|
||||
* @see lchown() which does not dereference symbolic links
|
||||
* @see /etc/passwd for user ids
|
||||
* @see /etc/group for group ids
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
int chown(const char *pathname, uint32_t uid, uint32_t gid) {
|
||||
return fchownat$sysv(AT_FDCWD, pathname, uid, gid, 0);
|
||||
}
|
45
libc/calls/close-nt.c
Normal file
45
libc/calls/close-nt.c
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
textwindows int close$nt(int fd) {
|
||||
bool32 ok;
|
||||
if (isfdindex(fd)) {
|
||||
if (g_fds.p[fd].kind == kFdFile) {
|
||||
/*
|
||||
* Like Linux, closing a file on Windows doesn't guarantee it's
|
||||
* immediately synced to disk. But unlike Linux, this could cause
|
||||
* subsequent operations, e.g. unlink() to break w/ access error.
|
||||
*/
|
||||
FlushFileBuffers(g_fds.p[fd].handle);
|
||||
}
|
||||
ok = CloseHandle(g_fds.p[fd].handle);
|
||||
if (g_fds.p[fd].kind == kFdConsole) {
|
||||
ok &= CloseHandle(g_fds.p[fd].extra);
|
||||
}
|
||||
removefd(fd);
|
||||
return ok ? 0 : winerr();
|
||||
} else {
|
||||
return ebadf();
|
||||
}
|
||||
}
|
49
libc/calls/close.c
Normal file
49
libc/calls/close.c
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/sock/internal.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/zipos/zipos.h"
|
||||
|
||||
/**
|
||||
* Closes file descriptor.
|
||||
*
|
||||
* @return 0 on success, or -1 w/ errno
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
int close(int fd) {
|
||||
int rc;
|
||||
if (fd == -1) return 0;
|
||||
if (isfdkind(fd, kFdZip)) {
|
||||
rc = weaken(__zipos_close)(
|
||||
(struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle);
|
||||
} else if (!IsWindows()) {
|
||||
rc = close$sysv(fd);
|
||||
} else if (isfdkind(fd, kFdSocket)) {
|
||||
rc = weaken(closesocket$nt)(fd);
|
||||
} else {
|
||||
rc = close$nt(fd);
|
||||
}
|
||||
removefd(fd);
|
||||
return rc;
|
||||
}
|
73
libc/calls/copyfd.c
Normal file
73
libc/calls/copyfd.c
Normal file
|
@ -0,0 +1,73 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/bits/safemacros.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
* Copies data between file descriptors the slow way.
|
||||
*
|
||||
* @return -1 on error/interrupt, 0 on eof, or [1..uptobytes] on success
|
||||
* @see copy_file_range() for file ↔ file
|
||||
* @see sendfile() for seekable → socket
|
||||
* @see splice() for fd ↔ pipe
|
||||
*/
|
||||
ssize_t copyfd(int infd, int64_t *inopt_out_inoffset, int to_fd,
|
||||
int64_t *inopt_out_outoffset, size_t uptobytes, uint32_t flags) {
|
||||
size_t i;
|
||||
int64_t offset;
|
||||
ssize_t got, wrote;
|
||||
static unsigned char buf[1024 * 64];
|
||||
/* unsigned char buf[1024 * 3]; */
|
||||
uptobytes = min(sizeof(buf), uptobytes);
|
||||
if (inopt_out_inoffset) {
|
||||
got = pread(infd, buf, uptobytes, *inopt_out_inoffset);
|
||||
} else {
|
||||
got = read(infd, buf, uptobytes);
|
||||
}
|
||||
if (got == -1) return -1;
|
||||
offset = inopt_out_outoffset ? *inopt_out_outoffset : -1;
|
||||
for (i = 0; i < got; i += wrote) {
|
||||
tryagain:
|
||||
if (inopt_out_outoffset) {
|
||||
wrote = pwrite(to_fd, buf, got - i, offset + i);
|
||||
} else {
|
||||
wrote = write(to_fd, buf, got - i);
|
||||
}
|
||||
if (wrote != -1) continue;
|
||||
if (errno == EINTR) {
|
||||
if (inopt_out_inoffset != NULL) {
|
||||
return -1;
|
||||
}
|
||||
goto tryagain;
|
||||
}
|
||||
if (errno == EWOULDBLOCK) {
|
||||
assert(inopt_out_inoffset != NULL); /* or caller is nuts */
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
if (inopt_out_inoffset) *inopt_out_inoffset += got;
|
||||
if (inopt_out_outoffset) *inopt_out_outoffset += got;
|
||||
return got;
|
||||
}
|
64
libc/calls/copyfile.c
Normal file
64
libc/calls/copyfile.c
Normal file
|
@ -0,0 +1,64 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/struct/stat.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/sysv/consts/at.h"
|
||||
#include "libc/sysv/consts/madv.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
|
||||
int copyfile(const char *frompath, const char *topath, bool dontoverwrite) {
|
||||
if (IsWindows()) {
|
||||
char16_t frompath16[PATH_MAX], topath16[PATH_MAX];
|
||||
if (mkntpath(frompath, frompath16) == -1) return -1;
|
||||
if (mkntpath(topath, topath16) == -1) return -1;
|
||||
if (CopyFile(frompath16, topath16, dontoverwrite)) {
|
||||
return 0;
|
||||
} else {
|
||||
return winerr();
|
||||
}
|
||||
} else {
|
||||
struct stat st;
|
||||
ssize_t transferred;
|
||||
int rc, fromfd, tofd;
|
||||
int64_t inoffset, outoffset;
|
||||
rc = -1;
|
||||
if ((fromfd = openat$sysv(AT_FDCWD, frompath, O_RDONLY, 0)) != -1) {
|
||||
if (fstat$sysv(fromfd, &st) != -1 &&
|
||||
(tofd = openat$sysv(AT_FDCWD, topath,
|
||||
O_WRONLY | O_CREAT | (dontoverwrite ? O_EXCL : 0),
|
||||
st.st_mode & 0777)) != -1) {
|
||||
inoffset = 0;
|
||||
outoffset = 0;
|
||||
while (st.st_size && (transferred = copy_file_range(
|
||||
fromfd, &inoffset, tofd, &outoffset,
|
||||
st.st_size, 0)) != -1) {
|
||||
st.st_size -= transferred;
|
||||
}
|
||||
if (!st.st_size) rc = 0;
|
||||
rc |= close$sysv(tofd);
|
||||
}
|
||||
rc |= close$sysv(fromfd);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
}
|
36
libc/calls/creat.c
Normal file
36
libc/calls/creat.c
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
|
||||
/**
|
||||
* Creates new file, returning open()'d file descriptor.
|
||||
*
|
||||
* @param file is a UTF-8 string, which is truncated if it exists
|
||||
* @param mode is an octal user/group/other permission, e.g. 0755
|
||||
* @return a number registered with the system to track the open file,
|
||||
* which must be stored using a 64-bit type in order to support both
|
||||
* System V and Windows, and must be closed later on using close()
|
||||
* @see touch()
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
nodiscard int creat(const char *file, uint32_t mode) {
|
||||
return open(file, O_CREAT | O_WRONLY | O_TRUNC, mode);
|
||||
}
|
38
libc/calls/createfd.c
Normal file
38
libc/calls/createfd.c
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
* Finds open file descriptor slot.
|
||||
*/
|
||||
ssize_t createfd(void) {
|
||||
size_t fd;
|
||||
for (;;) {
|
||||
while (g_fds.f < g_fds.n) {
|
||||
if (g_fds.p[(fd = g_fds.f++)].kind == kFdEmpty) {
|
||||
return fd;
|
||||
}
|
||||
}
|
||||
if (growfds() == -1) return -1;
|
||||
}
|
||||
}
|
32
libc/calls/dprintf.c
Normal file
32
libc/calls/dprintf.c
Normal file
|
@ -0,0 +1,32 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=8 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
|
||||
/**
|
||||
* Formats string directly to system i/o device.
|
||||
*/
|
||||
int(dprintf)(int fd, const char *fmt, ...) {
|
||||
int rc;
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
rc = (vdprintf)(fd, fmt, va);
|
||||
va_end(va);
|
||||
return rc;
|
||||
}
|
54
libc/calls/dup-nt.c
Normal file
54
libc/calls/dup-nt.c
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
* Implements dup(), dup2(), and dup3() for Windows NT.
|
||||
*/
|
||||
textwindows int dup$nt(int oldfd, int newfd, int flags) {
|
||||
if (!isfdkind(oldfd, kFdFile)) return ebadf();
|
||||
if (newfd == -1) {
|
||||
if ((newfd = createfd()) == -1) return -1;
|
||||
} else if (isfdindex(newfd)) {
|
||||
close(newfd);
|
||||
} else if (isfdlegal(newfd)) {
|
||||
do {
|
||||
if (growfds() == -1) return -1;
|
||||
} while (newfd >= g_fds.n);
|
||||
} else {
|
||||
return ebadf();
|
||||
}
|
||||
if (DuplicateHandle(GetCurrentProcess(), g_fds.p[oldfd].handle,
|
||||
GetCurrentProcess(), &g_fds.p[newfd].handle, 0,
|
||||
(flags & O_CLOEXEC), kNtDuplicateSameAccess)) {
|
||||
g_fds.p[newfd].kind = g_fds.p[oldfd].kind;
|
||||
g_fds.p[newfd].flags = flags;
|
||||
return newfd;
|
||||
} else {
|
||||
return winerr();
|
||||
}
|
||||
}
|
37
libc/calls/dup.c
Normal file
37
libc/calls/dup.c
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
|
||||
/**
|
||||
* Duplicates file descriptor/handle.
|
||||
*
|
||||
* @param fd remains open afterwards
|
||||
* @return some arbitrary new number for fd
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
nodiscard int dup(int fd) {
|
||||
if (!IsWindows()) {
|
||||
return dup$sysv(fd);
|
||||
} else {
|
||||
return dup$nt(fd, -1, 0);
|
||||
}
|
||||
}
|
40
libc/calls/dup2.c
Normal file
40
libc/calls/dup2.c
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
|
||||
/**
|
||||
* Duplicates file descriptor, granting it specific number.
|
||||
*
|
||||
* @param oldfd isn't closed afterwards
|
||||
* @param newfd if already assigned, is silently closed beforehand;
|
||||
* unless it's equal to oldfd, in which case dup2() is a no-op
|
||||
* @return new file descriptor, or -1 w/ errno
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
int dup2(int oldfd, int newfd) {
|
||||
if (oldfd == newfd) return newfd;
|
||||
if (!IsWindows()) {
|
||||
return dup3$sysv(oldfd, newfd, 0);
|
||||
} else {
|
||||
return dup$nt(oldfd, newfd, 0);
|
||||
}
|
||||
}
|
47
libc/calls/dup3-sysv.c
Normal file
47
libc/calls/dup3-sysv.c
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/errno.h"
|
||||
|
||||
#define __NR_dup3_linux 0x0124 /*RHEL5:CVE-2010-3301*/
|
||||
|
||||
int32_t dup3$sysv(int32_t oldfd, int32_t newfd, int flags) {
|
||||
static bool once, demodernize;
|
||||
int olderr, fd;
|
||||
if (!once) {
|
||||
once = true;
|
||||
olderr = errno;
|
||||
fd = __dup3$sysv(oldfd, newfd, flags);
|
||||
if ((fd == -1 && errno == ENOSYS) || fd == __NR_dup3_linux) {
|
||||
demodernize = true;
|
||||
errno = olderr;
|
||||
goto OldSkool;
|
||||
}
|
||||
} else if (demodernize) {
|
||||
goto OldSkool;
|
||||
} else {
|
||||
fd = __dup3$sysv(oldfd, newfd, flags);
|
||||
}
|
||||
return fd;
|
||||
OldSkool:
|
||||
fd = dup2$sysv(oldfd, newfd);
|
||||
if (flags) fd = fixupnewfd$sysv(fd, flags);
|
||||
return fd;
|
||||
}
|
44
libc/calls/dup3.c
Normal file
44
libc/calls/dup3.c
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
* Duplicates file descriptor/handle.
|
||||
*
|
||||
* On Windows, we can't guarantee the desired file descriptor is used.
|
||||
* We can however remap the standard handles (non-atomically) if their
|
||||
* symbolic names are used.
|
||||
*
|
||||
* @param oldfd isn't closed afterwards
|
||||
* @param newfd if already assigned, is silently closed beforehand;
|
||||
* unless it's equal to oldfd, in which case dup2() is a no-op
|
||||
* @flags can have O_CLOEXEC
|
||||
*/
|
||||
int dup3(int oldfd, int newfd, int flags) {
|
||||
if (oldfd == newfd) return einval();
|
||||
if (!IsWindows()) {
|
||||
return dup3$sysv(oldfd, newfd, flags);
|
||||
} else {
|
||||
return dup$nt(oldfd, newfd, flags);
|
||||
}
|
||||
}
|
65
libc/calls/fadvise-nt.c
Normal file
65
libc/calls/fadvise-nt.c
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/nt/enum/fileflagandattributes.h"
|
||||
#include "libc/nt/enum/filesharemode.h"
|
||||
#include "libc/nt/enum/status.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/nt/nt/file.h"
|
||||
#include "libc/nt/ntdll.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/struct/fileaccessinformation.h"
|
||||
#include "libc/nt/struct/filebasicinformation.h"
|
||||
#include "libc/nt/struct/iostatusblock.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
textwindows int fadvise$nt(int fd, uint64_t offset, uint64_t len, int advice) {
|
||||
int64_t h2;
|
||||
NtStatus status;
|
||||
uint32_t sharemode;
|
||||
struct NtIoStatusBlock iostatus;
|
||||
struct NtFileBasicInformation basicinfo;
|
||||
struct NtFileAccessInformation accessinfo;
|
||||
if (!isfdkind(fd, kFdFile)) return ebadf();
|
||||
sharemode = /* xxx: no clue how to query this */
|
||||
kNtFileShareRead | kNtFileShareWrite | kNtFileShareDelete;
|
||||
/* TODO(jart): can we do it in one call w/ NtQueryObject? */
|
||||
if (!NtError(status = NtQueryInformationFile(g_fds.p[fd].handle, &iostatus,
|
||||
&basicinfo, sizeof(basicinfo),
|
||||
kNtFileBasicInformation)) &&
|
||||
!NtError(status = NtQueryInformationFile(g_fds.p[fd].handle, &iostatus,
|
||||
&accessinfo, sizeof(accessinfo),
|
||||
kNtFileAccessInformation))) {
|
||||
if ((h2 = ReOpenFile(g_fds.p[fd].handle, accessinfo.AccessFlags, sharemode,
|
||||
advice | basicinfo.FileAttributes)) != -1) {
|
||||
if (h2 != g_fds.p[fd].handle) {
|
||||
CloseHandle(g_fds.p[fd].handle);
|
||||
g_fds.p[fd].handle = h2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return winerr();
|
||||
} else if (status == kNtStatusDllNotFound) {
|
||||
return enosys();
|
||||
} else {
|
||||
return ntreturn(status);
|
||||
}
|
||||
}
|
40
libc/calls/fadvise.c
Normal file
40
libc/calls/fadvise.c
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
|
||||
/**
|
||||
* Drops hints to O/S about intended I/O behavior.
|
||||
*
|
||||
* It makes a huge difference. For example, when copying a large file,
|
||||
* it can stop the system from persisting GBs of useless memory content.
|
||||
*
|
||||
* @param len 0 means ‘til end of file
|
||||
* @param advice can be MADV_SEQUENTIAL, MADV_RANDOM, etc.
|
||||
* @return -1 on error
|
||||
*/
|
||||
int fadvise(int fd, uint64_t offset, uint64_t len, int advice) {
|
||||
if (!IsWindows()) {
|
||||
return fadvise$sysv(fd, offset, len, advice); /* linux & freebsd */
|
||||
} else {
|
||||
return fadvise$nt(fd, offset, len, advice);
|
||||
}
|
||||
}
|
76
libc/calls/fallocate.c
Normal file
76
libc/calls/fallocate.c
Normal file
|
@ -0,0 +1,76 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/nt/enum/fsctl.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/nt/struct/filezerodatainformation.h"
|
||||
#include "libc/sysv/consts/falloc.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
* Manipulates underlying physical medium of file.
|
||||
*
|
||||
* This system call generalizes to many powerful use cases on Linux,
|
||||
* such as creating gigantic sparse files that take up little space.
|
||||
* This API can polyfill a certain subset of parameters safely, e.g.
|
||||
* ones identical to ftruncate(), but errs on the side of caution.
|
||||
*
|
||||
* @param fd must be open for writing
|
||||
* @param mode can be 0, FALLOC_xxx
|
||||
* @param length is how much physical space to reserve / commit
|
||||
* @return 0 on success, or -1 w/ errno
|
||||
* @see ftruncate()
|
||||
*/
|
||||
int fallocate(int fd, int32_t mode, int64_t offset, int64_t length) {
|
||||
int rc;
|
||||
uint32_t br;
|
||||
if (mode == -1 /* our sysvconsts definition */) return eopnotsupp();
|
||||
if (!mode && !length) return ftruncate(fd, offset);
|
||||
if (IsLinux()) {
|
||||
rc = fallocate$sysv(fd, mode, offset, length);
|
||||
if (rc == 0x011d) rc = enosys(); /*RHEL5:CVE-2010-3301*/
|
||||
return rc;
|
||||
} else if (!IsWindows()) {
|
||||
return posix_fallocate$sysv(fd, offset, length);
|
||||
} else if (IsWindows()) {
|
||||
if (!isfdkind(fd, kFdFile)) return ebadf();
|
||||
if (mode == FALLOC_FL_ZERO_RANGE) {
|
||||
if (DeviceIoControl(
|
||||
g_fds.p[fd].handle, kNtFsctlSetZeroData,
|
||||
&(struct NtFileZeroDataInformation){offset, offset + length},
|
||||
sizeof(struct NtFileZeroDataInformation), NULL, 0, &br, NULL)) {
|
||||
return 0;
|
||||
} else {
|
||||
return winerr();
|
||||
}
|
||||
} else if (!mode && !offset) {
|
||||
/*
|
||||
* this should commit physical space
|
||||
* but not guaranteed zero'd like linux
|
||||
*/
|
||||
return ftruncate$nt(fd, length);
|
||||
} else {
|
||||
return eopnotsupp();
|
||||
}
|
||||
} else {
|
||||
return enosys();
|
||||
}
|
||||
}
|
48
libc/calls/fchmod.c
Normal file
48
libc/calls/fchmod.c
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
* Changes file permissions via open()'d file descriptor, e.g.:
|
||||
*
|
||||
* CHECK_NE(-1, chmod("foo/bar.txt", 0644));
|
||||
* CHECK_NE(-1, chmod("o/default/program.com", 0755));
|
||||
* CHECK_NE(-1, chmod("privatefolder/", 0700));
|
||||
*
|
||||
* The esoteric bits generally available on System V are:
|
||||
*
|
||||
* CHECK_NE(-1, chmod("/opt/", 01000)); // sticky bit
|
||||
* CHECK_NE(-1, chmod("/usr/bin/sudo", 04755)); // setuid bit
|
||||
* CHECK_NE(-1, chmod("/usr/bin/wall", 02755)); // setgid bit
|
||||
*
|
||||
* This works on Windows NT if you ignore the error ;-)
|
||||
*
|
||||
* @param mode contains octal flags (base 8)
|
||||
* @errors ENOSYS
|
||||
* @asyncsignalsafe
|
||||
* @see chmod()
|
||||
*/
|
||||
int fchmod(int fd, uint32_t mode) {
|
||||
/* TODO(jart): Windows */
|
||||
return fchmod$sysv(fd, mode);
|
||||
}
|
36
libc/calls/fchown.c
Normal file
36
libc/calls/fchown.c
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/sysv/consts/at.h"
|
||||
|
||||
/**
|
||||
* Changes owner and/or group of file, via open()'d descriptor.
|
||||
*
|
||||
* @param uid is user id, or -1u to not change
|
||||
* @param gid is group id, or -1u to not change
|
||||
* @return 0 on success, or -1 w/ errno
|
||||
* @see /etc/passwd for user ids
|
||||
* @see /etc/group for group ids
|
||||
*/
|
||||
int fchown(int fd, uint32_t uid, uint32_t gid) {
|
||||
/* TODO(jart): Windows? */
|
||||
return fchown$sysv(fd, uid, gid);
|
||||
}
|
40
libc/calls/fchownat.c
Normal file
40
libc/calls/fchownat.c
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
|
||||
/**
|
||||
* Changes owner and/or group of pathname.
|
||||
*
|
||||
* @param dirfd is open()'d relative-to directory, or AT_FDCWD, etc.
|
||||
* @param uid is user id, or -1 to not change
|
||||
* @param gid is group id, or -1 to not change
|
||||
* @param flags can have AT_SYMLINK_NOFOLLOW, etc.
|
||||
* @return 0 on success, or -1 w/ errno
|
||||
* @see chown(), lchown() for shorthand notation
|
||||
* @see /etc/passwd for user ids
|
||||
* @see /etc/group for group ids
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
int fchownat(int dirfd, const char *pathname, uint32_t uid, uint32_t gid,
|
||||
uint32_t flags) {
|
||||
/* TODO(jart): Windows? */
|
||||
return fchownat$sysv(dirfd, pathname, uid, gid, flags);
|
||||
}
|
40
libc/calls/fcntl-nt.c
Normal file
40
libc/calls/fcntl-nt.c
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/sysv/consts/f.h"
|
||||
#include "libc/sysv/consts/fd.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
textwindows int fcntl$nt(int fd, int cmd, unsigned arg) {
|
||||
if (!isfdindex(fd)) return ebadf();
|
||||
switch (cmd) {
|
||||
case F_GETFD:
|
||||
return GetHandleInformation(g_fds.p[fd].handle, &arg) ? (arg ^ FD_CLOEXEC)
|
||||
: -1;
|
||||
case F_SETFD:
|
||||
return SetHandleInformation(g_fds.p[fd].handle, FD_CLOEXEC,
|
||||
arg ^ FD_CLOEXEC)
|
||||
? 0
|
||||
: -1;
|
||||
default:
|
||||
return 0; /* TODO(jart): Implement me. */
|
||||
}
|
||||
}
|
40
libc/calls/fcntl.c
Normal file
40
libc/calls/fcntl.c
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
|
||||
/**
|
||||
* Does things with file descriptor, via re-imagined hourglass api, e.g.
|
||||
*
|
||||
* CHECK_NE(-1, fcntl(fd, F_SETFD, FD_CLOEXEC));
|
||||
*
|
||||
* @param cmd can be F_{GET,SET}{FD,FL}, etc.
|
||||
* @param arg can be FD_CLOEXEC, etc. depending
|
||||
* @return 0 on success, or -1 w/ errno
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
int fcntl(int fd, int cmd, int arg) {
|
||||
if (!IsWindows()) {
|
||||
return fcntl$sysv(fd, cmd, arg);
|
||||
} else {
|
||||
return fcntl$nt(fd, cmd, arg);
|
||||
}
|
||||
}
|
32
libc/calls/fdatasync-nt.c
Normal file
32
libc/calls/fdatasync-nt.c
Normal file
|
@ -0,0 +1,32 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
textwindows int fdatasync$nt(int fd) {
|
||||
if (!isfdkind(fd, kFdFile)) return ebadf();
|
||||
/*
|
||||
* XXX: On Windows NT this might be more analagous to fflush() and
|
||||
* Microsoft docs say to do manual block i/o for database-ish
|
||||
* guarantees on disk persistence. Consider: Really good UPS.
|
||||
*/
|
||||
return FlushFileBuffers(g_fds.p[fd].handle) ? 0 : winerr();
|
||||
}
|
37
libc/calls/fdatasync.c
Normal file
37
libc/calls/fdatasync.c
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
|
||||
/**
|
||||
* Blocks until kernel flushes non-metadata buffers for fd to disk.
|
||||
*
|
||||
* @return 0 on success, or -1 w/ errno
|
||||
* @see fsync(), sync_file_range()
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
int fdatasync(int fd) {
|
||||
if (!IsWindows()) {
|
||||
return fdatasync$sysv(fd);
|
||||
} else {
|
||||
return fdatasync$nt(fd);
|
||||
}
|
||||
}
|
28
libc/calls/fdkind.c
Normal file
28
libc/calls/fdkind.c
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
|
||||
enum FdKind fdkind(int fd) {
|
||||
if (isfdindex(fd)) {
|
||||
return g_fds.p[fd].kind;
|
||||
} else {
|
||||
return kFdEmpty;
|
||||
}
|
||||
}
|
44
libc/calls/fileexists.c
Normal file
44
libc/calls/fileexists.c
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/stat.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
* Returns true if file exists at path.
|
||||
*
|
||||
* Please note that things which aren't strictly files, e.g. directories
|
||||
* or sockets, could be considered files for the purposes of this
|
||||
* function. The stat() function may be used to differentiate them.
|
||||
*/
|
||||
bool fileexists(const char *path) {
|
||||
/* TODO(jart): Use fast path on NT? */
|
||||
struct stat st;
|
||||
int olderr = errno;
|
||||
int rc = stat(path, &st);
|
||||
if (rc == -1 && (errno == ENOENT || errno == ENOTDIR)) {
|
||||
errno = olderr;
|
||||
}
|
||||
return rc != -1;
|
||||
}
|
40
libc/calls/fixntmagicpath.ncabi.c
Normal file
40
libc/calls/fixntmagicpath.ncabi.c
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/ntmagicpaths.h"
|
||||
#include "libc/nexgen32e/tinystrcmp.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
|
||||
textwindows const char *(fixntmagicpath)(const char *path, unsigned flags) {
|
||||
const struct NtMagicPaths *mp = &kNtMagicPaths;
|
||||
asm("" : "+r"(mp));
|
||||
if (path[0] != '/') return path;
|
||||
if (tinystrcmp(path, mp->devtty) == 0) {
|
||||
if ((flags & O_ACCMODE) == O_RDONLY) {
|
||||
return mp->conin;
|
||||
} else if ((flags & O_ACCMODE) == O_WRONLY) {
|
||||
return mp->conout;
|
||||
}
|
||||
}
|
||||
if (tinystrcmp(path, mp->devnull) == 0) return mp->nul;
|
||||
if (tinystrcmp(path, mp->devstdin) == 0) return mp->conin;
|
||||
if (tinystrcmp(path, mp->devstdout) == 0) return mp->conout;
|
||||
return path;
|
||||
}
|
36
libc/calls/fixupnewfd.c
Normal file
36
libc/calls/fixupnewfd.c
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/sysv/consts/f.h"
|
||||
#include "libc/sysv/consts/fd.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
|
||||
/**
|
||||
* Applies file descriptor fixups on XNU or old Linux.
|
||||
* @see fixupnewsockfd$sysv() for socket file descriptors
|
||||
*/
|
||||
int fixupnewfd$sysv(int fd, int flags) {
|
||||
if (fd != -1) {
|
||||
if (flags & O_CLOEXEC) fcntl$sysv(fd, F_SETFD, FD_CLOEXEC);
|
||||
fcntl$sysv(fd, F_SETFL,
|
||||
(fcntl$sysv(fd, F_GETFL, 0) ^ (flags & O_NONBLOCK)));
|
||||
}
|
||||
return fd;
|
||||
}
|
44
libc/calls/flock-nt.c
Normal file
44
libc/calls/flock-nt.c
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/struct/byhandlefileinformation.h"
|
||||
#include "libc/nt/struct/overlapped.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/lock.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
textwindows int flock$nt(int fd, int op) {
|
||||
struct NtOverlapped ov;
|
||||
struct NtByHandleFileInformation info;
|
||||
if (!isfdkind(fd, kFdFile)) return ebadf();
|
||||
memset(&ov, 0, sizeof(ov));
|
||||
if (GetFileInformationByHandle(g_fds.p[fd].handle, &info) &&
|
||||
((!(op & LOCK_UN) &&
|
||||
LockFileEx(g_fds.p[fd].handle, op, 0, info.nFileSizeLow,
|
||||
info.nFileSizeHigh, &ov)) ||
|
||||
((op & LOCK_UN) && UnlockFileEx(g_fds.p[fd].handle, 0, info.nFileSizeLow,
|
||||
info.nFileSizeHigh, &ov)))) {
|
||||
return 0;
|
||||
} else {
|
||||
return winerr();
|
||||
}
|
||||
}
|
37
libc/calls/flock.c
Normal file
37
libc/calls/flock.c
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
|
||||
/**
|
||||
* Acquires lock on file.
|
||||
*
|
||||
* @param op can have LOCK_{SH,EX,NB,UN} for shared, exclusive,
|
||||
* non-blocking, and unlocking
|
||||
* @return 0 on success, or -1 w/ errno
|
||||
*/
|
||||
int flock(int fd, int op) {
|
||||
if (!IsWindows()) {
|
||||
return flock$sysv(fd, op);
|
||||
} else {
|
||||
return flock$nt(fd, op);
|
||||
}
|
||||
}
|
35
libc/calls/fork.c
Normal file
35
libc/calls/fork.c
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
|
||||
/**
|
||||
* Creates new process zygote style.
|
||||
*
|
||||
* @return 0 to child, child pid to parent, or -1 on error
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
int fork(void) {
|
||||
int rc;
|
||||
rc = fork$sysv();
|
||||
if (rc == 0) __onfork();
|
||||
return rc;
|
||||
}
|
39
libc/calls/fprot2nt.c
Normal file
39
libc/calls/fprot2nt.c
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/nt/enum/filemapflags.h"
|
||||
#include "libc/nt/memory.h"
|
||||
#include "libc/sysv/consts/map.h"
|
||||
#include "libc/sysv/consts/prot.h"
|
||||
|
||||
#define HAS(X, BITS) (((X) & (BITS)) == (BITS))
|
||||
|
||||
/**
|
||||
* Converts System Five memory protection flags to Windows NT, Part 2.
|
||||
* @see libc/sysv/consts.sh
|
||||
*/
|
||||
uint32_t fprot2nt(int prot, int flags) {
|
||||
return (HAS(prot, PROT_READ) ? kNtFileMapRead : 0) |
|
||||
(HAS(prot, PROT_WRITE) ? kNtFileMapWrite : 0) |
|
||||
(HAS(prot, PROT_EXEC) ? kNtFileMapExecute : 0) |
|
||||
(HAS(flags, MAP_PRIVATE) ? kNtFileMapCopy : 0) |
|
||||
(HAS(flags, kNtSecLargePages) ? kNtFileMapLargePages : 0) |
|
||||
(HAS(flags, kNtSecReserve) ? kNtFileMapReserve : 0);
|
||||
}
|
71
libc/calls/fstat-nt.c
Normal file
71
libc/calls/fstat-nt.c
Normal file
|
@ -0,0 +1,71 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/safemacros.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/struct/stat.h"
|
||||
#include "libc/conv/conv.h"
|
||||
#include "libc/nt/enum/fileflagandattributes.h"
|
||||
#include "libc/nt/enum/fileinfobyhandleclass.h"
|
||||
#include "libc/nt/enum/filetype.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/struct/byhandlefileinformation.h"
|
||||
#include "libc/nt/struct/filecompressioninfo.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/s.h"
|
||||
|
||||
textwindows int fstat$nt(int64_t handle, struct stat *st) {
|
||||
uint64_t actualsize;
|
||||
enum NtFileType filetype;
|
||||
struct NtByHandleFileInformation wst;
|
||||
struct NtFileCompressionInfo fci;
|
||||
if (GetFileInformationByHandle(handle, &wst)) {
|
||||
memset(st, 0, sizeof(*st));
|
||||
filetype = GetFileType(handle);
|
||||
st->st_mode =
|
||||
(S_IRUSR | S_IXUSR |
|
||||
(!(wst.dwFileAttributes & kNtFileAttributeReadonly) ? S_IWUSR : 0) |
|
||||
((wst.dwFileAttributes & kNtFileAttributeNormal) ? S_IFREG : 0) |
|
||||
((wst.dwFileAttributes & kNtFileFlagOpenReparsePoint) ? S_IFLNK : 0) |
|
||||
((wst.dwFileAttributes & kNtFileAttributeDirectory)
|
||||
? S_IFDIR
|
||||
: (((filetype == kNtFileTypeDisk) ? S_IFBLK : 0) |
|
||||
((filetype == kNtFileTypeChar) ? S_IFCHR : 0) |
|
||||
((filetype == kNtFileTypePipe) ? S_IFIFO : 0))));
|
||||
filetimetotimespec(&st->st_atim, wst.ftLastAccessFileTime);
|
||||
filetimetotimespec(&st->st_mtim, wst.ftLastWriteFileTime);
|
||||
filetimetotimespec(&st->st_ctim, wst.ftCreationFileTime);
|
||||
st->st_size = (uint64_t)wst.nFileSizeHigh << 32 | wst.nFileSizeLow;
|
||||
st->st_blksize = PAGESIZE;
|
||||
st->st_dev = wst.dwVolumeSerialNumber;
|
||||
st->st_ino = (uint64_t)wst.nFileIndexHigh << 32 | wst.nFileIndexLow;
|
||||
st->st_nlink = wst.nNumberOfLinks;
|
||||
if (GetFileInformationByHandleEx(handle, kNtFileCompressionInfo, &fci,
|
||||
sizeof(fci))) {
|
||||
actualsize = fci.CompressedFileSize;
|
||||
} else {
|
||||
actualsize = st->st_size;
|
||||
}
|
||||
st->st_blocks = roundup(actualsize, PAGESIZE) / 512;
|
||||
return 0;
|
||||
} else {
|
||||
return winerr();
|
||||
}
|
||||
}
|
32
libc/calls/fstat-sysv.c
Normal file
32
libc/calls/fstat-sysv.c
Normal file
|
@ -0,0 +1,32 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
|
||||
/**
|
||||
* Supports fstat(), etc. implementations.
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
int32_t fstat$sysv(int32_t fd, struct stat *st) {
|
||||
int res;
|
||||
if ((res = __fstat$sysv(fd, st)) != -1) {
|
||||
stat2linux(st);
|
||||
}
|
||||
return res;
|
||||
}
|
41
libc/calls/fstat.c
Normal file
41
libc/calls/fstat.c
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/zipos/zipos.h"
|
||||
|
||||
/**
|
||||
* Returns information about file, via open()'d descriptor.
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
int fstat(int fd, struct stat *st) {
|
||||
if (isfdkind(fd, kFdZip)) {
|
||||
return weaken(__zipos_fstat)(
|
||||
(struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, st);
|
||||
} else if (!IsWindows()) {
|
||||
return fstat$sysv(fd, st);
|
||||
} else {
|
||||
if (!isfdkind(fd, kFdFile)) return ebadf();
|
||||
return fstat$nt(g_fds.p[fd].handle, st);
|
||||
}
|
||||
}
|
33
libc/calls/fstatat-sysv.c
Normal file
33
libc/calls/fstatat-sysv.c
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
|
||||
/**
|
||||
* Supports stat(), lstat(), fstatat(), etc. implementations.
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
int32_t fstatat$sysv(int32_t dirfd, const char *pathname, struct stat *st,
|
||||
int32_t flags) {
|
||||
int32_t rc;
|
||||
if ((rc = __fstatat$sysv(dirfd, pathname, st, flags)) != -1) {
|
||||
stat2linux(st);
|
||||
}
|
||||
return rc;
|
||||
}
|
49
libc/calls/fstatat.c
Normal file
49
libc/calls/fstatat.c
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/sysv/consts/at.h"
|
||||
|
||||
/**
|
||||
* Performs stat() w/ features for threaded apps.
|
||||
*
|
||||
* @param dirfd can be AT_FDCWD or an open directory descriptor, and is
|
||||
* ignored if pathname is absolute
|
||||
* @param flags can have AT_{EMPTY_PATH,NO_AUTOMOUNT,SYMLINK_NOFOLLOW}
|
||||
* @return 0 on success, or -1 w/ errno
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
int fstatat(int dirfd, const char *pathname, struct stat *st, uint32_t flags) {
|
||||
int olderr = errno;
|
||||
int rc = fstatat$sysv(dirfd, pathname, st, flags);
|
||||
if (rc != -1) {
|
||||
stat2linux(st);
|
||||
} else if (errno == ENOSYS && dirfd == AT_FDCWD) {
|
||||
if (!flags) {
|
||||
errno = olderr;
|
||||
rc = stat(pathname, st);
|
||||
} else if (flags == AT_SYMLINK_NOFOLLOW) {
|
||||
errno = olderr;
|
||||
rc = lstat(pathname, st);
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
37
libc/calls/fsync.c
Normal file
37
libc/calls/fsync.c
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
|
||||
/**
|
||||
* Blocks until kernel flushes buffers for fd to disk.
|
||||
*
|
||||
* @return 0 on success, or -1 w/ errno
|
||||
* @see fdatasync(), sync_file_range()
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
int fsync(int fd) {
|
||||
if (!IsWindows()) {
|
||||
return fsync$sysv(fd);
|
||||
} else {
|
||||
return fdatasync$nt(fd);
|
||||
}
|
||||
}
|
38
libc/calls/ftruncate-nt.c
Normal file
38
libc/calls/ftruncate-nt.c
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/nt/enum/filemovemethod.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
textwindows int ftruncate$nt(int fd, uint64_t length) {
|
||||
bool32 ok;
|
||||
int64_t tell;
|
||||
if (!isfdkind(fd, kFdFile)) return ebadf();
|
||||
tell = -1;
|
||||
if (SetFilePointerEx(g_fds.p[fd].handle, 0, &tell, kNtFileCurrent)) {
|
||||
ok = SetFilePointerEx(g_fds.p[fd].handle, length, NULL, kNtFileBegin) &&
|
||||
SetEndOfFile(g_fds.p[fd].handle);
|
||||
SetFilePointerEx(g_fds.p[fd].handle, tell, NULL, kNtFileBegin);
|
||||
return ok ? 0 : winerr();
|
||||
} else {
|
||||
return winerr();
|
||||
}
|
||||
}
|
41
libc/calls/ftruncate.c
Normal file
41
libc/calls/ftruncate.c
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
|
||||
/**
|
||||
* Changes size of file.
|
||||
*
|
||||
* @param fd must be open for writing
|
||||
* @param length may be greater than current current file size, in which
|
||||
* case System V guarantees it'll be zero'd but Windows NT doesn't;
|
||||
* since the prior extends logically and the latter physically
|
||||
* @return 0 on success, or -1 w/ errno
|
||||
* @asyncsignalsafe
|
||||
* @see fallocate()
|
||||
*/
|
||||
int ftruncate(int fd, int64_t length) {
|
||||
if (!IsWindows()) {
|
||||
return ftruncate$sysv(fd, length);
|
||||
} else {
|
||||
return ftruncate$nt(fd, length);
|
||||
}
|
||||
}
|
43
libc/calls/g_fds.c
Normal file
43
libc/calls/g_fds.c
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/bits/pushpop.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/sysv/consts/fileno.h"
|
||||
|
||||
struct Fds g_fds;
|
||||
|
||||
INITIALIZER(300, _init_g_fds, {
|
||||
struct Fds *fds;
|
||||
fds = VEIL("D", &g_fds);
|
||||
pushmov(&fds->f, 3ul);
|
||||
pushmov(&fds->n, ARRAYLEN(fds->__init_p));
|
||||
fds->p = fds->__init_p;
|
||||
fds->__init_p[STDIN_FILENO].kind = pushpop(kFdFile);
|
||||
fds->__init_p[STDOUT_FILENO].kind = pushpop(kFdFile);
|
||||
fds->__init_p[STDERR_FILENO].kind = pushpop(kFdFile);
|
||||
fds->__init_p[STDIN_FILENO].handle = GetStdHandle(pushpop(kNtStdInputHandle));
|
||||
fds->__init_p[STDOUT_FILENO].handle =
|
||||
GetStdHandle(pushpop(kNtStdOutputHandle));
|
||||
fds->__init_p[STDERR_FILENO].handle =
|
||||
GetStdHandle(pushpop(kNtStdErrorHandle));
|
||||
})
|
30
libc/calls/g_ntstartupinfo.c
Normal file
30
libc/calls/g_ntstartupinfo.c
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/nt/startupinfo.h"
|
||||
#include "libc/nt/struct/startupinfo.h"
|
||||
|
||||
/**
|
||||
* GetStartupInfo() singleton.
|
||||
* @see libc/runtime/winmain.c
|
||||
*/
|
||||
struct NtStartupInfo g_ntstartupinfo;
|
||||
|
||||
STATIC_YOINK("_init_g_ntstartupinfo");
|
27
libc/calls/g_ntstartupinfo_init.S
Normal file
27
libc/calls/g_ntstartupinfo_init.S
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.h"
|
||||
.yoink __FILE__
|
||||
|
||||
.init.start 400,_init_g_ntstartupinfo
|
||||
ezlea g_ntstartupinfo,cx
|
||||
mov %rsp,%rbp
|
||||
ntcall __imp_GetStartupInfoW
|
||||
.init.end 400,_init_g_ntstartupinfo,globl,hidden
|
30
libc/calls/g_ntsysteminfo.c
Normal file
30
libc/calls/g_ntsysteminfo.c
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/nt/struct/systeminfo.h"
|
||||
#include "libc/nt/systeminfo.h"
|
||||
|
||||
/**
|
||||
* GetSystemInfo() singleton.
|
||||
* @see libc/runtime/winmain.c
|
||||
*/
|
||||
struct NtSystemInfo g_ntsysteminfo;
|
||||
|
||||
STATIC_YOINK("_init_g_ntsysteminfo");
|
27
libc/calls/g_ntsysteminfo_init.S
Normal file
27
libc/calls/g_ntsysteminfo_init.S
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.h"
|
||||
.yoink __FILE__
|
||||
|
||||
.init.start 400,_init_g_ntsysteminfo
|
||||
ezlea g_ntsysteminfo,cx
|
||||
mov %rsp,%rbp
|
||||
ntcall __imp_GetSystemInfo
|
||||
.init.end 400,_init_g_ntsysteminfo,globl,hidden
|
22
libc/calls/g_sighandrvas.c
Normal file
22
libc/calls/g_sighandrvas.c
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
|
||||
int g_sighandrvas[NSIG];
|
70
libc/calls/getauxval.c
Normal file
70
libc/calls/getauxval.c
Normal file
|
@ -0,0 +1,70 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/dce.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/auxv.h"
|
||||
|
||||
/**
|
||||
* Returns auxiliary value, or zero if kernel didn't provide it.
|
||||
*
|
||||
* This function is typically regarded as a libc implementation detail;
|
||||
* thus, the source code is the documentation.
|
||||
*
|
||||
* @see libc/sysv/consts.sh
|
||||
* @see System Five Application Binary Interface § 3.4.3
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
unsigned long getauxval(unsigned long at) {
|
||||
unsigned long res = 0;
|
||||
if (at != -1) {
|
||||
if (!IsWindows()) {
|
||||
if (!g_auxv) return 0;
|
||||
if (IsXnu()) {
|
||||
if (at) {
|
||||
const char *name =
|
||||
at == AT_EXECFN ? "executable_path" : (const char *)at;
|
||||
const char **auxv = (const char **)g_auxv;
|
||||
unsigned namelen = strlen(name);
|
||||
for (int i = 0; auxv[i]; ++i) {
|
||||
if (strncmp(auxv[i], name, namelen) == 0 &&
|
||||
auxv[i][namelen] == '=') {
|
||||
res = (intptr_t)&auxv[i][namelen + 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (const unsigned long *ap = g_auxv; *ap; ap += 2) {
|
||||
if (ap[0] == at) {
|
||||
res = ap[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* TODO(jart): GetProcessImageFileName */
|
||||
}
|
||||
if (res == 0 && at == AT_EXECFN) {
|
||||
res = (uintptr_t)program_invocation_name;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
37
libc/calls/getcwd-nt.c
Normal file
37
libc/calls/getcwd-nt.c
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
textwindows char *getcwd$nt(char *buf, size_t size) {
|
||||
uint16_t name16[PATH_MAX];
|
||||
if (GetCurrentDirectory(PATH_MAX, name16)) {
|
||||
if (tprecode16to8(buf, size, name16) < size - 1) {
|
||||
return buf;
|
||||
} else {
|
||||
erange();
|
||||
}
|
||||
} else {
|
||||
winerr();
|
||||
}
|
||||
return NULL;
|
||||
}
|
57
libc/calls/getcwd.c
Normal file
57
libc/calls/getcwd.c
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
* Returns current working directory.
|
||||
*
|
||||
* @param buf is where UTF-8 NUL-terminated path string gets written,
|
||||
* which may be NULL to ask this function to malloc a buffer
|
||||
* @param size is number of bytes available in buf, e.g. PATH_MAX,
|
||||
* which may be 0 if buf NULL
|
||||
* @return buf containing system-normative path or NULL w/ errno
|
||||
* @see get_current_dir_name() which is better
|
||||
* @error ERANGE, EINVAL
|
||||
*/
|
||||
char *(getcwd)(char *buf, size_t size) {
|
||||
buf[0] = '\0';
|
||||
if (!IsWindows()) {
|
||||
int olderr = errno;
|
||||
if (getcwd$sysv(buf, size) != NULL) {
|
||||
return buf;
|
||||
} else if (IsXnu() && errno == ENOSYS) {
|
||||
if (size >= 2) {
|
||||
buf[0] = '.'; /* XXX: could put forth more effort */
|
||||
buf[1] = '\0';
|
||||
errno = olderr;
|
||||
return buf;
|
||||
} else {
|
||||
erange();
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
} else {
|
||||
return getcwd$nt(buf, size);
|
||||
}
|
||||
}
|
38
libc/calls/getenv.c
Normal file
38
libc/calls/getenv.c
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/bits/safemacros.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
/**
|
||||
* Returns value of environment variable, or NULL if not found.
|
||||
*/
|
||||
char *getenv(const char *name) {
|
||||
char *empty[1] = {NULL};
|
||||
char **ep = firstnonnull(environ, empty);
|
||||
unsigned namelen = strlen(name);
|
||||
for (int i = 0; ep[i]; ++i) {
|
||||
if (strncmp(ep[i], name, namelen) == 0 && ep[i][namelen] == '=') {
|
||||
return &ep[i][namelen + 1];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
36
libc/calls/getfiledescriptorsize.c
Normal file
36
libc/calls/getfiledescriptorsize.c
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/stat.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/nt/files.h"
|
||||
|
||||
/**
|
||||
* Determines size of open file.
|
||||
*
|
||||
* @return file byte length, or -1ul w/ errno
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
size_t getfiledescriptorsize(int fd) {
|
||||
struct stat st;
|
||||
if (fstat(fd, &st) == -1) return SIZE_MAX;
|
||||
return st.st_size;
|
||||
}
|
38
libc/calls/getfilesize.c
Normal file
38
libc/calls/getfilesize.c
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/struct/stat.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
/**
|
||||
* Returns the byte length of file by path.
|
||||
*
|
||||
* @return number of bytes, or -1ul w/ errno
|
||||
* @see getfiledescriptorsize
|
||||
*/
|
||||
size_t GetFileSize(const char *pathname) {
|
||||
struct stat st;
|
||||
if (stat(pathname, &st) == -1) return SIZE_MAX;
|
||||
return st.st_size;
|
||||
}
|
55
libc/calls/getntsyspath.S
Normal file
55
libc/calls/getntsyspath.S
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.h"
|
||||
.yoink __FILE__
|
||||
|
||||
/ Obtains WIN32 magic path, e.g. GetTempPathA.
|
||||
/
|
||||
/ @param rax is address of ANSI path provider function
|
||||
/ @param rdi is output buffer
|
||||
/ @param rdx is output buffer size in bytes that's >0
|
||||
/ @return eax is string length w/ NUL that's ≤ edx
|
||||
/ @return rdi is rdi+edx
|
||||
.text.startup
|
||||
__getntsyspath:
|
||||
push %rbp
|
||||
mov %rsp,%rbp
|
||||
push %rdx
|
||||
movpp %rdi,%rcx # call f=%rax(p1=%rcx,p2=%rdx)
|
||||
sub $40,%rsp
|
||||
call *%rax
|
||||
xor %edx,%edx
|
||||
mov -8(%rbp),%ecx # restore %edx param as %ecx
|
||||
cmp %eax,%ecx # use current dir on overflow
|
||||
cmovbe %edx,%eax
|
||||
cmp $1,%eax # leave empty strings empty
|
||||
jbe 1f
|
||||
cmpb $'\\,-1(%rdi,%rax) # guarantee trailing slash
|
||||
je 1f
|
||||
movw $'\\,(%rdi,%rax)
|
||||
inc %eax
|
||||
1: inc %rdi # change backslash to slash
|
||||
cmpb $'\\,-1(%rdi)
|
||||
jne 2f
|
||||
movb $'/,-1(%rdi)
|
||||
2: loop 1b
|
||||
leave
|
||||
ret
|
||||
.endfn __getntsyspath,globl,hidden
|
54
libc/calls/getpid.c
Normal file
54
libc/calls/getpid.c
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/nt/process.h"
|
||||
#include "libc/runtime/missioncritical.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
|
||||
static int g_pid;
|
||||
|
||||
static void __updatepid(void) {
|
||||
atfork(__updatepid, NULL);
|
||||
g_pid = __getpid();
|
||||
}
|
||||
|
||||
int __getpid(void) {
|
||||
if (!IsWindows()) {
|
||||
return GETPID();
|
||||
} else {
|
||||
return NtGetPid();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns process id.
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
int getpid(void) {
|
||||
static bool once;
|
||||
if (!once) {
|
||||
once = true;
|
||||
__updatepid();
|
||||
}
|
||||
return g_pid;
|
||||
}
|
53
libc/calls/getppid.c
Normal file
53
libc/calls/getppid.c
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/nt/nt/process.h"
|
||||
#include "libc/nt/ntdll.h"
|
||||
#include "libc/nt/process.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/struct/processbasicinformation.h"
|
||||
|
||||
static textwindows noinline int32_t getppid$nt(void) {
|
||||
struct NtProcessBasicInformation ProcessInformation;
|
||||
uint32_t gotsize = 0;
|
||||
if (!NtError(
|
||||
NtQueryInformationProcess(GetCurrentProcess(), 0, &ProcessInformation,
|
||||
sizeof(ProcessInformation), &gotsize)) &&
|
||||
gotsize >= sizeof(ProcessInformation) &&
|
||||
ProcessInformation.InheritedFromUniqueProcessId) {
|
||||
/* TODO(jart): Fix type mismatch and do we need to close this? */
|
||||
return ProcessInformation.InheritedFromUniqueProcessId;
|
||||
}
|
||||
return GetCurrentProcessId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns parent process id.
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
int32_t getppid(void) {
|
||||
if (!IsWindows()) {
|
||||
return getppid$sysv();
|
||||
} else {
|
||||
return getppid$nt();
|
||||
}
|
||||
}
|
50
libc/calls/getpriority-nt.c
Normal file
50
libc/calls/getpriority-nt.c
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/kntprioritycombos.h"
|
||||
#include "libc/conv/conv.h"
|
||||
#include "libc/nt/enum/processcreationflags.h"
|
||||
#include "libc/nt/enum/threadpriority.h"
|
||||
#include "libc/nt/process.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/thread.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/sysv/consts/prio.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
textwindows int getpriority$nt(int ignored) {
|
||||
size_t i;
|
||||
uint32_t tier, lg2tier, wut;
|
||||
if ((tier = GetPriorityClass(GetCurrentProcess())) != 0 &&
|
||||
(wut = GetThreadPriority(GetCurrentThread())) != -1u) {
|
||||
lg2tier = ffs(tier);
|
||||
for (i = 0; i < kNtPriorityCombosLen; ++i) {
|
||||
if (kNtPriorityCombos[i].lg2tier == lg2tier &&
|
||||
kNtPriorityCombos[i].wut == wut) {
|
||||
return kNtPriorityCombos[i].nice;
|
||||
}
|
||||
}
|
||||
abort();
|
||||
} else {
|
||||
return winerr();
|
||||
}
|
||||
}
|
37
libc/calls/getpriority.c
Normal file
37
libc/calls/getpriority.c
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
|
||||
/**
|
||||
* Returns nice value of thing.
|
||||
*
|
||||
* @param which can be PRIO_PROCESS, PRIO_PGRP, PRIO_USER
|
||||
* @param who is the pid, pgid, or uid (0 means current)
|
||||
* @return value ∈ [-NZERO,NZERO) or -1 w/ errno
|
||||
* @see setpriority(), nice()
|
||||
*/
|
||||
int getpriority(int which, unsigned who) {
|
||||
if (!IsWindows()) {
|
||||
return getpriority$sysv(which, who) - 20;
|
||||
} else {
|
||||
return getsetpriority$nt(which, who, 0, getpriority$nt);
|
||||
}
|
||||
}
|
28
libc/calls/getprocaddressmodule.c
Normal file
28
libc/calls/getprocaddressmodule.c
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/nt/dll.h"
|
||||
#include "libc/calls/calls.h"
|
||||
|
||||
/**
|
||||
* Returns address of function in a DLL that's already loaded.
|
||||
*/
|
||||
textwindows void *getprocaddressmodule(const char *module, const char *symbol) {
|
||||
return GetProcAddress(GetModuleHandle(module), symbol);
|
||||
}
|
37
libc/calls/getrlimit.c
Normal file
37
libc/calls/getrlimit.c
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
* Gets resource limit for current process.
|
||||
*
|
||||
* @param resource can be RLIMIT_{CPU,FSIZE,DATA,STACK,CORE,RSS,etc.}
|
||||
* @param rlim receives result, modified only on success
|
||||
* @return 0 on success or -1 w/ errno
|
||||
* @see libc/sysv/consts.sh
|
||||
*/
|
||||
int getrlimit(int resource, struct rlimit *rlim) {
|
||||
/* TODO(jart): Windows */
|
||||
if (resource == -1) return einval();
|
||||
return getrlimit$sysv(resource, rlim);
|
||||
}
|
65
libc/calls/getrusage.c
Normal file
65
libc/calls/getrusage.c
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/struct/rusage.h"
|
||||
#include "libc/conv/conv.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/nt/accounting.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/struct/filetime.h"
|
||||
#include "libc/nt/thread.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/rusage.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
static textwindows noinline int getrusage$nt(int who, struct rusage *usage) {
|
||||
struct NtFileTime CreationFileTime;
|
||||
struct NtFileTime ExitFileTime;
|
||||
struct NtFileTime KernelFileTime;
|
||||
struct NtFileTime UserFileTime;
|
||||
memset(usage, 0, sizeof(*usage));
|
||||
if ((who == RUSAGE_SELF ? GetProcessTimes : GetThreadTimes)(
|
||||
(who == RUSAGE_SELF ? GetCurrentProcess : GetCurrentThread)(),
|
||||
&CreationFileTime, &ExitFileTime, &KernelFileTime, &UserFileTime)) {
|
||||
filetimetotimeval(&usage->ru_utime, UserFileTime);
|
||||
filetimetotimeval(&usage->ru_stime, KernelFileTime);
|
||||
return 0;
|
||||
} else {
|
||||
return winerr();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns resource usage statistics.
|
||||
*
|
||||
* @param who can be RUSAGE_{SELF,CHILDREN,THREAD}
|
||||
* @return 0 on success, or -1 w/ errno
|
||||
*/
|
||||
int getrusage(int who, struct rusage *usage) {
|
||||
if (who == 99) return enosys(); /* @see libc/sysv/consts.sh */
|
||||
if (!usage) return efault();
|
||||
if (!IsWindows()) {
|
||||
return getrusage$sysv(who, usage);
|
||||
} else {
|
||||
return getrusage$nt(who, usage);
|
||||
}
|
||||
}
|
30
libc/calls/getsetpriority-nt.c
Normal file
30
libc/calls/getsetpriority-nt.c
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/conv/conv.h"
|
||||
#include "libc/sysv/consts/prio.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
textwindows int getsetpriority$nt(int which, unsigned who, int value,
|
||||
int (*impl)(int)) {
|
||||
if (which != PRIO_PROCESS && which != PRIO_PGRP) return einval();
|
||||
if (who && abs(who) != getpid() && abs(who) != gettid()) return eopnotsupp();
|
||||
return impl(value);
|
||||
}
|
40
libc/calls/gettid.c
Normal file
40
libc/calls/gettid.c
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/nt/thread.h"
|
||||
|
||||
/**
|
||||
* Returns current thread id.
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
uint32_t gettid(void) {
|
||||
if (!IsWindows()) {
|
||||
uint32_t res;
|
||||
res = gettid$sysv();
|
||||
if (res <= 0) {
|
||||
res = getpid();
|
||||
}
|
||||
return res;
|
||||
} else {
|
||||
return GetCurrentThreadId();
|
||||
}
|
||||
}
|
73
libc/calls/getuid.c
Normal file
73
libc/calls/getuid.c
Normal file
|
@ -0,0 +1,73 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/nt/accounting.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/str/knuthmultiplicativehash.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/auxv.h"
|
||||
|
||||
static textwindows noinline uint32_t GetUserNameHash(void) {
|
||||
char16_t buf[257];
|
||||
uint32_t size = ARRAYLEN(buf);
|
||||
GetUserName(&buf, &size);
|
||||
return KnuthMultiplicativeHash32(buf, size >> 1);
|
||||
}
|
||||
|
||||
static uint32_t getuidgid(int at, uint32_t impl(void)) {
|
||||
if (!IsWindows()) {
|
||||
if (at != -1) {
|
||||
return getauxval(at);
|
||||
} else {
|
||||
return impl();
|
||||
}
|
||||
} else {
|
||||
return GetUserNameHash();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns real user id of process.
|
||||
*
|
||||
* This never fails. On Windows, which doesn't really have this concept,
|
||||
* we return a deterministic value that's likely to work. On Linux, this
|
||||
* is fast.
|
||||
*
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
uint32_t getuid(void) {
|
||||
return getuidgid(AT_UID, getuid$sysv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns real group id of process.
|
||||
*
|
||||
* This never fails. On Windows, which doesn't really have this concept,
|
||||
* we return a deterministic value that's likely to work. On Linux, this
|
||||
* is fast.
|
||||
*
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
uint32_t getgid(void) {
|
||||
return getuidgid(AT_GID, getgid$sysv);
|
||||
}
|
22
libc/calls/grantpt.c
Normal file
22
libc/calls/grantpt.c
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
|
||||
int grantpt(int fd) { return 0; }
|
44
libc/calls/growfds.c
Normal file
44
libc/calls/growfds.c
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
int growfds(void) {
|
||||
size_t i, n;
|
||||
struct Fd *p;
|
||||
if (weaken(realloc)) {
|
||||
if ((p = weaken(realloc)(g_fds.p != g_fds.__init_p ? g_fds.p : NULL,
|
||||
(n = ((i = g_fds.n) * 2)) * sizeof(*p)))) {
|
||||
do {
|
||||
p[i++].kind = kFdEmpty;
|
||||
} while (i < n);
|
||||
g_fds.p = p;
|
||||
g_fds.n = n;
|
||||
return 0;
|
||||
} else {
|
||||
return enomem();
|
||||
}
|
||||
} else {
|
||||
return emfile();
|
||||
}
|
||||
}
|
41
libc/calls/hefty/access.c
Normal file
41
libc/calls/hefty/access.c
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/dce.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/sysv/consts/at.h"
|
||||
|
||||
/**
|
||||
* Checks if effective user can access path in particular ways.
|
||||
*
|
||||
* @param path is a filename or directory
|
||||
* @param mode can be R_OK, W_OK, X_OK, F_OK
|
||||
* @return 0 if ok, or -1 and sets errno
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
int access(const char *path, int mode) {
|
||||
if (!IsWindows()) {
|
||||
return faccessat$sysv(AT_FDCWD, path, mode, 0);
|
||||
} else {
|
||||
char16_t path16[PATH_MAX];
|
||||
if (mkntpath(path, path16) == -1) return -1;
|
||||
return ntaccesscheck(path16, mode);
|
||||
}
|
||||
}
|
170
libc/calls/hefty/commandv.c
Normal file
170
libc/calls/hefty/commandv.c
Normal file
|
@ -0,0 +1,170 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/alg/alg.h"
|
||||
#include "libc/bits/progn.h"
|
||||
#include "libc/bits/safemacros.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/conv/conv.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/nt/ntdll.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/ok.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
static struct critbit0 g_commandv;
|
||||
|
||||
textstartup static void g_commandv_init(void) {
|
||||
__cxa_atexit(critbit0_clear, &g_commandv, NULL);
|
||||
}
|
||||
|
||||
const void *const g_commandv_ctor[] initarray = {g_commandv_init};
|
||||
|
||||
static int accessexe(char pathname[hasatleast PATH_MAX], size_t len,
|
||||
const char *ext) {
|
||||
len = stpcpy(&pathname[len], ext) - &pathname[0];
|
||||
if (access(pathname, X_OK) != -1) {
|
||||
return len;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static int accesscmd(char pathname[hasatleast PATH_MAX], const char *path,
|
||||
const char *name, size_t namelen) { /* cf. %PATHEXT% */
|
||||
int rc;
|
||||
char *p;
|
||||
bool hasdot;
|
||||
size_t pathlen, len;
|
||||
pathlen = strlen(path);
|
||||
if (pathlen + 1 + namelen + 1 + 4 + 1 > PATH_MAX) return -1;
|
||||
p = mempcpy(pathname, path, pathlen);
|
||||
if (pathlen) *p++ = '/';
|
||||
p = mempcpy(p, name, namelen);
|
||||
len = p - &pathname[0];
|
||||
hasdot = !!memchr(basename(name), '.', namelen);
|
||||
if ((hasdot && (rc = accessexe(pathname, len, "")) != -1) ||
|
||||
(!hasdot &&
|
||||
((rc = accessexe(pathname, len, ".com")) != -1 ||
|
||||
(IsWindows() && (rc = accessexe(pathname, len, ".exe")) != -1) ||
|
||||
(!IsWindows() && (rc = accessexe(pathname, len, "")) != -1)))) {
|
||||
return rc;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static int searchcmdpath(char pathname[hasatleast PATH_MAX], const char *name,
|
||||
size_t namelen) {
|
||||
int rc;
|
||||
char *ep, *path, *pathtok;
|
||||
struct critbit0 deduplicate;
|
||||
rc = -1;
|
||||
pathtok = ep =
|
||||
strdup(firstnonnull(getenv("PATH"), "/bin:/usr/local/bin:/usr/bin"));
|
||||
memset(&deduplicate, 0, sizeof(deduplicate));
|
||||
while ((path = strsep(&pathtok, IsWindows() ? ";" : ":"))) {
|
||||
if (strchr(path, '=')) continue;
|
||||
if (!critbit0_insert(&deduplicate, path)) continue;
|
||||
if ((rc = accesscmd(pathname, path, name, namelen)) != -1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
critbit0_clear(&deduplicate);
|
||||
free(ep);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static char *mkcmdquery(const char *name, size_t namelen,
|
||||
char scratch[hasatleast PATH_MAX]) {
|
||||
char *p;
|
||||
if (namelen + 1 + 1 > PATH_MAX) return NULL;
|
||||
p = mempcpy(scratch, name, namelen);
|
||||
*p++ = '=';
|
||||
*p++ = '\0';
|
||||
if (IsWindows() || IsXnu()) strntolower(scratch, namelen);
|
||||
return &scratch[0];
|
||||
}
|
||||
|
||||
static const char *cachecmd(const char *name, size_t namelen,
|
||||
const char *pathname, size_t pathnamelen) {
|
||||
size_t entrylen;
|
||||
char *res, *entry;
|
||||
if ((entry = malloc((entrylen = namelen + 1 + pathnamelen) + 1))) {
|
||||
mkcmdquery(name, namelen, entry);
|
||||
res = memcpy(&entry[namelen + 1], pathname, pathnamelen + 1);
|
||||
critbit0_emplace(&g_commandv, entry, entrylen);
|
||||
} else {
|
||||
res = NULL;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static const char *getcmdcache(const char *name, size_t namelen,
|
||||
char scratch[hasatleast PATH_MAX]) {
|
||||
const char *entry;
|
||||
if ((entry = critbit0_get(&g_commandv, mkcmdquery(name, namelen, scratch)))) {
|
||||
return &entry[namelen + 1];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
noinline static const char *findcmdpath(const char *name,
|
||||
char pathname[hasatleast PATH_MAX]) {
|
||||
char *p;
|
||||
int rc, olderr;
|
||||
size_t len;
|
||||
olderr = errno;
|
||||
if (!(len = strlen(name))) return PROGN(enoent(), NULL);
|
||||
if (memchr(name, '=', len)) return PROGN(einval(), NULL);
|
||||
if ((p = getcmdcache(name, len, pathname)) ||
|
||||
(((IsWindows() &&
|
||||
((rc = accesscmd(pathname, kNtSystemDirectory, name, len)) != -1 ||
|
||||
(rc = accesscmd(pathname, kNtWindowsDirectory, name, len)) != -1)) ||
|
||||
(rc = accesscmd(pathname, "", name, len)) != -1 ||
|
||||
(!strpbrk(name, "/\\") &&
|
||||
(rc = searchcmdpath(pathname, name, len)) != -1)) &&
|
||||
(p = cachecmd(name, len, pathname, rc)))) {
|
||||
errno = olderr;
|
||||
return p;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves pathname of executable.
|
||||
*
|
||||
* This does the same thing as `command -v` in bourne shell. Path
|
||||
* lookups are cached for the lifetime of the process. Paths with
|
||||
* multiple components will skip the resolution process. Undotted
|
||||
* basenames get automatic .com and .exe suffix resolution on all
|
||||
* platforms. Windows' system directories will always trump PATH.
|
||||
*
|
||||
* @return execve()'able path, or NULL w/ errno
|
||||
* @errno ENOENT, EACCES, ENOMEM
|
||||
* @see free(), execvpe()
|
||||
*/
|
||||
const char *commandv(const char *name) {
|
||||
char pathname[PATH_MAX];
|
||||
return findcmdpath(name, pathname);
|
||||
}
|
190
libc/calls/hefty/dirstream.c
Normal file
190
libc/calls/hefty/dirstream.c
Normal file
|
@ -0,0 +1,190 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/bits/progn.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/struct/dirent.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/struct/win32finddata.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/dt.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
struct dirstream {
|
||||
int64_t tell;
|
||||
int64_t fd;
|
||||
union {
|
||||
struct {
|
||||
unsigned buf_pos;
|
||||
unsigned buf_end;
|
||||
char buf[BUFSIZ];
|
||||
};
|
||||
struct {
|
||||
struct dirent winent;
|
||||
char __d_name[PATH_MAX];
|
||||
bool isdone;
|
||||
struct NtWin32FindData windata;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
static textwindows noinline DIR *opendir$nt(const char *name) {
|
||||
int len;
|
||||
DIR *res;
|
||||
char16_t name16[PATH_MAX];
|
||||
if ((len = mkntpath(name, name16)) == -1) return NULL;
|
||||
if (len + 2 + 1 > PATH_MAX) return PROGN(enametoolong(), NULL);
|
||||
if (name16[len - 1] == u'/' || name16[len - 1] == u'\\') {
|
||||
name16[--len] = u'\0';
|
||||
}
|
||||
name16[len++] = u'/';
|
||||
name16[len++] = u'*';
|
||||
name16[len] = u'\0';
|
||||
if (!(res = calloc(1, sizeof(DIR)))) return NULL;
|
||||
if ((res->fd = FindFirstFile(name16, &res->windata)) != -1) {
|
||||
return res;
|
||||
} else {
|
||||
winerr();
|
||||
free(res);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens directory so readdir() and closedir() may be called.
|
||||
*
|
||||
* @returns newly allocated DIR object, or NULL w/ errno
|
||||
* @errors ENOENT, ENOTDIR, EACCES, EMFILE, ENFILE, ENOMEM
|
||||
*/
|
||||
DIR *opendir(const char *name) {
|
||||
if (!IsWindows() && !IsXnu()) {
|
||||
int fd;
|
||||
DIR *res = NULL;
|
||||
if ((fd = open(name, O_RDONLY | O_DIRECTORY | O_CLOEXEC, 0)) != -1) {
|
||||
if (!(res = fdopendir(fd))) close(fd);
|
||||
}
|
||||
return res;
|
||||
} else if (IsWindows()) {
|
||||
return opendir$nt(name);
|
||||
} else {
|
||||
enosys(); /* TODO(jart): Implement me! */
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates directory object for file descriptor.
|
||||
*
|
||||
* @param fd gets owned by this function, if it succeeds
|
||||
* @return new directory object, which must be freed by closedir(),
|
||||
* or NULL w/ errno
|
||||
* @errors ENOMEM and fd is closed
|
||||
*/
|
||||
DIR *fdopendir(int fd) {
|
||||
if (!IsWindows() && !IsXnu()) {
|
||||
DIR *dir;
|
||||
if ((dir = calloc(1, sizeof(*dir)))) {
|
||||
dir->fd = fd;
|
||||
return dir;
|
||||
}
|
||||
} else {
|
||||
enosys(); /* TODO(jart): Implement me! */
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads next entry from DIR.
|
||||
*
|
||||
* This API doesn't define any particular ordering.
|
||||
*
|
||||
* @param dir is the object opendir() or fdopendir() returned
|
||||
* @return next entry or NULL on end or error, which can be
|
||||
* differentiated by setting errno to 0 beforehand
|
||||
*/
|
||||
struct dirent *readdir(DIR *dir) {
|
||||
if (!IsWindows()) {
|
||||
if (dir->buf_pos >= dir->buf_end) {
|
||||
int rc;
|
||||
if (!(rc = getdents(dir->fd, dir->buf, BUFSIZ)) || rc == -1) {
|
||||
return NULL;
|
||||
}
|
||||
dir->buf_pos = 0;
|
||||
dir->buf_end = rc;
|
||||
}
|
||||
/* TODO(jart): Check FreeBSD and OpenBSD again regarding this */
|
||||
char *record = dir->buf + dir->buf_pos;
|
||||
char *name = record + 8 + 8 + 2;
|
||||
size_t namelen = strlen(name);
|
||||
unsigned char dtype = name[namelen + 1];
|
||||
memmove(name + 1, name, namelen + 1); /* shove forward one byte */
|
||||
*name = dtype; /* is dirent d_type field */
|
||||
struct dirent *ent = (void *)record;
|
||||
dir->buf_pos += ent->d_reclen;
|
||||
dir->tell = ent->d_off;
|
||||
return ent;
|
||||
} else {
|
||||
if (dir->isdone) return NULL;
|
||||
struct dirent *ent = &dir->winent;
|
||||
memset(ent, 0, sizeof(*ent));
|
||||
ent->d_reclen =
|
||||
sizeof(*ent) +
|
||||
tprecode16to8(ent->d_name, PATH_MAX, dir->windata.cFileName) + 1;
|
||||
dir->isdone = FindNextFile(dir->fd, &dir->windata);
|
||||
return ent;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes directory object returned by opendir().
|
||||
* @return 0 on success or -1 w/ errno
|
||||
*/
|
||||
int closedir(DIR *dir) {
|
||||
int rc;
|
||||
if (dir) {
|
||||
if (!IsWindows()) {
|
||||
rc = close(dir->fd);
|
||||
} else {
|
||||
rc = FindClose(dir->fd) ? 0 : winerr();
|
||||
}
|
||||
free(dir);
|
||||
} else {
|
||||
rc = 0;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns current byte offset into directory data.
|
||||
*/
|
||||
long telldir(DIR *dir) {
|
||||
return dir->tell;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns file descriptor associated with DIR object.
|
||||
*/
|
||||
int dirfd(DIR *dir) {
|
||||
return dir->fd;
|
||||
}
|
47
libc/calls/hefty/execl.c
Normal file
47
libc/calls/hefty/execl.c
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/calls/hefty/mkvarargv.h"
|
||||
#include "libc/calls/calls.h"
|
||||
|
||||
/**
|
||||
* Executes program, with current environment.
|
||||
*
|
||||
* The current process is replaced with the executed one.
|
||||
*
|
||||
* @param prog will not be PATH searched, see execlp()
|
||||
* @param arg[0] is the name of the program to run
|
||||
* @param arg[1,n-2] optionally specify program arguments
|
||||
* @param arg[n-1] is NULL
|
||||
* @return doesn't return on success, otherwise -1 w/ errno
|
||||
* @notasyncsignalsafe (TODO)
|
||||
*/
|
||||
int execl(const char *exe, const char *arg, ... /*, NULL*/) {
|
||||
va_list va;
|
||||
void *argv;
|
||||
va_start(va, arg);
|
||||
if ((argv = mkvarargv(arg, va))) {
|
||||
execve(exe, argv, environ);
|
||||
free(argv);
|
||||
}
|
||||
va_end(va);
|
||||
return -1;
|
||||
}
|
48
libc/calls/hefty/execle.c
Normal file
48
libc/calls/hefty/execle.c
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/calls/hefty/mkvarargv.h"
|
||||
#include "libc/calls/calls.h"
|
||||
|
||||
/**
|
||||
* Executes program, with custom environment.
|
||||
*
|
||||
* The current process is replaced with the executed one.
|
||||
*
|
||||
* @param prog will not be PATH searched, see commandv()
|
||||
* @param arg[0] is the name of the program to run
|
||||
* @param arg[1,n-3] optionally specify program arguments
|
||||
* @param arg[n-2] is NULL
|
||||
* @param arg[n-1] is a pointer to a ["key=val",...,NULL] array
|
||||
* @return doesn't return on success, otherwise -1 w/ errno
|
||||
* @notasyncsignalsafe (TODO)
|
||||
*/
|
||||
int execle(const char *exe, const char *arg,
|
||||
... /*, NULL, char *const envp[] */) {
|
||||
va_list va;
|
||||
void *argv;
|
||||
va_start(va, arg);
|
||||
if ((argv = mkvarargv(arg, va))) {
|
||||
execve(exe, argv, va_arg(va, char *const *));
|
||||
free(argv);
|
||||
}
|
||||
va_end(va);
|
||||
return -1;
|
||||
}
|
50
libc/calls/hefty/execlp.c
Normal file
50
libc/calls/hefty/execlp.c
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/calls/hefty/mkvarargv.h"
|
||||
#include "libc/calls/calls.h"
|
||||
|
||||
/**
|
||||
* Executes program, with PATH search and current environment.
|
||||
*
|
||||
* The current process is replaced with the executed one.
|
||||
*
|
||||
* @param prog is program to launch (may be PATH searched)
|
||||
* @param arg[0] is the name of the program to run
|
||||
* @param arg[1,n-2] optionally specify program arguments
|
||||
* @param arg[n-1] is NULL
|
||||
* @return doesn't return on success, otherwise -1 w/ errno
|
||||
* @notasyncsignalsafe
|
||||
*/
|
||||
int execlp(const char *prog, const char *arg, ... /*, NULL*/) {
|
||||
char *exe;
|
||||
if ((exe = commandv(prog))) {
|
||||
va_list va;
|
||||
void *argv;
|
||||
va_start(va, arg);
|
||||
if ((argv = mkvarargv(arg, va))) {
|
||||
execve(exe, argv, environ);
|
||||
free(argv);
|
||||
}
|
||||
va_end(va);
|
||||
}
|
||||
return -1;
|
||||
}
|
29
libc/calls/hefty/execv.c
Normal file
29
libc/calls/hefty/execv.c
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/calls/calls.h"
|
||||
|
||||
/**
|
||||
* Replaces process with specific program, using default environment.
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
int execv(const char *exe, char *const argv[]) {
|
||||
return execve(exe, argv, environ);
|
||||
}
|
55
libc/calls/hefty/execve-nt.c
Normal file
55
libc/calls/hefty/execve-nt.c
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/hefty/internal.h"
|
||||
#include "libc/calls/hefty/ntspawn.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/nt/enum/startf.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/struct/startupinfo.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/fileno.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/sysv/consts/sock.h"
|
||||
|
||||
static textwindows int64_t passstdhand$nt(int fd) {
|
||||
if (g_fds.p[fd].kind != kFdEmpty &&
|
||||
!(g_fds.p[fd].flags &
|
||||
(g_fds.p[fd].kind == kFdSocket ? SOCK_CLOEXEC : O_CLOEXEC))) {
|
||||
return g_fds.p[fd].handle;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
textwindows int execve$nt(const char *program, char *const argv[],
|
||||
char *const envp[]) {
|
||||
struct NtStartupInfo startinfo;
|
||||
memset(&startinfo, 0, sizeof(startinfo));
|
||||
startinfo.cb = sizeof(struct NtStartupInfo);
|
||||
startinfo.dwFlags = kNtStartfUsestdhandles;
|
||||
startinfo.hStdInput = passstdhand$nt(STDIN_FILENO);
|
||||
startinfo.hStdOutput = passstdhand$nt(STDOUT_FILENO);
|
||||
startinfo.hStdError = passstdhand$nt(STDERR_FILENO);
|
||||
if (ntspawn(program, argv, envp, NULL, NULL, true, 0, NULL, &startinfo,
|
||||
NULL) != -1) {
|
||||
for (;;) TerminateProcess(GetCurrentProcess(), 0);
|
||||
}
|
||||
return -1;
|
||||
}
|
43
libc/calls/hefty/execve.c
Normal file
43
libc/calls/hefty/execve.c
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/hefty/internal.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
|
||||
/**
|
||||
* Replaces current process with program.
|
||||
*
|
||||
* @param program will not be PATH searched, see commandv()
|
||||
* @param argv[0] is the name of the program to run
|
||||
* @param argv[1,n-2] optionally specify program arguments
|
||||
* @param argv[n-1] is NULL
|
||||
* @param envp[0,n-2] specifies "foo=bar" environment variables
|
||||
* @param envp[n-1] is NULL
|
||||
* @return doesn't return, or -1 w/ errno
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
int execve(const char *program, char *const argv[], char *const envp[]) {
|
||||
if (!IsWindows()) {
|
||||
return execve$sysv(program, argv, envp);
|
||||
} else {
|
||||
return execve$nt(program, argv, envp);
|
||||
}
|
||||
}
|
29
libc/calls/hefty/execvp.c
Normal file
29
libc/calls/hefty/execvp.c
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/calls/calls.h"
|
||||
|
||||
/**
|
||||
* Replaces process, with path search, using default environment.
|
||||
* @notasyncsignalsafe
|
||||
*/
|
||||
int execvp(const char *file, char *const argv[]) {
|
||||
return execvpe(file, argv, environ);
|
||||
}
|
40
libc/calls/hefty/execvpe.c
Normal file
40
libc/calls/hefty/execvpe.c
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/calls/calls.h"
|
||||
|
||||
/**
|
||||
* Executes program, with path environment search.
|
||||
*
|
||||
* The current process is replaced with the executed one.
|
||||
*
|
||||
* @param prog is the program to launch
|
||||
* @param argv is [file,argv₁..argvₙ₋₁,NULL]
|
||||
* @param envp is ["key=val",...,NULL]
|
||||
* @return doesn't return on success, otherwise -1 w/ errno
|
||||
* @notasyncsignalsafe
|
||||
*/
|
||||
int execvpe(const char *prog, char *const argv[], char *const *envp) {
|
||||
char *exe;
|
||||
if ((exe = commandv(prog))) {
|
||||
execve(exe, argv, envp);
|
||||
}
|
||||
return -1;
|
||||
}
|
44
libc/calls/hefty/faccessat.c
Normal file
44
libc/calls/hefty/faccessat.c
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/sysv/consts/at.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
* Checks if effective user can access path in particular ways.
|
||||
*
|
||||
* @param dirfd is usually AT_FDCWD
|
||||
* @param path is a filename or directory
|
||||
* @param flags can be R_OK, W_OK, X_OK, F_OK
|
||||
* @return 0 if ok, or -1 and sets errno
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
int faccessat(int dirfd, const char *path, int mode, uint32_t flags) {
|
||||
if (!IsWindows()) {
|
||||
return faccessat$sysv(dirfd, path, mode, flags);
|
||||
} else {
|
||||
char16_t path16[PATH_MAX];
|
||||
if (dirfd != AT_FDCWD || flags) return einval();
|
||||
if (mkntpath(path, path16) == -1) return -1;
|
||||
return ntaccesscheck(path16, mode);
|
||||
}
|
||||
}
|
78
libc/calls/hefty/filecmp.c
Normal file
78
libc/calls/hefty/filecmp.c
Normal file
|
@ -0,0 +1,78 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/alg/alg.h"
|
||||
#include "libc/bits/safemacros.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/madv.h"
|
||||
#include "libc/sysv/consts/map.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/sysv/consts/prot.h"
|
||||
|
||||
static void *filecmp$mmap(int fd, size_t size) {
|
||||
return size ? mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0) : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares contents of files with memcmp().
|
||||
*
|
||||
* @return ≤0, 0, or ≥0 based on comparison; or ≠0 on error, in which
|
||||
* case we make our best effort to sift failing filenames rightward,
|
||||
* and errno can be set to 0 beforehand to differentiate errors
|
||||
*/
|
||||
int filecmp(const char *pathname1, const char *pathname2) {
|
||||
int res, olderr;
|
||||
int fd1 = -1;
|
||||
int fd2 = -1;
|
||||
char *addr1 = MAP_FAILED;
|
||||
char *addr2 = MAP_FAILED;
|
||||
size_t size1 = 0;
|
||||
size_t size2 = 0;
|
||||
if ((fd1 = open(pathname1, O_RDONLY)) != -1 &&
|
||||
(fd2 = open(pathname2, O_RDONLY)) != -1 &&
|
||||
(size1 = getfiledescriptorsize(fd1)) != -1 &&
|
||||
(size2 = getfiledescriptorsize(fd2)) != -1 &&
|
||||
(addr1 = filecmp$mmap(fd1, size1)) != MAP_FAILED &&
|
||||
(addr2 = filecmp$mmap(fd2, size2)) != MAP_FAILED) {
|
||||
olderr = errno;
|
||||
madvise(addr1, size1, MADV_WILLNEED | MADV_SEQUENTIAL);
|
||||
madvise(addr2, size2, MADV_WILLNEED | MADV_SEQUENTIAL);
|
||||
errno = olderr;
|
||||
res = memcmp(addr1, addr2, min(size1, size2));
|
||||
if (!res && size1 != size2) {
|
||||
char kNul = '\0';
|
||||
if (size1 > size2) {
|
||||
res = cmpub(addr1 + size2, &kNul);
|
||||
} else {
|
||||
res = cmpub(addr2 + size1, &kNul);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
res = cmpuq(&fd1, &fd2) | 1;
|
||||
}
|
||||
olderr = errno;
|
||||
munmap(addr1, size1);
|
||||
munmap(addr2, size2);
|
||||
close(fd1);
|
||||
close(fd2);
|
||||
errno = olderr;
|
||||
return res;
|
||||
}
|
40
libc/calls/hefty/get_current_dir_name.c
Normal file
40
libc/calls/hefty/get_current_dir_name.c
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/safemacros.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
* Returns current working directory.
|
||||
*
|
||||
* If the PWD environment variable is set, that'll be returned (since
|
||||
* it's faster than issuing a system call).
|
||||
*
|
||||
* @return pointer that must be free()'d, or NULL w/ errno
|
||||
*/
|
||||
nodiscard char *get_current_dir_name(void) {
|
||||
char *buf, *res;
|
||||
if ((res = getenv("PWD"))) return strdup(res);
|
||||
if (!(buf = malloc(PATH_MAX))) return NULL;
|
||||
if (!(res = (getcwd)(buf, PATH_MAX))) free(buf);
|
||||
return res;
|
||||
}
|
73
libc/calls/hefty/hefty.mk
Normal file
73
libc/calls/hefty/hefty.mk
Normal file
|
@ -0,0 +1,73 @@
|
|||
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
||||
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# Cosmopolitan System Call Compatibility Layer
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# This subpackage exports functions traditionally understood as system
|
||||
# calls that Cosmopolitan needs to wrap in a nontrivial way, requiring
|
||||
# things like dynamic memory allocation.
|
||||
|
||||
PKGS += LIBC_CALLS_HEFTY
|
||||
|
||||
LIBC_CALLS_HEFTY_ARTIFACTS += LIBC_CALLS_HEFTY_A
|
||||
LIBC_CALLS_HEFTY = $(LIBC_CALLS_HEFTY_A_DEPS) $(LIBC_CALLS_HEFTY_A)
|
||||
LIBC_CALLS_HEFTY_A = o/$(MODE)/libc/calls/hefty/hefty.a
|
||||
LIBC_CALLS_HEFTY_A_FILES := $(wildcard libc/calls/hefty/*)
|
||||
LIBC_CALLS_HEFTY_A_HDRS = $(filter %.h,$(LIBC_CALLS_HEFTY_A_FILES))
|
||||
LIBC_CALLS_HEFTY_A_SRCS_S = $(filter %.S,$(LIBC_CALLS_HEFTY_A_FILES))
|
||||
LIBC_CALLS_HEFTY_A_SRCS_C = $(filter %.c,$(LIBC_CALLS_HEFTY_A_FILES))
|
||||
|
||||
LIBC_CALLS_HEFTY_A_SRCS = \
|
||||
$(LIBC_CALLS_HEFTY_A_SRCS_S) \
|
||||
$(LIBC_CALLS_HEFTY_A_SRCS_C)
|
||||
|
||||
LIBC_CALLS_HEFTY_A_OBJS = \
|
||||
$(LIBC_CALLS_HEFTY_A_SRCS:%=o/$(MODE)/%.zip.o) \
|
||||
$(LIBC_CALLS_HEFTY_A_SRCS_S:%.S=o/$(MODE)/%.o) \
|
||||
$(LIBC_CALLS_HEFTY_A_SRCS_C:%.c=o/$(MODE)/%.o)
|
||||
|
||||
LIBC_CALLS_HEFTY_A_CHECKS = \
|
||||
$(LIBC_CALLS_HEFTY_A).pkg \
|
||||
$(LIBC_CALLS_HEFTY_A_HDRS:%=o/$(MODE)/%.ok)
|
||||
|
||||
LIBC_CALLS_HEFTY_A_DIRECTDEPS = \
|
||||
LIBC_ALG \
|
||||
LIBC_CONV \
|
||||
LIBC_FMT \
|
||||
LIBC_MEM \
|
||||
LIBC_STR \
|
||||
LIBC_NEXGEN32E \
|
||||
LIBC_RUNTIME \
|
||||
LIBC_CALLS \
|
||||
LIBC_STUBS \
|
||||
LIBC_NT_KERNELBASE \
|
||||
LIBC_SYSV_CALLS \
|
||||
LIBC_SYSV
|
||||
|
||||
LIBC_CALLS_HEFTY_A_DEPS := \
|
||||
$(call uniq,$(foreach x,$(LIBC_CALLS_HEFTY_A_DIRECTDEPS),$($(x))))
|
||||
|
||||
$(LIBC_CALLS_HEFTY_A): \
|
||||
libc/calls/hefty/ \
|
||||
$(LIBC_CALLS_HEFTY_A).pkg \
|
||||
$(LIBC_CALLS_HEFTY_A_OBJS)
|
||||
|
||||
$(LIBC_CALLS_HEFTY_A).pkg: \
|
||||
$(LIBC_CALLS_HEFTY_A_OBJS) \
|
||||
$(foreach x,$(LIBC_CALLS_HEFTY_A_DIRECTDEPS),$($(x)_A).pkg)
|
||||
|
||||
LIBC_CALLS_HEFTY_LIBS = $(foreach x,$(LIBC_CALLS_HEFTY_ARTIFACTS),$($(x)))
|
||||
LIBC_CALLS_HEFTY_SRCS = $(foreach x,$(LIBC_CALLS_HEFTY_ARTIFACTS),$($(x)_SRCS))
|
||||
LIBC_CALLS_HEFTY_HDRS = $(foreach x,$(LIBC_CALLS_HEFTY_ARTIFACTS),$($(x)_HDRS))
|
||||
LIBC_CALLS_HEFTY_BINS = $(foreach x,$(LIBC_CALLS_HEFTY_ARTIFACTS),$($(x)_BINS))
|
||||
LIBC_CALLS_HEFTY_CHECKS = $(foreach x,$(LIBC_CALLS_HEFTY_ARTIFACTS),$($(x)_CHECKS))
|
||||
LIBC_CALLS_HEFTY_OBJS = $(foreach x,$(LIBC_CALLS_HEFTY_ARTIFACTS),$($(x)_OBJS))
|
||||
LIBC_CALLS_HEFTY_TESTS = $(foreach x,$(LIBC_CALLS_HEFTY_ARTIFACTS),$($(x)_TESTS))
|
||||
$(LIBC_CALLS_HEFTY_OBJS): $(BUILD_FILES) libc/calls/hefty/hefty.mk
|
||||
|
||||
.PHONY: o/$(MODE)/libc/calls/hefty
|
||||
o/$(MODE)/libc/calls/hefty: $(LIBC_CALLS_HEFTY_CHECKS)
|
14
libc/calls/hefty/internal.h
Normal file
14
libc/calls/hefty/internal.h
Normal file
|
@ -0,0 +1,14 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_CALLS_HEFTY_INTERNAL_H_
|
||||
#define COSMOPOLITAN_LIBC_CALLS_HEFTY_INTERNAL_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
int execve$nt(const char *, char *const[], char *const[]) hidden;
|
||||
int spawnve$nt(unsigned, int[3], const char *, char *const[],
|
||||
char *const[]) hidden;
|
||||
int spawnve$sysv(unsigned, int[3], const char *, char *const[],
|
||||
char *const[]) hidden;
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_CALLS_HEFTY_INTERNAL_H_ */
|
98
libc/calls/hefty/mkntcmdline.c
Normal file
98
libc/calls/hefty/mkntcmdline.c
Normal file
|
@ -0,0 +1,98 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/alg/arraylist2.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/hefty/ntspawn.h"
|
||||
#include "libc/conv/conv.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/nexgen32e/hascharacter.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/fileno.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
#define APPENDCHAR(C) \
|
||||
do { \
|
||||
if (mkntcmdline_append(&cmdline_p, &cmdline_i, &cmdline_n, C) == -1) { \
|
||||
goto error; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static int mkntcmdline_append(char16_t **p, size_t *i, size_t *n, char16_t c) {
|
||||
return APPEND(p, i, n, &c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts System V argv to Windows-style command line.
|
||||
*
|
||||
* Escaping is performed and it's designed to round-trip with
|
||||
* getdosargv() or getdosargv(). This function does NOT escape
|
||||
* command interpreter syntax, e.g. $VAR (sh), %VAR% (cmd).
|
||||
*
|
||||
* @param argv is an a NULL-terminated array of UTF-8 strings
|
||||
* @return freshly allocated lpCommandLine or NULL w/ errno
|
||||
* @kudos Daniel Colascione for teaching how to quote
|
||||
* @see libc/runtime/dosargv.c
|
||||
*/
|
||||
hidden textwindows nodiscard char16_t *mkntcmdline(char *const argv[]) {
|
||||
wint_t wc;
|
||||
size_t i, j;
|
||||
char16_t cbuf[2];
|
||||
char16_t *cmdline_p = NULL;
|
||||
size_t cmdline_i = 0;
|
||||
size_t cmdline_n = 0;
|
||||
if (argv[0]) {
|
||||
for (i = 0; argv[i]; ++i) {
|
||||
if (i) APPENDCHAR(u' ');
|
||||
bool needsquote = !argv[i] || !!argv[i][strcspn(argv[i], " \t\n\v\"")];
|
||||
if (needsquote) APPENDCHAR(u'"');
|
||||
for (j = 0;;) {
|
||||
if (needsquote) {
|
||||
int slashes = 0;
|
||||
while (argv[i][j] && argv[i][j] == u'\\') slashes++, j++;
|
||||
slashes <<= 1;
|
||||
if (argv[i][j] == u'"') slashes++;
|
||||
while (slashes--) APPENDCHAR(u'\\');
|
||||
}
|
||||
if (!argv[i][j]) break;
|
||||
j += abs(tpdecode(&argv[i][j], &wc));
|
||||
if (CONCAT(&cmdline_p, &cmdline_i, &cmdline_n, cbuf,
|
||||
abs(pututf16(cbuf, ARRAYLEN(cbuf), wc, false))) == -1) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
if (needsquote) APPENDCHAR(u'"');
|
||||
}
|
||||
APPENDCHAR(u'\0');
|
||||
if (cmdline_i > CMD_MAX) {
|
||||
e2big();
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
einval();
|
||||
}
|
||||
return cmdline_p;
|
||||
error:
|
||||
free(cmdline_p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#undef APPENDCHAR
|
69
libc/calls/hefty/mkntenvblock.c
Normal file
69
libc/calls/hefty/mkntenvblock.c
Normal file
|
@ -0,0 +1,69 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/alg/arraylist2.h"
|
||||
#include "libc/calls/hefty/ntspawn.h"
|
||||
#include "libc/conv/conv.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
* Copies sorted environment variable block for Windows.
|
||||
*
|
||||
* This is designed to meet the requirements of CreateProcess().
|
||||
*
|
||||
* @param envp is an a NULL-terminated array of UTF-8 strings
|
||||
* @return freshly allocated lpEnvironment or NULL w/ errno
|
||||
*/
|
||||
textwindows char16_t *mkntenvblock(char *const envp[]) {
|
||||
size_t block_i = 0;
|
||||
size_t block_n = 0;
|
||||
char16_t *block_p = NULL;
|
||||
size_t i, j;
|
||||
if (!(envp = sortenvp(envp))) goto error;
|
||||
const char16_t kNul = u'\0';
|
||||
for (i = 0; envp[i]; ++i) {
|
||||
unsigned consumed;
|
||||
for (j = 0;; j += consumed) {
|
||||
wint_t wc;
|
||||
char16_t cbuf[2];
|
||||
consumed = abs(tpdecode(&envp[i][j], &wc));
|
||||
if (CONCAT(&block_p, &block_i, &block_n, cbuf,
|
||||
abs(pututf16(cbuf, ARRAYLEN(cbuf), wc, false))) == -1) {
|
||||
goto error;
|
||||
}
|
||||
if (!wc) break;
|
||||
}
|
||||
}
|
||||
if (APPEND(&block_p, &block_i, &block_n, &kNul) == -1) {
|
||||
goto error;
|
||||
}
|
||||
if (block_i > ENV_MAX) {
|
||||
e2big();
|
||||
goto error;
|
||||
}
|
||||
free(envp);
|
||||
return block_p;
|
||||
error:
|
||||
free(envp);
|
||||
free(block_p);
|
||||
return NULL;
|
||||
}
|
32
libc/calls/hefty/mkvarargv.h
Normal file
32
libc/calls/hefty/mkvarargv.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_CALLS_HEFTY_MKVARARGV_H_
|
||||
#define COSMOPOLITAN_LIBC_CALLS_HEFTY_MKVARARGV_H_
|
||||
#include "libc/alg/arraylist2.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
/**
|
||||
* Turns variadic program arguments into array.
|
||||
*
|
||||
* This is a support function for execl(), execlp(), spawnl(), etc.
|
||||
*
|
||||
* @note type signatures are fubar for these functions
|
||||
*/
|
||||
forceinline void *mkvarargv(const char *arg1, va_list va) {
|
||||
size_t i, n;
|
||||
const char **p, *arg;
|
||||
i = 0;
|
||||
n = 0;
|
||||
p = NULL;
|
||||
arg = arg1;
|
||||
do {
|
||||
if (APPEND(&p, &i, &n, &arg) == -1) {
|
||||
free(p);
|
||||
return NULL;
|
||||
}
|
||||
} while ((arg = va_arg(va, const char *)));
|
||||
return p;
|
||||
}
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_CALLS_HEFTY_MKVARARGV_H_ */
|
87
libc/calls/hefty/ntaccesscheck.c
Normal file
87
libc/calls/hefty/ntaccesscheck.c
Normal file
|
@ -0,0 +1,87 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/nt/enum/accessmask.h"
|
||||
#include "libc/nt/enum/securityinformation.h"
|
||||
#include "libc/nt/errors.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/struct/genericmapping.h"
|
||||
#include "libc/nt/struct/privilegeset.h"
|
||||
#include "libc/nt/struct/securitydescriptor.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/sysv/consts/ok.h"
|
||||
|
||||
/**
|
||||
* Checks if current process has access to folder or file.
|
||||
*
|
||||
* @param flags can have R_OK, W_OK, X_OK, etc.
|
||||
* @return 0 if authorized, or -1 w/ errno
|
||||
* @kudos Aaron Ballman for teaching how to do this
|
||||
* @see libc/sysv/consts.sh
|
||||
*/
|
||||
textwindows int ntaccesscheck(const char16_t *pathname, uint32_t flags) {
|
||||
int rc;
|
||||
bool32 result;
|
||||
int64_t hToken, hImpersonatedToken;
|
||||
uint32_t secsize, granted, privsize;
|
||||
struct NtPrivilegeSet privileges;
|
||||
struct NtGenericMapping mapping;
|
||||
struct NtSecurityDescriptor security;
|
||||
struct NtSecurityDescriptor *psecurity;
|
||||
const uint32_t request = kNtOwnerSecurityInformation |
|
||||
kNtGroupSecurityInformation |
|
||||
kNtDaclSecurityInformation;
|
||||
granted = 0;
|
||||
result = false;
|
||||
psecurity = &security;
|
||||
secsize = sizeof(security);
|
||||
privsize = sizeof(privileges);
|
||||
memset(&privileges, 0, sizeof(privileges));
|
||||
mapping.GenericRead = kNtFileGenericRead;
|
||||
mapping.GenericWrite = kNtFileGenericWrite;
|
||||
mapping.GenericExecute = kNtFileGenericExecute;
|
||||
mapping.GenericAll = kNtFileAllAccess;
|
||||
MapGenericMask(&flags, &mapping);
|
||||
hImpersonatedToken = hToken = -1;
|
||||
if ((GetFileSecurity(pathname, request, psecurity, 0, &secsize) ||
|
||||
(GetLastError() == kNtErrorInsufficientBuffer &&
|
||||
(psecurity = malloc(secsize)) &&
|
||||
GetFileSecurity(pathname, request, psecurity, secsize, &secsize))) &&
|
||||
OpenProcessToken(GetCurrentProcess(),
|
||||
kNtTokenImpersonate | kNtTokenQuery | kNtTokenDuplicate |
|
||||
kNtStandardRightsRead,
|
||||
&hToken) &&
|
||||
DuplicateToken(hToken, kNtSecurityImpersonation, &hImpersonatedToken) &&
|
||||
AccessCheck(psecurity, hImpersonatedToken, flags, &mapping, &privileges,
|
||||
&privsize, &granted, &result) &&
|
||||
(result || flags == F_OK)) {
|
||||
rc = 0;
|
||||
} else {
|
||||
rc = winerr();
|
||||
}
|
||||
free_s(&psecurity);
|
||||
close(hImpersonatedToken);
|
||||
close(hToken);
|
||||
return rc;
|
||||
}
|
88
libc/calls/hefty/ntspawn.c
Normal file
88
libc/calls/hefty/ntspawn.c
Normal file
|
@ -0,0 +1,88 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/alg/alg.h"
|
||||
#include "libc/alg/arraylist.h"
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/bits/safemacros.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/hefty/ntspawn.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/conv/conv.h"
|
||||
#include "libc/nt/process.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/fileno.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
* Spawns process on Windows NT.
|
||||
*
|
||||
* This function delegates to CreateProcess() with UTF-8 → UTF-16
|
||||
* translation and argv escaping. Please note this will NOT escape
|
||||
* command interpreter syntax.
|
||||
*
|
||||
* @param program will not be PATH searched, see commandv()
|
||||
* @param argv[0] is the name of the program to run
|
||||
* @param argv[1,n-2] optionally specifies program arguments
|
||||
* @param argv[n-1] is NULL
|
||||
* @param envp[𝟶,m-2] specifies "foo=bar" environment variables, which
|
||||
* don't need to be passed in sorted order; however, this function
|
||||
* goes faster the closer they are to sorted
|
||||
* @param envp[m-1] is NULL
|
||||
* @param bInheritHandles means handles already marked inheritable will
|
||||
* be inherited; which, assuming the System V wrapper functions are
|
||||
* being used, should mean (1) all files and sockets that weren't
|
||||
* opened with O_CLOEXEC; and (2) all memory mappings
|
||||
* @param opt_out_lpProcessInformation can be used to return process and
|
||||
* thread IDs to parent, as well as open handles that need close()
|
||||
* @return 0 on success, or -1 w/ errno
|
||||
* @see spawnve() which abstracts this function
|
||||
*/
|
||||
textwindows int ntspawn(
|
||||
const char *program, char *const argv[], char *const envp[],
|
||||
struct NtSecurityAttributes *opt_lpProcessAttributes,
|
||||
struct NtSecurityAttributes *opt_lpThreadAttributes, bool32 bInheritHandles,
|
||||
uint32_t dwCreationFlags, const char16_t *opt_lpCurrentDirectory,
|
||||
/*nodiscard*/ const struct NtStartupInfo *lpStartupInfo,
|
||||
struct NtProcessInformation *opt_out_lpProcessInformation) {
|
||||
int rc;
|
||||
char16_t program16[PATH_MAX], *lpCommandLine, *lpEnvironment;
|
||||
lpCommandLine = NULL;
|
||||
lpEnvironment = NULL;
|
||||
if (mkntpath(program, program16) != -1 &&
|
||||
(lpCommandLine = mkntcmdline(argv)) &&
|
||||
(lpEnvironment = mkntenvblock(envp))) {
|
||||
if (CreateProcess(program16, lpCommandLine, opt_lpProcessAttributes,
|
||||
opt_lpThreadAttributes, bInheritHandles,
|
||||
dwCreationFlags | kNtCreateUnicodeEnvironment,
|
||||
lpEnvironment, opt_lpCurrentDirectory, lpStartupInfo,
|
||||
opt_out_lpProcessInformation)) {
|
||||
rc = 0;
|
||||
} else {
|
||||
rc = winerr();
|
||||
}
|
||||
} else {
|
||||
rc = -1;
|
||||
}
|
||||
free(lpCommandLine);
|
||||
free(lpEnvironment);
|
||||
return rc;
|
||||
}
|
20
libc/calls/hefty/ntspawn.h
Normal file
20
libc/calls/hefty/ntspawn.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_CALLS_HEFTY_NTSPAWN_H_
|
||||
#define COSMOPOLITAN_LIBC_CALLS_HEFTY_NTSPAWN_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
struct NtProcessInformation;
|
||||
struct NtSecurityAttributes;
|
||||
struct NtStartupInfo;
|
||||
|
||||
char **sortenvp(char *const[]) hidden nodiscard paramsnonnull();
|
||||
char16_t *mkntcmdline(char *const[]) hidden nodiscard paramsnonnull();
|
||||
char16_t *mkntenvblock(char *const[]) hidden nodiscard paramsnonnull();
|
||||
int ntspawn(const char *, char *const[], char *const[],
|
||||
struct NtSecurityAttributes *, struct NtSecurityAttributes *,
|
||||
bool32, uint32_t, const char16_t *, const struct NtStartupInfo *,
|
||||
struct NtProcessInformation *) paramsnonnull((1, 2, 3, 9)) hidden;
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_CALLS_HEFTY_NTSPAWN_H_ */
|
49
libc/calls/hefty/replaceuser.c
Normal file
49
libc/calls/hefty/replaceuser.c
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/safemacros.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/calls/calls.h"
|
||||
|
||||
/**
|
||||
* Replaces tilde in path w/ user home folder.
|
||||
*
|
||||
* @param path is NULL propagating
|
||||
* @return must be free()'d
|
||||
*/
|
||||
char *replaceuser(const char *path) {
|
||||
char *res, *p;
|
||||
const char *home;
|
||||
size_t pathlen, homelen;
|
||||
res = NULL;
|
||||
if (path && *path++ == '~' && !isempty((home = getenv("HOME")))) {
|
||||
while (*path == '/') path++;
|
||||
pathlen = strlen(path);
|
||||
homelen = strlen(home);
|
||||
while (homelen && home[homelen - 1] == '/') homelen--;
|
||||
if ((p = res = malloc(pathlen + 1 + homelen + 1))) {
|
||||
p = mempcpy(p, home, homelen);
|
||||
*p++ = '/';
|
||||
memcpy(p, path, pathlen + 1);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
89
libc/calls/hefty/slurp.c
Normal file
89
libc/calls/hefty/slurp.c
Normal file
|
@ -0,0 +1,89 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/alg/arraylist2.h"
|
||||
#include "libc/bits/safemacros.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/stat.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/madv.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
|
||||
static size_t getfilesize(int fd) {
|
||||
struct stat st;
|
||||
st.st_size = 0;
|
||||
fstat(fd, &st);
|
||||
return st.st_size;
|
||||
}
|
||||
|
||||
static size_t smudgefilesize(size_t size) {
|
||||
return roundup(size, PAGESIZE) + PAGESIZE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads entire file into memory.
|
||||
*
|
||||
* This function is fantastic for being lazy. It may waste space if the
|
||||
* file is large, but it's implemented in a conscientious way that won't
|
||||
* bomb the systemwide page cache. It means performance too, naturally.
|
||||
*
|
||||
* @return contents which must be free()'d or NULL w/ errno
|
||||
*/
|
||||
char *slurp(const char *path, size_t *opt_out_readlength) {
|
||||
int fd;
|
||||
ssize_t rc;
|
||||
char *res, *p;
|
||||
size_t i, n, got, want;
|
||||
res = NULL;
|
||||
if ((fd = open(path, O_RDONLY)) == -1) goto Failure;
|
||||
n = getfilesize(fd);
|
||||
/* TODO(jart): Fix this, it's totally broken */
|
||||
if (!(res = valloc(smudgefilesize(n)))) goto Failure;
|
||||
if (n > FRAMESIZE) fadvise(fd, 0, n, MADV_SEQUENTIAL);
|
||||
i = 0;
|
||||
for (;;) {
|
||||
want = smudgefilesize(n - i);
|
||||
TryAgain:
|
||||
if ((rc = read(fd, &res[i], want)) == -1) {
|
||||
if (errno == EINTR) goto TryAgain;
|
||||
goto Failure;
|
||||
}
|
||||
got = (size_t)rc;
|
||||
if (i + 1 >= n) {
|
||||
if ((p = realloc(res, smudgefilesize((n += n >> 1))))) {
|
||||
res = p;
|
||||
} else {
|
||||
goto Failure;
|
||||
}
|
||||
}
|
||||
i += got;
|
||||
if (got == 0) break;
|
||||
if (got > want) abort();
|
||||
}
|
||||
if (opt_out_readlength) *opt_out_readlength = i;
|
||||
res[i] = '\0';
|
||||
close(fd);
|
||||
return res;
|
||||
Failure:
|
||||
free(res);
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
68
libc/calls/hefty/sortenvp.c
Normal file
68
libc/calls/hefty/sortenvp.c
Normal file
|
@ -0,0 +1,68 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/alg/alg.h"
|
||||
#include "libc/alg/arraylist.h"
|
||||
#include "libc/calls/hefty/ntspawn.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/nexgen32e/tinystrcmp.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
static int sortenvpcb(const char **a, const char **b) { return strcmp(*a, *b); }
|
||||
|
||||
static void slowsort(char **a, int n) {
|
||||
size_t i, j;
|
||||
const char *t;
|
||||
for (i = 1; i < n; ++i) {
|
||||
j = i;
|
||||
t = a[i];
|
||||
while (j > 0 && tinystrcmp(t, a[j - 1]) < 0) {
|
||||
a[j] = a[j - 1];
|
||||
--j;
|
||||
}
|
||||
a[j] = t;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies environment variable pointers and sorts them.
|
||||
*
|
||||
* This is useful for (a) binary searching; and (b) keeping the NT
|
||||
* Executive happy, which wants strings to be ordered by UNICODE
|
||||
* codepoint identifiers. That's basically what uint8_t comparisons on
|
||||
* UTF8-encoded data gives us.
|
||||
*
|
||||
* @param envp is a NULL-terminated string array
|
||||
* @return newly allocated sorted copy of envp pointer array
|
||||
*/
|
||||
hidden textwindows nodiscard char **sortenvp(char *const envp[]) {
|
||||
size_t count = 0;
|
||||
while (envp[count]) count++;
|
||||
size_t bytesize = (count + 1) * sizeof(char *);
|
||||
char **copy = malloc(bytesize);
|
||||
if (copy) {
|
||||
memcpy(copy, envp, bytesize);
|
||||
if (IsTiny()) {
|
||||
slowsort(copy, count);
|
||||
} else {
|
||||
qsort(copy, count, sizeof(char *), (void *)sortenvpcb);
|
||||
}
|
||||
}
|
||||
return copy;
|
||||
}
|
26
libc/calls/hefty/spawn.h
Normal file
26
libc/calls/hefty/spawn.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_CALLS_HEFTY_SPAWN_H_
|
||||
#define COSMOPOLITAN_LIBC_CALLS_HEFTY_SPAWN_H_
|
||||
|
||||
#define SPAWN_DETACH 1
|
||||
#define SPAWN_TABULARASA 2
|
||||
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
int spawnve(unsigned, int[3], const char *, char *const[], char *const[])
|
||||
paramsnonnull((3, 4, 5));
|
||||
int spawnl(unsigned, int[3], const char *, const char *, ...) nullterminated()
|
||||
paramsnonnull((3, 4));
|
||||
int spawnlp(unsigned, int[3], const char *, const char *, ...) nullterminated()
|
||||
paramsnonnull((3, 4));
|
||||
int spawnle(unsigned, int[3], const char *, const char *, ...)
|
||||
nullterminated((1)) paramsnonnull((3, 4));
|
||||
int spawnv(unsigned, int[3], const char *, char *const[]) paramsnonnull((3, 4));
|
||||
int spawnvp(unsigned, int[3], const char *, char *const[])
|
||||
paramsnonnull((3, 4));
|
||||
int spawnvpe(unsigned, int[3], const char *, char *const[], char *const[])
|
||||
paramsnonnull((3, 4, 5));
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_CALLS_HEFTY_SPAWN_H_ */
|
49
libc/calls/hefty/spawnl.c
Normal file
49
libc/calls/hefty/spawnl.c
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/hefty/mkvarargv.h"
|
||||
#include "libc/calls/hefty/spawn.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
|
||||
/**
|
||||
* Launches program, with current environment.
|
||||
*
|
||||
* @param stdiofds may optionally be passed to customize standard i/o
|
||||
* @param stdiofds[𝑖] may be -1 to receive a pipe() fd
|
||||
* @param prog is program to launch (may be PATH searched)
|
||||
* @param arg[0] is the name of the program to run
|
||||
* @param arg[1,n-2] optionally specify program arguments
|
||||
* @param arg[n-1] is NULL
|
||||
* @return pid of child, or -1 w/ errno
|
||||
*/
|
||||
int spawnl(unsigned flags, int stdiofds[3], const char *exe, const char *arg,
|
||||
... /*, NULL*/) {
|
||||
int rc;
|
||||
va_list va;
|
||||
void *argv;
|
||||
rc = -1;
|
||||
va_start(va, arg);
|
||||
if ((argv = mkvarargv(arg, va))) {
|
||||
rc = spawnve(flags, stdiofds, exe, argv, environ);
|
||||
free(argv);
|
||||
}
|
||||
va_end(va);
|
||||
return rc;
|
||||
}
|
53
libc/calls/hefty/spawnlp.c
Normal file
53
libc/calls/hefty/spawnlp.c
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/hefty/mkvarargv.h"
|
||||
#include "libc/calls/hefty/spawn.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
|
||||
/**
|
||||
* Launches program, with PATH search and current environment.
|
||||
*
|
||||
* @param stdiofds may optionally be passed to customize standard i/o
|
||||
* @param stdiofds[𝑖] may be -1 to receive a pipe() fd
|
||||
* @param prog is program to launch (may be PATH searched)
|
||||
* @param arg[0] is the name of the program to run
|
||||
* @param arg[1,n-2] optionally specify program arguments
|
||||
* @param arg[n-1] is NULL
|
||||
* @return pid of child, or -1 w/ errno
|
||||
*/
|
||||
nodiscard int spawnlp(unsigned flags, int stdiofds[3], const char *prog,
|
||||
const char *arg, ... /*, NULL*/) {
|
||||
int pid;
|
||||
char *exe;
|
||||
va_list va;
|
||||
void *argv;
|
||||
pid = -1;
|
||||
if ((exe = commandv(prog))) {
|
||||
va_start(va, arg);
|
||||
if ((argv = mkvarargv(arg, va))) {
|
||||
pid = spawnve(flags, stdiofds, exe, argv, environ);
|
||||
free(argv);
|
||||
}
|
||||
va_end(va);
|
||||
}
|
||||
return pid;
|
||||
}
|
98
libc/calls/hefty/spawnve-nt.c
Normal file
98
libc/calls/hefty/spawnve-nt.c
Normal file
|
@ -0,0 +1,98 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/xchg.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/hefty/internal.h"
|
||||
#include "libc/calls/hefty/ntspawn.h"
|
||||
#include "libc/calls/hefty/spawn.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/nt/enum/startf.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/nt/ipc.h"
|
||||
#include "libc/nt/process.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/startupinfo.h"
|
||||
#include "libc/nt/struct/processinformation.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/fileno.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
|
||||
textwindows int spawnve$nt(unsigned flags, int stdiofds[3], const char *program,
|
||||
char *const argv[], char *const envp[]) {
|
||||
int pid;
|
||||
size_t i;
|
||||
int tubes[3];
|
||||
int64_t handle, h, *x, *y;
|
||||
struct NtStartupInfo sti;
|
||||
struct NtProcessInformation procinfo;
|
||||
|
||||
handle = 0;
|
||||
memset(&sti, 0, sizeof(sti));
|
||||
sti.cb = sizeof(sti);
|
||||
sti.dwFlags = kNtStartfUsestdhandles;
|
||||
|
||||
if ((pid = createfd()) == -1) return -1;
|
||||
|
||||
for (i = 0; i < 3; ++i) {
|
||||
if (stdiofds[i] == -1) {
|
||||
x = &h;
|
||||
y = &sti.stdiofds[i];
|
||||
if (kIoMotion[i]) xchg(&x, &y);
|
||||
if ((tubes[i] = createfd()) != -1 &&
|
||||
CreatePipe(x, y, &kNtIsInheritable, 0)) {
|
||||
g_fds.p[tubes[i]].handle = h;
|
||||
} else {
|
||||
handle = -1;
|
||||
}
|
||||
} else {
|
||||
sti.stdiofds[i] = g_fds.p[stdiofds[i]].handle;
|
||||
}
|
||||
}
|
||||
|
||||
if (handle != -1 &&
|
||||
ntspawn(program, argv, envp, NULL, NULL,
|
||||
(flags & SPAWN_TABULARASA) ? false : true,
|
||||
(flags & SPAWN_DETACH)
|
||||
? (kNtCreateNewProcessGroup | kNtDetachedProcess |
|
||||
kNtCreateBreakawayFromJob)
|
||||
: 0,
|
||||
NULL, &sti, &procinfo) != -1) {
|
||||
CloseHandle(procinfo.hThread);
|
||||
handle = procinfo.hProcess;
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; ++i) {
|
||||
if (stdiofds[i] == -1) {
|
||||
if (handle != -1) {
|
||||
stdiofds[i] = tubes[i];
|
||||
g_fds.p[tubes[i]].kind = kFdFile;
|
||||
g_fds.p[tubes[i]].flags = O_CLOEXEC;
|
||||
CloseHandle(sti.stdiofds[i]);
|
||||
} else {
|
||||
CloseHandle(tubes[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_fds.p[pid].kind = kFdProcess;
|
||||
g_fds.p[pid].handle = handle;
|
||||
g_fds.p[pid].flags = flags;
|
||||
return pid;
|
||||
}
|
121
libc/calls/hefty/spawnve-sysv.c
Normal file
121
libc/calls/hefty/spawnve-sysv.c
Normal file
|
@ -0,0 +1,121 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program 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; version 2 of the License. │
|
||||
│ │
|
||||
│ This program 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 this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/hefty/internal.h"
|
||||
#include "libc/calls/hefty/spawn.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/conv/conv.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/paths.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/at.h"
|
||||
#include "libc/sysv/consts/fileno.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
|
||||
int spawnve$sysv(unsigned flags, int stdiofds[3], const char *program,
|
||||
char *const argv[], char *const envp[]) {
|
||||
int rc, pid, fd;
|
||||
size_t i, j, len;
|
||||
int32_t tubes[3][2];
|
||||
char **argv2, MZqFpD[8];
|
||||
void *argv3;
|
||||
|
||||
pid = 0;
|
||||
argv2 = NULL;
|
||||
argv3 = argv;
|
||||
|
||||
/*
|
||||
* αcτµαlly pδrταblε εxεcµταblε w/ thompson shell script
|
||||
* morphology needs to be launched via command interpreter.
|
||||
*/
|
||||
if (endswith(program, ".com") || endswith(program, ".exe")) {
|
||||
memset(MZqFpD, 0, sizeof(MZqFpD));
|
||||
fd = openat$sysv(AT_FDCWD, program, O_RDONLY, 0);
|
||||
read$sysv(fd, MZqFpD, sizeof(MZqFpD));
|
||||
close$sysv(fd);
|
||||
if (memcmp(MZqFpD, "MZqFpD", 6) == 0) {
|
||||
/*
|
||||
* If we got this:
|
||||
*
|
||||
* spawn(/bin/echo, [echo, hi, there])
|
||||
*
|
||||
* It will become this:
|
||||
*
|
||||
* spawn(/bin/sh, [sh, /bin/echo, hi, there])
|
||||
*/
|
||||
len = 1;
|
||||
while (argv[len]) len++;
|
||||
if ((argv2 = malloc((2 + len + 1) * sizeof(char *)))) {
|
||||
i = 0, j = 1;
|
||||
argv2[i++] = "sh";
|
||||
argv2[i++] = program;
|
||||
while (j < len) argv2[i++] = argv[j++];
|
||||
argv2[i] = NULL;
|
||||
argv3 = argv2;
|
||||
program = "/bin/sh";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; ++i) {
|
||||
if (stdiofds[i] == -1) {
|
||||
pid |= pipe$sysv(tubes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (pid != -1) {
|
||||
if ((pid = fork$sysv()) == 0) {
|
||||
if (flags & SPAWN_DETACH) {
|
||||
if (setsid() == -1) abort();
|
||||
if ((rc = fork$sysv()) == -1) abort();
|
||||
if (rc > 0) _exit(0);
|
||||
}
|
||||
for (i = 0; i < 3; ++i) {
|
||||
if (stdiofds[i] == -1) {
|
||||
close$sysv(tubes[i][kIoMotion[i]]);
|
||||
fd = tubes[i][!kIoMotion[i]];
|
||||
} else {
|
||||
fd = stdiofds[i];
|
||||
}
|
||||
dup2$sysv(fd, i);
|
||||
}
|
||||
execve$sysv(program, argv3, envp);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; ++i) {
|
||||
if (stdiofds[i] == -1) {
|
||||
close$sysv(tubes[i][!kIoMotion[i]]);
|
||||
fd = tubes[i][kIoMotion[i]];
|
||||
if (pid != -1) {
|
||||
stdiofds[i] = fd;
|
||||
} else {
|
||||
close$sysv(fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (argv2) free(argv2);
|
||||
return pid;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue