Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Glob sorting doesn't work in some cases
- X-seq: zsh-workers 42040
- From: Dima Kogan <dima@xxxxxxxxxxxxxxx>
- To: zsh-workers@xxxxxxx
- Subject: Glob sorting doesn't work in some cases
- Date: Sun, 19 Nov 2017 17:55:59 -0800
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=secretsauce.net; h=content-type:date:from:message-id:mime-version:subject:to :x-me-sender:x-me-sender:x-sasl-enc; s=fm1; bh=tukUXYokLykXN4hRO NEyYsAuaN++fzYeF5z2GVVX/Mw=; b=xdgpcQPpm4Po4yezXVpnEKedxvrLgOlDJ 1y2EaIMuyOm9I76JLcHN31Ic47y26MZseRduNbRtUlOxfz7GJFRCOxRuDTI0hix/ qBR2wjPIbb65rB4E28991PTjHfuT/eQT2mFJ9j/wcfeLER5Vk1wjqbHgPMJSUetE a/uKbkv/8Sm5KSDT0+eo03iE0KTHFtmYjZiVvRtoiHARxkI8vlcxxelz0hYlmcdI 8iTKmhuW8h4KQ3T4wCF58xiU1ZH19qjVmJXCLtv7IWALOSCuktLZg8wEIkb8SBk9 PJdHl+n+PLWGQRVVHfzkt8rKRjpXQKnPyROsDBSzKH6aJ7cC61aNw==
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=content-type:date:from:message-id :mime-version:subject:to:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; bh=tukUXYokLykXN4hRONEyYsAuaN++fzYeF5z2GVVX/Mw=; b=WZBe+FbB D4PioAEEY45rkrhUHePSR4TBBKa+C4YG8yXMu8hzT7AcJ6cDzEVu0N2t5BS4h2UW quk5X32cFd5PR2qOYl4aLUOxTu6MnrLAJQNxa7UcruVJPciHXOf7GkQi9ZSRppIE onCQsZvnkQZzIsnSDTiEAXbpnUFXRduX1M5WhF8O/aRRUka9sOrfKp/36wnkddno grVmI84f36grLnUxlm7rlDq/JFjXug0sOj+H6509JFwpNZ+fDqsJx+r5pcEdxFPH sJj9xdjNqBjZf4mIaMxa/afPS+0kXU61ODxCfu8plf8dJ5foV2+7oEFh1Mr7JwWB yfamdcVyREOSTA==
- List-help: <mailto:zsh-workers-help@zsh.org>
- List-id: Zsh Workers List <zsh-workers.zsh.org>
- List-post: <mailto:zsh-workers@zsh.org>
- List-unsubscribe: <mailto:zsh-workers-unsubscribe@zsh.org>
- Mailing-list: contact zsh-workers-help@xxxxxxx; run by ezmlm
Hi.
I hit a corner case in zsh glob sorting today. Look:
dima@scrawny:/tmp$ mkdir dir1; touch dir1/file
dima@scrawny:/tmp$ mkdir dir2; touch dir2/file
dima@scrawny:/tmp$ mkdir dir3; touch dir3/file
dima@scrawny:/tmp$ echo dir*/file(om)
dir2/file dir3/file dir1/file
dima@scrawny:/tmp$ echo dir*/file(Om)
dir2/file dir3/file dir1/file
I.e. I made some dummy files, then asked zsh to tell me about them in
most-recently-modified order, and then again in the REVERSE order of
that. Note that neither of these is right, and the reverse part didn't
work either.
This looks like a corner case. If I look at dir*/file(.om) or
dir*/file*(om) then it works fine.
In any case, we can see that when this fails zsh isn't even looking at
the time stamps at all:
dima@scrawny:/tmp$ strace -e lstat zsh -f -c 'echo dir*/file(om) > /dev/null'
+++ exited with 0 +++
dima@scrawny:/tmp$ strace -e lstat zsh -f -c 'echo dir*/file(.om) > /dev/null'
lstat("dir1/file", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
lstat("dir3/file", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
lstat("dir2/file", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
+++ exited with 0 +++
This can be fixed with this patch:
--- glob.c 2017-11-19 13:25:19.142071142 -0800
+++ glob.c 2017-08-27 13:18:25.000000000 -0700
@@ -387,7 +387,7 @@
qn = qn->next;
}
} else if (!checked) {
- if (statfullpath(s, NULL, 1)) {
+ if (statfullpath(s, &buf, 1)) {
unqueue_signals();
return;
}
This makes it work. To be clear, I don't completely understand why this
NULL is here, but it was there for 17 years, so there could easily be
something here I don't understand. The patch makes sense, however. This
function has a 'struct stat buf' to receive results of a stat() and an
'int statted' to indicate that we have done this. Every time we actually
do a stat() (via a statfullpath()), we update statted appropriately.
EXCEPT for the path patched above. So when we hit the failure we
1. statfullpath(NULL); this does NOT update buf, but does set statted=1
2. Then a bit later we test if (statted & 1)
3. Which is true. So we then do stuff with buf, which is actually
uninitialized
Please Cc me when replying. I'm not subscribed to the list.
Thanks!
dima
Messages sorted by:
Reverse Date,
Date,
Thread,
Author