Re: [PATCH] patch: handle files with no final newline

"Roberto A. Foglietta via busybox" <[email protected]> Sun, 19 Apr 2026 16:15:58 +0200
Newsgroups gmane.linux.busybox
Message-ID <CAJGKYO72wWpS2aeF1J=Y0aHRGVVU7Mq_Vwf=J8476RngsjK7nA@mail.gmail.com>
On Sun, 19 Apr 2026 at 12:38, Roberto A. Foglietta
<[email protected]> wrote:
>
> On Sun, 19 Apr 2026 at 11:58, Roberto A. Foglietta
> <[email protected]> wrote:
> >
> > On Sun, 19 Apr 2026 at 11:04, Ron Yorston via busybox
> > <[email protected]> wrote:
>
> > if(*patchline == '\\') {
> > do_stuff; continue;
> > }
> >
> > Using keyword "continue" into a "switch" isn't a good idea because the
> > "continue"/"break" duo would not refer to the same level of nested
> > coding: "break" to the "switch" and "continue" to the upper loop.
> > Therefore if(new case) continue; if(like before) is a better stylistic
> > choice rather than injecting a "continue" into a "switch"/"case".
> > However, it is not a mistake by itself.
> >
>
> Ron's patch applied and on the top of it another one for code janitoring.
>
> https://github.com/robang74/busybox/commits/bugfixes/

Janitoring patch updated v3, and:

commit 2e1294489e34ef084f2c66294a051c23ac89b9e1 (HEAD -> bugfixes,
origin/bugfixes)
Author: Roberto A. Foglietta <[email protected]>
Date:   Sun Apr 19 16:04:10 2026 +0200

    handle files with no final newline, !ungetc EOF

    The Ron's patch peek ahead and introduces an ungetc EOF potentially
    fragile when busybox is compiled against libc (old) alternatives.

    Signed-off-by: Roberto A. Foglietta <[email protected]>

diff --git a/editors/patch.c b/editors/patch.c
index 3a915b844..5a695a978 100644
--- a/editors/patch.c
+++ b/editors/patch.c
@@ -454,7 +454,7 @@ int patch_main(int argc UNUSED_PARAM, char **argv)
                                        // Peek ahead for '\ No
newline at end of file', mark
                                        // previous line, if it exists.
                                        int c = getchar();
-                                       ungetc(c, stdin);
+                                       if (c != EOF) ungetc(c, stdin);
                                        if (c == '\\') {
                                                if (TT.current_hunk->prev)

TT.current_hunk->prev->no_newline = TRUE;

However, I still puzzled about the use of getc to peek ahead because
how the do_line() is changed instead of something like

        if (TT.state > 1 && *dlist->data != TT.state)
                fdprintf(TT.state == 2 ? 2 : TT.fileout,
-                       "%s\n", dlist->data + (TT.state > 3 ? 1 : 0));
+ "%s%s", new_line ? "\n" : "", string

deciding the next round if append a '\n' or not, but possibly I did
not get in full the logic behind patch.c and the "prev" element.

Anyway, protecting ungetc by EOF is optional, by standard behaviour
should not cause any harm but some old/alternatives than libc
are/might be buggy about it.

Best regards, R-