<div dir="ltr"><div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Feb 25, 2019 at 12:01 PM Rob Landley <<a href="mailto:rob@landley.net">rob@landley.net</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On 2/25/19 11:29 AM, enh wrote:<br>
> To be honest I was calling xflush() from so many places because it was an easy<br>
> way to get the if (ferror) perror_exit("write"); Possibly what I want is an<br>
> xferror() that xflush() can call...<br>
> <br>
> <br>
> where would you want to call xferror that xflush wouldn't be appropriate?<br>
<br>
Anywhere you want to stop a command after "head" ate the first screen of data<br>
and closed the pipe, or similar. (cmp <(blah) <(blah), yes | anything, etc.)<br></blockquote><div><br></div><div>assuming s/screen/buffer/...</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
(It's basically another facet of the sigpipe problem.)<br>
<br>
> (fread<br>
> is the main place one needs ferror normally, and toybox has remarkably few calls<br>
> to fread, neither of which seem to actually need to care.)<br>
<br>
The only _input_ advantage of FILE * is really for getline(). Everything else<br>
it's just as easy to read input blocks and chop 'em up myself.<br>
<br>
(The problem with getline() is you don't know where the terminators are ahead of<br>
time so you never know how _much_ to read, so you either read a byte at a time<br>
which is _painfully_ slow or you have leftover data you need to keep around<br>
because zcat | thingy isn't seekable input.)<br>
<br>
Write collation's generally fun, and you can sing "nagle" to the dreidl song,<br>
but then we spend all our time arguing about flushing. :)<br>
<br>
P.S. I'm _so_ glad dprintf() made it into posix-2008. Pity there isn't a<br>
dscanf() but that gets back to getline on unbufferd filehandles being hard.<br>
<br>
> Sigh, we should probably make the helpful ones explicit and remove the rest.<br>
> <br>
> sgtm.<br>
> <br>
> looking at all the callers, xputs isn't used much at all (21 calls in toys/) and<br>
> most of them seem dubious. xprintf is a lot more popular (338), but -- though<br>
> it's harder to tell because there are so many -- nothing particularly<br>
> convincingly in need of a flush stood out.<br>
<br>
Before you go _too_ far down that path...<br>
<br>
What I propose is having xprintf() and xputc() and friends still do the "check<br>
for error and xexit()", but _not_ do the flush. Call xflush() explicitly when<br>
you need a flush.<br></blockquote><div><br></div><div>right, so they'd bail you out early from a buffer-full flush, but otherwise be just like the direct call.</div><div><br></div><div>sgtm.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
> i'm assuming this will be like FLAG, where we'll do it as we're touching things<br>
> for other reasons?<br>
> <br>
> I'll add a cleaup pass to the todo heap...<br>
> <br>
> (you should probably keep that list checked in, or even stored as issues in the<br>
> github bug tracker.)<br>
<br>
It does not make any sense to anyone other than me, and is not nearly as<br>
organized as you think. Attached is my "top of the heap" file. Which is only one<br>
of the many "not checked in" files at the top of my working toybox tree:<br>
<br>
$ git status | grep -v / | grep -v '[.]sw' | wc<br>
77 116 1165<br>
<br>
Which is not one of the entries in the "todo" subdirectory there:<br>
<br>
$ ls todo<br>
19.patch howto.txt ootree.patch todo2.txt<br>
bc.lib iconv.txt patches todo3.txt<br>
blah ifconfig.txt patch.patch todo4.txt<br>
blah2 lib.patch pending.patch todo.android<br>
config2help.patch lsofdiff.patch projects.txt todo.small<br>
date.patch ltrace.sh pscomments.patch todo.txt<br>
dest mdev2.patch ps.txt tofix.txt<br>
explicit.patch mdev.patch release.txt torelease.txt<br>
explorer.patch mdev.txt sub toysh.c<br>
file2.diff meep.patch sub2 wc2.patch<br>
file.diff needed.txt sub3 wc.patch<br>
getconf2.c netcat.patch temp.patch zcat.txt<br>
getconf.c net.diff test.txt<br>
getconf.sh nettest test_xargs.diff<br>
gzip.txt newsh.c this is a longish name<br>
<br>
Which is not one of the 34 changed files "git diff" shows with notes to self like:<br>
<br>
--- a/toys/other/losetup.c<br>
+++ b/toys/other/losetup.c<br>
@@ -4,7 +4,7 @@<br>
*<br>
* No standard. (Sigh.)<br>
<br>
-USE_LOSETUP(NEWTOY(losetup, ">2S(sizelimit)#s(show)ro#j:fdca[!afj]", TOYFLAG_SB<br>
+USE_LOSETUP(NEWTOY(losetup, ">2S(sizelimit)#s(show)ro#j:fdcaA[!afj]", TOYFLAG_S<br>
<br>
config LOSETUP<br>
bool "losetup"<br>
@@ -29,6 +29,7 @@ config LOSETUP<br>
-o Start association at OFFSET into FILE<br>
-r Read only<br>
-S Limit SIZE of loopback association (alias --sizelimit)<br>
+ -A Auto-detach device when unmounted<br>
*/<br>
<br>
#define FOR_losetup<br></blockquote><div><br></div><div>(that kind of thing especially can be done as a TODO: at the top of the file. there's even some precedent.)</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
Which is a reminder to me to use<br>
<a href="https://git.kernel.org/pub/scm/linux/kernel/git/history/history.git/commit/?id=96c5865559ce" rel="noreferrer" target="_blank">https://git.kernel.org/pub/scm/linux/kernel/git/history/history.git/commit/?id=96c5865559ce</a><br>
and then probably have mount.c take advantage of that (except "object lifetime<br>
rules" is my go-to thing to harp on in software designs and changing them like<br>
that requires reinspection of assumptions)...<br>
<br>
Moving up one level from there, the "toybox" directory that my actual toybox git<br>
repos (plural) are in has 82 files/directories in it. Some of which ar test<br>
files, like thr.c which has:<br>
<br>
#include <pthread.h><br>
#include <stdio.h><br>
<br>
void *spin(void *data)<br>
{<br>
unsigned i;<br>
<br>
for (i = 0; i<4000000000; i++);<br>
<br>
return 0;<br>
}<br>
<br>
int main(int argc, char *argv[])<br>
{<br>
pthread_t tt[4];<br>
void *res;<br>
int i;<br>
<br>
for (i=0; i<4; i++) pthread_create(tt+i, 0, spin, 0);<br>
for (i=0; i<4; i++) pthread_join(tt[i], &res);<br>
<br>
return ;<br>
}<br>
<br>
Which we were talking about a week or so back, about making top -H get<br>
per-thread CPU right. (The test file reminds me of the todo item.)<br>
<br>
And of course there's browser tabs:<br>
<br>
<a href="https://en.wikipedia.org/wiki/Design_of_the_FAT_file_system#File_Allocation_Table" rel="noreferrer" target="_blank">https://en.wikipedia.org/wiki/Design_of_the_FAT_file_system#File_Allocation_Table</a><br>
<a href="https://rsync.samba.org/how-rsync-works.html" rel="noreferrer" target="_blank">https://rsync.samba.org/how-rsync-works.html</a><br>
<a href="https://en.wikipedia.org/wiki/Karatsuba_algorithm" rel="noreferrer" target="_blank">https://en.wikipedia.org/wiki/Karatsuba_algorithm</a><br>
<a href="http://cgit.openembedded.org/meta-openembedded/tree/meta-oe/recipes-core/toybox" rel="noreferrer" target="_blank">http://cgit.openembedded.org/meta-openembedded/tree/meta-oe/recipes-core/toybox</a><br>
<br>
(Sooo many browser tabs.)<br>
<br>
And buckets of old emails with yet more, todo items left in them, ala:<br>
<a href="http://lists.landley.net/pipermail/toybox-landley.net/2019-February/010196.html" rel="noreferrer" target="_blank">http://lists.landley.net/pipermail/toybox-landley.net/2019-February/010196.html</a><br>
<br>
And open console tabs with things in them, most recently this grep output:<br>
toys/posix/nl.c: xprintf("%s", line);<br>
toys/posix/ps.c: printf("%s", TT.pgrep.d ? TT.pgrep.d : "\n");<br>
toys/posix/strings.c: printf("%s", string);<br>
toys/posix/ulimit.c: printf("%s", toybuf);<br>
<br>
Which reminds me "oh right, do a cleanup pass on the tree for the %s stuff we<br>
were talking about last email"...<br>
<br>
And another tab has open a 250 line "podcast.txt" file (not from any of the<br>
above directories) I've written trying to outline a walkthrough of the toybox<br>
code reminding me of concepts I need to remember to try to explain (here, I'll<br>
attach that too, of course it's _also_ unfinished and incoherent and means<br>
nothing to anyone but me)...<br>
<br>
It's not as simple as "check it in". As with things like "test suite" and<br>
"documentation", there's a huge amount of cycles needed just to _curate_ it and<br>
process this compost heap into usable work product...<br>
<br>
As I said, this mess tends to be a symptom of "not enough time to clear backlog"<br>
so even little things accumulate. Heck, I've got a dozen or so half-composed<br>
email reply windows open just like this one...<br></blockquote><div><br></div><div>i know, you list these every time this comes up :-)</div><div><br></div><div>but even if you can't solve the whole problem, anything you can do to reduce your <a href="https://en.wikipedia.org/wiki/Bus_factor">https://en.wikipedia.org/wiki/Bus_factor</a> helps...</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
Rob<br>
</blockquote></div></div></div>