The putc macro is specified as returning an int, but our
type conversion rules turned it into a uint. Put in the
appropriate cast to make the type what we want.
aux/na was comparing the return of putc with <0, when it should
have been comparing against EOF, which is not specified as -ve.
aux/ms2 was zero-extending the mask for the address when it
should have been sign extended.
The current date and time APIs on Plan 9 are not good. They're
inflexible, non-threadsafe, and don't expose timezone information.
This commit adds new time APIs that allow parsing arbitrary
dates, work from multiple threads, and can handle timezones
effectively.
C99 integer constants with no type suffix promote differently
depending on the way that they're written: hex and oct consts
promote as int => uint => long => ulong => vlong => uvlong.
Decimal constants are always signed.
We used to promote all values to uint on overflow, and never
went wider. This change fixes that, and adds a warning when
a decimal constant that would have been promoted to uint in
the past gets promoted to int.
The de-duplication of txt, nullrr, cert, key and sig records
reduced all records to a single one.
Also, dblookup1() missed the txt record case and did not return
a unique list of rr's.
Now we consider these records unique if their value is different.
The new txtequiv() function does that for TXT records, which is
a bit tricky as it needs to take different segmentation into account.
the previous patch broke 64-bit ops as the type for the
operation is determined from the first argument to
gopcode() (nod1.type), not the type the result (nod.type).
so we need to include the conversion of nod1 type to
the type of nod.
the bug can be reproduced with the following test case:
#include <u.h>
#include <libc.h>
void
main()
{
int size = 1;
size*=1.5;
exits(0);
}
this produces the following assembly:
TEXT main+0(SB),0,$16
MOVW $1,R1
FCVTZSDW $1.50000000000000000e+00,R2 <- tries to convert rhs to int??
MULW R2,R1,R2 <- multiplication done in int? bug!
MOV $0,R0
BL ,exits+0(SB)
RETURN ,
END ,
the confusion comes from the *= operation using the wrong type
for the multiplication. in this case we should use the float
type of the rhs, do the operation, and then convert the result
back to int type of the lhs.
this change ports the same logic from 5c's getasop().
Characters greater than 0X80 will cause a read beyond the bounds of the
array chars[]. For particular unicode characters this can cause deroff
to segfault.
A minimal example:
$ deroff
.EQ
u∈
Segmentation fault
Throughout deroff, charclass() is used instead of directly indexing
chars[] so I presume this was just missed.
version(5) says:
If the server does not understand the client's version
string, it should respond with an Rversion message (not
Rerror) with the version string the 7 characters
``unknown''.
Pre-lib9p file servers -- all except cwfs(4) -- do return Rerror.
lib9p(2) follows the above spec, although ignoring the next part
concerning comparison after period-stripping. It assumes an
Fcall.version starting with "9P" is correctly formed and returns
the only supported version of the protocol, which seems alright.
This patch brings pre-lib9p servers in accordance with the spec.
The current logging prints a debug line for every
message in an inbox, which is unusably verbose.
This removes the prints for unchanged messages,
and adds a print for flag changes.
The $SCRIPTS were added to $TARG, which complicates the all rule, as
each script's object file must be suppressed.
Fix by removing $SCRIPTS from $TARG, removing the script object file
suppression rule, and overriding the install rule.
The script bin install rule assumes that only one script install is
called at a time. Valid calls like 'mk -a /$objtype/replica/changes
/$objtype/replica/pull' will fail.
Fix by adding a for loop.
Remove the unused $UPDATE variable.
to reproduce:
ipnet=foo0 ip=192.168.0.0 ipmask=/16
ipnet=foo1 ip=192.168.0.0 ipmask=/24
ip=192.168.0.1 sys=foo2
% ndb/ipquery sys foo2 ipnet ipmask
ipnet=foo0 ipmask=/16
we would expect to get ipnet=foo1 here as it is more
specific subnet.
the solution is to order the subnets by prefix length
in subnet() before calling filter(), so that we process
the longest prefixes first.
ape cp, mv, and cc build with ?c, not pcc
ape cp and mv just ignore one or two extra flags,
instead of providing posix compatibility
it's better to fail then do nothing
remove cp.c and mv.c
move cc.c to /sys/src/ape/9src so it doesn't
need its own mkfile rule
we have to disable interrupts during mmuwalk() of user pages
as we can get preempted during mmu walk and the original
m->pml4 might become one of a different process.
Handle cases where parameterless macros expand to each other:
#define FOO BAR
#define BAR FOO
FOO
There were cases where the macros didn't make it into the hidesets,
and we would recurse infinitely. This fixes that.
This change makes it mandatory for programs to call segflush() on
code that is not in the text segment if they want to execute it.
As a side effect, this means that everything but the text segment
will be non-executable by default, even without the SG_NOEXEC
attribute. Segments with the SG_NOEXEC attribute never become
executable, even when segflush() is called on them.
when wstating a file, its directory should be updated to
reflect this change.
here is what the manpage states:
> The mtime field reflects the time of the last change of content
> (except when later changed by wstat). For a directory it is the
> time of the most recent remove, create, or wstat of a file in the
> directory.
when wstating a file, its directory should be updated to
reflect this change.
here is what the manpage states:
> The mtime field reflects the time of the last change of content
> (except when later changed by wstat). For a directory it is the
> time of the most recent remove, create, or wstat of a file in the
> directory.
When calling putc, we need to return either EOF
or the character returned. To distinguish the
two, we need to avoid sign extending 0xff. The
code attempted to do this, but the order of
operations was wrong, so we ended up masking,
setting a character, and then sign extending
the character.
This fixes things so we mask after assignment.
For big mailboxes with imap4d, ignoring the index and trying to scan
the mailbox concurrently is not very productive. Just wait for the
other upas/fs to write the whole index.
The issue is that imap might time out and make another connection
spawning even more upas/fs instances that all then try to rebuild
the index concurrently.
this breaks interrupt key handling in rio. theres also no
point in trying todo so as rio sends the note to the whole
process group so the subcommand should have got the note
already.
just wait for the subprocess to terminate.
the date, from and replyto fields where unstable, in that the value
read depended on the state of the cache.
fixing the from and replyto fields is easy, we just handle the
substitution in parsebody().
the date field however requires us to put the date822 into the index
so it can be recovered without requiering to reparse the header
(and body, as we might have a message/rfc822 message with promoted
fields).
with these changes, the fields will be consistent and independnet
of the cache state.
a small optimization also has been added:
after parsing the body, attachments and substitution of from/replyto,
the boundary and unixfrom strings are not needed anymore and can
be freed early.
When read() failed, we were casting the -1 return to
unsigned, which would cause us to index out of bounds.
found using dovecot imap test suite. While we're here,
let's remove the stray debug prints.
widen and move the KMAP window to a new address so we can
handle the 8GB of physical memory of the new raspberry pi4.
the new memory map on pi4 uses the following 4 banks:
0x000000000 0x03e600000
0x040000000 0x0fc000000 <- soc.dramsize (only < 4GB)
0x100000000 0x180000000
0x180000000 0x200000000
On the 8GB variant of the raspberry pi 4,
the eeprom chip for the xhci controller is missing and
instead loaded from sdram (by the gpu firmware).
for this, the gpu firmware needs to be notified of
the xhci controllers pci bus address (after reset)
that was assigned by our pci enumeration code.
parsing the unixheader in mdir fetch routine is the wrong place,
as no invalid character handling has been performed yet. also
the string is not neccesarily null terminated.
avoid duplication with plan9 mbox parsing and just do it in
parseheaders(), which already handles faking the unix headers
for pop3 and imap.
instruction cache maintenance is done on tlb miss;
when a page gets fauled in; with putmmu() checking
the page->txtflush cpu bitmap.
syssegflush() used to only call flushmmu() after
segflush() for the calling process, but when a segment
is shared with other processes, we have to flush the
other processes tlb as well.
this adds the missing procflushseg() call into segflush().
note that procflushseg() leaves the calling process alone,
so the flushmmu() call in syssegflush() is still required.
segmentioproc() does not need to call flushmmu() after
segflush() as it is never going to jump to the modified
page, hence the stale icache does not matter.
make sure we look for the end of the header within the
pointer range, and not accidentally read beyond hend.
also, messages are not null terminated, so this could
even go beyond the email data buffer.
get rid of mimeflag which was only used for some assert
checks.
take header length into account when comparing header
against ignored header strings.
The sample frequency is an artificial parameter used for
isochronous out transfers to better match the target
frequency (usually, a sound card).
when hz is set, devusb adjusts the endpoint's maxpkt to get
the requested frequency and a multiple of the samplesize per
packet.
however, when hz is not set, then we should calculate the
frequency from maxpkt, ntds and pollival, so all parameters
will be consistent with each other.
this breaks the sample from the seconds manpage, and overall
produces funky results. this needs alot more testing.
term% seconds '23 may 2011'
seconds: tmparse: invalid date 23 may 2011 near 'may 2011'
term% seconds '2019-01-01 00:00:00'
-118370073600
Redo date handling in libc almost entirely. This allows
handling dates and times from outside your timezones,
fixes timezone loading in multithreaded applications,
and allows parsing and formatting using custom format
strings.
As a test of the APIs, we replace the formatting code in
seconds(1), shrinking it massively.
The last commit missed a few removals, and made it
unnecessarily hard to do an update.
Redo date handling in libc almost entirely. This allows
handling dates and times from outside your timezones,
fixes timezone loading in multithreaded applications,
and allows parsing and formatting using custom format
strings.
As a test of the APIs, we replace the formatting code in
seconds(1), shrinking it massively.
Go expects the error to be one of the three errors returned in
Bell Labs Plan 9. As listed in
f7ba82d68f/src/cmd/go/internal/lockedfile/lockedfile_plan9.go (L16):
// Opening an exclusive-use file returns an error.
// The expected error strings are:
//
// - "open/create -- file is locked" (cwfs, kfs)
// - "exclusive lock" (fossil)
// - "exclusive use file already open" (ramfs)
var lockedErrStrings = [...]string{
"file is locked",
"exclusive lock",
"exclusive use file already open",
}
This brings acme scrolling behaviour in line with that of 9front's rio
and sam, where the amount scrolled varies with a vertical position of
the pointer within the window, similar to how the scrollbar works.
At some point it would be good to implement a line-at-a-time scrolling
when the Shift key is pressed, as seen in rio. For this to happen the
acme keyboard input needs to be rewritten in terms of /dev/kbd instead
of relying on keyboard(2) -- that is, the /dev/cons interface.
Added a ver= field to the filter to distinguish the ip version.
By default, a filter is parsed as ipv6, and after parsing
proto, src and dst fields are converted to ipv4. When no
ver= field is specified, a ip version filter is implicitely
added and both protocols are parsed.
This change also gets rid of the fast compare types as the
filed might not be aligned correctly in the packet.
This also fixes the ifc= filter, as we have to check any
local address.
Based off the following 3 commits:
4a3fb87264f8bc03fc62f00ef335056f30d18023
45f8ba54143323f08a21343633764caa59aa3ea3
fdf6ef333705c844bcf3ccf2f93b2773f1a6aa41
Reading /mnt/acme/log reports a log of window create,
put, focus, and delete events, as they happen. It blocks
until the next event is available.
Example log output:
8 new /Users/rsc/foo.go
8 put /Users/rsc/foo.go
8 del /Users/rsc/foo.go
This lets acme-aware programs react to file writes, for example
compiling code, running a test, or updating an import block.
We used to just return the first address of the incoming
interface regardless of if the address matches the source
ip type and scope.
This change tries to find the best interface address that
will match the source ip so it can be used as a source
address when replying to the packet.
Flags can be runes. That means that we can't just
look at p[1] to decide if we have a named argument,
we need to look one rune forward. This change
does that.
The new command marks the target window as a scratch window -- a window
whose state cannot be "dirtied" by changes made to its body, therefore
avoiding warnings about unsaved changes when deleting the window or
exiting acme.
Existing examples of scratch windows are error, directory, and guide
windows, whose scratchness is set internally.
With the new command users and programs alike can create their own
scratch windows. This is put to use in acme's own win(1).
basically, we want the following commands to print
the same pid twice:
rc -c 'cat /dev/pid &;echo $apid'
vs:
rc -c 'a=1 cat /dev/pid &;echo $apid'
basically, Xsimple() calls exitnext() to determine if
a simple command should be promoted to exec, by peeking
ahead into the code and searching for Xexit instruction.
Xexit might not follow immediately after the Xsimple
instruction because of redirections, which exitnext()
would skip.
but it would not skip the Xunlocal instructions that
where added by the variable assignment.
the maketab helper program was generated in parallel, which
had a dependency to y.tab.h which lead to yacc running
twice in parallel.
this removes the dependency to y.tab.h in the virtual
maketab.$objtype target to prevent this race condition.
the dependency to y.tab.h is resolved in the main mk at the
$cputype.maketab target which serializes with the other
targets.
the page attribute table was initialized in mmuinit(), which is
too late for bootscreen(). So now we check for PAT support and
insert the write-combine entry early in cpuidentify().
this might have been the cause of some slow EFI framebuffers on
machines with overlapping or insufficient MTRR entries.
at the _cas0 label, the linker would generate spurious stack
adjustment before the return:
atexitdont+0x84 0x000000000003614c CLREX $0xf
atexitdont+0x88 0x0000000000036150 MOVW R31,R0
atexitdont+0x8c 0x0000000000036154 MOV (SP)16!,R30 <- ????????????
atexitdont+0x90 0x0000000000036158 RETURN
the work arround is to move the code into its own cas0
text symbol.
this fixes impossible cwfs crashes in srvi().
When passing an absolute file path to yacc, we would skip
initializing inpath, leaving it null. This would cause Bopen
to die. We would similarly fail to report an error if we tried
to get the current working directory, and then die when
constructing inpath.
This fixes both cases.
as with recent changes, cc's malloc() could make the hunk pointer
misaligned. in the the compilers, the hunk pointer is used directly
by the lexer with no effort to to keep the hunk pointer aligned.
alloc/malloc still return aligned pointers, but hunk itself can
be on a odd address after allocation of a odd sized amount of bytes.
however, in the linkers, this assumption appears to be differnet. as
most allocations mostly allocate padded structures. however, symbol
lookup allocates strings on byte-size ganularity and the cc's malloc
would misalign the hunk pointer after the malloc() call. while the
rest of the code assumed hunk pointer was always aligned.
this change removes all the hunk pointer fiddling from the linker,
and we just call malloc() (which will use the fast implmenentation
of cc, and should not really make much of a performance difference).
We're missing type flags for:
hh: char
ll: vlong
z: size_t
t: ptrdiff_t
j: intmax_t
The lack of '%lld' was causing us to fail when parsing
timezone files. This brings us in line with the specifiers
in the C99 standard, section 7.19.6.2p11
ipiput4() and ipiput6() are called with the incoming interface rlocked
while ipoput4() and ipoput6() also rlock() the outgoing interface once
a route has been found. it is common that the incoming and outgoing
interfaces are the same recusive rlocking().
the deadlock happens when a reader holds the rlock for the incoming interface,
then ip/ipconfig tries to add a new address, trying to wlock the interface.
as there are still active readers on the ifc, ip/ipconfig process gets queued
on the inteface RWlock.
now the reader finds the outgoing route which has the same interface as the
incoming packet and tries to rlock the ifc again. but now theres a writer
queued, so we also go to sleep waiting four outselfs to release the lock.
the solution is to never wait for the outgoing interface rlock, but instead
use non-queueing canrlock() and if it cannot be acquired, discard the packet.
do not touch s->map on SG_PHYSICAL type segments as they do
not have a pte map (s->mapsize == 0 && s->map == nil).
also remove the SG_PHYSICAL switch in freepte(), this is never
reached.
the calculation for the control endpoint0 output device context
missed the context size scaling shift, resulting in botched
stall handling as we would not read the correct endpoint status
value.
note, this calculation only affected control endpoint 0, which
was handled separately from all other endpoints.
When a match() fails, we need to unget the character we
tried to match against, rather than leaving it consumed.
Also, we can't break out of a conversion before we reach
the end of a format string, because things like the '%n'
conversion do not consume anything, and should still be
handled.
As said in the code comment:
Elecom trackball report descriptor lies by
omission, failing to mention all its buttons.
We patch the descriptor with a correct count
which lets us parse full reports. Tested with:
Elecom HUGE (M-HT1DRBK, M-HT1URBK)
The descriptor fixup is adapted from Linux kernel:
drivers/hid/hid-elecom.c
in which a more detailed account of why and how this
works may be found.
A followup change to nusb/kb will be needed to expose
these additional events for potential remapping.
spectacular bug. cmpswap() had a sign extension bug
using sign extending MOV to load the old compare
value and LDXRW using zero extension while the CMP
instruction compared 64 bit registers.
this caused cmpswap with negative old value always
to fail.
interestingly, libc's version of this function was
fine.
C99 requires that if intXX_t types are defined, int_fastxx_t and
int_leastxx_t types are defined as well. We define all three to
be identical (intXX_t == int_fastXX_t == int_leastXX_t).
This makes the flagfmt parser more robust and accepting
a looser input language — namely by allowing whitespace
around specifier fields and ignoring any empty fields.
Long flagfmts can thus be pleasingly displayed:
flagfmt='
a, b, c, C:cache,
m:mtpt mountpoint,
s:srvn srvname'
The mount() and bind() syscalls return -1 on error,
and the mountid sequence number on success.
The manpage states that the mountid sequence number
is a positive integer, but the kernels implementation
currently uses a unsigned 32-bit integer and does not
guarantee that the mountid will not become negative.
Most code just cares about the error, so test for
the -1 error value only.
mischief provided the following test that shows the issue:
ramfs -S crash
aux/9pcon /srv/crash <<EOF
Tversion 8192 9P2000
Tattach 0 -1 $user ''
Tcreate 0 dir 020000000777 0
Tattach 5 -1 $user ''
Twalk 5 6 dir
Tread 6 0 512
EOF
the problem is that lib9p wrongly allowed reads on closed fids,
due to the permission check only considering the lower 2 bits.
a closed fid has fid->omode == -1 and it would pass on read for:
(-1 & 3) == 3 == OEXEC
the following change explicitely checks for for the closed case
and also rejects writes on directories (they are rejected on
open/create, but a broken 9p client could still issue the request).
when reclaiming pages from an image, always reclaim all
the hash chains equally. that way, we avoid being biased
towards the chains at the start of the Image.pghash[] array.
images can be in two states: active or inactive. inactive
images are the ones which are not used by program while
active ones aare.
when reclaiming pages, we should try to reclaim pages
from inactive images first and only if that set becomes
exhausted attempt to release text pages and attempt to
reclaim pages from active images.
when we run out of Image structures, it makes only sense
to reclaim pages from inactive images, as reclaiming pages
from active ones will never free any Image structures.
change putimage() to require a image already locked and
make it unlock the image. this avoids many pointless
unlock()/lock() sequences as all callers of putimage()
already had the image locked.
- nil check pl_blue allocation, and don't do it every time pl_rtdraw is called
- fix re-adding previously removed flushimage calls
- correct format for pointer
- sysfatal in pl_drawinit on error
if we do 'CAT(foo bar, baz quux)', the resulting token row
should have 3 tokens: 'foo', 'barbaz', 'quux'.
tested by jonasa, rebuilding /sys/src, perl, netsurf, and nuklear.
Modify aux/kbdfs to work with neo2 layout.
- add new modifier, increase limit on layers.
- Add Kaltgr for mod3
- Add mod4
This change only implements the alphanumeric
block of the keyboard in the kbmap, as neo2
is mainly used for blind typing and is not
needed that much anywhere else, this leaves
the numpad like it is.
(Thanks, jstsmthrgk@jstsmthrgk.eu)
grow selection from point of click, not start of selection region.
starting at the beginning of the selection region causes the match
logic to kick in, which is confusing.
the caller of macexpand() needs one more byte in
the buffer to append peekc.
make macexpand() actually check for buffer overflow.
just use strdup() to duplicate include file name
instead of the hunk dance.
move GETC() macro in cc.h
looks like linux changed the device tree names for
the memory node:
4b17654f51 (diff-ac03c9402b807c11d42edc9e8d03dfc7)
this fixes the memory size detection with latest firmware
on raspberry pi4-b (4GB) for kenji.
with scroll-wheel scrolling, this case can happen with the
command window:
umbraticus → cinap: create fullscreen file buffer by right-clicking in cmd window
slookup() copies to symb, so use the symb[NSYMB] buffer directly
to declare type conversion functions and get rid of the arbitrary
sized local buffer. replace sprint() with snprint().
We used to treat all operators as right associative,
which means that we would evaluate them incorrecty.
For example, '2 - 1 + 1' would evaluate as '2 - (1 + 2)',
instead of '(2 - 1) + 1'.
This adds an assoc parameter to struct pri, and then uses
it to decide how to evaluate operators.
when pushing expressions in cpp, particularly complex ones could
overflow the stack and silently corrupt our data structures. add
checks when we push, and bump the stack size up.
for floating point operations, reuse the return register
on the right hand side if it has higher complex number
than the left hand side to conserve registers.
this makes the following code compile, that was previously
run out of floating point register:
float
f(float r[15])
{
return (r[0] + (r[1] * (r[2] + r[3] * (r[4] + r[5] * (r[6] + r[7] * (r[8] + r[9] * (r[10] + r[11] * (r[12] + r[13] * r[14]))))))));
}
the downside is that this produces extra move operations.
BurnZeZ reported this the other day. It seems like if we have
a pipeline that looks like:
fn foo{cat < <{echo hi}}
then the '<' will get merged in /env/'fn#foo'. This change
fixes pcmd to add a space. It looks to me like this is the
only token that can get merged this way by pcmd.