fix: align POSIX stdio and argument handling, clarify Intel iwlwifi licensing
This commit is contained in:
@@ -91,6 +91,14 @@ void _start(void) {
|
||||
|
||||
argbuf[len] = '\0';
|
||||
|
||||
/* Split on spaces, honouring '...' and "..." so an argument can
|
||||
contain them: `git commit -m "two words"` has to reach main()
|
||||
as two arguments, not three. The quotes are removed, and the
|
||||
token is rewritten in place -- the unquoted form is never
|
||||
longer than the quoted one, so it always fits. Quotes are the
|
||||
only metacharacter: there is no escaping and no substitution,
|
||||
which is deliberate. The kernel hands over one flat string
|
||||
(SYS_GETARGS) and this is a tokenizer, not a shell. */
|
||||
char* p = argbuf;
|
||||
while (*p != '\0' && argc < 255) {
|
||||
while (*p == ' ') {
|
||||
@@ -101,15 +109,27 @@ void _start(void) {
|
||||
break;
|
||||
}
|
||||
|
||||
argv[argc++] = p;
|
||||
char* out = p;
|
||||
argv[argc++] = out;
|
||||
|
||||
while (*p != '\0' && *p != ' ') {
|
||||
char quote = 0;
|
||||
while (*p != '\0' && (quote != 0 || *p != ' ')) {
|
||||
if (quote == 0 && (*p == '"' || *p == '\'')) {
|
||||
quote = *p++;
|
||||
} else if (quote != 0 && *p == quote) {
|
||||
quote = 0;
|
||||
p++;
|
||||
} else {
|
||||
*out++ = *p++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Step over the separator before terminating: the write
|
||||
below lands on the byte p is about to leave behind. */
|
||||
if (*p != '\0') {
|
||||
p++;
|
||||
}
|
||||
|
||||
if (*p != '\0') {
|
||||
*p++ = '\0';
|
||||
}
|
||||
*out = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
@@ -2081,8 +2081,35 @@ int open(const char *path, int flags, ...) {
|
||||
return h;
|
||||
}
|
||||
|
||||
/*
|
||||
* The standard descriptors are the terminal, NOT file handles.
|
||||
*
|
||||
* 0/1/2 are not handles the kernel ever issued -- SYS_OPEN allocates from its
|
||||
* own space and would have to return 0 for these to line up, which it does
|
||||
* not. Passing them to SYS_READ/SYS_FWRITE addresses whatever handle happens
|
||||
* to hold that number, or fails: before this, every write(2, ...) was
|
||||
* silently discarded, so a POSIX program that reports errors with write()
|
||||
* rather than fprintf() printed nothing at all. stdio already routes std
|
||||
* streams to SYS_PUTCHAR (see fwrite/fprintf); these do the same, so the two
|
||||
* paths agree.
|
||||
*/
|
||||
int read(int fd, void *buf, size_t count) {
|
||||
if (buf == NULL) return -1;
|
||||
|
||||
if (fd == STDIN_FILENO) {
|
||||
/* Line-oriented, like the terminal itself: return as soon as a
|
||||
line is complete rather than blocking for the full count. */
|
||||
char *dst = (char *)buf;
|
||||
size_t i = 0;
|
||||
while (i < count) {
|
||||
int c = fgetc(stdin);
|
||||
if (c == EOF) break;
|
||||
dst[i++] = (char)c;
|
||||
if (c == '\n') break;
|
||||
}
|
||||
return (int)i;
|
||||
}
|
||||
|
||||
unsigned long pos = (fd >= 0 && fd < _FD_POS_MAX) ? _fd_pos[fd] : 0;
|
||||
int ret = (int)_zos_syscall4(SYS_READ, (long)fd, (long)buf, (long)pos, (long)count);
|
||||
if (ret > 0 && fd >= 0 && fd < _FD_POS_MAX)
|
||||
@@ -2092,6 +2119,14 @@ int read(int fd, void *buf, size_t count) {
|
||||
|
||||
int write(int fd, const void *buf, size_t count) {
|
||||
if (buf == NULL) return -1;
|
||||
|
||||
if (fd == STDOUT_FILENO || fd == STDERR_FILENO) {
|
||||
const char *src = (const char *)buf;
|
||||
for (size_t i = 0; i < count; i++)
|
||||
_zos_syscall1(SYS_PUTCHAR, (long)(unsigned char)src[i]);
|
||||
return (int)count;
|
||||
}
|
||||
|
||||
unsigned long pos = (fd >= 0 && fd < _FD_POS_MAX) ? _fd_pos[fd] : 0;
|
||||
int ret = (int)_zos_syscall4(SYS_FWRITE, (long)fd, (long)buf, (long)pos, (long)count);
|
||||
if (ret > 0 && fd >= 0 && fd < _FD_POS_MAX)
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user