Re: [hackers] [st][PATCH] Add support for DSR response "OK" escape sequence
On 6.2.2023 1.39, Adam Price wrote: tsetattr(csiescseq.arg, csiescseq.narg); break; - case 'n': /* DSR – Device Status Report (cursor position) */ - if (csiescseq.arg[0] == 6) { + case 'n': /* DSR – Device Status Report */ + switch (csiescseq.arg[0]) { + case 5: /* Status Report "OK" `0n` */ + ttywrite("\033[0n", sizeof("\033[0n"), 0); This will write a NUL byte to the tty, which doesn't seem intentional. + break; + case 6: /* Report Cursor Position (CPR) `;R` */ len = snprintf(buf, sizeof(buf), "\033[%i;%iR", term.c.y+1, term.c.x+1); -- Santtu
Re: [hackers] [sbase][PATCH 1/2] libutil: Implement a simple yes/no prompt
On 20.11.2022 16.58, Tom Schwindl wrote:> I don't quite get why there is a variable argument list instead of just using a single argument which contains the prompt. I can't see the need for formatting in a y/n prompt. I also wouldn't use `nomsg' since it just polutes stderr. The specification for the -i flag says that the prompt must include the path, so if the function is to print the prompt, formatting does make sense. -- Santtu
Re: [hackers] [sbase][PATCH 2/2] cp, mv, rm: Add `-i` for confirmation prompts
On 19.11.2022 23.46, Alan Potteiger wrote: diff --git a/mv.c b/mv.c index 8441f9c..51efde5 100644 --- a/mv.c +++ b/mv.c @@ -49,6 +57,9 @@ main(int argc, char *argv[]) ARGBEGIN { case 'f': break; +case 'i': +mv_iflag = 1; +break; default: usage(); } ARGEND diff --git a/rm.c b/rm.c index 8bebfcb..70da082 100644 --- a/rm.c +++ b/rm.c @@ -19,6 +19,9 @@ main(int argc, char *argv[]) case 'f': r.flags |= SILENT; break; +case 'i': +rm_iflag = 1; +break; case 'R': case 'r': r.maxdepth = 0; The POSIX specification says that for mv[0] and rm[1], -f and -i cancel each other out, with the last taking effect. [0]: https://pubs.opengroup.org/onlinepubs/009604599/utilities/mv.html [1]: https://pubs.opengroup.org/onlinepubs/009604599/utilities/rm.html -- Santtu
Re: [hackers] [st][PATCH] Fix buffer overflow when handling composed input
On 24.10.2022 13.01, NRK wrote:> But which approach to take is the maintainer's call, not mine. I've attched both fixed-size and dynamic-allocation patch (but simplified without goto). The dynmaic[sic] version incorrectly passes sizeof(buf), where buf is char *, as the size of buffer in the "happy case" leading to unnecessary hits to the dynamic path. -- Santtu
Re: [hackers] [dmenu][PATCH] insert: use long instead of ssize_t
On 2.9.2022 23.38, NRK wrote: `ssize_t` is bit of an exotic type. by POSIX, it's only guaranteed to be able to hold {-1, SSIZE_MAX} [0], meaning that negative values less than -1 isn't guaranteed to representable in `ssize_t` (though it works out in practice). by default `ctrl+u` will call `insert()` with `-cursor` which can be lesser than `-1`. so just use `long` instead which doesn't have such issues. Could also use ptrdiff_t[0], although very likely long and ptrdiff_t are the same type. > @@ -540,7 +540,7 @@ paste(void) > if (XGetWindowProperty(dpy, win, utf8, 0, (sizeof text / 4) + 1, False, > utf8, &da, &di, &dl, &dl, (unsigned char **)&p) >== Success && p) { > - insert(p, (q = strchr(p, '\n')) ? q - p : (ssize_t)strlen(p)); > + insert(p, (q = strchr(p, '\n')) ? q - p : (long)strlen(p)); The true-branch of this ternary would already have type ptrdiff_t, as it is a substraction of pointers. >XFree(p); >} >drawmenu(); [0]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/stddef.h.html -- Santtu
Re: [hackers] [dmenu] tab-complete: figure out the size before copying || NRK
On 2.9.2022 14.01, g...@suckless.org wrote: commit 528d39b011afb7ef6fd794ba6b74155d4e69bc68 dmenu.c b/dmenu.c index 969f6d8..6b285df 100644 --- a/dmenu.c +++ b/dmenu.c @@ -517,9 +517,9 @@ insert: case XK_Tab: if (!sel) return; - strncpy(text, sel->text, sizeof text - 1); + cursor = strnlen(sel->text, sizeof text - 1); + memcpy(text, sel->text, cursor); text[sizeof text - 1] = '\0' This should now be text[cursor] = '\0'; (Try, for example: printf "short\nlongerstring\n" | dmenu and type in: lon^Ks and end up with shortgerstring) - cursor = strlen(text); match(); break; } -- Santtu
[hackers] [PATCH] strings: Correctly handle non-UTF-8 data
Make fgetrune() put the breaking byte back, if it was not the only one read, as this may be the start of the next, valid, rune. Also consider erroneous runes to break a valid sequence, otherwise there will be false-positive matches. --- libutf/fgetrune.c | 3 +++ strings.c | 4 +--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/libutf/fgetrune.c b/libutf/fgetrune.c index 8cd78c6..97536fa 100644 --- a/libutf/fgetrune.c +++ b/libutf/fgetrune.c @@ -20,6 +20,9 @@ fgetrune(Rune *r, FILE *fp) if (ferror(fp)) return -1; + if (*r == Runeerror && i > 1) + ungetc(buf[--i], fp); + return i; } diff --git a/strings.c b/strings.c index 8f5a154..13b54ea 100644 --- a/strings.c +++ b/strings.c @@ -20,9 +20,7 @@ strings(FILE *fp, const char *fname, size_t min) for (off = 0, i = 0; (bread = efgetrune(&r, fp, fname)); ) { off += bread; - if (r == Runeerror) - continue; - if (!isprintrune(r)) { + if (r == Runeerror || !isprintrune(r)) { if (i == min) putchar('\n'); i = 0; -- 2.25.1
[hackers] [sbase][PATCH] printf: Fixes and tweaks
Allow the use of multiple flags per conversion, as most flags are not mutually exclusive. Remove all dynamic memory usage, relying on stack buffer and variables instead for generated format strings and character arguments. Fix reading past format string end (with check before strchr) and use of strtoll. Only allow %% verbatim and simplify setting cooldown and process all literal data in one iteration of the loop. Fix incorrect default "width" value, and allow negative widths via *. Consume away any length specifiers (l and h). --- printf.c | 121 +-- 1 file changed, 54 insertions(+), 67 deletions(-) diff --git a/printf.c b/printf.c index 039dac7..aa0a2df 100644 --- a/printf.c +++ b/printf.c @@ -9,6 +9,8 @@ #include "utf.h" #include "util.h" +static const char FLAGS[] = "#0- +"; + static void usage(void) { @@ -18,12 +20,13 @@ usage(void) int main(int argc, char *argv[]) { - Rune *rarg; + Rune rarg; + char fmtbuf[sizeof(FLAGS) + sizeof("%*.*ll")]; size_t i, j, argi, lastargi, formatlen, blen; long long num; double dou; int cooldown = 0, width, precision, ret = 0; - char *format, *tmp, *arg, *fmt, flag; + char *format, *tmp, *arg; argv0 = argv[0]; if (argc < 2) @@ -38,40 +41,46 @@ main(int argc, char *argv[]) if (formatlen == 0) return 0; lastargi = 0; - for (i = 0, argi = 2; !cooldown || i < formatlen; i++, i = cooldown ? i : (i % formatlen)) { + for (i = 0, argi = 2; +!cooldown || i < formatlen; +cooldown = argi >= argc, i = (i + 1) % (formatlen + cooldown)) { + char flags[sizeof(FLAGS)] = { 0 }; if (i == 0) { if (lastargi == argi) break; lastargi = argi; } if (format[i] != '%') { - putchar(format[i]); + size_t n = strcspn(format + i + 1, "%"); + fwrite(format + i, sizeof(*format), n + 1, stdout); + i += n; continue; } - /* flag */ - for (flag = '\0', i++; strchr("#-+ 0", format[i]); i++) { - flag = format[i]; + if (format[++i] == '%') { + putchar('%'); + continue; } + /* flag */ + for (; i < formatlen && strchr(FLAGS, format[i]); i++) + flags[strcspn(flags, (const char[]){ format[i], '\0' })] = format[i]; + /* field width */ - width = -1; + width = 0; if (format[i] == '*') { if (argi < argc) - width = estrtonum(argv[argi++], 0, INT_MAX); - else - cooldown = 1; + width = estrtonum(argv[argi++], INT_MIN, INT_MAX); i++; } else { - j = i; - for (; strchr("+-0123456789", format[i]); i++); - if (j != i) { - tmp = estrndup(format + j, i - j); - width = estrtonum(tmp, 0, INT_MAX); - free(tmp); - } else { - width = 0; + num = strtoll(format + i, &tmp, 10); + if (num > INT_MAX) { + if (tmp - format - i > INT_MAX) + tmp = format + i + INT_MAX; + eprintf("field width %.*s not in range\n", (int)(tmp - format - i), format + i); } + width = num; + i = tmp - format; } /* field precision */ @@ -80,33 +89,25 @@ main(int argc, char *argv[]) if (format[++i] == '*') { if (argi < argc) precision = estrtonum(argv[argi++], 0, INT_MAX); - else - cooldown = 1; i++; } else { - j = i; - for (; strchr("+-0123456789", format[i]); i++); - if (j != i) { - tmp = estrndup(format + j, i - j); - precision = estrtonum(tmp, 0, INT_MAX); - free(tmp); - } else { - precision = 0; + num = strtoll(format
Re: [hackers] [dwm][PATCH] Update monitor positions also on removal
On 9.4.2022 13.51, Hiltjo Posthuma wrote: I've heard similar reports with monitor plugging and unplugging not working nicely. Can someone test this patch and report back these conditions or if it improves things? FWIW I've been using this change ever since I submitted it, and plug and unplug extra monitors multiple times a day, and have not needed dwm restarts ever since (don't even use the restart patch anymore =). -- Santtu
[hackers] [dwm][PATCH] Update monitor positions also on removal
When monitors are removed, the coordinates of existing monitors may change, if the removed monitors had smaller coordinates than the remaining ones. Remove special case handling so that the same update-if-necessary loop is run also in the case when monitors are removed. --- dwm.c | 68 +-- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/dwm.c b/dwm.c index a96f33c..85419e3 100644 --- a/dwm.c +++ b/dwm.c @@ -1874,42 +1874,42 @@ updategeom(void) memcpy(&unique[j++], &info[i], sizeof(XineramaScreenInfo)); XFree(info); nn = j; - if (n <= nn) { /* new monitors available */ - for (i = 0; i < (nn - n); i++) { - for (m = mons; m && m->next; m = m->next); - if (m) - m->next = createmon(); - else - mons = createmon(); + + /* new monitors if nn > n */ + for (i = n; i < nn; i++) { + for (m = mons; m && m->next; m = m->next); + if (m) + m->next = createmon(); + else + mons = createmon(); + } + for (i = 0, m = mons; i < nn && m; m = m->next, i++) + if (i >= n + || unique[i].x_org != m->mx || unique[i].y_org != m->my + || unique[i].width != m->mw || unique[i].height != m->mh) + { + dirty = 1; + m->num = i; + m->mx = m->wx = unique[i].x_org; + m->my = m->wy = unique[i].y_org; + m->mw = m->ww = unique[i].width; + m->mh = m->wh = unique[i].height; + updatebarpos(m); } - for (i = 0, m = mons; i < nn && m; m = m->next, i++) - if (i >= n - || unique[i].x_org != m->mx || unique[i].y_org != m->my - || unique[i].width != m->mw || unique[i].height != m->mh) - { - dirty = 1; - m->num = i; - m->mx = m->wx = unique[i].x_org; - m->my = m->wy = unique[i].y_org; - m->mw = m->ww = unique[i].width; - m->mh = m->wh = unique[i].height; - updatebarpos(m); - } - } else { /* less monitors available nn < n */ - for (i = nn; i < n; i++) { - for (m = mons; m && m->next; m = m->next); - while ((c = m->clients)) { - dirty = 1; - m->clients = c->next; - detachstack(c); - c->mon = mons; - attach(c); - attachstack(c); - } - if (m == selmon) - selmon = mons; - cleanupmon(m); + /* removed monitors if n > nn */ + for (i = nn; i < n; i++) { + for (m = mons; m && m->next; m = m->next); + while ((c = m->clients)) { + dirty = 1; + m->clients = c->next; + detachstack(c); + c->mon = mons; + attach(c); + attachstack(c); } + if (m == selmon) + selmon = mons; + cleanupmon(m); } free(unique); } else -- 2.32.0
[hackers] [st][PATCH] Delay redrawals on palette changes
Build on auto-sync and only mark window dirty on palette changes and let the event handler do the actual draw. --- st.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/st.c b/st.c index 51049ba..c71fa06 100644 --- a/st.c +++ b/st.c @@ -1927,7 +1927,7 @@ strhandle(void) else if (xsetcolorname(defaultfg, p)) fprintf(stderr, "erresc: invalid foreground color: %s\n", p); else - redraw(); + tfulldirt(); return; case 11: if (narg < 2) @@ -1940,7 +1940,7 @@ strhandle(void) else if (xsetcolorname(defaultbg, p)) fprintf(stderr, "erresc: invalid background color: %s\n", p); else - redraw(); + tfulldirt(); return; case 12: if (narg < 2) @@ -1953,7 +1953,7 @@ strhandle(void) else if (xsetcolorname(defaultcs, p)) fprintf(stderr, "erresc: invalid cursor color: %s\n", p); else - redraw(); + tfulldirt(); return; case 4: /* color set */ if (narg < 3) @@ -1975,7 +1975,7 @@ strhandle(void) * TODO if defaultbg color is changed, borders * are dirty */ - redraw(); + tfulldirt(); } return; } -- 2.32.0