Make improvements for Actually Portable Emacs

- Get SIGWINCH working again on the New Technology
- Correctly handle O_NOFOLLOW in open() on Windows
- Implement synthetic umask() functionality on Windows
- Do a better job managing file execute access on Windows
- Fill in `st_uid` and `st_gid` with username hash on Windows
- Munge UNICODE control pictures into control codes on Windows
- Do a better job ensuring Windows console settings are restored
- Introduce KPRINTF_LOG environment variable to log kprintf to a file
This commit is contained in:
Justine Tunney 2023-08-19 06:41:06 -07:00
parent 9c7b81ee0f
commit 965516e313
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
108 changed files with 1126 additions and 807 deletions

View file

@ -17,9 +17,11 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/assert.h"
#include "libc/atomic.h"
#include "libc/calls/calls.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/dce.h"
#include "libc/intrin/atomic.h"
#include "libc/intrin/strace.internal.h"
#include "libc/limits.h"
#include "libc/macros.internal.h"
@ -27,7 +29,7 @@
#include "libc/runtime/runtime.h"
#include "libc/str/str.h"
static uint32_t KnuthMultiplicativeHash32(const void *buf, size_t size) {
static uint32_t __kmp32(const void *buf, size_t size) {
size_t i;
uint32_t h;
const uint32_t kPhiPrime = 0x9e3779b1;
@ -36,18 +38,24 @@ static uint32_t KnuthMultiplicativeHash32(const void *buf, size_t size) {
return h;
}
static textwindows dontinline uint32_t GetUserNameHash(void) {
textwindows uint32_t __synthesize_uid(void) {
char16_t buf[257];
uint32_t size = ARRAYLEN(buf);
GetUserName(&buf, &size);
return KnuthMultiplicativeHash32(buf, size >> 1) & INT_MAX;
static atomic_uint uid;
uint32_t tmp, size = ARRAYLEN(buf);
if (!(tmp = atomic_load_explicit(&uid, memory_order_acquire))) {
GetUserName(&buf, &size);
tmp = __kmp32(buf, size >> 1) & INT_MAX;
if (!tmp) ++tmp;
atomic_store_explicit(&uid, tmp, memory_order_release);
}
return tmp;
}
/**
* 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.
* we return a hash of the username.
*
* @return user id (always successful)
* @asyncsignalsafe
@ -61,7 +69,7 @@ uint32_t getuid(void) {
} else if (!IsWindows()) {
rc = sys_getuid();
} else {
rc = GetUserNameHash();
rc = __synthesize_uid();
}
npassert(rc >= 0);
STRACE("%s() → %d", "getuid", rc);
@ -72,7 +80,7 @@ uint32_t getuid(void) {
* 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.
* we return a hash of the username.
*
* @return group id (always successful)
* @asyncsignalsafe
@ -86,7 +94,7 @@ uint32_t getgid(void) {
} else if (!IsWindows()) {
rc = sys_getgid();
} else {
rc = GetUserNameHash();
rc = __synthesize_uid();
}
npassert(rc >= 0);
STRACE("%s() → %d", "getgid", rc);