when user does read of exactly 12*12 bytes on draw
ctl file, the snprint() adds one more \0 byte writing
beyond the user buffer and corrupting memory.
fix this by not snprint()ing the final space and add
it manually.
according to a comment in linux driver, reading Isrc2
register caused interrupts to be disabled. we used
to read Isrc2 in ifstat() and it was confirmed that
reading ifstat locks up ethernet. removing the Isrc2
read in ifstats, and also reenable interrupts after
reading Isrc2 when the interrupt was not for us.
(this is from the linux driver)
in replenish(), set ring software write pointer (Sring.wp)
*before* the hardware write index register. otherwise
rx() could get status notification for completed
receive but wont find the rx descriptor in the ring.
handle uint wrap arround when calculating ring fill
count and remaining count.
the stats and ifstats files in the 3rd level of a netif
are not per connection, but for the interface.
this made fstat fail for /net/ether0/N/*stats where N > 0
as the NETID() bits in the qid didnt compare.
cachechars() used to skip over characters on its own when
loadchar() could not find the character or a PJW replacement.
this resulted in wrong width calculation. now we just return
and handle the case inside _string and _stringwidth.
fix subfont leak in stringwidth()
remove annoying prints in stringwidth()
scrollwheel now works proportional to y mouse position.
special case is when shift is hold down. then scrollwheel
will work like before and scroll one line up or down.
from erik quanstros 9fans post:
i think the list insertion code needs a single-read
test that f->alarm != 0. to prevent the 0 from
acting like a fencepost. e.g. trying to insert -10 into
list -40 -30 0 -20.
if(alarms.head) {
l = &alarms.head;
for(f = *l; f; f = f->palarm) {
>> fw = f->alarm;
>> if(fw != 0 && (long)(fw - when) >= 0) {
up->palarm = f;
*l = up;
goto done;
}
l = &f->palarm;
}
*l = up;
}
disabling mouse packet streaming command 0xf5 can fail
when a packet is currently transmitted.
this can be seen when one moves the mouse while running:
while(){echo accelerated >/dev/mousectl; sleep 0.5}
make sure not to dereference Proc* nil pointer. this can potentially
happen from devip which has code like:
if(er->read4p)
postnote(er->read4p, 1, "unbind", 0);
the process it is about to kill can zero er->read4p at any time,
so there is the possibility of the condition to be true and then
er->read4p becoming nil.
check if the process has already exited (p->pid == 0) in postnote()
under p->debug qlock.
when alarmkproc is commited to send the alarm note to the process,
the process might have exited already, or worse, being reused for
another process. pexit() zeros p->alarm at the beginning, but the
kalarmproc() might read p->alarm before pexit() zeroed it, decide
to send the note, then get preempted and pexit() releases the proc.
once kalarmproc() is resumed, the proc might be already something
different and we send the note to the wrong thing.
we now check p->alarm under the debug qlock. that way, pexit()
cannot make progress while we test the condition.
remove the error label arround postnote(). postnote does not raise
error.
make sure noteid is valid (>0).
prohibit changing note group of kernel processes. this is also
checked for in pgrpnote().
prevent "none" user from changing its note group to another "none"
sessions. this would allow him to send notes other none processes
other than its own.
this works differently from mischiefs original patch. instead of
overloading the address bar, we popup our own enter box. the
function can be invoked from the menu or by hitting ^F.
add new functions pageaddr() that returns a string describing
the page to be loaded. it is in the form of:
/path/to/file!pagename!subpage!....
one can jump to such a page by calling trywalk(name, addr)
where name and addr get concatinated with ! to form a page
address and then the currently loaded pages are walked up
to the nearest page which is then returned. (or nil when
not found). the remaining address will be set in the global
pagewalk variable.
once pages get loaded (asynchronously), pagewalk1() gets
called again on addpage() and continues the walking up to the
last page.
new program flag -j <addr> was added to jump to a page on
startup.
page address (without filename) can also be supplied in
plumb message with the "addr" attribute.
rio looks backwards in the line for the beginning of a filename
that needs to be completed with ^F. this change makes the
characters: =, ^, ( and { stoppers, so filename completion
will work in all these cases:
foobar=/foo/ba^F; for(i in (fo^F ba^F)){/bin/baz^F
this means completion will not work for prefixes having these
special characters in them.
thanks to burnzez for bringing it up.
dont spam the console with qfull warnings. this makes things worse.
handle loopback packets as stated in the comment. we call etheriq()
with fromwire=1 for loopback packets so etheriq() can pass the packet
on (without copying) or free it. dont inhibit interrupts while calling
etheriq(). etheriq() can safely be called from process and interrupt
context. it is unclear what this was supposed to fix and testing didnt
seem to have any odd effects.
(11:02:29 PM) me: why is buf in /sys/src/9/port/devssl.c:/^sslwrite only 128 bytes?
(11:02:58 PM) me: it makes it so you can't use a 128 bytes secret as negotiated by infauth in a secretin or secretout ctl message
(11:03:30 PM) me: which in turn means you can't use such a secret with pushssl(2)
(11:06:15 PM) me: inferno's sslwrite is limited to 32 bytes, but its ssl library writes to the secret files instead of to the ctl file
(11:08:50 PM) mischief: what should it be instead of 128 bytes
(11:08:58 PM) me: larger
(11:09:16 PM) mischief: how about 129 bytes?
(11:09:59 PM) me: also broken in 9front, by the way
(11:15:14 PM) me: i guess it should be replaced with parsecmd
get rid of the service buffer limit. keep service buffers
on a global freelist protected by lock.
dont fatal when we hit the process limit. instead, just
abort the rpc with an error.
handle rendezvous() interrupts.
when a replicated source image with a clipr with clipr.min > Pt(0, 0),
drawclip() would properly translate the src->clipr on the dstr
but then clamp the source rectangle back on src->r.
while traversing down multiple layers, this would cause the translation to
be applied multiple times to the dst rectangle giving the wrong image result.
this change adds a new drawclipnorepl() function that avoids the clamping
of source and mask rectangles to src->r and mask->r. this is then used in
libmemlayer.
the final memimagedraw() call will call drawclip() which will do the final
claming.
a testcase is provided:
#include <u.h>
#include <libc.h>
#include <draw.h>
Image *blue;
Image *red;
void
main(int, char *argv[])
{
Image *i;
if(initdraw(nil, nil, argv[0]) < 0)
sysfatal("initdraw: %r");
i = allocimage(display, screen->r, screen->chan, 1, DWhite);
red = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DRed);
blue = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DPaleblue);
replclipr(red, 1, Rect(10, 10, 110, 110));
replclipr(blue, 1, Rect(11, 11, 111, 111));
/* draw on non-layer, works correctly */
draw(i, i->r, red, nil, ZP);
draw(i, i->r, blue, nil, ZP);
draw(screen, screen->r, i, nil, i->r.min);
flushimage(display, 1);
/* draw on (screen) layer is too far to the right */
draw(screen, screen->r, red, nil, ZP);
draw(screen, screen->r, blue, nil, ZP);
flushimage(display, 1);
for(;;){
sleep(1000);
}
}
the nt blob ends with 4 zero bytes, this is not the same as
the EOL av-pair terminator!
this makes ntlmv2 work with windows xp with LmCompatibityLevel = 3
extending factotums and the auth servers mschap implementation
to handle variable length NT response for NTLMv2.
fix some minor bugs.
only tested with cifs so far.
replaced the p->pid != 0 check with up->parentpid != 0 so
p->pid == up->parentpid is never true for p->pid == 0.
avoid allocating the wait records when up->parentpid == 0.
when a process got forked with RFNOWAIT, its p->parent will still
point to the parent process, but its p->parentpid == 0.
this causes the "parent still alive" check in pexit to get confused
as it only checked p->pid == up->parentpid. this condition is *TRUE*
in the case of RFNOWAIT when the parent process is actually dead
(p->pid == 0) so we attached the wait structure to the dead parent
leaking the memory.
we do not need to wait for fork/execed program to finish when
not collecting waitmsg. this reduces the number of rio
processes hanging arround for each window shell just waiting
for it to terminate and then dumping the waitmsg.
U9fs(4) misuses Fcall.afid in its p9any authentication module.
The afid field of Fcall structure is only valid with Tauth or Tattach.
Tread, Twrite, Tclunk should use rx->fid instead. It's been lucky so
far to get the job done because rx->afid survives from previous
Tauth/Tattach. The issue pops up when several authentications happen
concurrently.
Test case:
u9fs = 'host with u9fs on tcp!*!564'
9fs $u9fs; for(i in 1 2 3 4 5 6 7 8){ 9fs $u9fs & }; wait
Should:
no errors
Should not:
mount failed: authentication failed
we might get a unreachable nameserver ip from a parent
nameserver. if the remaining set of nameservers does not
loop, we should try to resolve them.
so skip the loopcheck for nameservers already tried.
validurl() is just used to check if the string is a full
absolute url with a protocol scheme. we do not have to
match the host part *exactly*, only if there is *something*
in the hostpart.
Add pages for esc1+shift and esc1+ctrl - some UK USB keyboards (Dell) and it seems some
German ones: https://groups.google.com/forum/#!topic/comp.os.plan9/ycok6NTCWCg seem to
generate an esc1 + code scancode combination for the pipe/backslash key. Seems like
overkill to add two whole pages for just two keys, but there again RAM is cheap these days.
Probably should take the changes across to omap/kbd.c (and by extension bcm/kbd.c)
but the changes are trivial.
catch the error() that can be thrown by sleep() and tsleep()
in kprocs.
add missing pexit() calls.
always set the freemem argument to pexit() from kproc otherwise
the process gets added to the broken list.
catch the error() that can be thrown by sleep() and tsleep()
in kprocs.
add missing pexit() calls.
always set the freemem argument to pexit() from kproc otherwise
the process gets added to the broken list.
from 9atom/acmearrowfun patch:
reported by mark van atten
In Plan 9 acme, if you type
{}
then go back and type text between the brackets
{Curiouser and curiouser!}
the right arrow is blocked when you want to go over the closing
bracket to continue typing to its right. (If you first go to the left,
and then back to the right, it works.)
Same for the other brackets: [ ], ( ), < >.
noted that brackets are not necessary. same behavior with any
character.
fix is to textcommit before moving.
we have to fail the whole query that got no cached
nameservers and nameservers are looping, not just omit
the looping nameserver. issuequery() will refresh
nameserver info for the domain when recursing up.
never try to resolve a nameserver address when that nameserver
is in the set of nameservers already being queried.
this situation can happen when the Ta and Taaaa RR's expire, but
the Tns records are still in the cache so there is no usable
nameserver but they still refer to each another.
stop absolute/relative dual use of RR.ttl. now RR.ttl is
*always* the *relative* ttl value. we derive absolute
timeout in RR.expire.
remove unused lookuptime field in DN. replace refs and
keep with mark field in DN. we do not care about the
number of references. only *iff* it is referenced, so
use a single bit for that (bit 0). for keep, we use
bit 1.
remove dolock parameter in dnagenever(), it is not
needed. we always need to lock.
mark local dns servers and domains as never to be aged.
the keeper bit is *just* a cache optimization, preventing
the domain and the domains it points to from being flushed.
it should not be used as a write protect bit in rrattach()
for preventing spoofing as it will prevent updates of say,
cname domains.
remove "removing spam ..." message. these are usualy just
hints, so normal. still, remove the hint as we currently
do no check if the nameserver has authority over the
cname domain.
remove "mydnsquery: trying to send to myself (%s); bzzzt"
message. this can happen when myaddr() fails for other
reasons. myaddr() will print error for us anyway.
ndb keys are strictly case sensitive, so consitently
use strcmp() when comparing attribute keys.
dblookup() used to lower case convert its name argument
inplace to match domain/sys name in ndb. better to do
the convesion in its own buffer and only read from the
name argument.
always use cistrcmp() when comparing DN.name.
the Domlen constant denotes the size of the buffer including
the null terminator. consistently use it as such.
have to hold dnlock in freearea() before reading list
head pointer.
the image cache should not hold onto the text file channel
when not neccesary. now, the image keeps track of the number
of page cache references in Image.pgref. if the number of
page cache references and Image.ref are equal, this means
all the references to this image are from the page cache.
so no segments are using this image. in that case, we can
close the channel, but keep the Image in the hash table.
when attachimage() finds our image, it will check if Image.c
is nil and reattach the channel to the image before it is
used.
the Image.nocache flag isnt needed anymore.
the libmad samples need to be scaled properly. the
previous assumption was that it is 32 bits, but it
really is MAD_F_FRACTBITS + sign bit and rest used
for overflow.
thanks eekee!
in ape's vfprintf we don't check if the file we're writing is actually a string buffer, resulting in a return of -1, when we should actually return the number of bytes that would be written.
frinsert() shouldnt modify the runes passed and the
buffer isnt going to be modified my us during the call
so removing the temporary copies.
namecomplete() makes utf-8 copies of the rune strings so
theres no need to copy the runes.
xfidflush() now uses a simpler way to flush another xfid.
when we can send to Xfid.c channel, we know that the
xfid is completed. so all xfidflush() needs todo is to
do an alt sending to both Xfid.c and Xfid.flushc.
once the send to Xfid.c succeeds, we know the xfid is gone
and we can respond to the flush request.
theres no need to keep track of flush state anymore. so
Xfid.active and Xfid.flushing can be removed.
note, that it is ok to respond normally to a currently
flushed request.
flushing isnt optional for concurrently handled requests.
we need to ensure that Rflush is replied *after* the
origianl request.
so we assign the flushtag for *every* xfid in xfidctl(),
and filsysrespond() checks if the xfid was flushed
*after* replying and wakes up the flushing xfid.
when multiple flushes are send, they need to be replied
in order. we ensure this by having the flush xfid taking
over the flushtag (synchronized with a new fs->csyncflush
channel) so the next flush will flush the previous flush.
the diver used to skip auto negotiation when
auto-negotiation enable (bit 12 in command register)
was clear.
setting the bit now, which makes auto negotiation work.
we skip auto negotiation only when it was already enabled
and status regiser indicates completion (bit 9).
the shr mount is linked into the Mhead with m->to initially nil. only
after the the server has been attached is m->to set. just check for
it in createdir().
the image cache has the property of keeping a channel
for the executable binary arround which prevents the
mountpoint from going away.
this can easily be reproduced by running:
@{rfork n; ramfs; cp /bin/echo /tmp; /tmp/echo}
observe how ramfs stays arround until the image is
reclaimed. the echo binary is also cached but is
unreachable from any namespace.
we now restrict the caching to mounts that use the client
cache (-C flag) only. this should always be the case
for /bin. places where this isnt the case might observe
a performance regression.
closechanq() is unable to fork a new closeproc when palloc
is locked. so we spawn a closeproc early in chandevinit()
and make sure theres always one process arround to handle
the queue.
we'r getting a rectangle taller than a single line from
coladd() which causes textresize() to collapse the tag
text to zero height.
should probably fix coladd() instead.
introduce kernel inspured Block structure with
read/write pointers to pass packets arround.
the intend is to avoid copying when adding/removing
frame headers and simplifying the drivers.
the driver now calls etheriq() directly allowing it to
queue multiple packets in one pass without having
to keep state.
transmit gets a buffer passed that has room for
frame headers and trailers so no copying is needed.
blocks are refcounted avoiding another copy when
passed to only one receive queue (common case).
receive queues are now limited to 100KB avoiding
buffer bloat.
Dq* a memory leak in destroyfid has been fixed.
lots of minor cleanups.
from: http://9fans.net/archive/2013/04/327
since <compose>x is not yet entrenched, i have a suggestion for ease of
input. suppose <compose>x were redefined so the syntax were
"<compose>x[0-9a-f]+;". in the case that 6 hex digits are entered, then
the ";" is not necessary.
not only would this allow for entering 21-bit runes, it would also allow for
short sequences to be entered more easily.
- erik
using strlen() gives the number of bytes in the utf-8 string.
could use utflen() instead, but decided to just go in a loop
and get rid of the counters all together.
UTF-16 surrogates are not handled.
the process is *NOT* allowed to exit after a srvrelease() as
it still holds a reference (srv->rref) preventing the srv
from beging freed/ended (listensrv) before srvacquire().
ethernet packets with sizes that where not multiples of 4 where
discarded because the check uses the smsc frame size instead of
the payload size. when a usb read returns just one packet, theres
no next frame header and the calculated frame size is bigger than
the usb read which caused the whole packet to be discarded as invalid.
thanks to mischief for testing and debugging!
usb is bound after /dev, so a hanging usb device will hang
access to /dev. we avoid this by releasing the srv, which
allows the fs to still handle reads and walks of the
directories.
ios are serialized by a qlock in the Umsc structure.
add checktag and nil checks in cfsdump() making sure to notice
when the roroot directory structures is corrupted.
cwrecur() used tag == Tsuper to indicate that this is the first
level recursive invocation. this is confusing as we really expect
Tdir tag in that case for the root directory. instead, we now
pass the correct tag (Tdir) and use cw->depth > 1 to see if we
are past the root.
the block tag was only checked when the block was not in
the memory cache. check the tag always!
fork child exportfs with new rendezvous group.
fix missing close of pipe filedescriptors on error.
fix missing close of other end of pipe in child.
dont bark when we get eof on the first init string read.
this condition can happen when unmount opens and
immidiately closes a exported srv file.
running page in own note group avoids killing it when we
exit mothra.
copypaste dupfds() function from page and use it to close
unneeded file descriptors.
we are not using stdout (fd=1) and it, so dup nullfd over it.
this drops the old window reference when using with -w flag.
the RFNAMEG flag isnt needed because we are calling newwindow()
which forks the namespace for us.
reopen stdin/stdout for the external viewer to the new window.
newwindow() used to mount the new window directly on /dev, resulting
in the old window and the new one being mounted over each other.
we now try to unmount the old window from /dev first, mount new
window to /mnt/wsys (replacing the old) and then bind /mnt/wsys
before /dev.
if theres no /mnt/wsys, just mount window directly before /dev.
dont rely on postnote to shutdown client. instead, make reads on
cons, kbd and mouse error. when we mount a window system over
exportfs, the pid useless and even dangerous! pid should be
only used by clients forked by rio itself.
fix bug in resized(), goodrect() takes rect in screen coordinates!
make rectonscreen() fix window size if the window doesnt fit
on the screen.
improve goodrect() to check for windows outside of the screen or
bigger than screen without borders visible.
the openbsd sis(4) driver does not actually go through the rest
of softreset() with sis cards. also, rev 635 reads the mac address
differently, so copy-paste code from openbsd to handle that.
the automatic routing from jack to dac/adc sometimes gets us
a path thats not audible. manually specifying a route path
gets us arround these. the syntax is just a comma separated
list of node ids in the "pin" and "inpin" audioctl commands
instead of a single pin node id.
to find alternative paths, audiostat now lists all the widgets;
not just the pins; and ther input connections.
initially mute all pins and amps of all function groups.
connectpath() and disconnectpath() will mute and unmute
the widgets as required later.
forkret() labels the instructions that can raise exceptions
so they can be handled in trap(). this can happen when
segment descriptors get invalidated.
the standard is i/o bar 0 is the mixer and bar 1 is status/control.
the magic with the bar sizes made it fail in qemu. so removing it
for now as all devices seen so far comply to the standard.
if we ever see a sis7012 where this might be swaped uncomment the i=0;
the busywait timeout is too long in ac97mixreset() because rd/wr
have a timeout on ther own. just remove the busy looping and do
a one second delay after mixer reset. (tested with t23)
semaphore locks have much higher overhead than initially presented
in the "Semaphores in Plan9" paper. until the reason for it has been
found out i will revert the changes.
validaddr looks up the segments for an address range
and checks the flags and if the address range lies
within bounds on the segments.
as we'r going to lookup the segment in the syssem*
syscalls anyway, we can do the checks ourselfs avoiding
the double segment array lookups.
the implication of this tho is that now a semaphore cannot
span multiple segments. but this would be highly unusual
given that segments are page aligned.
smart boot manager has a "FAT" signature in its mbr causing
9bootfat to "detect" it as a fat filesystem and then fails
to find plan9.ini.
there shouldnt be a fat filesystem on harddrives at block 0, only
on floppy drives. but some bioses use floppy drive numbers
for usb harddrives so still check for a partition table.
thanks aap for debugging this.