From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=0.2 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED autolearn=no autolearn_force=no version=3.4.4 Received: (qmail 5521 invoked from network); 23 Jan 2022 10:09:41 -0000 Received: from 4ess.inri.net (216.126.196.42) by inbox.vuxu.org with ESMTPUTF8; 23 Jan 2022 10:09:41 -0000 Received: from wopr.sciops.net ([216.126.196.60]) by 4ess; Sat Jan 22 20:07:02 -0500 2022 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sciops.net; s=20210706; t=1642900012; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to; bh=x5OxsYPVswlMCV/A3MJl8Q9doXO/6nCBuqqVX7zwQoI=; b=OGWPGeaDzgZYgv2Yvs/yUnrYmOtztDXzvBKDlYWoEQjVENPvxq60iL9+zQhGm9Vmdorej8 vQCzUkH5Ixsz6WScADn1qiCQxmnVa9ibDpupbyYk3U1LAm9m4GFsIT0BeyamqRmr5PwF2C o1eIkPwTUHergxikZiEReA97+ZOhxuA= Received: by wopr.sciops.net (OpenSMTPD) with ESMTPSA id d14107fb (TLSv1.2:ECDHE-RSA-CHACHA20-POLY1305:256:NO) for <9front@9front.org>; Sat, 22 Jan 2022 17:06:51 -0800 (PST) Message-ID: <3C8884F6BBE0B93D0C93B16F93BD589F@wopr.sciops.net> Date: Sun, 23 Jan 2022 02:06:49 +0100 From: qwx@sciops.net To: 9front@9front.org In-Reply-To: <54BF37272CB09CDCF27C49908F804900@prosimetrum.com> MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit List-ID: <9front.9front.org> List-Help: X-Glyph: ➈ X-Bullshit: distributed compliant ACPI over TOR map/reduce method-based singleton framework-aware optimizer Subject: Re: [9front] delete in page(1) Reply-To: 9front@9front.org Precedence: bulk > I like this new feature too but am able to crash by popping pages of > a large pdf. At first I thought it only happened when the whole doc > had not yet loaded but I think it may also occur even when every > thing is in memory. Of course being able to drop pages from a pdf is > probably of questionable utility... In fact it occurs all the time in pdfs, probably elsewhere. It's a stupid bug that should be fixed with this new patch. The patch actually doesn't distinguish between pages of a pdf or files in a subdirectory. Previously, you couldn't pop or delete anything that wasn't directly at the root, meaning that if you did `page $dir', you would not be able to do anything to pages under $dir. Hopefully this thing is done and dusted for now... Thanks, qwx diff 9d43029ff984435111eff658308a44b4f3eee1cc uncommitted --- a//sys/src/cmd/page.c +++ b//sys/src/cmd/page.c @@ -74,7 +74,10 @@ Czerox, Cwrite, Cext, + Cpop, Cdummy2, + Cdelete, + Cdummy3, Cquit, }; @@ -98,7 +101,10 @@ [Czerox] "zerox", 'z', 0, 0, [Cwrite] "write", 'w', 0, 0, [Cext] "ext", 'x', 0, 0, + [Cpop] "pop", 'p', 0, 0, [Cdummy2] "", 0, 0, 0, + [Cdelete] "delete", 'D', 0, 0, + [Cdummy3] "", 0, 0, 0, [Cquit] "quit", 'q', Kdel, Keof, }; @@ -134,6 +140,7 @@ void showpage(Page *); void drawpage(Page *); Point pagesize(Page *); +void drawlock(int); Page* addpage(Page *up, char *name, int (*popen)(Page *), void *pdata, int fd) @@ -987,6 +994,72 @@ } } +/* doesn't actually free the page entry or touch links to avoid breakage */ +Page* +freepage(Page *p, Page *prev) +{ + Page *next, *up; + + drawlock(0); + unloadpage(p); + drawlock(1); + if(p->fd >= 0) + close(p->fd); + p->fd = -1; + /* not touching p->data */ + free(p->name); + p->name = nil; + p->open = nil; + next = nextpage(p); + up = p->up; + if(up->down == p){ + if(up->tail != p) + up->down = next; + else + up->down = nil; + }else if(up->tail == p){ + up->tail = prev; + prev->next = nil; + }else + prev->next = next; + return next; +} + +Page* +poppage(Page *p, int del) +{ + Page *t, *prev, *next; + + if(p == nil) + return nil; + if(p == root) + return p; + if(del){ + if(!(access(p->name, OREAD) == 0 && remove(p->name) == 0 + || p->data != nil && access(p->data, OREAD) == 0 && remove(p->data) == 0)){ + fprint(2, "remove %s: %r", p->name); + return p; + } + } + qlock(&pagelock); + for(t = p->down, prev = p; t != nil && t->up != p->up; prev = t, t = next){ + qlock(t); + next = freepage(t, prev); + qunlock(t); + } + p->down = nil; + prev = prevpage(p); + next = freepage(p, prev); + qunlock(&pagelock); + qunlock(p); + if(next != nil){ + forward = 1; + return next; + } + forward = -1; + return prev; +} + /* * A draw operation that touches only the area contained in bot but not in top. * mp and sp get aligned with bot.min. @@ -1462,8 +1535,10 @@ { char buf[NPATH], *s; Point o; - int fd; + int fd, del; + Page *p; + del = 0; switch(i){ case Corigsize: pos = ZP; @@ -1547,6 +1622,25 @@ break; case Csnarf: writeaddr(current, "/dev/snarf"); + break; + case Cdelete: + del = 1; + /* wet floor */ + case Cpop: + if(current == nil || !canqlock(current)) + break; + if((p = poppage(current, del)) == current){ + qunlock(current); + break; + } + if((current = p) == nil){ + drawlock(0); + draw(screen, screen->r, paper, nil, ZP); + drawframe(screen->r); + drawlock(1); + break; + } + showpage(current); break; case Cnext: forward = 1;