mirror of
https://github.com/jart/cosmopolitan.git
synced 2024-05-13 09:02:41 +00:00
Compare commits
7 commits
2c2d483efd
...
7514a9b6b0
Author | SHA1 | Date | |
---|---|---|---|
7514a9b6b0 | |||
38d0728107 | |||
2dfb72d278 | |||
346a78ddc0 | |||
7eaa6a0061 | |||
2a2c1ad806 | |||
69db501c68 |
|
@ -20,6 +20,10 @@
|
|||
|
||||
pthread_spinlock_t _pthread_lock_obj;
|
||||
|
||||
void _pthread_init(void) {
|
||||
(void)pthread_spin_init(&_pthread_lock_obj, 0);
|
||||
}
|
||||
|
||||
void _pthread_lock(void) {
|
||||
pthread_spin_lock(&_pthread_lock_obj);
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/state.internal.h"
|
||||
#include "libc/calls/struct/sigset.h"
|
||||
#include "libc/calls/struct/sigset.internal.h"
|
||||
#include "libc/calls/syscall-nt.internal.h"
|
||||
|
@ -34,12 +35,45 @@
|
|||
#include "libc/nt/thread.h"
|
||||
#include "libc/proc/proc.internal.h"
|
||||
#include "libc/runtime/internal.h"
|
||||
#include "libc/runtime/memtrack.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/runtime/syslib.internal.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
#include "libc/thread/posixthread.internal.h"
|
||||
#include "libc/thread/tls.h"
|
||||
|
||||
static void _onfork_prepare(void) {
|
||||
if (_weaken(_pthread_onfork_prepare)) {
|
||||
_weaken(_pthread_onfork_prepare)();
|
||||
}
|
||||
_pthread_lock();
|
||||
__fds_lock();
|
||||
__mmi_lock();
|
||||
}
|
||||
|
||||
static void _onfork_parent(void) {
|
||||
__mmi_unlock();
|
||||
__fds_unlock();
|
||||
_pthread_unlock();
|
||||
if (_weaken(_pthread_onfork_parent)) {
|
||||
_weaken(_pthread_onfork_parent)();
|
||||
}
|
||||
}
|
||||
|
||||
static void _onfork_child(void) {
|
||||
pthread_mutexattr_t attr;
|
||||
pthread_mutexattr_init(&attr);
|
||||
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
|
||||
extern pthread_mutex_t __mmi_lock_obj;
|
||||
pthread_mutex_init(&__mmi_lock_obj, &attr);
|
||||
pthread_mutex_init(&__fds_lock_obj, &attr);
|
||||
pthread_mutexattr_destroy(&attr);
|
||||
_pthread_init();
|
||||
if (_weaken(_pthread_onfork_child)) {
|
||||
_weaken(_pthread_onfork_child)();
|
||||
}
|
||||
}
|
||||
|
||||
int _fork(uint32_t dwCreationFlags) {
|
||||
struct Dll *e;
|
||||
int ax, dx, tid, parent;
|
||||
|
@ -47,8 +81,8 @@ int _fork(uint32_t dwCreationFlags) {
|
|||
BLOCK_SIGNALS;
|
||||
if (IsWindows())
|
||||
__proc_lock();
|
||||
if (__threaded && _weaken(_pthread_onfork_prepare)) {
|
||||
_weaken(_pthread_onfork_prepare)();
|
||||
if (__threaded) {
|
||||
_onfork_prepare();
|
||||
}
|
||||
if (!IsWindows()) {
|
||||
ax = sys_fork();
|
||||
|
@ -99,14 +133,14 @@ int _fork(uint32_t dwCreationFlags) {
|
|||
atomic_store_explicit(&pt->pt_canceled, false, memory_order_relaxed);
|
||||
|
||||
// run user fork callbacks
|
||||
if (__threaded && _weaken(_pthread_onfork_child)) {
|
||||
_weaken(_pthread_onfork_child)();
|
||||
if (__threaded) {
|
||||
_onfork_child();
|
||||
}
|
||||
STRACE("fork() → 0 (child of %d)", parent);
|
||||
} else {
|
||||
// this is the parent process
|
||||
if (__threaded && _weaken(_pthread_onfork_parent)) {
|
||||
_weaken(_pthread_onfork_parent)();
|
||||
if (__threaded) {
|
||||
_onfork_parent();
|
||||
}
|
||||
if (IsWindows())
|
||||
__proc_unlock();
|
||||
|
|
|
@ -17,42 +17,98 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/syscall_support-nt.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/intrin/safemacros.internal.h"
|
||||
#include "libc/intrin/weaken.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/mem/gc.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/temp.h"
|
||||
#include "libc/x/x.h"
|
||||
|
||||
__static_yoink("__utf16to8");
|
||||
|
||||
static char *get_pagerpath(char *pathbuf, size_t pathbufsz) {
|
||||
char *pagerpath;
|
||||
if (strcmp(nulltoempty(getenv("TERM")), "dumb") && isatty(0) && isatty(1) &&
|
||||
((pagerpath = commandv("less", pathbuf, pathbufsz)) ||
|
||||
(pagerpath = commandv("more", pathbuf, pathbufsz)) ||
|
||||
(pagerpath = commandv("more.exe", pathbuf, pathbufsz)) ||
|
||||
(pagerpath = commandv("more.com", pathbuf, pathbufsz)))) {
|
||||
return pagerpath;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool run_pager(char *args[hasatleast 3]) {
|
||||
char16_t widepath[PATH_MAX];
|
||||
int n, pid;
|
||||
kprintf("utf16to8 %p\n", _weaken(__utf16to8));
|
||||
if (IsWindows() && !strcasecmp(args[0], "/C/Windows/System32/more.com") &&
|
||||
(!_weaken(__utf16to8) || ((n = __mkntpath(args[1], widepath)) == -1) ||
|
||||
!(args[1] = gc(_weaken(__utf16to8)(widepath, n, 0))))) {
|
||||
return false;
|
||||
}
|
||||
if ((pid = fork()) != -1) {
|
||||
putenv("LC_ALL=C.UTF-8");
|
||||
putenv("LESSCHARSET=utf-8");
|
||||
putenv("LESS=-RS");
|
||||
if (!pid) {
|
||||
execv(args[0], args);
|
||||
_Exit(127);
|
||||
}
|
||||
waitpid(pid, 0, 0);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays wall of text in terminal with pagination.
|
||||
*/
|
||||
void __paginate(int fd, const char *s) {
|
||||
int tfd, pid;
|
||||
int tfd;
|
||||
char *args[3] = {0};
|
||||
char tmppath[] = "/tmp/paginate.XXXXXX";
|
||||
char progpath[PATH_MAX];
|
||||
if (strcmp(nulltoempty(getenv("TERM")), "dumb") && isatty(0) && isatty(1) &&
|
||||
((args[0] = commandv("less", progpath, sizeof(progpath))) ||
|
||||
(args[0] = commandv("more", progpath, sizeof(progpath))) ||
|
||||
(args[0] = commandv("more.exe", progpath, sizeof(progpath))))) {
|
||||
bool done;
|
||||
if ((args[0] = get_pagerpath(progpath, sizeof(progpath)))) {
|
||||
if ((tfd = mkstemp(tmppath)) != -1) {
|
||||
write(tfd, s, strlen(s));
|
||||
close(tfd);
|
||||
args[1] = tmppath;
|
||||
if ((pid = fork()) != -1) {
|
||||
putenv("LC_ALL=C.UTF-8");
|
||||
putenv("LESSCHARSET=utf-8");
|
||||
putenv("LESS=-RS");
|
||||
if (!pid) {
|
||||
execv(args[0], args);
|
||||
_Exit(127);
|
||||
}
|
||||
waitpid(pid, 0, 0);
|
||||
unlink(tmppath);
|
||||
done = run_pager(args);
|
||||
unlink(tmppath);
|
||||
if (done) {
|
||||
return;
|
||||
}
|
||||
unlink(tmppath);
|
||||
}
|
||||
}
|
||||
write(fd, s, strlen(s));
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays a file in terminal with pagination
|
||||
*/
|
||||
void __paginate_file(int fd, const char *path) {
|
||||
char *args[3] = {0};
|
||||
char progpath[PATH_MAX];
|
||||
if ((args[0] = get_pagerpath(progpath, sizeof(progpath)))) {
|
||||
args[1] = (char *)path;
|
||||
if (run_pager(args)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
int sfd = open(path, O_RDONLY);
|
||||
if (sfd != -1) {
|
||||
ssize_t n;
|
||||
while ((n = read(sfd, progpath, sizeof(progpath)) > 0)) {
|
||||
write(fd, progpath, n);
|
||||
}
|
||||
}
|
||||
close(sfd);
|
||||
}
|
||||
|
|
|
@ -233,6 +233,7 @@ static textwindows dontinstrument uint32_t __proc_worker(void *arg) {
|
|||
* Lazy initializes process tracker data structures and worker.
|
||||
*/
|
||||
static textwindows void __proc_setup(void) {
|
||||
__enable_threads();
|
||||
__proc.onbirth = CreateEvent(0, 0, 0, 0); // auto reset
|
||||
__proc.haszombies = CreateEvent(0, 1, 0, 0); // manual reset
|
||||
__proc.thread = CreateThread(0, 65536, __proc_worker, 0,
|
||||
|
|
|
@ -103,6 +103,7 @@ int verynice(void);
|
|||
void __warn_if_powersave(void);
|
||||
void _Exit1(int) libcesque wontreturn;
|
||||
void __paginate(int, const char *);
|
||||
void __paginate_file(int, const char *);
|
||||
/* memory management */
|
||||
void _weakfree(void *);
|
||||
void *_mapanon(size_t) attributeallocsize((1)) mallocesque;
|
||||
|
|
|
@ -105,6 +105,7 @@ intptr_t _pthread_syshand(struct PosixThread *) libcesque;
|
|||
long _pthread_cancel_ack(void) libcesque;
|
||||
void _pthread_decimate(void) libcesque;
|
||||
void _pthread_free(struct PosixThread *, bool) libcesque;
|
||||
void _pthread_init(void) libcesque;
|
||||
void _pthread_lock(void) libcesque;
|
||||
void _pthread_onfork_child(void) libcesque;
|
||||
void _pthread_onfork_parent(void) libcesque;
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
#include "libc/macros.internal.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/proc/proc.internal.h"
|
||||
#include "libc/runtime/memtrack.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/thread/posixthread.internal.h"
|
||||
|
@ -47,8 +46,6 @@ static struct AtForks {
|
|||
atomic_int allocated;
|
||||
} _atforks;
|
||||
|
||||
extern pthread_spinlock_t _pthread_lock_obj;
|
||||
|
||||
static void _pthread_onfork(int i) {
|
||||
struct AtFork *a;
|
||||
unassert(0 <= i && i <= 2);
|
||||
|
@ -65,27 +62,13 @@ static void _pthread_onfork(int i) {
|
|||
|
||||
void _pthread_onfork_prepare(void) {
|
||||
_pthread_onfork(0);
|
||||
_pthread_lock();
|
||||
__fds_lock();
|
||||
__mmi_lock();
|
||||
}
|
||||
|
||||
void _pthread_onfork_parent(void) {
|
||||
__mmi_unlock();
|
||||
__fds_unlock();
|
||||
_pthread_unlock();
|
||||
_pthread_onfork(1);
|
||||
}
|
||||
|
||||
void _pthread_onfork_child(void) {
|
||||
pthread_mutexattr_t attr;
|
||||
pthread_mutexattr_init(&attr);
|
||||
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
|
||||
extern pthread_mutex_t __mmi_lock_obj;
|
||||
pthread_mutex_init(&__mmi_lock_obj, &attr);
|
||||
pthread_mutex_init(&__fds_lock_obj, &attr);
|
||||
pthread_mutexattr_destroy(&attr);
|
||||
(void)pthread_spin_init(&_pthread_lock_obj, 0);
|
||||
_pthread_onfork(2);
|
||||
}
|
||||
|
||||
|
|
|
@ -60,6 +60,9 @@ __static_yoink("nsync_mu_trylock");
|
|||
__static_yoink("nsync_mu_rlock");
|
||||
__static_yoink("nsync_mu_runlock");
|
||||
__static_yoink("_pthread_atfork");
|
||||
__static_yoink("_pthread_onfork_prepare");
|
||||
__static_yoink("_pthread_onfork_parent");
|
||||
__static_yoink("_pthread_onfork_child");
|
||||
|
||||
#define MAP_ANON_OPENBSD 0x1000
|
||||
#define MAP_STACK_OPENBSD 0x4000
|
||||
|
|
Loading…
Reference in a new issue